aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/eet/src/lib/eet_image.c
diff options
context:
space:
mode:
Diffstat (limited to 'libraries/eet/src/lib/eet_image.c')
-rw-r--r--libraries/eet/src/lib/eet_image.c1820
1 files changed, 1820 insertions, 0 deletions
diff --git a/libraries/eet/src/lib/eet_image.c b/libraries/eet/src/lib/eet_image.c
new file mode 100644
index 0000000..79f6f90
--- /dev/null
+++ b/libraries/eet/src/lib/eet_image.c
@@ -0,0 +1,1820 @@
1#ifdef HAVE_CONFIG_H
2# include <config.h>
3#endif /* ifdef HAVE_CONFIG_H */
4
5#ifdef HAVE_ALLOCA_H
6# include <alloca.h>
7#elif defined __GNUC__
8# define alloca __builtin_alloca
9#elif defined _AIX
10# define alloca __alloca
11#elif defined _MSC_VER
12# include <malloc.h>
13# define alloca _alloca
14#else /* ifdef HAVE_ALLOCA_H */
15# include <stddef.h>
16# ifdef __cplusplus
17extern "C"
18# endif /* ifdef __cplusplus */
19void *alloca(size_t);
20#endif /* ifdef HAVE_ALLOCA_H */
21
22#ifdef HAVE_NETINET_IN_H
23# ifdef __OpenBSD__
24# include <sys/types.h>
25# endif /* ifdef __OpenBSD__ */
26# include <netinet/in.h>
27#endif /* ifdef HAVE_NETINET_IN_H */
28
29#ifdef _WIN32
30# include <winsock2.h>
31# define HAVE_BOOLEAN
32#endif /* ifdef _WIN32 */
33
34#include <stdio.h>
35#include <string.h>
36#include <setjmp.h>
37#include <zlib.h>
38#include <jpeglib.h>
39
40#include "Eet.h"
41#include "Eet_private.h"
42
43/*---*/
44
45typedef struct _JPEG_error_mgr *emptr;
46
47/*---*/
48
49struct _JPEG_error_mgr
50{
51 struct jpeg_error_mgr pub;
52 jmp_buf setjmp_buffer;
53};
54
55struct jpeg_membuf_src
56{
57 struct jpeg_source_mgr pub;
58
59 const unsigned char *buf;
60 size_t len;
61 struct jpeg_membuf_src *self;
62};
63
64static void
65_eet_jpeg_membuf_src_init(j_decompress_ptr cinfo)
66{
67 /* FIXME: Use attribute unused */
68 (void)cinfo;
69} /* _eet_jpeg_membuf_src_init */
70
71static boolean
72_eet_jpeg_membuf_src_fill(j_decompress_ptr cinfo)
73{
74 static const JOCTET jpeg_eoi[2] = { 0xFF, JPEG_EOI };
75 struct jpeg_membuf_src *src = (struct jpeg_membuf_src *)cinfo->src;
76
77 src->pub.bytes_in_buffer = sizeof(jpeg_eoi);
78 src->pub.next_input_byte = jpeg_eoi;
79
80 return TRUE;
81} /* _eet_jpeg_membuf_src_fill */
82
83static void
84_eet_jpeg_membuf_src_skip(j_decompress_ptr cinfo,
85 long num_bytes)
86{
87 struct jpeg_membuf_src *src = (struct jpeg_membuf_src *)cinfo->src;
88
89 src->pub.bytes_in_buffer -= num_bytes;
90 src->pub.next_input_byte += num_bytes;
91} /* _eet_jpeg_membuf_src_skip */
92
93static void
94_eet_jpeg_membuf_src_term(j_decompress_ptr cinfo)
95{
96 struct jpeg_membuf_src *src = ((struct jpeg_membuf_src *)cinfo->src)->self;
97
98 free(src);
99 cinfo->src = NULL;
100} /* _eet_jpeg_membuf_src_term */
101
102static int
103eet_jpeg_membuf_src(j_decompress_ptr cinfo,
104 const void *buf,
105 size_t len)
106{
107 struct jpeg_membuf_src *src;
108
109 src = calloc(1, sizeof(*src));
110 if (!src)
111 return -1;
112
113 src->self = src;
114
115 cinfo->src = &src->pub;
116 src->buf = buf;
117 src->len = len;
118 src->pub.init_source = _eet_jpeg_membuf_src_init;
119 src->pub.fill_input_buffer = _eet_jpeg_membuf_src_fill;
120 src->pub.skip_input_data = _eet_jpeg_membuf_src_skip;
121 src->pub.resync_to_restart = jpeg_resync_to_restart;
122 src->pub.term_source = _eet_jpeg_membuf_src_term;
123 src->pub.bytes_in_buffer = src->len;
124 src->pub.next_input_byte = src->buf;
125
126 return 0;
127} /* eet_jpeg_membuf_src */
128
129struct jpeg_membuf_dst
130{
131 struct jpeg_destination_mgr pub;
132
133 void **dst_buf;
134 size_t *dst_len;
135
136 unsigned char *buf;
137 size_t len;
138 int failed;
139 struct jpeg_membuf_dst *self;
140};
141
142static void
143_eet_jpeg_membuf_dst_init(j_compress_ptr cinfo)
144{
145 /* FIXME: Use eina attribute */
146 (void)cinfo;
147} /* _eet_jpeg_membuf_dst_init */
148
149static boolean
150_eet_jpeg_membuf_dst_flush(j_compress_ptr cinfo)
151{
152 struct jpeg_membuf_dst *dst = (struct jpeg_membuf_dst *)cinfo->dest;
153 unsigned char *buf;
154
155 if (dst->len >= 0x40000000 ||
156 !(buf = realloc(dst->buf, dst->len * 2)))
157 {
158 dst->failed = 1;
159 dst->pub.next_output_byte = dst->buf;
160 dst->pub.free_in_buffer = dst->len;
161 return TRUE;
162 }
163
164 dst->pub.next_output_byte =
165 buf + ((unsigned char *)dst->pub.next_output_byte - dst->buf);
166 dst->buf = buf;
167 dst->pub.free_in_buffer += dst->len;
168 dst->len *= 2;
169
170 return FALSE;
171} /* _eet_jpeg_membuf_dst_flush */
172
173static void
174_eet_jpeg_membuf_dst_term(j_compress_ptr cinfo)
175{
176 struct jpeg_membuf_dst *dst = ((struct jpeg_membuf_dst *)cinfo->dest)->self;
177
178 if (dst->failed)
179 {
180 *dst->dst_buf = NULL;
181 *dst->dst_len = 0;
182 free(dst->buf);
183 }
184 else
185 {
186 *dst->dst_buf = dst->buf;
187 *dst->dst_len = (unsigned char *)dst->pub.next_output_byte - dst->buf;
188 }
189
190 free(dst);
191 cinfo->dest = NULL;
192} /* _eet_jpeg_membuf_dst_term */
193
194static int
195eet_jpeg_membuf_dst(j_compress_ptr cinfo,
196 void **buf,
197 size_t *len)
198{
199 struct jpeg_membuf_dst *dst;
200
201 dst = calloc(1, sizeof(*dst));
202 if (!dst)
203 return -1;
204
205 dst->buf = malloc(32768);
206 if (!dst->buf)
207 {
208 free(dst);
209 return -1;
210 }
211
212 dst->self = dst;
213 dst->len = 32768;
214
215 cinfo->dest = &dst->pub;
216 dst->pub.init_destination = _eet_jpeg_membuf_dst_init;
217 dst->pub.empty_output_buffer = _eet_jpeg_membuf_dst_flush;
218 dst->pub.term_destination = _eet_jpeg_membuf_dst_term;
219 dst->pub.free_in_buffer = dst->len;
220 dst->pub.next_output_byte = dst->buf;
221 dst->dst_buf = buf;
222 dst->dst_len = len;
223 dst->failed = 0;
224
225 return 0;
226} /* eet_jpeg_membuf_dst */
227
228/*---*/
229
230static void _JPEGFatalErrorHandler(j_common_ptr cinfo);
231static void _JPEGErrorHandler(j_common_ptr cinfo);
232static void _JPEGErrorHandler2(j_common_ptr cinfo,
233 int msg_level);
234
235static int
236eet_data_image_jpeg_header_decode(const void *data,
237 int size,
238 unsigned int *w,
239 unsigned int *h);
240static int
241eet_data_image_jpeg_rgb_decode(const void *data,
242 int size,
243 unsigned int src_x,
244 unsigned int src_y,
245 unsigned int *d,
246 unsigned int w,
247 unsigned int h,
248 unsigned int row_stride);
249static void *
250eet_data_image_jpeg_alpha_decode(const void *data,
251 int size,
252 unsigned int src_x,
253 unsigned int src_y,
254 unsigned int *d,
255 unsigned int w,
256 unsigned int h,
257 unsigned int row_stride);
258static void *
259eet_data_image_lossless_convert(int *size,
260 const void *data,
261 unsigned int w,
262 unsigned int h,
263 int alpha);
264static void *
265eet_data_image_lossless_compressed_convert(int *size,
266 const void *data,
267 unsigned int w,
268 unsigned int h,
269 int alpha,
270 int compression);
271static void *
272eet_data_image_jpeg_convert(int *size,
273 const void *data,
274 unsigned int w,
275 unsigned int h,
276 int alpha,
277 int quality);
278static void *
279eet_data_image_jpeg_alpha_convert(int *size,
280 const void *data,
281 unsigned int w,
282 unsigned int h,
283 int alpha,
284 int quality);
285
286/*---*/
287
288static int _eet_image_words_bigendian = -1;
289
290/*---*/
291
292#define SWAP64(x) (x) = \
293 ((((unsigned long long)(x) & 0x00000000000000ffULL) << 56) | \
294 (((unsigned long long)(x) & 0x000000000000ff00ULL) << 40) | \
295 (((unsigned long long)(x) & 0x0000000000ff0000ULL) << 24) | \
296 (((unsigned long long)(x) & 0x00000000ff000000ULL) << 8) | \
297 (((unsigned long long)(x) & 0x000000ff00000000ULL) >> 8) | \
298 (((unsigned long long)(x) & 0x0000ff0000000000ULL) >> 24) | \
299 (((unsigned long long)(x) & 0x00ff000000000000ULL) >> 40) | \
300 (((unsigned long long)(x) & 0xff00000000000000ULL) >> 56))
301#define SWAP32(x) (x) = \
302 ((((int)(x) & 0x000000ff) << 24) | \
303 (((int)(x) & 0x0000ff00) << 8) | \
304 (((int)(x) & 0x00ff0000) >> 8) | \
305 (((int)(x) & 0xff000000) >> 24))
306#define SWAP16(x) (x) = \
307 ((((short)(x) & 0x00ff) << 8) | \
308 (((short)(x) & 0xff00) >> 8))
309
310#ifdef CONV8
311# undef CONV8
312#endif /* ifdef CONV8 */
313#ifdef CONV16
314# undef CONV16
315#endif /* ifdef CONV16 */
316#ifdef CONV32
317# undef CONV32
318#endif /* ifdef CONV32 */
319#ifdef CONV64
320# undef CONV64
321#endif /* ifdef CONV64 */
322
323#define CONV8(x)
324#define CONV16(x) {if (_eet_image_words_bigendian) {SWAP16(x); }}
325#define CONV32(x) {if (_eet_image_words_bigendian) {SWAP32(x); }}
326#define CONV64(x) {if (_eet_image_words_bigendian) {SWAP64(x); }}
327
328/*---*/
329
330static void
331_JPEGFatalErrorHandler(j_common_ptr cinfo)
332{
333 emptr errmgr;
334
335 errmgr = (emptr)cinfo->err;
336 /* cinfo->err->output_message(cinfo);*/
337 longjmp(errmgr->setjmp_buffer, 1);
338 return;
339} /* _JPEGFatalErrorHandler */
340
341static void
342_JPEGErrorHandler(j_common_ptr cinfo __UNUSED__)
343{
344 /* emptr errmgr; */
345
346 /* errmgr = (emptr) cinfo->err; */
347 /* cinfo->err->output_message(cinfo);*/
348 /* longjmp(errmgr->setjmp_buffer, 1);*/
349 return;
350} /* _JPEGErrorHandler */
351
352static void
353_JPEGErrorHandler2(j_common_ptr cinfo __UNUSED__,
354 int msg_level __UNUSED__)
355{
356 /* emptr errmgr; */
357
358 /* errmgr = (emptr) cinfo->err; */
359 /* cinfo->err->output_message(cinfo);*/
360 /* longjmp(errmgr->setjmp_buffer, 1);*/
361 return;
362} /* _JPEGErrorHandler2 */
363
364static int
365eet_data_image_jpeg_header_decode(const void *data,
366 int size,
367 unsigned int *w,
368 unsigned int *h)
369{
370 struct jpeg_decompress_struct cinfo;
371 struct _JPEG_error_mgr jerr;
372
373 memset(&cinfo, 0, sizeof (struct jpeg_decompress_struct));
374
375 cinfo.err = jpeg_std_error(&(jerr.pub));
376 jerr.pub.error_exit = _JPEGFatalErrorHandler;
377 jerr.pub.emit_message = _JPEGErrorHandler2;
378 jerr.pub.output_message = _JPEGErrorHandler;
379 if (setjmp(jerr.setjmp_buffer))
380 return 0;
381
382 jpeg_create_decompress(&cinfo);
383
384 if (eet_jpeg_membuf_src(&cinfo, data, (size_t)size))
385 {
386 jpeg_destroy_decompress(&cinfo);
387 return 0;
388 }
389
390 jpeg_read_header(&cinfo, TRUE);
391 cinfo.do_fancy_upsampling = FALSE;
392 cinfo.do_block_smoothing = FALSE;
393 jpeg_start_decompress(&cinfo);
394
395 /* head decoding */
396 *w = cinfo.output_width;
397 *h = cinfo.output_height;
398
399 free(cinfo.src);
400 cinfo.src = NULL;
401
402 jpeg_destroy_decompress(&cinfo);
403
404 if ((*w < 1) || (*h < 1) || (*w > 8192) || (*h > 8192))
405 return 0;
406
407 return 1;
408} /* eet_data_image_jpeg_header_decode */
409
410static int
411eet_data_image_jpeg_rgb_decode(const void *data,
412 int size,
413 unsigned int src_x,
414 unsigned int src_y,
415 unsigned int *d,
416 unsigned int w,
417 unsigned int h,
418 unsigned int row_stride)
419{
420 struct jpeg_decompress_struct cinfo;
421 struct _JPEG_error_mgr jerr;
422 unsigned char *ptr, *line[16], *tdata = NULL;
423 unsigned int *ptr2, *tmp;
424 unsigned int iw, ih;
425 unsigned int x, y, l, scans;
426 unsigned int i;
427
428 /* FIXME: handle src_x, src_y and row_stride correctly */
429 if (!d)
430 return 0;
431
432 memset(&cinfo, 0, sizeof (struct jpeg_decompress_struct));
433
434 cinfo.err = jpeg_std_error(&(jerr.pub));
435 jerr.pub.error_exit = _JPEGFatalErrorHandler;
436 jerr.pub.emit_message = _JPEGErrorHandler2;
437 jerr.pub.output_message = _JPEGErrorHandler;
438 if (setjmp(jerr.setjmp_buffer))
439 return 0;
440
441 jpeg_create_decompress(&cinfo);
442
443 if (eet_jpeg_membuf_src(&cinfo, data, (size_t)size))
444 {
445 jpeg_destroy_decompress(&cinfo);
446 return 0;
447 }
448
449 jpeg_read_header(&cinfo, TRUE);
450 cinfo.dct_method = JDCT_ISLOW; // JDCT_FLOAT JDCT_IFAST(quality loss)
451 cinfo.do_fancy_upsampling = FALSE;
452 cinfo.do_block_smoothing = FALSE;
453 jpeg_start_decompress(&cinfo);
454
455 /* head decoding */
456 iw = cinfo.output_width;
457 ih = cinfo.output_height;
458 if ((iw != w) || (ih != h))
459 {
460 free(cinfo.src);
461 cinfo.src = NULL;
462
463 jpeg_destroy_decompress(&cinfo);
464 return 0;
465 }
466
467 /* end head decoding */
468 /* data decoding */
469 if (cinfo.rec_outbuf_height > 16)
470 {
471 free(cinfo.src);
472 cinfo.src = NULL;
473
474 jpeg_destroy_decompress(&cinfo);
475 return 0;
476 }
477
478 tdata = alloca((iw) * 16 * 3);
479 ptr2 = d;
480
481 if (cinfo.output_components == 3)
482 {
483 for (i = 0; i < (unsigned int)cinfo.rec_outbuf_height; i++)
484 line[i] = tdata + (i * (iw) * 3);
485 for (l = 0; l < ih; l += cinfo.rec_outbuf_height)
486 {
487 jpeg_read_scanlines(&cinfo, line, cinfo.rec_outbuf_height);
488 scans = cinfo.rec_outbuf_height;
489 if ((ih - l) < scans)
490 scans = ih - l;
491
492 ptr = tdata;
493
494 if (l + scans >= src_y && l < src_y + h)
495 {
496 y = src_y - l;
497 if (src_y < l)
498 y = 0;
499
500 for (ptr += 3 * iw * y; y < scans && (y + l) < (src_y + h);
501 y++)
502 {
503 tmp = ptr2;
504 ptr += 3 * src_x;
505 for (x = 0; x < w; x++)
506 {
507 *ptr2 =
508 (0xff000000) |
509 ((ptr[0]) << 16) | ((ptr[1]) << 8) | (ptr[2]);
510 ptr += 3;
511 ptr2++;
512 }
513 ptr += 3 * (iw - w);
514 ptr2 = tmp + row_stride / 4;
515 }
516 }
517 }
518 }
519 else if (cinfo.output_components == 1)
520 {
521 for (i = 0; i < (unsigned int)cinfo.rec_outbuf_height; i++)
522 line[i] = tdata + (i * (iw));
523 for (l = 0; l < (ih); l += cinfo.rec_outbuf_height)
524 {
525 jpeg_read_scanlines(&cinfo, line, cinfo.rec_outbuf_height);
526 scans = cinfo.rec_outbuf_height;
527 if (((ih) - l) < scans)
528 scans = (ih) - l;
529
530 ptr = tdata;
531
532 if (l >= src_y && l < src_y + h)
533 {
534 y = src_y - l;
535 if (src_y < l)
536 y = 0;
537
538 for (ptr += iw * y; y < scans && (y + l) < (src_y + h); y++)
539 {
540 tmp = ptr2;
541 ptr += src_x;
542 for (x = 0; x < w; x++)
543 {
544 *ptr2 =
545 (0xff000000) |
546 ((ptr[0]) << 16) | ((ptr[0]) << 8) | (ptr[0]);
547 ptr++;
548 ptr2++;
549 }
550 ptr += iw - w;
551 ptr2 = tmp + row_stride / 4;
552 }
553 }
554 }
555 }
556
557 /* end data decoding */
558 jpeg_finish_decompress(&cinfo);
559 jpeg_destroy_decompress(&cinfo);
560 return 1;
561} /* eet_data_image_jpeg_rgb_decode */
562
563static void *
564eet_data_image_jpeg_alpha_decode(const void *data,
565 int size,
566 unsigned int src_x,
567 unsigned int src_y,
568 unsigned int *d,
569 unsigned int w,
570 unsigned int h,
571 unsigned int row_stride)
572{
573 struct jpeg_decompress_struct cinfo;
574 struct _JPEG_error_mgr jerr;
575 unsigned char *ptr, *line[16], *tdata = NULL;
576 unsigned int *ptr2, *tmp;
577 unsigned int x, y, l, scans;
578 unsigned int i, iw;
579
580 memset(&cinfo, 0, sizeof (struct jpeg_decompress_struct));
581
582 cinfo.err = jpeg_std_error(&(jerr.pub));
583 jerr.pub.error_exit = _JPEGFatalErrorHandler;
584 jerr.pub.emit_message = _JPEGErrorHandler2;
585 jerr.pub.output_message = _JPEGErrorHandler;
586 if (setjmp(jerr.setjmp_buffer))
587 return NULL;
588
589 jpeg_create_decompress(&cinfo);
590
591 if (eet_jpeg_membuf_src(&cinfo, data, (size_t)size))
592 {
593 jpeg_destroy_decompress(&cinfo);
594 return NULL;
595 }
596
597 jpeg_read_header(&cinfo, TRUE);
598 cinfo.dct_method = JDCT_ISLOW; // JDCT_FLOAT JDCT_IFAST(quality loss)
599 cinfo.do_fancy_upsampling = FALSE;
600 cinfo.do_block_smoothing = FALSE;
601 jpeg_start_decompress(&cinfo);
602
603 /* head decoding */
604 iw = cinfo.output_width;
605 if (w != cinfo.output_width
606 || h != cinfo.output_height)
607 {
608 free(cinfo.src);
609 cinfo.src = NULL;
610
611 jpeg_destroy_decompress(&cinfo);
612 return NULL;
613 }
614
615 /* end head decoding */
616 /* data decoding */
617 if (cinfo.rec_outbuf_height > 16)
618 {
619 free(cinfo.src);
620 cinfo.src = NULL;
621
622 jpeg_destroy_decompress(&cinfo);
623 return NULL;
624 }
625
626 tdata = alloca(w * 16 * 3);
627 ptr2 = d;
628 if (cinfo.output_components == 1)
629 {
630 for (i = 0; i < (unsigned int)cinfo.rec_outbuf_height; i++)
631 line[i] = tdata + (i * w);
632 for (l = 0; l < h; l += cinfo.rec_outbuf_height)
633 {
634 jpeg_read_scanlines(&cinfo, line, cinfo.rec_outbuf_height);
635 scans = cinfo.rec_outbuf_height;
636 if ((h - l) < scans)
637 scans = h - l;
638
639 ptr = tdata;
640
641 if (l >= src_y && l < src_y + h)
642 {
643 y = src_y - l;
644 if (src_y < l)
645 y = 0;
646
647 for (ptr += iw * y; y < scans && (y + l) < (src_y + h); y++)
648 {
649 tmp = ptr2;
650 ptr += src_x;
651 for (x = 0; x < w; x++)
652 {
653 *ptr2 =
654 ((*ptr2) & 0x00ffffff) |
655 ((ptr[0]) << 24);
656 ptr++;
657 ptr2++;
658 }
659 ptr += iw - w;
660 ptr2 = tmp + row_stride / 4;
661 }
662 }
663 }
664 }
665
666 /* end data decoding */
667 jpeg_finish_decompress(&cinfo);
668 jpeg_destroy_decompress(&cinfo);
669 return d;
670} /* eet_data_image_jpeg_alpha_decode */
671
672static void *
673eet_data_image_lossless_convert(int *size,
674 const void *data,
675 unsigned int w,
676 unsigned int h,
677 int alpha)
678{
679 if (_eet_image_words_bigendian == -1)
680 {
681 unsigned long int v;
682
683 v = htonl(0x12345678);
684 if (v == 0x12345678)
685 _eet_image_words_bigendian = 1;
686 else
687 _eet_image_words_bigendian = 0;
688 }
689
690 {
691 unsigned char *d;
692 int *header;
693
694 d = malloc((w * h * 4) + (8 * 4));
695 if (!d)
696 return NULL;
697
698 header = (int *)d;
699 memset(d, 0, 32);
700
701 header[0] = 0xac1dfeed;
702 header[1] = w;
703 header[2] = h;
704 header[3] = alpha;
705
706 memcpy(d + 32, data, w * h * 4);
707
708 if (_eet_image_words_bigendian)
709 {
710 unsigned int i;
711
712 for (i = 0; i < ((w * h) + 8); i++) SWAP32(header[i]);
713 }
714
715 *size = ((w * h * 4) + (8 * 4));
716 return d;
717 }
718} /* eet_data_image_lossless_convert */
719
720static void *
721eet_data_image_lossless_compressed_convert(int *size,
722 const void *data,
723 unsigned int w,
724 unsigned int h,
725 int alpha,
726 int compression)
727{
728 if (_eet_image_words_bigendian == -1)
729 {
730 unsigned long int v;
731
732 v = htonl(0x12345678);
733 if (v == 0x12345678)
734 _eet_image_words_bigendian = 1;
735 else
736 _eet_image_words_bigendian = 0;
737 }
738
739 {
740 unsigned char *d;
741 unsigned char *comp;
742 int *header;
743 int ret;
744 uLongf buflen;
745
746 d = malloc((w * h * 4) + (8 * 4));
747 if (!d)
748 return NULL;
749
750 buflen = (((w * h * 101) / 100) + 3) * 4;
751 comp = malloc(buflen);
752 if (!comp)
753 {
754 free(d);
755 return NULL;
756 }
757
758 header = (int *)d;
759 memset(d, 0, 32);
760
761 header[0] = 0xac1dfeed;
762 header[1] = w;
763 header[2] = h;
764 header[3] = alpha;
765 header[4] = compression;
766 memcpy(d + 32, data, w * h * 4);
767
768 if (_eet_image_words_bigendian)
769 {
770 unsigned int i;
771
772 for (i = 0; i < ((w * h) + 8); i++) SWAP32(header[i]);
773 }
774
775 ret = compress2((Bytef *)comp, &buflen,
776 (Bytef *)(d + 32),
777 (uLong)(w * h * 4),
778 compression);
779 if (ret != Z_OK || buflen > (w * h * 4))
780 {
781 free(comp);
782 free(d);
783 *size = -1;
784 return NULL;
785 }
786
787 memcpy(d + 32, comp, buflen);
788 *size = (8 * 4) + buflen;
789 free(comp);
790 return d;
791 }
792} /* eet_data_image_lossless_compressed_convert */
793
794static void *
795eet_data_image_jpeg_convert(int *size,
796 const void *data,
797 unsigned int w,
798 unsigned int h,
799 int alpha,
800 int quality)
801{
802 struct jpeg_compress_struct cinfo;
803 struct _JPEG_error_mgr jerr;
804 const int *ptr;
805 void *d = NULL;
806 size_t sz = 0;
807 JSAMPROW *jbuf;
808 unsigned char *buf;
809
810 (void)alpha; /* unused */
811
812 buf = alloca(3 * w);
813
814 memset(&cinfo, 0, sizeof (struct jpeg_compress_struct));
815
816 cinfo.err = jpeg_std_error(&(jerr.pub));
817 jerr.pub.error_exit = _JPEGFatalErrorHandler;
818 jerr.pub.emit_message = _JPEGErrorHandler2;
819 jerr.pub.output_message = _JPEGErrorHandler;
820 if (setjmp(jerr.setjmp_buffer))
821 return NULL;
822
823 jpeg_create_compress(&cinfo);
824
825 if (eet_jpeg_membuf_dst(&cinfo, &d, &sz))
826 {
827 jpeg_destroy_compress(&cinfo);
828 return NULL;
829 }
830
831 cinfo.image_width = w;
832 cinfo.image_height = h;
833 cinfo.input_components = 3;
834 cinfo.in_color_space = JCS_RGB;
835 cinfo.optimize_coding = FALSE;
836 cinfo.dct_method = JDCT_ISLOW; // JDCT_FLOAT JDCT_IFAST(quality loss)
837 if (quality < 60) cinfo.dct_method = JDCT_IFAST;
838 jpeg_set_defaults(&cinfo);
839 jpeg_set_quality(&cinfo, quality, TRUE);
840
841 if (quality >= 90)
842 {
843 cinfo.comp_info[0].h_samp_factor = 1;
844 cinfo.comp_info[0].v_samp_factor = 1;
845 cinfo.comp_info[1].h_samp_factor = 1;
846 cinfo.comp_info[1].v_samp_factor = 1;
847 cinfo.comp_info[2].h_samp_factor = 1;
848 cinfo.comp_info[2].v_samp_factor = 1;
849 }
850
851 jpeg_start_compress(&cinfo, TRUE);
852
853 while (cinfo.next_scanline < cinfo.image_height)
854 {
855 unsigned int i, j;
856
857 /* convert scaline from ARGB to RGB packed */
858 ptr = ((const int *)data) + cinfo.next_scanline * w;
859 for (j = 0, i = 0; i < w; i++)
860 {
861 buf[j++] = ((*ptr) >> 16) & 0xff;
862 buf[j++] = ((*ptr) >> 8) & 0xff;
863 buf[j++] = ((*ptr)) & 0xff;
864 ptr++;
865 }
866 jbuf = (JSAMPROW *)(&buf);
867 jpeg_write_scanlines(&cinfo, jbuf, 1);
868 }
869
870 jpeg_finish_compress(&cinfo);
871 jpeg_destroy_compress(&cinfo);
872
873 *size = sz;
874 return d;
875} /* eet_data_image_jpeg_convert */
876
877static void *
878eet_data_image_jpeg_alpha_convert(int *size,
879 const void *data,
880 unsigned int w,
881 unsigned int h,
882 int alpha,
883 int quality)
884{
885 unsigned char *d1, *d2;
886 unsigned char *d;
887 int *header;
888 int sz1, sz2;
889
890 (void)alpha; /* unused */
891
892 if (_eet_image_words_bigendian == -1)
893 {
894 unsigned long int v;
895
896 v = htonl(0x12345678);
897 if (v == 0x12345678)
898 _eet_image_words_bigendian = 1;
899 else
900 _eet_image_words_bigendian = 0;
901 }
902
903 {
904 const int *ptr;
905 void *dst = NULL;
906 size_t sz = 0;
907 struct _JPEG_error_mgr jerr;
908 JSAMPROW *jbuf;
909 struct jpeg_compress_struct cinfo;
910 unsigned char *buf;
911
912 buf = alloca(3 * w);
913
914 cinfo.err = jpeg_std_error(&(jerr.pub));
915 jerr.pub.error_exit = _JPEGFatalErrorHandler;
916 jerr.pub.emit_message = _JPEGErrorHandler2;
917 jerr.pub.output_message = _JPEGErrorHandler;
918 if (setjmp(jerr.setjmp_buffer))
919 return NULL;
920
921 jpeg_create_compress(&cinfo);
922 if (eet_jpeg_membuf_dst(&cinfo, &dst, &sz))
923 {
924 jpeg_destroy_compress(&cinfo);
925 return NULL;
926 }
927
928 cinfo.image_width = w;
929 cinfo.image_height = h;
930 cinfo.input_components = 3;
931 cinfo.in_color_space = JCS_RGB;
932 cinfo.optimize_coding = FALSE;
933 cinfo.dct_method = JDCT_ISLOW; // JDCT_FLOAT JDCT_IFAST(quality loss)
934 if (quality < 60) cinfo.dct_method = JDCT_IFAST;
935 jpeg_set_defaults(&cinfo);
936 jpeg_set_quality(&cinfo, quality, TRUE);
937 if (quality >= 90)
938 {
939 cinfo.comp_info[0].h_samp_factor = 1;
940 cinfo.comp_info[0].v_samp_factor = 1;
941 cinfo.comp_info[1].h_samp_factor = 1;
942 cinfo.comp_info[1].v_samp_factor = 1;
943 cinfo.comp_info[2].h_samp_factor = 1;
944 cinfo.comp_info[2].v_samp_factor = 1;
945 }
946
947 jpeg_start_compress(&cinfo, TRUE);
948
949 while (cinfo.next_scanline < cinfo.image_height)
950 {
951 unsigned int i, j;
952
953 ptr = ((const int *)data) + cinfo.next_scanline * w;
954 /* convert scaline from ARGB to RGB packed */
955 for (j = 0, i = 0; i < w; i++)
956 {
957 buf[j++] = ((*ptr) >> 16) & 0xff;
958 buf[j++] = ((*ptr) >> 8) & 0xff;
959 buf[j++] = ((*ptr)) & 0xff;
960 ptr++;
961 }
962 jbuf = (JSAMPROW *)(&buf);
963 jpeg_write_scanlines(&cinfo, jbuf, 1);
964 }
965
966 jpeg_finish_compress(&cinfo);
967 jpeg_destroy_compress(&cinfo);
968
969 d1 = dst;
970 sz1 = sz;
971 }
972 {
973 const int *ptr;
974 void *dst = NULL;
975 size_t sz = 0;
976 struct _JPEG_error_mgr jerr;
977 JSAMPROW *jbuf;
978 struct jpeg_compress_struct cinfo;
979 unsigned char *buf;
980
981 buf = alloca(3 * w);
982
983 cinfo.err = jpeg_std_error(&(jerr.pub));
984 jerr.pub.error_exit = _JPEGFatalErrorHandler;
985 jerr.pub.emit_message = _JPEGErrorHandler2;
986 jerr.pub.output_message = _JPEGErrorHandler;
987 if (setjmp(jerr.setjmp_buffer))
988 {
989 free(d1);
990 return NULL;
991 }
992
993 jpeg_create_compress(&cinfo);
994 if (eet_jpeg_membuf_dst(&cinfo, &dst, &sz))
995 {
996 jpeg_destroy_compress(&cinfo);
997 free(d1);
998 return NULL;
999 }
1000
1001 cinfo.image_width = w;
1002 cinfo.image_height = h;
1003 cinfo.input_components = 1;
1004 cinfo.in_color_space = JCS_GRAYSCALE;
1005 jpeg_set_defaults(&cinfo);
1006 jpeg_set_quality(&cinfo, quality, TRUE);
1007 if (quality >= 90)
1008 {
1009 cinfo.comp_info[0].h_samp_factor = 1;
1010 cinfo.comp_info[0].v_samp_factor = 1;
1011 cinfo.comp_info[1].h_samp_factor = 1;
1012 cinfo.comp_info[1].v_samp_factor = 1;
1013 cinfo.comp_info[2].h_samp_factor = 1;
1014 cinfo.comp_info[2].v_samp_factor = 1;
1015 }
1016
1017 jpeg_start_compress(&cinfo, TRUE);
1018
1019 while (cinfo.next_scanline < cinfo.image_height)
1020 {
1021 unsigned int i, j;
1022
1023 ptr = ((const int *)data) + cinfo.next_scanline * w;
1024 /* convert scaline from ARGB to RGB packed */
1025 for (j = 0, i = 0; i < w; i++)
1026 {
1027 buf[j++] = ((*ptr) >> 24) & 0xff;
1028 ptr++;
1029 }
1030 jbuf = (JSAMPROW *)(&buf);
1031 jpeg_write_scanlines(&cinfo, jbuf, 1);
1032 }
1033
1034 jpeg_finish_compress(&cinfo);
1035 jpeg_destroy_compress(&cinfo);
1036
1037 d2 = dst;
1038 sz2 = sz;
1039 }
1040 d = malloc(12 + sz1 + sz2);
1041 if (!d)
1042 {
1043 free(d1);
1044 free(d2);
1045 return NULL;
1046 }
1047
1048 header = (int *)d;
1049 header[0] = 0xbeeff00d;
1050 header[1] = sz1;
1051 header[2] = sz2;
1052 if (_eet_image_words_bigendian)
1053 {
1054 int i;
1055
1056 for (i = 0; i < 3; i++) SWAP32(header[i]);
1057 }
1058
1059 memcpy(d + 12, d1, sz1);
1060 memcpy(d + 12 + sz1, d2, sz2);
1061
1062 free(d1);
1063 free(d2);
1064 *size = 12 + sz1 + sz2;
1065 return d;
1066} /* eet_data_image_jpeg_alpha_convert */
1067
1068EAPI int
1069eet_data_image_write_cipher(Eet_File *ef,
1070 const char *name,
1071 const char *cipher_key,
1072 const void *data,
1073 unsigned int w,
1074 unsigned int h,
1075 int alpha,
1076 int comp,
1077 int quality,
1078 int lossy)
1079{
1080 void *d = NULL;
1081 int size = 0;
1082
1083 d = eet_data_image_encode(data, &size, w, h, alpha, comp, quality, lossy);
1084 if (d)
1085 {
1086 int v;
1087
1088 v = eet_write_cipher(ef, name, d, size, 0, cipher_key);
1089 free(d);
1090 return v;
1091 }
1092
1093 return 0;
1094} /* eet_data_image_write_cipher */
1095
1096EAPI int
1097eet_data_image_write(Eet_File *ef,
1098 const char *name,
1099 const void *data,
1100 unsigned int w,
1101 unsigned int h,
1102 int alpha,
1103 int comp,
1104 int quality,
1105 int lossy)
1106{
1107 return eet_data_image_write_cipher(ef,
1108 name,
1109 NULL,
1110 data,
1111 w,
1112 h,
1113 alpha,
1114 comp,
1115 quality,
1116 lossy);
1117} /* eet_data_image_write */
1118
1119EAPI void *
1120eet_data_image_read_cipher(Eet_File *ef,
1121 const char *name,
1122 const char *cipher_key,
1123 unsigned int *w,
1124 unsigned int *h,
1125 int *alpha,
1126 int *comp,
1127 int *quality,
1128 int *lossy)
1129{
1130 unsigned int *d = NULL;
1131 void *data = NULL;
1132 int free_data = 0;
1133 int size;
1134
1135 if (!cipher_key)
1136 data = (void *)eet_read_direct(ef, name, &size);
1137
1138 if (!data)
1139 {
1140 data = eet_read_cipher(ef, name, &size, cipher_key);
1141 free_data = 1;
1142 if (!data)
1143 return NULL;
1144 }
1145
1146 d = eet_data_image_decode(data, size, w, h, alpha, comp, quality, lossy);
1147
1148 if (free_data)
1149 free(data);
1150
1151 return d;
1152} /* eet_data_image_read_cipher */
1153
1154EAPI void *
1155eet_data_image_read(Eet_File *ef,
1156 const char *name,
1157 unsigned int *w,
1158 unsigned int *h,
1159 int *alpha,
1160 int *comp,
1161 int *quality,
1162 int *lossy)
1163{
1164 return eet_data_image_read_cipher(ef, name, NULL, w, h, alpha,
1165 comp, quality, lossy);
1166} /* eet_data_image_read */
1167
1168EAPI int
1169eet_data_image_read_to_surface_cipher(Eet_File *ef,
1170 const char *name,
1171 const char *cipher_key,
1172 unsigned int src_x,
1173 unsigned int src_y,
1174 unsigned int *d,
1175 unsigned int w,
1176 unsigned int h,
1177 unsigned int row_stride,
1178 int *alpha,
1179 int *comp,
1180 int *quality,
1181 int *lossy)
1182{
1183 void *data = NULL;
1184 int free_data = 0;
1185 int res = 1;
1186 int size;
1187
1188 if (!cipher_key)
1189 data = (void *)eet_read_direct(ef, name, &size);
1190
1191 if (!data)
1192 {
1193 data = eet_read_cipher(ef, name, &size, cipher_key);
1194 free_data = 1;
1195 if (!data)
1196 return 0;
1197 }
1198
1199 res = eet_data_image_decode_to_surface(data, size, src_x, src_y, d,
1200 w, h, row_stride, alpha,
1201 comp, quality, lossy);
1202
1203 if (free_data)
1204 free(data);
1205
1206 return res;
1207} /* eet_data_image_read_to_surface_cipher */
1208
1209EAPI int
1210eet_data_image_read_to_surface(Eet_File *ef,
1211 const char *name,
1212 unsigned int src_x,
1213 unsigned int src_y,
1214 unsigned int *d,
1215 unsigned int w,
1216 unsigned int h,
1217 unsigned int row_stride,
1218 int *alpha,
1219 int *comp,
1220 int *quality,
1221 int *lossy)
1222{
1223 return eet_data_image_read_to_surface_cipher(ef, name, NULL,
1224 src_x, src_y, d,
1225 w, h, row_stride,
1226 alpha, comp, quality,
1227 lossy);
1228} /* eet_data_image_read_to_surface */
1229
1230EAPI int
1231eet_data_image_header_read_cipher(Eet_File *ef,
1232 const char *name,
1233 const char *cipher_key,
1234 unsigned int *w,
1235 unsigned int *h,
1236 int *alpha,
1237 int *comp,
1238 int *quality,
1239 int *lossy)
1240{
1241 void *data = NULL;
1242 int size = 0;
1243 int free_data = 0;
1244 int d;
1245
1246 if (!cipher_key)
1247 data = (void *)eet_read_direct(ef, name, &size);
1248
1249 if (!data)
1250 {
1251 data = eet_read_cipher(ef, name, &size, cipher_key);
1252 free_data = 1;
1253 if (!data)
1254 return 0;
1255 }
1256
1257 d = eet_data_image_header_decode(data, size, w, h, alpha,
1258 comp, quality, lossy);
1259 if (free_data)
1260 free(data);
1261
1262 return d;
1263} /* eet_data_image_header_read_cipher */
1264
1265EAPI int
1266eet_data_image_header_read(Eet_File *ef,
1267 const char *name,
1268 unsigned int *w,
1269 unsigned int *h,
1270 int *alpha,
1271 int *comp,
1272 int *quality,
1273 int *lossy)
1274{
1275 return eet_data_image_header_read_cipher(ef, name, NULL,
1276 w, h, alpha,
1277 comp, quality, lossy);
1278} /* eet_data_image_header_read */
1279
1280EAPI void *
1281eet_data_image_encode_cipher(const void *data,
1282 const char *cipher_key,
1283 unsigned int w,
1284 unsigned int h,
1285 int alpha,
1286 int comp,
1287 int quality,
1288 int lossy,
1289 int *size_ret)
1290{
1291 void *d = NULL;
1292 void *ciphered_d = NULL;
1293 unsigned int ciphered_sz = 0;
1294 int size = 0;
1295
1296 if (lossy == 0)
1297 {
1298 if (comp > 0)
1299 d = eet_data_image_lossless_compressed_convert(&size, data,
1300 w, h, alpha, comp);
1301
1302 /* eet_data_image_lossless_compressed_convert will refuse to compress something
1303 if the result is bigger than the entry. */
1304 if (comp <= 0 || !d)
1305 d = eet_data_image_lossless_convert(&size, data, w, h, alpha);
1306 }
1307 else
1308 {
1309 if (!alpha)
1310 d = eet_data_image_jpeg_convert(&size, data, w, h, alpha, quality);
1311 else
1312 d = eet_data_image_jpeg_alpha_convert(&size, data,
1313 w, h, alpha, quality);
1314 }
1315
1316 if (cipher_key)
1317 {
1318 if(!eet_cipher(d, size, cipher_key, strlen(cipher_key), &ciphered_d,
1319 &ciphered_sz))
1320 {
1321 if (d)
1322 free(d);
1323
1324 d = ciphered_d;
1325 size = ciphered_sz;
1326 }
1327 else
1328 if (ciphered_d)
1329 free(ciphered_d);
1330 }
1331
1332 if (size_ret)
1333 *size_ret = size;
1334
1335 return d;
1336} /* eet_data_image_encode_cipher */
1337
1338EAPI void *
1339eet_data_image_encode(const void *data,
1340 int *size_ret,
1341 unsigned int w,
1342 unsigned int h,
1343 int alpha,
1344 int comp,
1345 int quality,
1346 int lossy)
1347{
1348 return eet_data_image_encode_cipher(data, NULL, w, h, alpha,
1349 comp, quality, lossy, size_ret);
1350} /* eet_data_image_encode */
1351
1352EAPI int
1353eet_data_image_header_decode_cipher(const void *data,
1354 const char *cipher_key,
1355 int size,
1356 unsigned int *w,
1357 unsigned int *h,
1358 int *alpha,
1359 int *comp,
1360 int *quality,
1361 int *lossy)
1362{
1363 int header[8];
1364 void *deciphered_d = NULL;
1365 unsigned int deciphered_sz = 0;
1366
1367 if (cipher_key)
1368 {
1369 if (!eet_decipher(data, size, cipher_key, strlen(cipher_key),
1370 &deciphered_d, &deciphered_sz))
1371 {
1372 data = deciphered_d;
1373 size = deciphered_sz;
1374 }
1375 else
1376 if (deciphered_d)
1377 free(deciphered_d);
1378 }
1379
1380 if (_eet_image_words_bigendian == -1)
1381 {
1382 unsigned long int v;
1383
1384 v = htonl(0x12345678);
1385 if (v == 0x12345678)
1386 _eet_image_words_bigendian = 1;
1387 else
1388 _eet_image_words_bigendian = 0;
1389 }
1390
1391 if (size < 32)
1392 return 0;
1393
1394 memcpy(header, data, 32);
1395 if (_eet_image_words_bigendian)
1396 {
1397 int i;
1398
1399 for (i = 0; i < 8; i++) SWAP32(header[i]);
1400 }
1401
1402 if ((unsigned)header[0] == 0xac1dfeed)
1403 {
1404 int iw, ih, al, cp;
1405
1406 iw = header[1];
1407 ih = header[2];
1408 al = header[3];
1409 cp = header[4];
1410 if ((iw < 1) || (ih < 1) || (iw > 8192) || (ih > 8192))
1411 return 0;
1412
1413 if ((cp == 0) && (size < ((iw * ih * 4) + 32)))
1414 return 0;
1415
1416 if (w)
1417 *w = iw;
1418
1419 if (h)
1420 *h = ih;
1421
1422 if (alpha)
1423 *alpha = al ? 1 : 0;
1424
1425 if (comp)
1426 *comp = cp;
1427
1428 if (lossy)
1429 *lossy = 0;
1430
1431 if (quality)
1432 *quality = 100;
1433
1434 return 1;
1435 }
1436 else if ((unsigned)header[0] == 0xbeeff00d)
1437 {
1438 unsigned int iw = 0, ih = 0;
1439 unsigned const char *dt;
1440 int sz1;
1441 int ok;
1442
1443 sz1 = header[1];
1444/* sz2 = header[2]; */
1445 dt = data;
1446 dt += 12;
1447 ok = eet_data_image_jpeg_header_decode(dt, sz1, &iw, &ih);
1448 if (ok)
1449 {
1450 if (w)
1451 *w = iw;
1452
1453 if (h)
1454 *h = ih;
1455
1456 if (alpha)
1457 *alpha = 1;
1458
1459 if (comp)
1460 *comp = 0;
1461
1462 if (lossy)
1463 *lossy = 1;
1464
1465 if (quality)
1466 *quality = 75;
1467
1468 return 1;
1469 }
1470 }
1471 else
1472 {
1473 unsigned int iw = 0, ih = 0;
1474 int ok;
1475
1476 ok = eet_data_image_jpeg_header_decode(data, size, &iw, &ih);
1477 if (ok)
1478 {
1479 if (w)
1480 *w = iw;
1481
1482 if (h)
1483 *h = ih;
1484
1485 if (alpha)
1486 *alpha = 0;
1487
1488 if (comp)
1489 *comp = 0;
1490
1491 if (lossy)
1492 *lossy = 1;
1493
1494 if (quality)
1495 *quality = 75;
1496
1497 return 1;
1498 }
1499 }
1500
1501 return 0;
1502} /* eet_data_image_header_decode_cipher */
1503
1504EAPI int
1505eet_data_image_header_decode(const void *data,
1506 int size,
1507 unsigned int *w,
1508 unsigned int *h,
1509 int *alpha,
1510 int *comp,
1511 int *quality,
1512 int *lossy)
1513{
1514 return eet_data_image_header_decode_cipher(data,
1515 NULL,
1516 size,
1517 w,
1518 h,
1519 alpha,
1520 comp,
1521 quality,
1522 lossy);
1523} /* eet_data_image_header_decode */
1524
1525static void
1526_eet_data_image_copy_buffer(const unsigned int *src,
1527 unsigned int src_x,
1528 unsigned int src_y,
1529 unsigned int src_w,
1530 unsigned int *dst,
1531 unsigned int w,
1532 unsigned int h,
1533 unsigned int row_stride)
1534{
1535 src += src_x + src_y * src_w;
1536
1537 if (row_stride == src_w * 4 && w == src_w)
1538 memcpy(dst, src, row_stride * h);
1539 else
1540 {
1541 unsigned int *over = dst;
1542 unsigned int y;
1543
1544 for (y = 0; y < h; ++y, src += src_w, over += row_stride)
1545 memcpy(over, src, w * 4);
1546 }
1547} /* _eet_data_image_copy_buffer */
1548
1549static int
1550_eet_data_image_decode_inside(const void *data,
1551 int size,
1552 unsigned int src_x,
1553 unsigned int src_y,
1554 unsigned int src_w,
1555 unsigned int src_h,
1556 unsigned int *d,
1557 unsigned int w,
1558 unsigned int h,
1559 unsigned int row_stride,
1560 int alpha,
1561 int comp,
1562 int quality,
1563 int lossy)
1564{
1565 if (lossy == 0 && quality == 100)
1566 {
1567 unsigned int *body;
1568
1569 body = ((unsigned int *)data) + 8;
1570 if (!comp)
1571 _eet_data_image_copy_buffer(body, src_x, src_y, src_w, d,
1572 w, h, row_stride);
1573 else
1574 {
1575 if (src_h == h && src_w == w && row_stride == src_w * 4)
1576 {
1577 uLongf dlen;
1578
1579 dlen = w * h * 4;
1580 uncompress((Bytef *)d, &dlen, (Bytef *)body,
1581 (uLongf)(size - 32));
1582 }
1583 else
1584 {
1585 Bytef *dtmp;
1586 uLongf dlen = src_w * src_h * 4;
1587
1588 /* FIXME: This could create a huge alloc. So compressed
1589 data and tile could not always work. */
1590 dtmp = malloc(dlen);
1591 if (!dtmp)
1592 return 0;
1593
1594 uncompress(dtmp, &dlen, (Bytef *)body, (uLongf)(size - 32));
1595
1596 _eet_data_image_copy_buffer((unsigned int *)dtmp,
1597 src_x, src_y, src_w, d,
1598 w, h, row_stride);
1599
1600 free(dtmp);
1601 }
1602 }
1603
1604 /* Fix swapiness. */
1605 if (_eet_image_words_bigendian)
1606 {
1607 unsigned int x;
1608
1609 for (x = 0; x < (w * h); x++) SWAP32(d[x]);
1610 }
1611 }
1612 else if (comp == 0 && lossy == 1)
1613 {
1614 if (alpha)
1615 {
1616 unsigned const char *dt;
1617 int header[8];
1618 int sz1, sz2;
1619
1620 memcpy(header, data, 32);
1621 if (_eet_image_words_bigendian)
1622 {
1623 int i;
1624
1625 for (i = 0; i < 8; i++) SWAP32(header[i]);
1626 }
1627
1628 sz1 = header[1];
1629 sz2 = header[2];
1630 dt = data;
1631 dt += 12;
1632
1633 if (eet_data_image_jpeg_rgb_decode(dt, sz1, src_x, src_y, d, w, h,
1634 row_stride))
1635 {
1636 dt += sz1;
1637 if (!eet_data_image_jpeg_alpha_decode(dt, sz2, src_x, src_y,
1638 d, w, h, row_stride))
1639 return 0;
1640 }
1641 }
1642 else if (!eet_data_image_jpeg_rgb_decode(data, size, src_x, src_y, d, w,
1643 h, row_stride))
1644 return 0;
1645 }
1646 else
1647 abort();
1648
1649 return 1;
1650} /* _eet_data_image_decode_inside */
1651
1652EAPI void *
1653eet_data_image_decode_cipher(const void *data,
1654 const char *cipher_key,
1655 int size,
1656 unsigned int *w,
1657 unsigned int *h,
1658 int *alpha,
1659 int *comp,
1660 int *quality,
1661 int *lossy)
1662{
1663 unsigned int *d = NULL;
1664 unsigned int iw, ih;
1665 int ialpha, icompress, iquality, ilossy;
1666 void *deciphered_d = NULL;
1667 unsigned int deciphered_sz = 0;
1668
1669 if (cipher_key)
1670 {
1671 if (!eet_decipher(data, size, cipher_key, strlen(cipher_key),
1672 &deciphered_d, &deciphered_sz))
1673 {
1674 data = deciphered_d;
1675 size = deciphered_sz;
1676 }
1677 else
1678 if (deciphered_d)
1679 free(deciphered_d);
1680 }
1681
1682 /* All check are done during header decode, this simplify the code a lot. */
1683 if (!eet_data_image_header_decode(data, size, &iw, &ih, &ialpha, &icompress,
1684 &iquality, &ilossy))
1685 return NULL;
1686
1687 d = malloc(iw * ih * 4);
1688 if (!d)
1689 return NULL;
1690
1691 if (!_eet_data_image_decode_inside(data, size, 0, 0, iw, ih, d, iw, ih, iw *
1692 4, ialpha, icompress, iquality, ilossy))
1693 {
1694 free(d);
1695 return NULL;
1696 }
1697
1698 if (w)
1699 *w = iw;
1700
1701 if (h)
1702 *h = ih;
1703
1704 if (alpha)
1705 *alpha = ialpha;
1706
1707 if (comp)
1708 *comp = icompress;
1709
1710 if (quality)
1711 *quality = iquality;
1712
1713 if (lossy)
1714 *lossy = ilossy;
1715
1716 return d;
1717} /* eet_data_image_decode_cipher */
1718
1719EAPI void *
1720eet_data_image_decode(const void *data,
1721 int size,
1722 unsigned int *w,
1723 unsigned int *h,
1724 int *alpha,
1725 int *comp,
1726 int *quality,
1727 int *lossy)
1728{
1729 return eet_data_image_decode_cipher(data, NULL, size, w, h,
1730 alpha, comp, quality, lossy);
1731} /* eet_data_image_decode */
1732
1733EAPI int
1734eet_data_image_decode_to_surface_cipher(const void *data,
1735 const char *cipher_key,
1736 int size,
1737 unsigned int src_x,
1738 unsigned int src_y,
1739 unsigned int *d,
1740 unsigned int w,
1741 unsigned int h,
1742 unsigned int row_stride,
1743 int *alpha,
1744 int *comp,
1745 int *quality,
1746 int *lossy)
1747{
1748 unsigned int iw, ih;
1749 int ialpha, icompress, iquality, ilossy;
1750 void *deciphered_d = NULL;
1751 unsigned int deciphered_sz = 0;
1752
1753 if (cipher_key)
1754 {
1755 if (!eet_decipher(data, size, cipher_key, strlen(cipher_key),
1756 &deciphered_d, &deciphered_sz))
1757 {
1758 data = deciphered_d;
1759 size = deciphered_sz;
1760 }
1761 else
1762 if (deciphered_d)
1763 free(deciphered_d);
1764 }
1765
1766 /* All check are done during header decode, this simplify the code a lot. */
1767 if (!eet_data_image_header_decode(data, size, &iw, &ih, &ialpha, &icompress,
1768 &iquality, &ilossy))
1769 return 0;
1770
1771 if (!d)
1772 return 0;
1773
1774 if (w * 4 > row_stride)
1775 return 0;
1776
1777 if (w > iw || h > ih)
1778 return 0;
1779
1780 if (!_eet_data_image_decode_inside(data, size, src_x, src_y, iw, ih, d, w, h,
1781 row_stride, ialpha, icompress, iquality,
1782 ilossy))
1783 return 0;
1784
1785 if (alpha)
1786 *alpha = ialpha;
1787
1788 if (comp)
1789 *comp = icompress;
1790
1791 if (quality)
1792 *quality = iquality;
1793
1794 if (lossy)
1795 *lossy = ilossy;
1796
1797 return 1;
1798} /* eet_data_image_decode_to_surface_cipher */
1799
1800EAPI int
1801eet_data_image_decode_to_surface(const void *data,
1802 int size,
1803 unsigned int src_x,
1804 unsigned int src_y,
1805 unsigned int *d,
1806 unsigned int w,
1807 unsigned int h,
1808 unsigned int row_stride,
1809 int *alpha,
1810 int *comp,
1811 int *quality,
1812 int *lossy)
1813{
1814 return eet_data_image_decode_to_surface_cipher(data, NULL, size,
1815 src_x, src_y, d,
1816 w, h, row_stride,
1817 alpha, comp, quality,
1818 lossy);
1819} /* eet_data_image_decode_to_surface */
1820