Skip to content
This repository was archived by the owner on Sep 28, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
# Next

* Add support to reading images from a `bytes` buffer, e.g.
```python
with open("chicago.jpg", "rb") as f:
img = accimage.Image(f.read())
```

# v0.1.1

* Bug fix: Horizontal crops prior to v0.1.1 didn't work.
Expand Down
1 change: 1 addition & 0 deletions accimage.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ typedef struct {

void image_copy_deinterleave(ImageObject* self, unsigned char* output_buffer);
void image_copy_deinterleave_float(ImageObject* self, float* output_buffer);
void image_from_buffer(ImageObject* self, void* buf, size_t size);
void image_from_jpeg(ImageObject* self, const char* path);
void image_resize(ImageObject* self, int new_height, int new_width, int antialiasing);
void image_flip_left_right(ImageObject* self);
Expand Down
19 changes: 14 additions & 5 deletions accimagemodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -242,13 +242,22 @@ static PyTypeObject Image_Type = {
};

static int Image_init(ImageObject *self, PyObject *args, PyObject *kwds) {
static char* argnames[] = { "path", NULL };
const char *path;

if (!PyArg_ParseTupleAndKeywords(args, kwds, "s", argnames, &path))
return -1;

image_from_jpeg(self, path);
if (PyArg_ParseTuple(args, "s", &path)) {
image_from_jpeg(self, path);
}
else {
Py_buffer buffer;

PyErr_Clear();
if (PyArg_ParseTuple(args, "y*", &buffer)) {
void* buf = buffer.buf;
Py_ssize_t size = buffer.len;
image_from_buffer(self, buf, size);
PyBuffer_Release(&buffer);
}
}

return PyErr_Occurred() ? -1 : 0;
}
Expand Down
33 changes: 22 additions & 11 deletions jpegloader.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,26 +20,17 @@ static void accimage_jpeg_error_exit(j_common_ptr cinfo) {
}


void image_from_jpeg(ImageObject* self, const char* path) {
void image_from_file(ImageObject* self, FILE* file) {
struct jpeg_decompress_struct state = { 0 };
struct accimage_jpeg_error_mgr jpeg_error;
FILE* file = NULL;
unsigned char* buffer = NULL;

file = fopen(path, "rb");
if (file == NULL) {
PyErr_Format(PyExc_IOError, "failed to open file %s", path);
goto cleanup;
}

state.err = jpeg_std_error(&jpeg_error.pub);
jpeg_error.pub.error_exit = accimage_jpeg_error_exit;
if (setjmp(jpeg_error.setjmp_buffer)) {
char error_message[JMSG_LENGTH_MAX];
(*state.err->format_message)((j_common_ptr) &state, error_message);
PyErr_Format(PyExc_IOError, "JPEG decoding failed: %s in file %s",
error_message, path);

PyErr_Format(PyExc_IOError, "JPEG decoding failed: %s", error_message);
goto cleanup;
}

Expand Down Expand Up @@ -87,3 +78,23 @@ void image_from_jpeg(ImageObject* self, const char* path) {
fclose(file);
}
}

void image_from_buffer(ImageObject* self, void* buf, size_t size) {
FILE* source = fmemopen(buf, size, "rb");
if (source == NULL) {
PyErr_Format(PyExc_IOError, "failed to call fmemopen on buffer");
return;
}

image_from_file(self, source);
}

void image_from_jpeg(ImageObject* self, const char* path) {
FILE* file = file = fopen(path, "rb");
if (file == NULL) {
PyErr_Format(PyExc_IOError, "failed to open file %s", path);
return;
}

image_from_file(self, file);
}
11 changes: 11 additions & 0 deletions test.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,17 @@ def test_reading_image():
assert image.height == 931


def test_reading_image_from_memory():
from_file = accimage.Image("chicago.jpg")
bytes = open("chicago.jpg", "rb").read()
from_bytes = accimage.Image(bytes)
if SAVE_IMAGES:
save_image('test_reading_image_from_memory.jpg', from_bytes)
assert from_bytes.width == 1920
assert from_bytes.height == 931
np.testing.assert_array_equal(image_to_np(from_file), image_to_np(from_bytes))


def test_resizing():
image = accimage.Image("chicago.jpg")

Expand Down