summaryrefslogtreecommitdiff
path: root/src/lib/emile
diff options
context:
space:
mode:
authorCedric BAIL <cedric@osg.samsung.com>2016-12-06 16:22:56 -0800
committerCedric BAIL <cedric@osg.samsung.com>2016-12-06 16:34:40 -0800
commitc8fef4a5567526eb2af9326c24f3a330645e59a0 (patch)
tree05bc7216eda9c6c6f402795bb490b024f0c4ce01 /src/lib/emile
parent889944fefef45ee9d715656427d6f1c523ec9867 (diff)
emile: add infrastructure for callback to request what to do with image.
First use of this infrastructure is to make JPEG decoding interruptible.
Diffstat (limited to 'src/lib/emile')
-rw-r--r--src/lib/emile/emile_image.c48
-rw-r--r--src/lib/emile/emile_image.h32
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
125 Eina_Bool (*data)(Emile_Image *image, Emile_Image_Property *prop, unsigned int property_size, void *pixels, Emile_Image_Load_Error *error); 125 Eina_Bool (*data)(Emile_Image *image, Emile_Image_Property *prop, unsigned int property_size, void *pixels, Emile_Image_Load_Error *error);
126 void (*close)(Emile_Image *image); 126 void (*close)(Emile_Image *image);
127 127
128 Emile_Action_Cb cancelled;
129 const void *cancelled_data;
130
128 Emile_Colorspace cspace; 131 Emile_Colorspace cspace;
129 132
130 Eina_Bool bin_source : 1; 133 Eina_Bool bin_source : 1;
@@ -136,6 +139,27 @@ struct _Emile_Image
136 Eina_Bool load_opts : 1; 139 Eina_Bool load_opts : 1;
137}; 140};
138 141
142static inline Eina_Bool
143_emile_image_cancelled_is(Emile_Image *image)
144{
145 if (!image->cancelled) return EINA_FALSE;
146 return image->cancelled((void*) image->cancelled_data, image, EMILE_ACTION_CANCELLED);
147}
148
149#define EMILE_IMAGE_TASK_CHECK(Image, Count, Mask, Error, Error_Handler) \
150 do { \
151 Count++; \
152 if ((Count & Mask) == Mask) \
153 { \
154 Count = 0; \
155 if (_emile_image_cancelled_is(Image)) \
156 { \
157 *Error = EMILE_IMAGE_LOAD_ERROR_CANCELLED; \
158 goto Error_Handler; \
159 } \
160 } \
161 } while (0);
162
139static const unsigned char * 163static const unsigned char *
140_emile_image_file_source_map(Emile_Image *image, unsigned int *length) 164_emile_image_file_source_map(Emile_Image *image, unsigned int *length)
141{ 165{
@@ -1629,6 +1653,7 @@ _emile_jpeg_data(Emile_Image *image,
1629 Eina_Bool ptrag_free = EINA_FALSE; 1653 Eina_Bool ptrag_free = EINA_FALSE;
1630 Eina_Bool r = EINA_FALSE; 1654 Eina_Bool r = EINA_FALSE;
1631 unsigned int length; 1655 unsigned int length;
1656 unsigned short count = 0;
1632 1657
1633 if (sizeof(Emile_Image_Property) != property_size) 1658 if (sizeof(Emile_Image_Property) != property_size)
1634 return EINA_FALSE; 1659 return EINA_FALSE;
@@ -1852,6 +1877,9 @@ _emile_jpeg_data(Emile_Image *image,
1852 line[i] = data + (i * w * 4); 1877 line[i] = data + (i * w * 4);
1853 for (l = 0; l < h; l += cinfo.rec_outbuf_height) 1878 for (l = 0; l < h; l += cinfo.rec_outbuf_height)
1854 { 1879 {
1880 // Check for continuing every 16 scanlines fetch
1881 EMILE_IMAGE_TASK_CHECK(image, count, 0xF, error, on_error);
1882
1855 jpeg_read_scanlines(&cinfo, line, cinfo.rec_outbuf_height); 1883 jpeg_read_scanlines(&cinfo, line, cinfo.rec_outbuf_height);
1856 scans = cinfo.rec_outbuf_height; 1884 scans = cinfo.rec_outbuf_height;
1857 if ((h - l) < scans) 1885 if ((h - l) < scans)
@@ -1998,6 +2026,9 @@ _emile_jpeg_data(Emile_Image *image,
1998 line[i] = data + (i * w * 3); 2026 line[i] = data + (i * w * 3);
1999 for (l = 0; l < h; l += cinfo.rec_outbuf_height) 2027 for (l = 0; l < h; l += cinfo.rec_outbuf_height)
2000 { 2028 {
2029 // Check for continuing every 16 scanlines fetch
2030 EMILE_IMAGE_TASK_CHECK(image, count, 0xF, error, on_error);
2031
2001 jpeg_read_scanlines(&cinfo, line, cinfo.rec_outbuf_height); 2032 jpeg_read_scanlines(&cinfo, line, cinfo.rec_outbuf_height);
2002 scans = cinfo.rec_outbuf_height; 2033 scans = cinfo.rec_outbuf_height;
2003 if ((h - l) < scans) 2034 if ((h - l) < scans)
@@ -2060,6 +2091,9 @@ _emile_jpeg_data(Emile_Image *image,
2060 line[i] = data + (i * w); 2091 line[i] = data + (i * w);
2061 for (l = 0; l < h; l += cinfo.rec_outbuf_height) 2092 for (l = 0; l < h; l += cinfo.rec_outbuf_height)
2062 { 2093 {
2094 // Check for continuing every 16 scanlines fetch
2095 EMILE_IMAGE_TASK_CHECK(image, count, 0xF, error, on_error);
2096
2063 jpeg_read_scanlines(&cinfo, line, cinfo.rec_outbuf_height); 2097 jpeg_read_scanlines(&cinfo, line, cinfo.rec_outbuf_height);
2064 scans = cinfo.rec_outbuf_height; 2098 scans = cinfo.rec_outbuf_height;
2065 if ((h - l) < scans) 2099 if ((h - l) < scans)
@@ -2411,6 +2445,17 @@ emile_image_jpeg_file_open(Eina_File *source,
2411} 2445}
2412 2446
2413EAPI void 2447EAPI void
2448emile_image_register(Emile_Image *image, Emile_Action_Cb callback, Emile_Action action, const void *data)
2449{
2450 if (!image) return ;
2451 // We only handle one type of callback for now
2452 if (action != EMILE_ACTION_CANCELLED) return ;
2453
2454 image->cancelled_data = data;
2455 image->cancelled = callback;
2456}
2457
2458EAPI void
2414emile_image_close(Emile_Image *image) 2459emile_image_close(Emile_Image *image)
2415{ 2460{
2416 if (!image) 2461 if (!image)
@@ -2476,6 +2521,9 @@ emile_load_error_str(Emile_Image *source EINA_UNUSED,
2476 2521
2477 case EMILE_IMAGE_LOAD_ERROR_UNKNOWN_FORMAT: 2522 case EMILE_IMAGE_LOAD_ERROR_UNKNOWN_FORMAT:
2478 return "Unexpected file format."; 2523 return "Unexpected file format.";
2524
2525 case EMILE_IMAGE_LOAD_ERROR_CANCELLED:
2526 return "Loading was stopped by an external request.";
2479 } 2527 }
2480 return NULL; 2528 return NULL;
2481} 2529}
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
102 EMILE_IMAGE_LOAD_ERROR_PERMISSION_DENIED = 3, /**< Permission denied to an existing file (or path) */ 102 EMILE_IMAGE_LOAD_ERROR_PERMISSION_DENIED = 3, /**< Permission denied to an existing file (or path) */
103 EMILE_IMAGE_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED = 4, /**< Allocation of resources failure prevented load */ 103 EMILE_IMAGE_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED = 4, /**< Allocation of resources failure prevented load */
104 EMILE_IMAGE_LOAD_ERROR_CORRUPT_FILE = 5, /**< File corrupt (but was detected as a known format) */ 104 EMILE_IMAGE_LOAD_ERROR_CORRUPT_FILE = 5, /**< File corrupt (but was detected as a known format) */
105 EMILE_IMAGE_LOAD_ERROR_UNKNOWN_FORMAT = 6 /**< File is not a known format */ 105 EMILE_IMAGE_LOAD_ERROR_UNKNOWN_FORMAT = 6, /**< File is not a known format */
106 EMILE_IMAGE_LOAD_ERROR_CANCELLED = 7 /**< File loading has been cancelled */
106} Emile_Image_Load_Error; /**< Emile image load error codes one can get - see emile_load_error_str() too. */ 107} Emile_Image_Load_Error; /**< Emile image load error codes one can get - see emile_load_error_str() too. */
107 108
108/** 109/**
@@ -141,6 +142,25 @@ typedef struct _Emile_Image_Animated Emile_Image_Animated;
141 */ 142 */
142typedef struct _Emile_Image_Property Emile_Image_Property; 143typedef struct _Emile_Image_Property Emile_Image_Property;
143 144
145/**
146 * @enum _Emile_Action
147 * @typedef Emile_Action
148 * What action emile is refering to.
149 * @since 1.19
150 */
151typedef enum _Emile_Action
152{
153 EMILE_ACTION_NONE = 0,
154 EMILE_ACTION_CANCELLED = 1
155} Emile_Action;
156
157/**
158 * @typedef Emile_Action_Cb
159 * A callback triggered by emile to learn what to do about a specific action.
160 * @since 1.19
161 */
162typedef Eina_Bool (*Emile_Action_Cb)(void *data, Emile_Image *image, Emile_Action action);
163
144struct _Emile_Image_Property 164struct _Emile_Image_Property
145{ 165{
146 struct 166 struct
@@ -286,6 +306,16 @@ EAPI Eina_Bool emile_image_head(Emile_Image * image, Emile_Image_Property * prop
286EAPI Eina_Bool emile_image_data(Emile_Image * image, Emile_Image_Property * prop, unsigned int property_size, void *pixels, Emile_Image_Load_Error * error); 306EAPI Eina_Bool emile_image_data(Emile_Image * image, Emile_Image_Property * prop, unsigned int property_size, void *pixels, Emile_Image_Load_Error * error);
287 307
288/** 308/**
309 * Register a callback for emile to ask what to do during the processing of an image
310 *
311 * @param image The Emile_Image handler to register on.
312 * @param callback The callback to use
313 * @param action The action this callback is triggered on.
314 * @since 1.19
315 */
316EAPI void emile_image_register(Emile_Image *image, Emile_Action_Cb callback, Emile_Action action, const void *data);
317
318/**
289 * Close an opened image handler. 319 * Close an opened image handler.
290 * 320 *
291 * @param source The handler to close. 321 * @param source The handler to close.