summaryrefslogtreecommitdiff
path: root/src/lib/eet
diff options
context:
space:
mode:
authorCedric BAIL <cedric@osg.samsung.com>2015-03-17 08:50:23 +0100
committerCedric BAIL <cedric@osg.samsung.com>2015-03-17 09:58:19 +0100
commitc221f33428ff8dfb8e8754573bdda7c72c4ffe71 (patch)
tree75fa3ceb38de05db268c6cf7c6f038362c55b239 /src/lib/eet
parentbafe5e9a7485db51d4cc52281fea6af6e7531934 (diff)
eet: use Emile to decode jpeg.
Diffstat (limited to 'src/lib/eet')
-rw-r--r--src/lib/eet/eet_image.c422
1 files changed, 97 insertions, 325 deletions
diff --git a/src/lib/eet/eet_image.c b/src/lib/eet/eet_image.c
index f6aee861d9..6cc05e59fd 100644
--- a/src/lib/eet/eet_image.c
+++ b/src/lib/eet/eet_image.c
@@ -72,80 +72,6 @@ struct _JPEG_error_mgr
72 jmp_buf setjmp_buffer; 72 jmp_buf setjmp_buffer;
73}; 73};
74 74
75struct jpeg_membuf_src
76{
77 struct jpeg_source_mgr pub;
78
79 const unsigned char *buf;
80 size_t len;
81 struct jpeg_membuf_src *self;
82};
83
84static void
85_eet_jpeg_membuf_src_init(j_decompress_ptr cinfo)
86{
87 /* FIXME: Use attribute unused */
88 (void)cinfo;
89}
90
91static boolean
92_eet_jpeg_membuf_src_fill(j_decompress_ptr cinfo)
93{
94 static const JOCTET jpeg_eoi[2] = { 0xFF, JPEG_EOI };
95 struct jpeg_membuf_src *src = (struct jpeg_membuf_src *)cinfo->src;
96
97 src->pub.bytes_in_buffer = sizeof(jpeg_eoi);
98 src->pub.next_input_byte = jpeg_eoi;
99
100 return TRUE;
101}
102
103static void
104_eet_jpeg_membuf_src_skip(j_decompress_ptr cinfo,
105 long num_bytes)
106{
107 struct jpeg_membuf_src *src = (struct jpeg_membuf_src *)cinfo->src;
108
109 src->pub.bytes_in_buffer -= num_bytes;
110 src->pub.next_input_byte += num_bytes;
111}
112
113static void
114_eet_jpeg_membuf_src_term(j_decompress_ptr cinfo)
115{
116 struct jpeg_membuf_src *src = ((struct jpeg_membuf_src *)cinfo->src)->self;
117
118 free(src);
119 cinfo->src = NULL;
120}
121
122static int
123eet_jpeg_membuf_src(j_decompress_ptr cinfo,
124 const void *buf,
125 size_t len)
126{
127 struct jpeg_membuf_src *src;
128
129 src = calloc(1, sizeof(*src));
130 if (!src)
131 return -1;
132
133 src->self = src;
134
135 cinfo->src = &src->pub;
136 src->buf = buf;
137 src->len = len;
138 src->pub.init_source = _eet_jpeg_membuf_src_init;
139 src->pub.fill_input_buffer = _eet_jpeg_membuf_src_fill;
140 src->pub.skip_input_data = _eet_jpeg_membuf_src_skip;
141 src->pub.resync_to_restart = jpeg_resync_to_restart;
142 src->pub.term_source = _eet_jpeg_membuf_src_term;
143 src->pub.bytes_in_buffer = src->len;
144 src->pub.next_input_byte = src->buf;
145
146 return 0;
147}
148
149struct jpeg_membuf_dst 75struct jpeg_membuf_dst
150{ 76{
151 struct jpeg_destination_mgr pub; 77 struct jpeg_destination_mgr pub;
@@ -163,7 +89,7 @@ static void
163_eet_jpeg_membuf_dst_init(j_compress_ptr cinfo) 89_eet_jpeg_membuf_dst_init(j_compress_ptr cinfo)
164{ 90{
165 /* FIXME: Use eina attribute */ 91 /* FIXME: Use eina attribute */
166 (void)cinfo; 92 (void)cinfo;
167} 93}
168 94
169static boolean 95static boolean
@@ -181,13 +107,13 @@ _eet_jpeg_membuf_dst_flush(j_compress_ptr cinfo)
181 return TRUE; 107 return TRUE;
182 } 108 }
183 109
184 dst->pub.next_output_byte = 110 dst->pub.next_output_byte =
185 buf + ((unsigned char *)dst->pub.next_output_byte - dst->buf); 111 buf + ((unsigned char *)dst->pub.next_output_byte - dst->buf);
186 dst->buf = buf; 112 dst->buf = buf;
187 dst->pub.free_in_buffer += dst->len; 113 dst->pub.free_in_buffer += dst->len;
188 dst->len *= 2; 114 dst->len *= 2;
189 115
190 return FALSE; 116 return FALSE;
191} 117}
192 118
193static void 119static void
@@ -247,11 +173,6 @@ eet_jpeg_membuf_dst(j_compress_ptr cinfo,
247 173
248/*---*/ 174/*---*/
249 175
250static void _eet_image_jpeg_error_exit_cb(j_common_ptr cinfo);
251static void _eet_image_jpeg_output_message_cb(j_common_ptr cinfo);
252static void _eet_image_jpeg_emit_message_cb(j_common_ptr cinfo,
253 int msg_level);
254
255static int 176static int
256eet_data_image_jpeg_header_decode(const void *data, 177eet_data_image_jpeg_header_decode(const void *data,
257 int size, 178 int size,
@@ -424,44 +345,40 @@ eet_data_image_jpeg_header_decode(const void *data,
424 unsigned int *w, 345 unsigned int *w,
425 unsigned int *h) 346 unsigned int *h)
426{ 347{
427 struct jpeg_decompress_struct cinfo; 348 Emile_Image_Load_Opts opts;
428 struct _JPEG_error_mgr jerr; 349 Emile_Image_Property prop;
350 Eina_Binbuf *bin;
351 Emile_Image *image;
352 Emile_Image_Load_Error error;
353 int r = 0;
429 354
430 memset(&cinfo, 0, sizeof (struct jpeg_decompress_struct)); 355 bin = eina_binbuf_manage_read_only_new_length(data, size);
356 if (!bin) return 0;
431 357
432 cinfo.err = jpeg_std_error(&(jerr.pub)); 358 memset(&opts, 0, sizeof (Emile_Image_Load_Opts));
433 jerr.pub.error_exit = _eet_image_jpeg_error_exit_cb;
434 jerr.pub.emit_message = _eet_image_jpeg_emit_message_cb;
435 jerr.pub.output_message = _eet_image_jpeg_output_message_cb;
436 if (setjmp(jerr.setjmp_buffer))
437 return 0;
438 359
439 jpeg_create_decompress(&cinfo); 360 image = emile_image_jpeg_memory_open(bin, &opts, NULL, &error);
361 if (!image) goto on_error;
440 362
441 if (eet_jpeg_membuf_src(&cinfo, data, (size_t)size)) 363 memset(&prop, 0, sizeof (prop));
442 {
443 jpeg_destroy_decompress(&cinfo);
444 return 0;
445 }
446 364
447 jpeg_read_header(&cinfo, TRUE); 365 if (!emile_image_head(image, &prop, sizeof (Emile_Image_Property), &error))
448 cinfo.do_fancy_upsampling = FALSE; 366 goto on_error;
449 cinfo.do_block_smoothing = FALSE;
450 jpeg_start_decompress(&cinfo);
451 367
452 /* head decoding */ 368 *w = prop.w;
453 *w = cinfo.output_width; 369 *h = prop.h;
454 *h = cinfo.output_height;
455 370
456 free(cinfo.src); 371 if (*w > 0 && *w <= 8192 &&
457 cinfo.src = NULL; 372 *h > 0 && *h <= 8192)
373 r = 1;
458 374
459 jpeg_destroy_decompress(&cinfo); 375 on_error:
376 fprintf(stderr, "eet_data_image_jpeg_header_decode: %i [%i, %i]\n", r, *w, *h);
460 377
461 if ((*w < 1) || (*h < 1) || (*w > 8192) || (*h > 8192)) 378 emile_image_close(image);
462 return 0; 379 eina_binbuf_free(bin);
463 380
464 return 1; 381 return r;
465} 382}
466 383
467static int 384static int
@@ -474,147 +391,48 @@ eet_data_image_jpeg_rgb_decode(const void *data,
474 unsigned int h, 391 unsigned int h,
475 unsigned int row_stride) 392 unsigned int row_stride)
476{ 393{
477 struct jpeg_decompress_struct cinfo; 394 Emile_Image_Load_Opts opts;
478 struct _JPEG_error_mgr jerr; 395 Emile_Image_Property prop;
479 unsigned char *ptr, *line[16], *tdata = NULL; 396 Emile_Image *image;
480 unsigned int *ptr2, *tmp; 397 Eina_Binbuf *bin;
481 unsigned int iw, ih; 398 Emile_Image_Load_Error error;
482 unsigned int x, y, l, scans; 399 int r = 0;
483 unsigned int i;
484 400
485 /* FIXME: handle src_x, src_y and row_stride correctly */ 401 /* FIXME: handle src_x, src_y and row_stride correctly */
486 if (!d) 402 if (!d)
487 return 0; 403 return 0;
488 404
489 memset(&cinfo, 0, sizeof (struct jpeg_decompress_struct)); 405 // Fix for ABI incompatibility between 1.10 and 1.11
490 406 /* if (cspace == 8) cspace = 9; */
491 cinfo.err = jpeg_std_error(&(jerr.pub));
492 jerr.pub.error_exit = _eet_image_jpeg_error_exit_cb;
493 jerr.pub.emit_message = _eet_image_jpeg_emit_message_cb;
494 jerr.pub.output_message = _eet_image_jpeg_output_message_cb;
495 if (setjmp(jerr.setjmp_buffer))
496 return 0;
497
498 jpeg_create_decompress(&cinfo);
499
500 if (eet_jpeg_membuf_src(&cinfo, data, (size_t)size))
501 {
502 jpeg_destroy_decompress(&cinfo);
503 return 0;
504 }
505
506 jpeg_read_header(&cinfo, TRUE);
507 cinfo.dct_method = JDCT_ISLOW; // JDCT_FLOAT JDCT_IFAST(quality loss)
508 cinfo.do_fancy_upsampling = FALSE;
509 cinfo.do_block_smoothing = FALSE;
510 jpeg_start_decompress(&cinfo);
511
512 /* head decoding */
513 iw = cinfo.output_width;
514 ih = cinfo.output_height;
515 if ((iw != w) || (ih != h))
516 {
517 free(cinfo.src);
518 cinfo.src = NULL;
519
520 jpeg_destroy_decompress(&cinfo);
521 return 0;
522 }
523
524 /* end head decoding */
525 /* data decoding */
526 if (cinfo.rec_outbuf_height > 16)
527 {
528 free(cinfo.src);
529 cinfo.src = NULL;
530 407
531 jpeg_destroy_decompress(&cinfo); 408 bin = eina_binbuf_manage_read_only_new_length(data, size);
532 return 0; 409 if (!bin) return 0;
533 }
534 410
535 tdata = alloca((iw) * 16 * 3); 411 memset(&opts, 0, sizeof (Emile_Image_Load_Opts));
536 ptr2 = d; 412 opts.region.x = src_x;
413 opts.region.y = src_y;
414 opts.region.w = w;
415 opts.region.h = h;
537 416
538 if (cinfo.output_components == 3) 417 image = emile_image_jpeg_memory_open(bin, &opts, NULL, &error);
539 { 418 if (!image) goto on_error;
540 for (i = 0; i < (unsigned int)cinfo.rec_outbuf_height; i++)
541 line[i] = tdata + (i * (iw) * 3);
542 for (l = 0; l < ih; l += cinfo.rec_outbuf_height)
543 {
544 jpeg_read_scanlines(&cinfo, line, cinfo.rec_outbuf_height);
545 scans = cinfo.rec_outbuf_height;
546 if ((ih - l) < scans)
547 scans = ih - l;
548 419
549 ptr = tdata; 420 memset(&prop, 0, sizeof (prop));
550 421
551 if (l + scans >= src_y && l < src_y + h) 422 if (!emile_image_head(image, &prop, sizeof (Emile_Image_Property), &error))
552 { 423 goto on_error;
553 y = src_y - l;
554 if (src_y < l)
555 y = 0;
556
557 for (ptr += 3 * iw * y; y < scans && (y + l) < (src_y + h);
558 y++)
559 {
560 tmp = ptr2;
561 ptr += 3 * src_x;
562 for (x = 0; x < w; x++)
563 {
564 *ptr2 =
565 (0xff000000) |
566 ((ptr[0]) << 16) | ((ptr[1]) << 8) | (ptr[2]);
567 ptr += 3;
568 ptr2++;
569 }
570 ptr += 3 * (iw - w);
571 ptr2 = tmp + row_stride / 4;
572 }
573 }
574 }
575 }
576 else if (cinfo.output_components == 1)
577 {
578 for (i = 0; i < (unsigned int)cinfo.rec_outbuf_height; i++)
579 line[i] = tdata + (i * (iw));
580 for (l = 0; l < (ih); l += cinfo.rec_outbuf_height)
581 {
582 jpeg_read_scanlines(&cinfo, line, cinfo.rec_outbuf_height);
583 scans = cinfo.rec_outbuf_height;
584 if (((ih) - l) < scans)
585 scans = (ih) - l;
586 424
587 ptr = tdata; 425 // FIXME: Change prototype to handle color space and destination region (w, h)
426 if (!emile_image_data(image, &prop, sizeof (Emile_Image_Property), d, &error))
427 goto on_error;
588 428
589 if (l >= src_y && l < src_y + h) 429 r = 1;
590 {
591 y = src_y - l;
592 if (src_y < l)
593 y = 0;
594 430
595 for (ptr += iw * y; y < scans && (y + l) < (src_y + h); y++) 431 on_error:
596 { 432 emile_image_close(image);
597 tmp = ptr2; 433 eina_binbuf_free(bin);
598 ptr += src_x;
599 for (x = 0; x < w; x++)
600 {
601 *ptr2 =
602 (0xff000000) |
603 ((ptr[0]) << 16) | ((ptr[0]) << 8) | (ptr[0]);
604 ptr++;
605 ptr2++;
606 }
607 ptr += iw - w;
608 ptr2 = tmp + row_stride / 4;
609 }
610 }
611 }
612 }
613 434
614 /* end data decoding */ 435 return r;
615 jpeg_finish_decompress(&cinfo);
616 jpeg_destroy_decompress(&cinfo);
617 return 1;
618} 436}
619 437
620static int 438static int
@@ -627,108 +445,62 @@ eet_data_image_jpeg_alpha_decode(const void *data,
627 unsigned int h, 445 unsigned int h,
628 unsigned int row_stride) 446 unsigned int row_stride)
629{ 447{
630 struct jpeg_decompress_struct cinfo; 448 Emile_Image_Load_Opts opts;
631 struct _JPEG_error_mgr jerr; 449 Emile_Image_Property prop;
632 unsigned char *ptr, *line[16], *tdata = NULL; 450 Emile_Image *image;
633 unsigned int *ptr2, *tmp; 451 Eina_Binbuf *bin;
634 unsigned int x, y, l, scans; 452 unsigned char *remember = NULL, *tmp;
635 unsigned int i, iw; 453 Emile_Image_Load_Error error;
454 int r = 0;
455 unsigned int i;
636 456
637 /* FIXME: handle src_x, src_y and row_stride correctly */ 457 /* FIXME: handle src_x, src_y and row_stride correctly */
638 if (!d) 458 if (!d)
639 return 0; 459 return 0;
640 460
641 memset(&cinfo, 0, sizeof (struct jpeg_decompress_struct)); 461 bin = eina_binbuf_manage_read_only_new_length(data, size);
642 462 if (!bin) return 0;
643 cinfo.err = jpeg_std_error(&(jerr.pub));
644 jerr.pub.error_exit = _eet_image_jpeg_error_exit_cb;
645 jerr.pub.emit_message = _eet_image_jpeg_emit_message_cb;
646 jerr.pub.output_message = _eet_image_jpeg_output_message_cb;
647 if (setjmp(jerr.setjmp_buffer))
648 return 0;
649 463
650 jpeg_create_decompress(&cinfo); 464 memset(&opts, 0, sizeof (Emile_Image_Load_Opts));
465 opts.region.x = src_x;
466 opts.region.y = src_y;
467 opts.region.w = w;
468 opts.region.h = h;
651 469
652 if (eet_jpeg_membuf_src(&cinfo, data, (size_t)size)) 470 image = emile_image_jpeg_memory_open(bin, &opts, NULL, &error);
653 { 471 if (!image) goto on_error;
654 jpeg_destroy_decompress(&cinfo);
655 return 0;
656 }
657 472
658 jpeg_read_header(&cinfo, TRUE); 473 memset(&prop, 0, sizeof (prop));
659 cinfo.dct_method = JDCT_ISLOW; // JDCT_FLOAT JDCT_IFAST(quality loss)
660 cinfo.do_fancy_upsampling = FALSE;
661 cinfo.do_block_smoothing = FALSE;
662 jpeg_start_decompress(&cinfo);
663
664 /* head decoding */
665 iw = cinfo.output_width;
666 if (w != cinfo.output_width
667 || h != cinfo.output_height)
668 {
669 free(cinfo.src);
670 cinfo.src = NULL;
671 474
672 jpeg_destroy_decompress(&cinfo); 475 if (!emile_image_head(image, &prop, sizeof (Emile_Image_Property), &error))
673 return 0; 476 goto on_error;
674 }
675 477
676 /* end head decoding */ 478 remember = tmp = malloc(sizeof (unsigned char) * w * h);
677 /* data decoding */ 479 if (!tmp) goto on_error;
678 if (cinfo.rec_outbuf_height > 16)
679 {
680 free(cinfo.src);
681 cinfo.src = NULL;
682 480
683 jpeg_destroy_decompress(&cinfo); 481 // Alpha should always be encoded as GRY8
684 return 0; 482 prop.cspace = EMILE_COLORSPACE_GRY8;
685 }
686 483
687 tdata = alloca(w * 16 * 3); 484 if (!emile_image_data(image, &prop, sizeof (Emile_Image_Property), tmp, &error))
688 ptr2 = d; 485 goto on_error;
689 486
690 if (cinfo.output_components == 1) 487 for (i = 0; i < w * h; i++)
691 { 488 {
692 for (i = 0; i < (unsigned int)cinfo.rec_outbuf_height; i++) 489 *d = ((*d) & 0x00ffffff) |
693 line[i] = tdata + (i * w); 490 ((*tmp) << 24);
694 for (l = 0; l < h; l += cinfo.rec_outbuf_height) 491 tmp++;
695 { 492 d++;
696 jpeg_read_scanlines(&cinfo, line, cinfo.rec_outbuf_height); 493 }
697 scans = cinfo.rec_outbuf_height;
698 if ((h - l) < scans)
699 scans = h - l;
700 494
701 ptr = tdata; 495 r = 1;
702 496
703 if (l >= src_y && l < src_y + h) 497 on_error:
704 { 498 free(remember);
705 y = src_y - l;
706 if (src_y < l)
707 y = 0;
708 499
709 for (ptr += iw * y; y < scans && (y + l) < (src_y + h); y++) 500 emile_image_close(image);
710 { 501 eina_binbuf_free(bin);
711 tmp = ptr2;
712 ptr += src_x;
713 for (x = 0; x < w; x++)
714 {
715 *ptr2 =
716 ((*ptr2) & 0x00ffffff) |
717 ((ptr[0]) << 24);
718 ptr++;
719 ptr2++;
720 }
721 ptr += iw - w;
722 ptr2 = tmp + row_stride / 4;
723 }
724 }
725 }
726 }
727 502
728 /* end data decoding */ 503 return r;
729 jpeg_finish_decompress(&cinfo);
730 jpeg_destroy_decompress(&cinfo);
731 return 1;
732} 504}
733 505
734// FIXME: Importing two functions from evas here: premul & unpremul 506// FIXME: Importing two functions from evas here: premul & unpremul