diff options
author | Cedric BAIL <cedric@osg.samsung.com> | 2016-12-06 16:22:56 -0800 |
---|---|---|
committer | Cedric BAIL <cedric@osg.samsung.com> | 2016-12-06 16:34:40 -0800 |
commit | c8fef4a5567526eb2af9326c24f3a330645e59a0 (patch) | |
tree | 05bc7216eda9c6c6f402795bb490b024f0c4ce01 | |
parent | 889944fefef45ee9d715656427d6f1c523ec9867 (diff) | |
download | efl-c8fef4a5567526eb2af9326c24f3a330645e59a0.tar.gz |
emile: add infrastructure for callback to request what to do with image.
First use of this infrastructure is to make JPEG decoding interruptible.
-rw-r--r-- | src/lib/emile/emile_image.c | 48 | ||||
-rw-r--r-- | src/lib/emile/emile_image.h | 32 |
2 files changed, 79 insertions, 1 deletions
diff --git a/src/lib/emile/emile_image.c b/src/lib/emile/emile_image.c index c7baff8ea1..59af9b475c 100644 --- a/src/lib/emile/emile_image.c +++ b/src/lib/emile/emile_image.c @@ -125,6 +125,9 @@ struct _Emile_Image Eina_Bool (*data)(Emile_Image *image, Emile_Image_Property *prop, unsigned int property_size, void *pixels, Emile_Image_Load_Error *error); void (*close)(Emile_Image *image); + Emile_Action_Cb cancelled; + const void *cancelled_data; + Emile_Colorspace cspace; Eina_Bool bin_source : 1; @@ -136,6 +139,27 @@ struct _Emile_Image Eina_Bool load_opts : 1; }; +static inline Eina_Bool +_emile_image_cancelled_is(Emile_Image *image) +{ + if (!image->cancelled) return EINA_FALSE; + return image->cancelled((void*) image->cancelled_data, image, EMILE_ACTION_CANCELLED); +} + +#define EMILE_IMAGE_TASK_CHECK(Image, Count, Mask, Error, Error_Handler) \ + do { \ + Count++; \ + if ((Count & Mask) == Mask) \ + { \ + Count = 0; \ + if (_emile_image_cancelled_is(Image)) \ + { \ + *Error = EMILE_IMAGE_LOAD_ERROR_CANCELLED; \ + goto Error_Handler; \ + } \ + } \ + } while (0); + static const unsigned char * _emile_image_file_source_map(Emile_Image *image, unsigned int *length) { @@ -1629,6 +1653,7 @@ _emile_jpeg_data(Emile_Image *image, Eina_Bool ptrag_free = EINA_FALSE; Eina_Bool r = EINA_FALSE; unsigned int length; + unsigned short count = 0; if (sizeof(Emile_Image_Property) != property_size) return EINA_FALSE; @@ -1852,6 +1877,9 @@ _emile_jpeg_data(Emile_Image *image, line[i] = data + (i * w * 4); for (l = 0; l < h; l += cinfo.rec_outbuf_height) { + // Check for continuing every 16 scanlines fetch + EMILE_IMAGE_TASK_CHECK(image, count, 0xF, error, on_error); + jpeg_read_scanlines(&cinfo, line, cinfo.rec_outbuf_height); scans = cinfo.rec_outbuf_height; if ((h - l) < scans) @@ -1998,6 +2026,9 @@ _emile_jpeg_data(Emile_Image *image, line[i] = data + (i * w * 3); for (l = 0; l < h; l += cinfo.rec_outbuf_height) { + // Check for continuing every 16 scanlines fetch + EMILE_IMAGE_TASK_CHECK(image, count, 0xF, error, on_error); + jpeg_read_scanlines(&cinfo, line, cinfo.rec_outbuf_height); scans = cinfo.rec_outbuf_height; if ((h - l) < scans) @@ -2060,6 +2091,9 @@ _emile_jpeg_data(Emile_Image *image, line[i] = data + (i * w); for (l = 0; l < h; l += cinfo.rec_outbuf_height) { + // Check for continuing every 16 scanlines fetch + EMILE_IMAGE_TASK_CHECK(image, count, 0xF, error, on_error); + jpeg_read_scanlines(&cinfo, line, cinfo.rec_outbuf_height); scans = cinfo.rec_outbuf_height; if ((h - l) < scans) @@ -2411,6 +2445,17 @@ emile_image_jpeg_file_open(Eina_File *source, } EAPI void +emile_image_register(Emile_Image *image, Emile_Action_Cb callback, Emile_Action action, const void *data) +{ + if (!image) return ; + // We only handle one type of callback for now + if (action != EMILE_ACTION_CANCELLED) return ; + + image->cancelled_data = data; + image->cancelled = callback; +} + +EAPI void emile_image_close(Emile_Image *image) { if (!image) @@ -2476,6 +2521,9 @@ emile_load_error_str(Emile_Image *source EINA_UNUSED, case EMILE_IMAGE_LOAD_ERROR_UNKNOWN_FORMAT: return "Unexpected file format."; + + case EMILE_IMAGE_LOAD_ERROR_CANCELLED: + return "Loading was stopped by an external request."; } return NULL; } diff --git a/src/lib/emile/emile_image.h b/src/lib/emile/emile_image.h index 9d6f1af8e0..0eef713171 100644 --- a/src/lib/emile/emile_image.h +++ b/src/lib/emile/emile_image.h @@ -102,7 +102,8 @@ typedef enum _Emile_Image_Load_Error EMILE_IMAGE_LOAD_ERROR_PERMISSION_DENIED = 3, /**< Permission denied to an existing file (or path) */ EMILE_IMAGE_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED = 4, /**< Allocation of resources failure prevented load */ EMILE_IMAGE_LOAD_ERROR_CORRUPT_FILE = 5, /**< File corrupt (but was detected as a known format) */ - EMILE_IMAGE_LOAD_ERROR_UNKNOWN_FORMAT = 6 /**< File is not a known format */ + EMILE_IMAGE_LOAD_ERROR_UNKNOWN_FORMAT = 6, /**< File is not a known format */ + EMILE_IMAGE_LOAD_ERROR_CANCELLED = 7 /**< File loading has been cancelled */ } Emile_Image_Load_Error; /**< Emile image load error codes one can get - see emile_load_error_str() too. */ /** @@ -141,6 +142,25 @@ typedef struct _Emile_Image_Animated Emile_Image_Animated; */ typedef struct _Emile_Image_Property Emile_Image_Property; +/** + * @enum _Emile_Action + * @typedef Emile_Action + * What action emile is refering to. + * @since 1.19 + */ +typedef enum _Emile_Action +{ + EMILE_ACTION_NONE = 0, + EMILE_ACTION_CANCELLED = 1 +} Emile_Action; + +/** + * @typedef Emile_Action_Cb + * A callback triggered by emile to learn what to do about a specific action. + * @since 1.19 + */ +typedef Eina_Bool (*Emile_Action_Cb)(void *data, Emile_Image *image, Emile_Action action); + struct _Emile_Image_Property { struct @@ -286,6 +306,16 @@ EAPI Eina_Bool emile_image_head(Emile_Image * image, Emile_Image_Property * prop EAPI Eina_Bool emile_image_data(Emile_Image * image, Emile_Image_Property * prop, unsigned int property_size, void *pixels, Emile_Image_Load_Error * error); /** + * Register a callback for emile to ask what to do during the processing of an image + * + * @param image The Emile_Image handler to register on. + * @param callback The callback to use + * @param action The action this callback is triggered on. + * @since 1.19 + */ +EAPI void emile_image_register(Emile_Image *image, Emile_Action_Cb callback, Emile_Action action, const void *data); + +/** * Close an opened image handler. * * @param source The handler to close. |