14 #include "evas_common.h"
15 #include "evas_private.h"
18 typedef struct _JPEG_error_mgr *emptr;
19 struct _JPEG_error_mgr
21 struct jpeg_error_mgr pub;
22 jmp_buf setjmp_buffer;
25 static void _JPEGFatalErrorHandler(j_common_ptr cinfo);
26 static void _JPEGErrorHandler(j_common_ptr cinfo);
27 static void _JPEGErrorHandler2(j_common_ptr cinfo, int msg_level);
29 static Eina_Bool evas_image_load_file_head_jpeg_internal(Image_Entry *ie, FILE *f, int *error) EINA_ARG_NONNULL(1, 2, 3);
30 static Eina_Bool evas_image_load_file_data_jpeg_internal(Image_Entry *ie, FILE *f, int *error) EINA_ARG_NONNULL(1, 2, 3);
31 #if 0 /* not used at the moment */
32 static int evas_image_load_file_data_jpeg_alpha_internal(Image_Entry *ie, FILE *f) EINA_ARG_NONNULL(1, 2);
35 static Eina_Bool evas_image_load_file_head_jpeg(Image_Entry *ie, const char *file, const char *key, int *error) EINA_ARG_NONNULL(1, 2, 4);
36 static Eina_Bool evas_image_load_file_data_jpeg(Image_Entry *ie, const char *file, const char *key, int *error) EINA_ARG_NONNULL(1, 2, 4);
38 static Evas_Image_Load_Func evas_image_load_jpeg_func =
41 evas_image_load_file_head_jpeg,
42 evas_image_load_file_data_jpeg
47 _JPEGFatalErrorHandler(j_common_ptr cinfo)
51 errmgr = (emptr) cinfo->err;
52 /* cinfo->err->output_message(cinfo);*/
53 longjmp(errmgr->setjmp_buffer, 1);
58 _JPEGErrorHandler(j_common_ptr cinfo __UNUSED__)
62 /* errmgr = (emptr) cinfo->err; */
63 /* cinfo->err->output_message(cinfo);*/
64 /* longjmp(errmgr->setjmp_buffer, 1);*/
69 _JPEGErrorHandler2(j_common_ptr cinfo __UNUSED__, int msg_level __UNUSED__)
73 /* errmgr = (emptr) cinfo->err; */
74 /* cinfo->err->output_message(cinfo);*/
75 /* longjmp(errmgr->setjmp_buffer, 1);*/
80 evas_image_load_file_head_jpeg_internal(Image_Entry *ie, FILE *f, int *error)
82 unsigned int w, h, scalew, scaleh;
83 struct jpeg_decompress_struct cinfo;
84 struct _JPEG_error_mgr jerr;
86 cinfo.err = jpeg_std_error(&(jerr.pub));
87 jerr.pub.error_exit = _JPEGFatalErrorHandler;
88 jerr.pub.emit_message = _JPEGErrorHandler2;
89 jerr.pub.output_message = _JPEGErrorHandler;
90 if (setjmp(jerr.setjmp_buffer))
92 jpeg_destroy_decompress(&cinfo);
93 if (cinfo.saw_JFIF_marker)
94 *error = EVAS_LOAD_ERROR_CORRUPT_FILE;
96 *error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
99 jpeg_create_decompress(&cinfo);
100 jpeg_stdio_src(&cinfo, f);
101 jpeg_read_header(&cinfo, TRUE);
102 cinfo.do_fancy_upsampling = FALSE;
103 cinfo.do_block_smoothing = FALSE;
104 cinfo.dct_method = JDCT_IFAST;
105 cinfo.dither_mode = JDITHER_ORDERED;
106 jpeg_start_decompress(&cinfo);
109 w = cinfo.output_width;
110 h = cinfo.output_height;
111 if ((w < 1) || (h < 1) || (w > IMG_MAX_SIZE) || (h > IMG_MAX_SIZE) ||
114 jpeg_destroy_decompress(&cinfo);
115 if (IMG_TOO_BIG(w, h))
116 *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
118 *error = EVAS_LOAD_ERROR_GENERIC;
121 if (ie->load_opts.scale_down_by > 1)
123 w /= ie->load_opts.scale_down_by;
124 h /= ie->load_opts.scale_down_by;
126 else if (ie->load_opts.dpi > 0.0)
128 w = (w * ie->load_opts.dpi) / 90.0;
129 h = (h * ie->load_opts.dpi) / 90.0;
131 else if ((ie->load_opts.w > 0) && (ie->load_opts.h > 0))
133 unsigned int w2 = w, h2 = h;
134 if (ie->load_opts.w > 0)
136 w2 = ie->load_opts.w;
137 h2 = (ie->load_opts.w * h) / w;
138 if ((ie->load_opts.h > 0) && (h2 > ie->load_opts.h))
141 h2 = ie->load_opts.h;
142 w3 = (ie->load_opts.h * w) / h;
147 else if (ie->load_opts.h > 0)
149 h2 = ie->load_opts.h;
150 w2 = (ie->load_opts.h * w) / h;
158 if ((w != cinfo.output_width) || (h != cinfo.output_height))
160 scalew = cinfo.output_width / w;
161 scaleh = cinfo.output_height / h;
164 if (scaleh < scalew) ie->scale = scaleh;
166 if (ie->scale > 8) ie->scale = 8;
167 else if (ie->scale < 1) ie->scale = 1;
169 if (ie->scale == 3) ie->scale = 2;
170 else if (ie->scale == 5) ie->scale = 4;
171 else if (ie->scale == 6) ie->scale = 4;
172 else if (ie->scale == 7) ie->scale = 4;
177 jpeg_destroy_decompress(&cinfo);
179 jpeg_create_decompress(&cinfo);
180 jpeg_stdio_src(&cinfo, f);
181 jpeg_read_header(&cinfo, TRUE);
182 cinfo.do_fancy_upsampling = FALSE;
183 cinfo.do_block_smoothing = FALSE;
185 cinfo.scale_denom = ie->scale;
186 jpeg_calc_output_dimensions(&(cinfo));
187 jpeg_start_decompress(&cinfo);
190 ie->w = cinfo.output_width;
191 ie->h = cinfo.output_height;
193 // be nice and clip region to image. if its totally outside, fail load
194 if ((ie->load_opts.region.w > 0) && (ie->load_opts.region.h > 0))
196 RECTS_CLIP_TO_RECT(ie->load_opts.region.x, ie->load_opts.region.y,
197 ie->load_opts.region.w, ie->load_opts.region.h,
199 if ((ie->load_opts.region.w <= 0) || (ie->load_opts.region.h <= 0))
201 jpeg_destroy_decompress(&cinfo);
202 *error = EVAS_LOAD_ERROR_GENERIC;
205 ie->w = ie->load_opts.region.w;
206 ie->h = ie->load_opts.region.h;
208 /* end head decoding */
210 jpeg_destroy_decompress(&cinfo);
211 *error = EVAS_LOAD_ERROR_NONE;
219 struct timeval timev;
221 gettimeofday(&timev, NULL);
222 return (double)timev.tv_sec + (((double)timev.tv_usec) / 1000000);
227 evas_image_load_file_data_jpeg_internal(Image_Entry *ie, FILE *f, int *error)
230 struct jpeg_decompress_struct cinfo;
231 struct _JPEG_error_mgr jerr;
232 DATA8 *ptr, *line[16], *data;
234 unsigned int x, y, l, i, scans;
237 cinfo.err = jpeg_std_error(&(jerr.pub));
238 jerr.pub.error_exit = _JPEGFatalErrorHandler;
239 jerr.pub.emit_message = _JPEGErrorHandler2;
240 jerr.pub.output_message = _JPEGErrorHandler;
241 if (setjmp(jerr.setjmp_buffer))
243 jpeg_destroy_decompress(&cinfo);
244 *error = EVAS_LOAD_ERROR_CORRUPT_FILE;
247 jpeg_create_decompress(&cinfo);
248 jpeg_stdio_src(&cinfo, f);
249 jpeg_read_header(&cinfo, TRUE);
250 cinfo.do_fancy_upsampling = FALSE;
251 cinfo.do_block_smoothing = FALSE;
252 cinfo.dct_method = JDCT_IFAST;
253 cinfo.dither_mode = JDITHER_ORDERED;
258 cinfo.scale_denom = ie->scale;
261 /* Colorspace conversion options */
262 /* libjpeg can do the following conversions: */
263 /* GRAYSCLAE => RGB YCbCr => RGB and YCCK => CMYK */
264 switch (cinfo.jpeg_color_space)
271 cinfo.out_color_space = JCS_RGB;
275 cinfo.out_color_space = JCS_CMYK;
280 jpeg_calc_output_dimensions(&(cinfo));
281 jpeg_start_decompress(&cinfo);
283 w = cinfo.output_width;
284 h = cinfo.output_height;
286 if ((ie->load_opts.region.w > 0) && (ie->load_opts.region.h > 0))
289 #ifdef BUILD_LOADER_JPEG_REGION
290 cinfo.region_x = ie->load_opts.region.x;
291 cinfo.region_y = ie->load_opts.region.y;
292 cinfo.region_w = ie->load_opts.region.w;
293 cinfo.region_h = ie->load_opts.region.h;
296 if ((!region) && ((w != ie->w) || (h != ie->h)))
298 // race condition, the file could have change from when we call header
299 // this test will not solve the problem with region code.
300 jpeg_destroy_decompress(&cinfo);
301 *error = EVAS_LOAD_ERROR_GENERIC;
305 ((ie->w != ie->load_opts.region.w) || (ie->h != ie->load_opts.region.h)))
307 ie->w = ie->load_opts.region.w;
308 ie->h = ie->load_opts.region.h;
311 if (!(((cinfo.out_color_space == JCS_RGB) &&
312 ((cinfo.output_components == 3) || (cinfo.output_components == 1))) ||
313 ((cinfo.out_color_space == JCS_CMYK) && (cinfo.output_components == 4))))
315 jpeg_destroy_decompress(&cinfo);
316 *error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
320 /* end head decoding */
322 if (cinfo.rec_outbuf_height > 16)
324 jpeg_destroy_decompress(&cinfo);
325 *error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
328 data = alloca(w * 16 * cinfo.output_components);
329 evas_cache_image_surface_alloc(ie, ie->w, ie->h);
330 if (ie->flags.loaded)
332 jpeg_destroy_decompress(&cinfo);
333 *error = EVAS_LOAD_ERROR_NONE;
336 ptr2 = evas_cache_image_pixels(ie);
339 *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
343 /* We handle first CMYK (4 components) */
344 if (cinfo.output_components == 4)
346 // FIXME: handle region
347 for (i = 0; (int)i < cinfo.rec_outbuf_height; i++)
348 line[i] = data + (i * w * 4);
349 for (l = 0; l < h; l += cinfo.rec_outbuf_height)
351 jpeg_read_scanlines(&cinfo, line, cinfo.rec_outbuf_height);
352 scans = cinfo.rec_outbuf_height;
353 if ((h - l) < scans) scans = h - l;
357 for (y = 0; y < scans; y++)
359 if (cinfo.saw_Adobe_marker)
361 for (x = 0; x < w; x++)
363 /* According to libjpeg doc, Photoshop inverse the values of C, M, Y and K, */
364 /* that is C is replaces by 255 - C, etc...*/
365 /* See the comment below for the computation of RGB values from CMYK ones. */
368 ((ptr[0] * ptr[3] / 255) << 16) |
369 ((ptr[1] * ptr[3] / 255) << 8) |
370 ((ptr[2] * ptr[3] / 255));
377 for (x = 0; x < w; x++)
379 /* Conversion from CMYK to RGB is done in 2 steps: */
380 /* CMYK => CMY => RGB (see http://www.easyrgb.com/index.php?X=MATH) */
381 /* after computation, if C, M, Y and K are between 0 and 1, we have: */
382 /* R = (1 - C) * (1 - K) * 255 */
383 /* G = (1 - M) * (1 - K) * 255 */
384 /* B = (1 - Y) * (1 - K) * 255 */
385 /* libjpeg stores CMYK values between 0 and 255, */
386 /* so we replace C by C * 255 / 255, etc... and we obtain: */
387 /* R = (255 - C) * (255 - K) / 255 */
388 /* G = (255 - M) * (255 - K) / 255 */
389 /* B = (255 - Y) * (255 - K) / 255 */
390 /* with C, M, Y and K between 0 and 255. */
393 (((255 - ptr[0]) * (255 - ptr[3]) / 255) << 16) |
394 (((255 - ptr[1]) * (255 - ptr[3]) / 255) << 8) |
395 (((255 - ptr[2]) * (255 - ptr[3]) / 255));
404 // if line # > region last line, break
405 if (l >= (ie->load_opts.region.y + ie->load_opts.region.h))
407 jpeg_destroy_decompress(&cinfo);
408 *error = EVAS_LOAD_ERROR_NONE;
411 // els if scan block intersects region start or later
412 else if ((l + scans) >
413 (ie->load_opts.region.y))
415 for (y = 0; y < scans; y++)
417 if (((y + l) >= ie->load_opts.region.y) &&
418 ((y + l) < (ie->load_opts.region.y + ie->load_opts.region.h)))
420 ptr += ie->load_opts.region.x;
421 if (cinfo.saw_Adobe_marker)
423 for (x = 0; x < ie->load_opts.region.w; x++)
425 /* According to libjpeg doc, Photoshop inverse the values of C, M, Y and K, */
426 /* that is C is replaces by 255 - C, etc...*/
427 /* See the comment below for the computation of RGB values from CMYK ones. */
430 ((ptr[0] * ptr[3] / 255) << 16) |
431 ((ptr[1] * ptr[3] / 255) << 8) |
432 ((ptr[2] * ptr[3] / 255));
439 for (x = 0; x < ie->load_opts.region.w; x++)
441 /* Conversion from CMYK to RGB is done in 2 steps: */
442 /* CMYK => CMY => RGB (see http://www.easyrgb.com/index.php?X=MATH) */
443 /* after computation, if C, M, Y and K are between 0 and 1, we have: */
444 /* R = (1 - C) * (1 - K) * 255 */
445 /* G = (1 - M) * (1 - K) * 255 */
446 /* B = (1 - Y) * (1 - K) * 255 */
447 /* libjpeg stores CMYK values between 0 and 255, */
448 /* so we replace C by C * 255 / 255, etc... and we obtain: */
449 /* R = (255 - C) * (255 - K) / 255 */
450 /* G = (255 - M) * (255 - K) / 255 */
451 /* B = (255 - Y) * (255 - K) / 255 */
452 /* with C, M, Y and K between 0 and 255. */
455 (((255 - ptr[0]) * (255 - ptr[3]) / 255) << 16) |
456 (((255 - ptr[1]) * (255 - ptr[3]) / 255) << 8) |
457 (((255 - ptr[2]) * (255 - ptr[3]) / 255));
462 ptr += (4 * (w - (ie->load_opts.region.x + ie->load_opts.region.w)));
471 /* We handle then RGB with 3 components */
472 else if (cinfo.output_components == 3)
479 printf("R| %p %5ix%5i %s: %5i %5i %5ix%5i - ",
483 ie->load_opts.region.x,
484 ie->load_opts.region.y,
485 ie->load_opts.region.w,
486 ie->load_opts.region.h);
490 for (i = 0; (int)i < cinfo.rec_outbuf_height; i++)
491 line[i] = data + (i * w * 3);
492 for (l = 0; l < h; l += cinfo.rec_outbuf_height)
494 jpeg_read_scanlines(&cinfo, line, cinfo.rec_outbuf_height);
495 scans = cinfo.rec_outbuf_height;
496 if ((h - l) < scans) scans = h - l;
500 for (y = 0; y < scans; y++)
502 for (x = 0; x < w; x++)
504 *ptr2 = ARGB_JOIN(0xff, ptr[0], ptr[1], ptr[2]);
512 // if line # > region last line, break
513 if (l >= (ie->load_opts.region.y + ie->load_opts.region.h))
515 jpeg_destroy_decompress(&cinfo);
518 printf("%3.3f\n", t);
520 *error = EVAS_LOAD_ERROR_NONE;
523 // else if scan block intersects region start or later
524 else if ((l + scans) >
525 (ie->load_opts.region.y))
527 for (y = 0; y < scans; y++)
529 if (((y + l) >= ie->load_opts.region.y) &&
530 ((y + l) < (ie->load_opts.region.y + ie->load_opts.region.h)))
532 ptr += (3 * ie->load_opts.region.x);
533 for (x = 0; x < ie->load_opts.region.w; x++)
535 *ptr2 = ARGB_JOIN(0xff, ptr[0], ptr[1], ptr[2]);
539 ptr += (3 * (w - (ie->load_opts.region.x + ie->load_opts.region.w)));
549 printf("%3.3f\n", t);
552 /* We finally handle RGB with 1 component */
553 else if (cinfo.output_components == 1)
555 for (i = 0; (int)i < cinfo.rec_outbuf_height; i++)
556 line[i] = data + (i * w);
557 for (l = 0; l < h; l += cinfo.rec_outbuf_height)
559 jpeg_read_scanlines(&cinfo, line, cinfo.rec_outbuf_height);
560 scans = cinfo.rec_outbuf_height;
561 if ((h - l) < scans) scans = h - l;
565 for (y = 0; y < scans; y++)
567 for (x = 0; x < w; x++)
569 *ptr2 = ARGB_JOIN(0xff, ptr[0], ptr[0], ptr[0]);
577 // if line # > region last line, break
578 if (l >= (ie->load_opts.region.y + ie->load_opts.region.h))
580 jpeg_destroy_decompress(&cinfo);
581 *error = EVAS_LOAD_ERROR_NONE;
584 // els if scan block intersects region start or later
585 else if ((l + scans) >
586 (ie->load_opts.region.y))
588 for (y = 0; y < scans; y++)
590 if (((y + l) >= ie->load_opts.region.y) &&
591 ((y + l) < (ie->load_opts.region.y + ie->load_opts.region.h)))
593 ptr += ie->load_opts.region.x;
594 for (x = 0; x < ie->load_opts.region.w; x++)
596 *ptr2 = ARGB_JOIN(0xff, ptr[0], ptr[0], ptr[0]);
600 ptr += w - (ie->load_opts.region.x + ie->load_opts.region.w);
609 /* end data decoding */
610 jpeg_finish_decompress(&cinfo);
611 jpeg_destroy_decompress(&cinfo);
612 *error = EVAS_LOAD_ERROR_NONE;
616 #if 0 /* not used at the moment */
618 evas_image_load_file_data_jpeg_alpha_internal(Image_Entry *ie, FILE *f, int *error)
621 struct jpeg_decompress_struct cinfo;
622 struct _JPEG_error_mgr jerr;
623 DATA8 *ptr, *line[16], *data;
625 int x, y, l, i, scans, prevy;
629 *error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
632 cinfo.err = jpeg_std_error(&(jerr.pub));
633 jerr.pub.error_exit = _JPEGFatalErrorHandler;
634 jerr.pub.emit_message = _JPEGErrorHandler2;
635 jerr.pub.output_message = _JPEGErrorHandler;
636 if (setjmp(jerr.setjmp_buffer))
638 jpeg_destroy_decompress(&cinfo);
639 *error = EVAS_LOAD_ERROR_CORRUPT_FILE;
642 jpeg_create_decompress(&cinfo);
643 jpeg_stdio_src(&cinfo, f);
644 jpeg_read_header(&cinfo, TRUE);
645 cinfo.do_fancy_upsampling = FALSE;
646 cinfo.do_block_smoothing = FALSE;
647 jpeg_start_decompress(&cinfo);
650 ie->w = w = cinfo.output_width;
651 ie->h = h = cinfo.output_height;
652 /* end head decoding */
654 if (cinfo.rec_outbuf_height > 16)
656 jpeg_destroy_decompress(&cinfo);
657 *error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
660 data = alloca(w * 16 * 3);
661 if (!ie->flags.loaded)
663 jpeg_destroy_decompress(&cinfo);
664 *error = EVAS_LOAD_ERROR_NONE;
667 ptr2 = evas_cache_image_pixels(ie);
669 if (cinfo.output_components == 3)
671 for (i = 0; i < cinfo.rec_outbuf_height; i++)
672 line[i] = data + (i * w * 3);
673 for (l = 0; l < h; l += cinfo.rec_outbuf_height)
675 jpeg_read_scanlines(&cinfo, line, cinfo.rec_outbuf_height);
676 scans = cinfo.rec_outbuf_height;
677 if ((h - l) < scans) scans = h - l;
679 for (y = 0; y < scans; y++)
681 for (x = 0; x < w; x++)
684 ((*ptr2) & 0x00ffffff) |
685 (((ptr[0] + ptr[1] + ptr[2]) / 3) << 24);
692 else if (cinfo.output_components == 1)
694 for (i = 0; i < cinfo.rec_outbuf_height; i++)
695 line[i] = data + (i * w);
696 for (l = 0; l < h; l += cinfo.rec_outbuf_height)
698 jpeg_read_scanlines(&cinfo, line, cinfo.rec_outbuf_height);
699 scans = cinfo.rec_outbuf_height;
700 if ((h - l) < scans) scans = h - l;
702 for (y = 0; y < scans; y++)
704 for (x = 0; x < w; x++)
707 ((*ptr2) & 0x00ffffff) |
715 /* end data decoding */
716 jpeg_finish_decompress(&cinfo);
717 jpeg_destroy_decompress(&cinfo);
718 *error = EVAS_LOAD_ERROR_NONE;
724 evas_image_load_file_head_jpeg(Image_Entry *ie, const char *file, const char *key, int *error)
729 f = fopen(file, "rb");
732 *error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
735 val = evas_image_load_file_head_jpeg_internal(ie, f, error);
742 evas_image_load_file_data_jpeg(Image_Entry *ie, const char *file, const char *key, int *error)
747 f = fopen(file, "rb");
750 *error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
753 val = evas_image_load_file_data_jpeg_internal(ie, f, error);
760 module_open(Evas_Module *em)
763 em->functions = (void *)(&evas_image_load_jpeg_func);
768 module_close(Evas_Module *em __UNUSED__)
772 static Evas_Module_Api evas_modapi =
774 EVAS_MODULE_API_VERSION,
783 EVAS_MODULE_DEFINE(EVAS_MODULE_TYPE_IMAGE_LOADER, image_loader, jpeg);
785 #ifndef EVAS_STATIC_BUILD_JPEG
786 EVAS_EINA_MODULE_DEFINE(image_loader, jpeg);