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);
28 static int _get_orientation_app0(char *app0_head, size_t remain_length);
29 static int _get_orientation_app1(char *app1_head, size_t remain_length);
30 static int _get_orientation(void *map, size_t length);
32 static Eina_Bool evas_image_load_file_head_jpeg_internal(Image_Entry *ie,
35 int *error) EINA_ARG_NONNULL(1, 2, 4);
36 static Eina_Bool evas_image_load_file_data_jpeg_internal(Image_Entry *ie,
39 int *error) EINA_ARG_NONNULL(1, 2, 4);
40 #if 0 /* not used at the moment */
41 static int evas_image_load_file_data_jpeg_alpha_internal(Image_Entry *ie, FILE *f) EINA_ARG_NONNULL(1, 2);
44 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);
45 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);
47 static Evas_Image_Load_Func evas_image_load_jpeg_func =
50 evas_image_load_file_head_jpeg,
51 evas_image_load_file_data_jpeg,
58 _JPEGFatalErrorHandler(j_common_ptr cinfo)
62 errmgr = (emptr) cinfo->err;
63 /* cinfo->err->output_message(cinfo);*/
64 longjmp(errmgr->setjmp_buffer, 1);
69 _JPEGErrorHandler(j_common_ptr cinfo __UNUSED__)
73 /* errmgr = (emptr) cinfo->err; */
74 /* cinfo->err->output_message(cinfo);*/
75 /* longjmp(errmgr->setjmp_buffer, 1);*/
80 _JPEGErrorHandler2(j_common_ptr cinfo __UNUSED__, int msg_level __UNUSED__)
84 /* errmgr = (emptr) cinfo->err; */
85 /* cinfo->err->output_message(cinfo);*/
86 /* longjmp(errmgr->setjmp_buffer, 1);*/
90 struct jpeg_membuf_src
92 struct jpeg_source_mgr pub;
94 const unsigned char *buf;
96 struct jpeg_membuf_src *self;
100 _evas_jpeg_membuf_src_init(j_decompress_ptr cinfo __UNUSED__)
105 _evas_jpeg_membuf_src_fill(j_decompress_ptr cinfo)
107 static const JOCTET jpeg_eoi[2] = { 0xFF, JPEG_EOI };
108 struct jpeg_membuf_src *src = (struct jpeg_membuf_src *)cinfo->src;
110 src->pub.bytes_in_buffer = sizeof(jpeg_eoi);
111 src->pub.next_input_byte = jpeg_eoi;
117 _evas_jpeg_membuf_src_skip(j_decompress_ptr cinfo,
120 struct jpeg_membuf_src *src = (struct jpeg_membuf_src *)cinfo->src;
122 if ((((long)src->pub.bytes_in_buffer - (long)src->len) > num_bytes) ||
123 ((long)src->pub.bytes_in_buffer < num_bytes))
125 (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo));
128 src->pub.bytes_in_buffer -= num_bytes;
129 src->pub.next_input_byte += num_bytes;
133 _evas_jpeg_membuf_src_term(j_decompress_ptr cinfo)
135 struct jpeg_membuf_src *src = (struct jpeg_membuf_src *)cinfo->src;
142 _evas_jpeg_membuf_src(j_decompress_ptr cinfo,
143 void *map, size_t length)
145 struct jpeg_membuf_src *src;
147 src = calloc(1, sizeof(*src));
153 cinfo->src = &src->pub;
156 src->pub.init_source = _evas_jpeg_membuf_src_init;
157 src->pub.fill_input_buffer = _evas_jpeg_membuf_src_fill;
158 src->pub.skip_input_data = _evas_jpeg_membuf_src_skip;
159 src->pub.resync_to_restart = jpeg_resync_to_restart;
160 src->pub.term_source = _evas_jpeg_membuf_src_term;
161 src->pub.bytes_in_buffer = src->len;
162 src->pub.next_input_byte = src->buf;
167 /*! Magic number for EXIF header, App0, App1*/
168 static const unsigned char ExifHeader[] = {0x45, 0x78, 0x69, 0x66, 0x00, 0x00};
169 static const unsigned char JfifHeader[] = {0x4A, 0x46, 0x49, 0x46, 0x00};
170 static const unsigned char JfxxHeader[] = {0x4A, 0x46, 0x58, 0x58, 0x00};
171 static const unsigned char App0[] = {0xff, 0xe0};
172 static const unsigned char App1[] = {0xff, 0xe1};
179 _get_orientation_app0(char *app0_head, size_t remain_length)
181 unsigned int length = 0;
182 unsigned int w = 0, h = 0;
183 unsigned int format = 0;
184 unsigned int data_size = 0;
187 /* p is appn's start pointer excluding app0 marker */
191 length = ((*p << 8) + *(p + 1));
193 /* JFIF segment format */
194 if (!memcmp(p + 2, JfifHeader, sizeof (JfifHeader)))
200 else if (!memcmp(p + 2, JfxxHeader, sizeof (JfxxHeader)))
202 if (*(p + 7) == 0x11)
210 data_size = format * w * h;
211 p += length + data_size;
213 if (!memcmp(p, App1, sizeof (App1)))
214 return _get_orientation_app1(p, remain_length - (2 + length + data_size));
220 _get_orientation_app1(char *app1_head, size_t remain_length)
224 ExifByteAlign byte_align;
225 unsigned int num_directory = 0;
229 /* start of app1 frame */
232 /* 1. check 4~9bype with Exif Header (0x45786966 0000) */
233 if (memcmp(buf + 4, ExifHeader, sizeof (ExifHeader))) return 0;
235 /* 2. get 10&11 byte get info of "II(0x4949)" or "MM(0x4d4d)" */
236 /* 3. get [18]&[19] get directory entry # */
237 if (!strncmp(buf + 10, "MM", 2))
239 byte_align = EXIF_BYTE_ALIGN_MM;
240 num_directory = ((*(buf + 18) << 8) + *(buf + 19));
241 orientation[0] = 0x01;
242 orientation[1] = 0x12;
244 else if (!strncmp(buf + 10, "II", 2))
246 byte_align = EXIF_BYTE_ALIGN_II;
247 num_directory = ((*(buf + 19) << 8) + *(buf + 18));
248 orientation[0] = 0x12;
249 orientation[1] = 0x01;
253 buf = app1_head + 20;
255 if (remain_length < (12 * num_directory + 20)) return 0;
259 for (i = 0; i < num_directory; i++ )
261 if (!strncmp(buf + j, orientation, 2))
263 /*get orientation tag */
264 if (byte_align == EXIF_BYTE_ALIGN_MM)
265 direction = *(buf+ j + 9);
266 else direction = *(buf+ j + 8);
289 _get_orientation(void *map, size_t length)
293 /* open file and get 22 byte frome file */
296 if (length < 22) return 0;
299 /* 2. check 2,3 bypte with APP0(0xFFE0) or APP1(0xFFE1) */
300 if (!memcmp(buf + 2, App0, sizeof (App0)))
301 return _get_orientation_app0(buf + 2, length - 2);
302 if (!memcmp(buf + 2, App1, sizeof (App1)))
303 return _get_orientation_app1(buf + 2, length - 2);
308 evas_image_load_file_head_jpeg_internal(Image_Entry *ie,
309 void *map, size_t length,
312 unsigned int w, h, scalew, scaleh;
313 struct jpeg_decompress_struct cinfo;
314 struct _JPEG_error_mgr jerr;
316 /* for rotation decoding */
318 Eina_Bool change_wh = EINA_FALSE;
319 unsigned int load_opts_w = 0, load_opts_h = 0;
321 memset(&cinfo, 0, sizeof(cinfo));
322 cinfo.err = jpeg_std_error(&(jerr.pub));
323 jerr.pub.error_exit = _JPEGFatalErrorHandler;
324 jerr.pub.emit_message = _JPEGErrorHandler2;
325 jerr.pub.output_message = _JPEGErrorHandler;
326 if (setjmp(jerr.setjmp_buffer))
328 jpeg_destroy_decompress(&cinfo);
329 _evas_jpeg_membuf_src_term(&cinfo);
330 if (cinfo.saw_JFIF_marker)
331 *error = EVAS_LOAD_ERROR_CORRUPT_FILE;
333 *error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
336 jpeg_create_decompress(&cinfo);
338 if (_evas_jpeg_membuf_src(&cinfo, map, length))
340 jpeg_destroy_decompress(&cinfo);
341 _evas_jpeg_membuf_src_term(&cinfo);
342 *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
346 jpeg_read_header(&cinfo, TRUE);
347 cinfo.do_fancy_upsampling = FALSE;
348 cinfo.do_block_smoothing = FALSE;
349 cinfo.dct_method = JDCT_ISLOW; // JDCT_FLOAT JDCT_IFAST(quality loss)
350 cinfo.dither_mode = JDITHER_ORDERED;
351 jpeg_start_decompress(&cinfo);
353 /* rotation decoding */
354 if (ie->load_opts.orientation)
356 degree = _get_orientation(map, length);
359 ie->load_opts.degree = degree;
360 ie->flags.rotated = EINA_TRUE;
362 if (degree == 90 || degree == 270)
363 change_wh = EINA_TRUE;
369 w = cinfo.output_width;
370 h = cinfo.output_height;
371 if ((w < 1) || (h < 1) || (w > IMG_MAX_SIZE) || (h > IMG_MAX_SIZE) ||
374 jpeg_destroy_decompress(&cinfo);
375 _evas_jpeg_membuf_src_term(&cinfo);
376 if (IMG_TOO_BIG(w, h))
377 *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
379 *error = EVAS_LOAD_ERROR_GENERIC;
382 if (ie->load_opts.scale_down_by > 1)
384 w /= ie->load_opts.scale_down_by;
385 h /= ie->load_opts.scale_down_by;
387 else if (ie->load_opts.dpi > 0.0)
389 w = (w * ie->load_opts.dpi) / 90.0;
390 h = (h * ie->load_opts.dpi) / 90.0;
392 else if ((ie->load_opts.w > 0) && (ie->load_opts.h > 0))
394 unsigned int w2 = w, h2 = h;
395 /* user set load_opts' w,h on the assumption
396 that image already rotated according to it's orientation info */
399 load_opts_w = ie->load_opts.w;
400 load_opts_h = ie->load_opts.h;
401 ie->load_opts.w = load_opts_h;
402 ie->load_opts.h = load_opts_w;
405 if (ie->load_opts.w > 0)
407 w2 = ie->load_opts.w;
408 h2 = (ie->load_opts.w * h) / w;
409 if ((ie->load_opts.h > 0) && (h2 > ie->load_opts.h))
412 h2 = ie->load_opts.h;
413 w3 = (ie->load_opts.h * w) / h;
418 else if (ie->load_opts.h > 0)
420 h2 = ie->load_opts.h;
421 w2 = (ie->load_opts.h * w) / h;
427 ie->load_opts.w = load_opts_w;
428 ie->load_opts.h = load_opts_h;
434 if ((w != cinfo.output_width) || (h != cinfo.output_height))
436 scalew = cinfo.output_width / w;
437 scaleh = cinfo.output_height / h;
440 if (scaleh < scalew) ie->scale = scaleh;
442 if (ie->scale > 8) ie->scale = 8;
443 else if (ie->scale < 1) ie->scale = 1;
445 if (ie->scale == 3) ie->scale = 2;
446 else if (ie->scale == 5) ie->scale = 4;
447 else if (ie->scale == 6) ie->scale = 4;
448 else if (ie->scale == 7) ie->scale = 4;
453 jpeg_destroy_decompress(&cinfo);
454 _evas_jpeg_membuf_src_term(&cinfo);
455 jpeg_create_decompress(&cinfo);
457 if (_evas_jpeg_membuf_src(&cinfo, map, length))
459 jpeg_destroy_decompress(&cinfo);
460 _evas_jpeg_membuf_src_term(&cinfo);
461 *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
465 jpeg_read_header(&cinfo, TRUE);
466 cinfo.do_fancy_upsampling = FALSE;
467 cinfo.do_block_smoothing = FALSE;
469 cinfo.scale_denom = ie->scale;
470 jpeg_calc_output_dimensions(&(cinfo));
471 jpeg_start_decompress(&cinfo);
474 ie->w = cinfo.output_width;
475 ie->h = cinfo.output_height;
477 // be nice and clip region to image. if its totally outside, fail load
478 if ((ie->load_opts.region.w > 0) && (ie->load_opts.region.h > 0))
480 unsigned int load_region_x = 0, load_region_y = 0;
481 unsigned int load_region_w = 0, load_region_h = 0;
482 if (ie->flags.rotated)
484 load_region_x = ie->load_opts.region.x;
485 load_region_y = ie->load_opts.region.y;
486 load_region_w = ie->load_opts.region.w;
487 load_region_h = ie->load_opts.region.h;
492 ie->load_opts.region.x = load_region_y;
493 ie->load_opts.region.y = h - (load_region_x + load_region_w);
494 ie->load_opts.region.w = load_region_h;
495 ie->load_opts.region.h = load_region_w;
498 ie->load_opts.region.x = w - (load_region_x+ load_region_w);
499 ie->load_opts.region.y = h - (load_region_y + load_region_h);
503 ie->load_opts.region.x = w - (load_region_y + load_region_h);
504 ie->load_opts.region.y = load_region_x;
505 ie->load_opts.region.w = load_region_h;
506 ie->load_opts.region.h = load_region_w;
513 RECTS_CLIP_TO_RECT(ie->load_opts.region.x, ie->load_opts.region.y,
514 ie->load_opts.region.w, ie->load_opts.region.h,
516 if ((ie->load_opts.region.w <= 0) || (ie->load_opts.region.h <= 0))
518 jpeg_destroy_decompress(&cinfo);
519 _evas_jpeg_membuf_src_term(&cinfo);
520 *error = EVAS_LOAD_ERROR_GENERIC;
523 ie->w = ie->load_opts.region.w;
524 ie->h = ie->load_opts.region.h;
525 if (ie->flags.rotated)
527 ie->load_opts.region.x = load_region_x;
528 ie->load_opts.region.y = load_region_y;
529 ie->load_opts.region.w = load_region_w;
530 ie->load_opts.region.h = load_region_h;
533 /* end head decoding */
542 jpeg_destroy_decompress(&cinfo);
543 _evas_jpeg_membuf_src_term(&cinfo);
544 *error = EVAS_LOAD_ERROR_NONE;
552 struct timeval timev;
554 gettimeofday(&timev, NULL);
555 return (double)timev.tv_sec + (((double)timev.tv_usec) / 1000000);
560 evas_image_load_file_data_jpeg_internal(Image_Entry *ie,
561 void *map, size_t size,
565 struct jpeg_decompress_struct cinfo;
566 struct _JPEG_error_mgr jerr;
567 DATA8 *ptr, *line[16], *data;
568 DATA32 *ptr2, *ptr_rotate = NULL;
569 unsigned int x, y, l, i, scans;
571 /* rotation setting */
572 unsigned int ie_w = 0, ie_h = 0;
573 unsigned int load_region_x = 0, load_region_y = 0;
574 unsigned int load_region_w = 0, load_region_h = 0;
575 volatile int degree = 0;
576 volatile Eina_Bool change_wh = EINA_FALSE;
577 Eina_Bool line_done = EINA_FALSE;
579 memset(&cinfo, 0, sizeof(cinfo));
580 if (ie->flags.rotated)
582 degree = ie->load_opts.degree;
583 if (degree == 90 || degree == 270)
584 change_wh = EINA_TRUE;
587 cinfo.err = jpeg_std_error(&(jerr.pub));
588 jerr.pub.error_exit = _JPEGFatalErrorHandler;
589 jerr.pub.emit_message = _JPEGErrorHandler2;
590 jerr.pub.output_message = _JPEGErrorHandler;
591 if (setjmp(jerr.setjmp_buffer))
593 jpeg_destroy_decompress(&cinfo);
594 _evas_jpeg_membuf_src_term(&cinfo);
595 *error = EVAS_LOAD_ERROR_CORRUPT_FILE;
598 jpeg_create_decompress(&cinfo);
600 if (_evas_jpeg_membuf_src(&cinfo, map, size))
602 jpeg_destroy_decompress(&cinfo);
603 _evas_jpeg_membuf_src_term(&cinfo);
604 *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
608 jpeg_read_header(&cinfo, TRUE);
609 cinfo.do_fancy_upsampling = FALSE;
610 cinfo.do_block_smoothing = FALSE;
611 cinfo.dct_method = JDCT_ISLOW; // JDCT_FLOAT JDCT_IFAST(quality loss)
612 cinfo.dither_mode = JDITHER_ORDERED;
617 cinfo.scale_denom = ie->scale;
620 /* Colorspace conversion options */
621 /* libjpeg can do the following conversions: */
622 /* GRAYSCLAE => RGB YCbCr => RGB and YCCK => CMYK */
623 switch (cinfo.jpeg_color_space)
630 cinfo.out_color_space = JCS_RGB;
634 cinfo.out_color_space = JCS_CMYK;
639 jpeg_calc_output_dimensions(&(cinfo));
640 jpeg_start_decompress(&cinfo);
642 w = cinfo.output_width;
643 h = cinfo.output_height;
656 if ((ie->load_opts.region.w > 0) && (ie->load_opts.region.h > 0))
660 if (ie->flags.rotated)
662 load_region_x = ie->load_opts.region.x;
663 load_region_y = ie->load_opts.region.y;
664 load_region_w = ie->load_opts.region.w;
665 load_region_h = ie->load_opts.region.h;
670 ie->load_opts.region.x = load_region_y;
671 ie->load_opts.region.y = h - (load_region_x + load_region_w);
672 ie->load_opts.region.w = load_region_h;
673 ie->load_opts.region.h = load_region_w;
676 ie->load_opts.region.x = w - (load_region_x+ load_region_w);
677 ie->load_opts.region.y = h - (load_region_y + load_region_h);
681 ie->load_opts.region.x = w - (load_region_y + load_region_h);
682 ie->load_opts.region.y = load_region_x;
683 ie->load_opts.region.w = load_region_h;
684 ie->load_opts.region.h = load_region_w;
691 #ifdef BUILD_LOADER_JPEG_REGION
692 cinfo.region_x = ie->load_opts.region.x;
693 cinfo.region_y = ie->load_opts.region.y;
694 cinfo.region_w = ie->load_opts.region.w;
695 cinfo.region_h = ie->load_opts.region.h;
698 if ((!region) && ((w != ie_w) || (h != ie_h)))
700 // race condition, the file could have change from when we call header
701 // this test will not solve the problem with region code.
702 jpeg_destroy_decompress(&cinfo);
703 _evas_jpeg_membuf_src_term(&cinfo);
704 *error = EVAS_LOAD_ERROR_GENERIC;
708 ((ie_w != ie->load_opts.region.w) || (ie_h != ie->load_opts.region.h)))
710 ie_w = ie->load_opts.region.w;
711 ie_h = ie->load_opts.region.h;
725 if (!(((cinfo.out_color_space == JCS_RGB) &&
726 ((cinfo.output_components == 3) || (cinfo.output_components == 1))) ||
727 ((cinfo.out_color_space == JCS_CMYK) && (cinfo.output_components == 4))))
729 jpeg_destroy_decompress(&cinfo);
730 _evas_jpeg_membuf_src_term(&cinfo);
731 *error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
735 /* end head decoding */
737 if (cinfo.rec_outbuf_height > 16)
739 jpeg_destroy_decompress(&cinfo);
740 _evas_jpeg_membuf_src_term(&cinfo);
741 *error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
744 data = alloca(w * 16 * cinfo.output_components);
745 evas_cache_image_surface_alloc(ie, ie->w, ie->h);
746 if (ie->flags.loaded)
748 jpeg_destroy_decompress(&cinfo);
749 _evas_jpeg_membuf_src_term(&cinfo);
750 *error = EVAS_LOAD_ERROR_NONE;
751 if (region && ie->flags.rotated)
753 ie->load_opts.region.x = load_region_x;
754 ie->load_opts.region.y = load_region_y;
755 ie->load_opts.region.w = load_region_w;
756 ie->load_opts.region.h = load_region_h;
760 if ((ie->flags.rotated) && change_wh)
762 ptr2 = malloc(ie->w * ie->h * sizeof(DATA32));
766 ptr2 = evas_cache_image_pixels(ie);
770 *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
774 /* We handle first CMYK (4 components) */
775 if (cinfo.output_components == 4)
777 // FIXME: handle region
778 for (i = 0; (int)i < cinfo.rec_outbuf_height; i++)
779 line[i] = data + (i * w * 4);
780 for (l = 0; l < h; l += cinfo.rec_outbuf_height)
782 jpeg_read_scanlines(&cinfo, line, cinfo.rec_outbuf_height);
783 scans = cinfo.rec_outbuf_height;
784 if ((h - l) < scans) scans = h - l;
788 for (y = 0; y < scans; y++)
790 if (cinfo.saw_Adobe_marker)
792 for (x = 0; x < w; x++)
794 /* According to libjpeg doc, Photoshop inverse the values of C, M, Y and K, */
795 /* that is C is replaces by 255 - C, etc...*/
796 /* See the comment below for the computation of RGB values from CMYK ones. */
799 ((ptr[0] * ptr[3] / 255) << 16) |
800 ((ptr[1] * ptr[3] / 255) << 8) |
801 ((ptr[2] * ptr[3] / 255));
808 for (x = 0; x < w; x++)
810 /* Conversion from CMYK to RGB is done in 2 steps: */
811 /* CMYK => CMY => RGB (see http://www.easyrgb.com/index.php?X=MATH) */
812 /* after computation, if C, M, Y and K are between 0 and 1, we have: */
813 /* R = (1 - C) * (1 - K) * 255 */
814 /* G = (1 - M) * (1 - K) * 255 */
815 /* B = (1 - Y) * (1 - K) * 255 */
816 /* libjpeg stores CMYK values between 0 and 255, */
817 /* so we replace C by C * 255 / 255, etc... and we obtain: */
818 /* R = (255 - C) * (255 - K) / 255 */
819 /* G = (255 - M) * (255 - K) / 255 */
820 /* B = (255 - Y) * (255 - K) / 255 */
821 /* with C, M, Y and K between 0 and 255. */
824 (((255 - ptr[0]) * (255 - ptr[3]) / 255) << 16) |
825 (((255 - ptr[1]) * (255 - ptr[3]) / 255) << 8) |
826 (((255 - ptr[2]) * (255 - ptr[3]) / 255));
835 // if line # > region last line, break
836 if (l >= (ie->load_opts.region.y + ie->load_opts.region.h))
838 line_done = EINA_TRUE;
839 /* if rotation flag is set , we have to rotate image */
841 /*jpeg_destroy_decompress(&cinfo);
842 _evas_jpeg_membuf_src_term(&cinfo);
843 *error = EVAS_LOAD_ERROR_NONE;
846 // els if scan block intersects region start or later
847 else if ((l + scans) >
848 (ie->load_opts.region.y))
850 for (y = 0; y < scans; y++)
852 if (((y + l) >= ie->load_opts.region.y) &&
853 ((y + l) < (ie->load_opts.region.y + ie->load_opts.region.h)))
855 ptr += ie->load_opts.region.x;
856 if (cinfo.saw_Adobe_marker)
858 for (x = 0; x < ie->load_opts.region.w; x++)
860 /* According to libjpeg doc, Photoshop inverse the values of C, M, Y and K, */
861 /* that is C is replaces by 255 - C, etc...*/
862 /* See the comment below for the computation of RGB values from CMYK ones. */
865 ((ptr[0] * ptr[3] / 255) << 16) |
866 ((ptr[1] * ptr[3] / 255) << 8) |
867 ((ptr[2] * ptr[3] / 255));
874 for (x = 0; x < ie->load_opts.region.w; x++)
876 /* Conversion from CMYK to RGB is done in 2 steps: */
877 /* CMYK => CMY => RGB (see http://www.easyrgb.com/index.php?X=MATH) */
878 /* after computation, if C, M, Y and K are between 0 and 1, we have: */
879 /* R = (1 - C) * (1 - K) * 255 */
880 /* G = (1 - M) * (1 - K) * 255 */
881 /* B = (1 - Y) * (1 - K) * 255 */
882 /* libjpeg stores CMYK values between 0 and 255, */
883 /* so we replace C by C * 255 / 255, etc... and we obtain: */
884 /* R = (255 - C) * (255 - K) / 255 */
885 /* G = (255 - M) * (255 - K) / 255 */
886 /* B = (255 - Y) * (255 - K) / 255 */
887 /* with C, M, Y and K between 0 and 255. */
890 (((255 - ptr[0]) * (255 - ptr[3]) / 255) << 16) |
891 (((255 - ptr[1]) * (255 - ptr[3]) / 255) << 8) |
892 (((255 - ptr[2]) * (255 - ptr[3]) / 255));
897 ptr += (4 * (w - (ie->load_opts.region.x + ie->load_opts.region.w)));
906 /* We handle then RGB with 3 components */
907 else if (cinfo.output_components == 3)
914 printf("R| %p %5ix%5i %s: %5i %5i %5ix%5i - ",
918 ie->load_opts.region.x,
919 ie->load_opts.region.y,
920 ie->load_opts.region.w,
921 ie->load_opts.region.h);
925 for (i = 0; (int)i < cinfo.rec_outbuf_height; i++)
926 line[i] = data + (i * w * 3);
927 for (l = 0; l < h; l += cinfo.rec_outbuf_height)
929 jpeg_read_scanlines(&cinfo, line, cinfo.rec_outbuf_height);
930 scans = cinfo.rec_outbuf_height;
931 if ((h - l) < scans) scans = h - l;
935 for (y = 0; y < scans; y++)
937 for (x = 0; x < w; x++)
939 *ptr2 = ARGB_JOIN(0xff, ptr[0], ptr[1], ptr[2]);
947 // if line # > region last line, break
948 // but not return immediately for rotation job
949 if (l >= (ie->load_opts.region.y + ie->load_opts.region.h))
951 line_done = EINA_TRUE;
952 /* if rotation flag is set , we have to rotate image */
955 // else if scan block intersects region start or later
956 else if ((l + scans) >
957 (ie->load_opts.region.y))
959 for (y = 0; y < scans; y++)
961 if (((y + l) >= ie->load_opts.region.y) &&
962 ((y + l) < (ie->load_opts.region.y + ie->load_opts.region.h)))
964 ptr += (3 * ie->load_opts.region.x);
965 for (x = 0; x < ie->load_opts.region.w; x++)
967 *ptr2 = ARGB_JOIN(0xff, ptr[0], ptr[1], ptr[2]);
971 ptr += (3 * (w - (ie->load_opts.region.x + ie->load_opts.region.w)));
981 printf("%3.3f\n", t);
984 /* We finally handle RGB with 1 component */
985 else if (cinfo.output_components == 1)
987 for (i = 0; (int)i < cinfo.rec_outbuf_height; i++)
988 line[i] = data + (i * w);
989 for (l = 0; l < h; l += cinfo.rec_outbuf_height)
991 jpeg_read_scanlines(&cinfo, line, cinfo.rec_outbuf_height);
992 scans = cinfo.rec_outbuf_height;
993 if ((h - l) < scans) scans = h - l;
997 for (y = 0; y < scans; y++)
999 for (x = 0; x < w; x++)
1001 *ptr2 = ARGB_JOIN(0xff, ptr[0], ptr[0], ptr[0]);
1009 // if line # > region last line, break
1010 if (l >= (ie->load_opts.region.y + ie->load_opts.region.h))
1012 line_done = EINA_TRUE;
1013 /* if rotation flag is set , we have to rotate image */
1015 /*jpeg_destroy_decompress(&cinfo);
1016 _evas_jpeg_membuf_src_term(&cinfo);
1017 *error = EVAS_LOAD_ERROR_NONE;
1020 // els if scan block intersects region start or later
1021 else if ((l + scans) >
1022 (ie->load_opts.region.y))
1024 for (y = 0; y < scans; y++)
1026 if (((y + l) >= ie->load_opts.region.y) &&
1027 ((y + l) < (ie->load_opts.region.y + ie->load_opts.region.h)))
1029 ptr += ie->load_opts.region.x;
1030 for (x = 0; x < ie->load_opts.region.w; x++)
1032 *ptr2 = ARGB_JOIN(0xff, ptr[0], ptr[0], ptr[0]);
1036 ptr += w - (ie->load_opts.region.x + ie->load_opts.region.w);
1045 /* if rotation operation need, rotate it */
1048 if (ie->flags.rotated)
1050 DATA32 *data1, *data2, *to, *from;
1051 int lx, ly, lw, lh, hw;
1057 data1 = evas_cache_image_pixels(ie);
1063 data2 = data1 + (lh * lw) -1;
1064 for (lx = (lw * lh) / 2; --lx >= 0;)
1077 if (ptr_rotate) data2 = ptr_rotate;
1081 to = data1 + lw - 1;
1084 else if (degree == 270)
1086 to = data1 + hw - lw;
1094 for (lx = ie->w; --lx >= 0;)
1096 for (ly =ie->h; --ly >= 0;)
1113 ie->load_opts.region.x = load_region_x;
1114 ie->load_opts.region.y = load_region_y;
1115 ie->load_opts.region.w = load_region_w;
1116 ie->load_opts.region.h = load_region_h;
1122 jpeg_destroy_decompress(&cinfo);
1123 _evas_jpeg_membuf_src_term(&cinfo);
1124 *error = EVAS_LOAD_ERROR_NONE;
1127 /* end data decoding */
1128 jpeg_finish_decompress(&cinfo);
1129 jpeg_destroy_decompress(&cinfo);
1130 _evas_jpeg_membuf_src_term(&cinfo);
1131 *error = EVAS_LOAD_ERROR_NONE;
1135 #if 0 /* not used at the moment */
1137 evas_image_load_file_data_jpeg_alpha_internal(Image_Entry *ie, FILE *f, int *error)
1140 struct jpeg_decompress_struct cinfo;
1141 struct _JPEG_error_mgr jerr;
1142 DATA8 *ptr, *line[16], *data;
1144 int x, y, l, i, scans, prevy;
1148 *error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
1151 cinfo.err = jpeg_std_error(&(jerr.pub));
1152 jerr.pub.error_exit = _JPEGFatalErrorHandler;
1153 jerr.pub.emit_message = _JPEGErrorHandler2;
1154 jerr.pub.output_message = _JPEGErrorHandler;
1155 if (setjmp(jerr.setjmp_buffer))
1157 jpeg_destroy_decompress(&cinfo);
1158 *error = EVAS_LOAD_ERROR_CORRUPT_FILE;
1161 jpeg_create_decompress(&cinfo);
1162 jpeg_stdio_src(&cinfo, f);
1163 jpeg_read_header(&cinfo, TRUE);
1164 cinfo.do_fancy_upsampling = FALSE;
1165 cinfo.do_block_smoothing = FALSE;
1166 jpeg_start_decompress(&cinfo);
1169 ie->w = w = cinfo.output_width;
1170 ie->h = h = cinfo.output_height;
1171 /* end head decoding */
1173 if (cinfo.rec_outbuf_height > 16)
1175 jpeg_destroy_decompress(&cinfo);
1176 *error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
1179 data = alloca(w * 16 * 3);
1180 if (!ie->flags.loaded)
1182 jpeg_destroy_decompress(&cinfo);
1183 *error = EVAS_LOAD_ERROR_NONE;
1186 ptr2 = evas_cache_image_pixels(ie);
1188 if (cinfo.output_components == 3)
1190 for (i = 0; i < cinfo.rec_outbuf_height; i++)
1191 line[i] = data + (i * w * 3);
1192 for (l = 0; l < h; l += cinfo.rec_outbuf_height)
1194 jpeg_read_scanlines(&cinfo, line, cinfo.rec_outbuf_height);
1195 scans = cinfo.rec_outbuf_height;
1196 if ((h - l) < scans) scans = h - l;
1198 for (y = 0; y < scans; y++)
1200 for (x = 0; x < w; x++)
1203 ((*ptr2) & 0x00ffffff) |
1204 (((ptr[0] + ptr[1] + ptr[2]) / 3) << 24);
1211 else if (cinfo.output_components == 1)
1213 for (i = 0; i < cinfo.rec_outbuf_height; i++)
1214 line[i] = data + (i * w);
1215 for (l = 0; l < h; l += cinfo.rec_outbuf_height)
1217 jpeg_read_scanlines(&cinfo, line, cinfo.rec_outbuf_height);
1218 scans = cinfo.rec_outbuf_height;
1219 if ((h - l) < scans) scans = h - l;
1221 for (y = 0; y < scans; y++)
1223 for (x = 0; x < w; x++)
1226 ((*ptr2) & 0x00ffffff) |
1234 /* end data decoding */
1235 jpeg_finish_decompress(&cinfo);
1236 jpeg_destroy_decompress(&cinfo);
1237 *error = EVAS_LOAD_ERROR_NONE;
1243 evas_image_load_file_head_jpeg(Image_Entry *ie,
1244 const char *file, const char *key __UNUSED__,
1249 Eina_Bool val = EINA_FALSE;
1251 f = eina_file_open(file, EINA_FALSE);
1254 *error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
1257 map = eina_file_map_all(f, EINA_FILE_WILLNEED);
1260 *error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
1264 val = evas_image_load_file_head_jpeg_internal(ie,
1265 map, eina_file_size_get(f),
1268 eina_file_map_free(f, map);
1276 evas_image_load_file_data_jpeg(Image_Entry *ie,
1277 const char *file, const char *key __UNUSED__,
1282 Eina_Bool val = EINA_FALSE;
1284 f = eina_file_open(file, EINA_FALSE);
1287 *error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
1290 map = eina_file_map_all(f, EINA_FILE_WILLNEED);
1293 *error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
1297 val = evas_image_load_file_data_jpeg_internal(ie,
1298 map, eina_file_size_get(f),
1301 eina_file_map_free(f, map);
1309 module_open(Evas_Module *em)
1312 em->functions = (void *)(&evas_image_load_jpeg_func);
1317 module_close(Evas_Module *em __UNUSED__)
1321 static Evas_Module_Api evas_modapi =
1323 EVAS_MODULE_API_VERSION,
1332 EVAS_MODULE_DEFINE(EVAS_MODULE_TYPE_IMAGE_LOADER, image_loader, jpeg);
1334 #ifndef EVAS_STATIC_BUILD_JPEG
1335 EVAS_EINA_MODULE_DEFINE(image_loader, jpeg);