jmp_buf setjmp_buffer;
};
-struct jpeg_membuf_src
-{
- struct jpeg_source_mgr pub;
-
- const unsigned char *buf;
- size_t len;
- struct jpeg_membuf_src *self;
-};
-
-static void
-_eet_jpeg_membuf_src_init(j_decompress_ptr cinfo)
-{
- /* FIXME: Use attribute unused */
- (void)cinfo;
-}
-
-static boolean
-_eet_jpeg_membuf_src_fill(j_decompress_ptr cinfo)
-{
- static const JOCTET jpeg_eoi[2] = { 0xFF, JPEG_EOI };
- struct jpeg_membuf_src *src = (struct jpeg_membuf_src *)cinfo->src;
-
- src->pub.bytes_in_buffer = sizeof(jpeg_eoi);
- src->pub.next_input_byte = jpeg_eoi;
-
- return TRUE;
-}
-
-static void
-_eet_jpeg_membuf_src_skip(j_decompress_ptr cinfo,
- long num_bytes)
-{
- struct jpeg_membuf_src *src = (struct jpeg_membuf_src *)cinfo->src;
-
- src->pub.bytes_in_buffer -= num_bytes;
- src->pub.next_input_byte += num_bytes;
-}
-
-static void
-_eet_jpeg_membuf_src_term(j_decompress_ptr cinfo)
-{
- struct jpeg_membuf_src *src = ((struct jpeg_membuf_src *)cinfo->src)->self;
-
- free(src);
- cinfo->src = NULL;
-}
-
-static int
-eet_jpeg_membuf_src(j_decompress_ptr cinfo,
- const void *buf,
- size_t len)
-{
- struct jpeg_membuf_src *src;
-
- src = calloc(1, sizeof(*src));
- if (!src)
- return -1;
-
- src->self = src;
-
- cinfo->src = &src->pub;
- src->buf = buf;
- src->len = len;
- src->pub.init_source = _eet_jpeg_membuf_src_init;
- src->pub.fill_input_buffer = _eet_jpeg_membuf_src_fill;
- src->pub.skip_input_data = _eet_jpeg_membuf_src_skip;
- src->pub.resync_to_restart = jpeg_resync_to_restart;
- src->pub.term_source = _eet_jpeg_membuf_src_term;
- src->pub.bytes_in_buffer = src->len;
- src->pub.next_input_byte = src->buf;
-
- return 0;
-}
-
struct jpeg_membuf_dst
{
struct jpeg_destination_mgr pub;
_eet_jpeg_membuf_dst_init(j_compress_ptr cinfo)
{
/* FIXME: Use eina attribute */
- (void)cinfo;
+ (void)cinfo;
}
static boolean
return TRUE;
}
- dst->pub.next_output_byte =
- buf + ((unsigned char *)dst->pub.next_output_byte - dst->buf);
- dst->buf = buf;
- dst->pub.free_in_buffer += dst->len;
- dst->len *= 2;
+ dst->pub.next_output_byte =
+ buf + ((unsigned char *)dst->pub.next_output_byte - dst->buf);
+ dst->buf = buf;
+ dst->pub.free_in_buffer += dst->len;
+ dst->len *= 2;
- return FALSE;
+ return FALSE;
}
static void
/*---*/
-static void _eet_image_jpeg_error_exit_cb(j_common_ptr cinfo);
-static void _eet_image_jpeg_output_message_cb(j_common_ptr cinfo);
-static void _eet_image_jpeg_emit_message_cb(j_common_ptr cinfo,
- int msg_level);
-
static int
eet_data_image_jpeg_header_decode(const void *data,
int size,
unsigned int *w,
unsigned int *h)
{
- struct jpeg_decompress_struct cinfo;
- struct _JPEG_error_mgr jerr;
+ Emile_Image_Load_Opts opts;
+ Emile_Image_Property prop;
+ Eina_Binbuf *bin;
+ Emile_Image *image;
+ Emile_Image_Load_Error error;
+ int r = 0;
- memset(&cinfo, 0, sizeof (struct jpeg_decompress_struct));
+ bin = eina_binbuf_manage_read_only_new_length(data, size);
+ if (!bin) return 0;
- cinfo.err = jpeg_std_error(&(jerr.pub));
- jerr.pub.error_exit = _eet_image_jpeg_error_exit_cb;
- jerr.pub.emit_message = _eet_image_jpeg_emit_message_cb;
- jerr.pub.output_message = _eet_image_jpeg_output_message_cb;
- if (setjmp(jerr.setjmp_buffer))
- return 0;
+ memset(&opts, 0, sizeof (Emile_Image_Load_Opts));
- jpeg_create_decompress(&cinfo);
+ image = emile_image_jpeg_memory_open(bin, &opts, NULL, &error);
+ if (!image) goto on_error;
- if (eet_jpeg_membuf_src(&cinfo, data, (size_t)size))
- {
- jpeg_destroy_decompress(&cinfo);
- return 0;
- }
+ memset(&prop, 0, sizeof (prop));
- jpeg_read_header(&cinfo, TRUE);
- cinfo.do_fancy_upsampling = FALSE;
- cinfo.do_block_smoothing = FALSE;
- jpeg_start_decompress(&cinfo);
+ if (!emile_image_head(image, &prop, sizeof (Emile_Image_Property), &error))
+ goto on_error;
- /* head decoding */
- *w = cinfo.output_width;
- *h = cinfo.output_height;
+ *w = prop.w;
+ *h = prop.h;
- free(cinfo.src);
- cinfo.src = NULL;
+ if (*w > 0 && *w <= 8192 &&
+ *h > 0 && *h <= 8192)
+ r = 1;
- jpeg_destroy_decompress(&cinfo);
+ on_error:
+ fprintf(stderr, "eet_data_image_jpeg_header_decode: %i [%i, %i]\n", r, *w, *h);
- if ((*w < 1) || (*h < 1) || (*w > 8192) || (*h > 8192))
- return 0;
+ emile_image_close(image);
+ eina_binbuf_free(bin);
- return 1;
+ return r;
}
static int
unsigned int h,
unsigned int row_stride)
{
- struct jpeg_decompress_struct cinfo;
- struct _JPEG_error_mgr jerr;
- unsigned char *ptr, *line[16], *tdata = NULL;
- unsigned int *ptr2, *tmp;
- unsigned int iw, ih;
- unsigned int x, y, l, scans;
- unsigned int i;
+ Emile_Image_Load_Opts opts;
+ Emile_Image_Property prop;
+ Emile_Image *image;
+ Eina_Binbuf *bin;
+ Emile_Image_Load_Error error;
+ int r = 0;
/* FIXME: handle src_x, src_y and row_stride correctly */
if (!d)
return 0;
- memset(&cinfo, 0, sizeof (struct jpeg_decompress_struct));
-
- cinfo.err = jpeg_std_error(&(jerr.pub));
- jerr.pub.error_exit = _eet_image_jpeg_error_exit_cb;
- jerr.pub.emit_message = _eet_image_jpeg_emit_message_cb;
- jerr.pub.output_message = _eet_image_jpeg_output_message_cb;
- if (setjmp(jerr.setjmp_buffer))
- return 0;
-
- jpeg_create_decompress(&cinfo);
-
- if (eet_jpeg_membuf_src(&cinfo, data, (size_t)size))
- {
- jpeg_destroy_decompress(&cinfo);
- return 0;
- }
-
- jpeg_read_header(&cinfo, TRUE);
- cinfo.dct_method = JDCT_ISLOW; // JDCT_FLOAT JDCT_IFAST(quality loss)
- cinfo.do_fancy_upsampling = FALSE;
- cinfo.do_block_smoothing = FALSE;
- jpeg_start_decompress(&cinfo);
-
- /* head decoding */
- iw = cinfo.output_width;
- ih = cinfo.output_height;
- if ((iw != w) || (ih != h))
- {
- free(cinfo.src);
- cinfo.src = NULL;
-
- jpeg_destroy_decompress(&cinfo);
- return 0;
- }
-
- /* end head decoding */
- /* data decoding */
- if (cinfo.rec_outbuf_height > 16)
- {
- free(cinfo.src);
- cinfo.src = NULL;
+ // Fix for ABI incompatibility between 1.10 and 1.11
+ /* if (cspace == 8) cspace = 9; */
- jpeg_destroy_decompress(&cinfo);
- return 0;
- }
+ bin = eina_binbuf_manage_read_only_new_length(data, size);
+ if (!bin) return 0;
- tdata = alloca((iw) * 16 * 3);
- ptr2 = d;
+ memset(&opts, 0, sizeof (Emile_Image_Load_Opts));
+ opts.region.x = src_x;
+ opts.region.y = src_y;
+ opts.region.w = w;
+ opts.region.h = h;
- if (cinfo.output_components == 3)
- {
- for (i = 0; i < (unsigned int)cinfo.rec_outbuf_height; i++)
- line[i] = tdata + (i * (iw) * 3);
- for (l = 0; l < ih; l += cinfo.rec_outbuf_height)
- {
- jpeg_read_scanlines(&cinfo, line, cinfo.rec_outbuf_height);
- scans = cinfo.rec_outbuf_height;
- if ((ih - l) < scans)
- scans = ih - l;
+ image = emile_image_jpeg_memory_open(bin, &opts, NULL, &error);
+ if (!image) goto on_error;
- ptr = tdata;
+ memset(&prop, 0, sizeof (prop));
- if (l + scans >= src_y && l < src_y + h)
- {
- y = src_y - l;
- if (src_y < l)
- y = 0;
-
- for (ptr += 3 * iw * y; y < scans && (y + l) < (src_y + h);
- y++)
- {
- tmp = ptr2;
- ptr += 3 * src_x;
- for (x = 0; x < w; x++)
- {
- *ptr2 =
- (0xff000000) |
- ((ptr[0]) << 16) | ((ptr[1]) << 8) | (ptr[2]);
- ptr += 3;
- ptr2++;
- }
- ptr += 3 * (iw - w);
- ptr2 = tmp + row_stride / 4;
- }
- }
- }
- }
- else if (cinfo.output_components == 1)
- {
- for (i = 0; i < (unsigned int)cinfo.rec_outbuf_height; i++)
- line[i] = tdata + (i * (iw));
- for (l = 0; l < (ih); l += cinfo.rec_outbuf_height)
- {
- jpeg_read_scanlines(&cinfo, line, cinfo.rec_outbuf_height);
- scans = cinfo.rec_outbuf_height;
- if (((ih) - l) < scans)
- scans = (ih) - l;
+ if (!emile_image_head(image, &prop, sizeof (Emile_Image_Property), &error))
+ goto on_error;
- ptr = tdata;
+ // FIXME: Change prototype to handle color space and destination region (w, h)
+ if (!emile_image_data(image, &prop, sizeof (Emile_Image_Property), d, &error))
+ goto on_error;
- if (l >= src_y && l < src_y + h)
- {
- y = src_y - l;
- if (src_y < l)
- y = 0;
+ r = 1;
- for (ptr += iw * y; y < scans && (y + l) < (src_y + h); y++)
- {
- tmp = ptr2;
- ptr += src_x;
- for (x = 0; x < w; x++)
- {
- *ptr2 =
- (0xff000000) |
- ((ptr[0]) << 16) | ((ptr[0]) << 8) | (ptr[0]);
- ptr++;
- ptr2++;
- }
- ptr += iw - w;
- ptr2 = tmp + row_stride / 4;
- }
- }
- }
- }
+ on_error:
+ emile_image_close(image);
+ eina_binbuf_free(bin);
- /* end data decoding */
- jpeg_finish_decompress(&cinfo);
- jpeg_destroy_decompress(&cinfo);
- return 1;
+ return r;
}
static int
unsigned int h,
unsigned int row_stride)
{
- struct jpeg_decompress_struct cinfo;
- struct _JPEG_error_mgr jerr;
- unsigned char *ptr, *line[16], *tdata = NULL;
- unsigned int *ptr2, *tmp;
- unsigned int x, y, l, scans;
- unsigned int i, iw;
+ Emile_Image_Load_Opts opts;
+ Emile_Image_Property prop;
+ Emile_Image *image;
+ Eina_Binbuf *bin;
+ unsigned char *remember = NULL, *tmp;
+ Emile_Image_Load_Error error;
+ int r = 0;
+ unsigned int i;
/* FIXME: handle src_x, src_y and row_stride correctly */
if (!d)
return 0;
- memset(&cinfo, 0, sizeof (struct jpeg_decompress_struct));
-
- cinfo.err = jpeg_std_error(&(jerr.pub));
- jerr.pub.error_exit = _eet_image_jpeg_error_exit_cb;
- jerr.pub.emit_message = _eet_image_jpeg_emit_message_cb;
- jerr.pub.output_message = _eet_image_jpeg_output_message_cb;
- if (setjmp(jerr.setjmp_buffer))
- return 0;
+ bin = eina_binbuf_manage_read_only_new_length(data, size);
+ if (!bin) return 0;
- jpeg_create_decompress(&cinfo);
+ memset(&opts, 0, sizeof (Emile_Image_Load_Opts));
+ opts.region.x = src_x;
+ opts.region.y = src_y;
+ opts.region.w = w;
+ opts.region.h = h;
- if (eet_jpeg_membuf_src(&cinfo, data, (size_t)size))
- {
- jpeg_destroy_decompress(&cinfo);
- return 0;
- }
+ image = emile_image_jpeg_memory_open(bin, &opts, NULL, &error);
+ if (!image) goto on_error;
- jpeg_read_header(&cinfo, TRUE);
- cinfo.dct_method = JDCT_ISLOW; // JDCT_FLOAT JDCT_IFAST(quality loss)
- cinfo.do_fancy_upsampling = FALSE;
- cinfo.do_block_smoothing = FALSE;
- jpeg_start_decompress(&cinfo);
-
- /* head decoding */
- iw = cinfo.output_width;
- if (w != cinfo.output_width
- || h != cinfo.output_height)
- {
- free(cinfo.src);
- cinfo.src = NULL;
+ memset(&prop, 0, sizeof (prop));
- jpeg_destroy_decompress(&cinfo);
- return 0;
- }
+ if (!emile_image_head(image, &prop, sizeof (Emile_Image_Property), &error))
+ goto on_error;
- /* end head decoding */
- /* data decoding */
- if (cinfo.rec_outbuf_height > 16)
- {
- free(cinfo.src);
- cinfo.src = NULL;
+ remember = tmp = malloc(sizeof (unsigned char) * w * h);
+ if (!tmp) goto on_error;
- jpeg_destroy_decompress(&cinfo);
- return 0;
- }
+ // Alpha should always be encoded as GRY8
+ prop.cspace = EMILE_COLORSPACE_GRY8;
- tdata = alloca(w * 16 * 3);
- ptr2 = d;
+ if (!emile_image_data(image, &prop, sizeof (Emile_Image_Property), tmp, &error))
+ goto on_error;
- if (cinfo.output_components == 1)
+ for (i = 0; i < w * h; i++)
{
- for (i = 0; i < (unsigned int)cinfo.rec_outbuf_height; i++)
- line[i] = tdata + (i * w);
- for (l = 0; l < h; l += cinfo.rec_outbuf_height)
- {
- jpeg_read_scanlines(&cinfo, line, cinfo.rec_outbuf_height);
- scans = cinfo.rec_outbuf_height;
- if ((h - l) < scans)
- scans = h - l;
+ *d = ((*d) & 0x00ffffff) |
+ ((*tmp) << 24);
+ tmp++;
+ d++;
+ }
- ptr = tdata;
+ r = 1;
- if (l >= src_y && l < src_y + h)
- {
- y = src_y - l;
- if (src_y < l)
- y = 0;
+ on_error:
+ free(remember);
- for (ptr += iw * y; y < scans && (y + l) < (src_y + h); y++)
- {
- tmp = ptr2;
- ptr += src_x;
- for (x = 0; x < w; x++)
- {
- *ptr2 =
- ((*ptr2) & 0x00ffffff) |
- ((ptr[0]) << 24);
- ptr++;
- ptr2++;
- }
- ptr += iw - w;
- ptr2 = tmp + row_stride / 4;
- }
- }
- }
- }
+ emile_image_close(image);
+ eina_binbuf_free(bin);
- /* end data decoding */
- jpeg_finish_decompress(&cinfo);
- jpeg_destroy_decompress(&cinfo);
- return 1;
+ return r;
}
// FIXME: Importing two functions from evas here: premul & unpremul