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.c1825
1 files changed, 0 insertions, 1825 deletions
diff --git a/libraries/eet/src/lib/eet_image.c b/libraries/eet/src/lib/eet_image.c
deleted file mode 100644
index b622236..0000000
--- a/libraries/eet/src/lib/eet_image.c
+++ /dev/null
@@ -1,1825 +0,0 @@
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}
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}
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}
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}
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}
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}
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}
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}
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}
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 int
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}
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}
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}
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}
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}
562
563static int
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 /* FIXME: handle src_x, src_y and row_stride correctly */
581 if (!d)
582 return 0;
583
584 memset(&cinfo, 0, sizeof (struct jpeg_decompress_struct));
585
586 cinfo.err = jpeg_std_error(&(jerr.pub));
587 jerr.pub.error_exit = _JPEGFatalErrorHandler;
588 jerr.pub.emit_message = _JPEGErrorHandler2;
589 jerr.pub.output_message = _JPEGErrorHandler;
590 if (setjmp(jerr.setjmp_buffer))
591 return 0;
592
593 jpeg_create_decompress(&cinfo);
594
595 if (eet_jpeg_membuf_src(&cinfo, data, (size_t)size))
596 {
597 jpeg_destroy_decompress(&cinfo);
598 return 0;
599 }
600
601 jpeg_read_header(&cinfo, TRUE);
602 cinfo.dct_method = JDCT_ISLOW; // JDCT_FLOAT JDCT_IFAST(quality loss)
603 cinfo.do_fancy_upsampling = FALSE;
604 cinfo.do_block_smoothing = FALSE;
605 jpeg_start_decompress(&cinfo);
606
607 /* head decoding */
608 iw = cinfo.output_width;
609 if (w != cinfo.output_width
610 || h != cinfo.output_height)
611 {
612 free(cinfo.src);
613 cinfo.src = NULL;
614
615 jpeg_destroy_decompress(&cinfo);
616 return 0;
617 }
618
619 /* end head decoding */
620 /* data decoding */
621 if (cinfo.rec_outbuf_height > 16)
622 {
623 free(cinfo.src);
624 cinfo.src = NULL;
625
626 jpeg_destroy_decompress(&cinfo);
627 return 0;
628 }
629
630 tdata = alloca(w * 16 * 3);
631 ptr2 = d;
632
633 if (cinfo.output_components == 1)
634 {
635 for (i = 0; i < (unsigned int)cinfo.rec_outbuf_height; i++)
636 line[i] = tdata + (i * w);
637 for (l = 0; l < h; l += cinfo.rec_outbuf_height)
638 {
639 jpeg_read_scanlines(&cinfo, line, cinfo.rec_outbuf_height);
640 scans = cinfo.rec_outbuf_height;
641 if ((h - l) < scans)
642 scans = h - l;
643
644 ptr = tdata;
645
646 if (l >= src_y && l < src_y + h)
647 {
648 y = src_y - l;
649 if (src_y < l)
650 y = 0;
651
652 for (ptr += iw * y; y < scans && (y + l) < (src_y + h); y++)
653 {
654 tmp = ptr2;
655 ptr += src_x;
656 for (x = 0; x < w; x++)
657 {
658 *ptr2 =
659 ((*ptr2) & 0x00ffffff) |
660 ((ptr[0]) << 24);
661 ptr++;
662 ptr2++;
663 }
664 ptr += iw - w;
665 ptr2 = tmp + row_stride / 4;
666 }
667 }
668 }
669 }
670
671 /* end data decoding */
672 jpeg_finish_decompress(&cinfo);
673 jpeg_destroy_decompress(&cinfo);
674 return 1;
675}
676
677static void *
678eet_data_image_lossless_convert(int *size,
679 const void *data,
680 unsigned int w,
681 unsigned int h,
682 int alpha)
683{
684 if (_eet_image_words_bigendian == -1)
685 {
686 unsigned long int v;
687
688 v = htonl(0x12345678);
689 if (v == 0x12345678)
690 _eet_image_words_bigendian = 1;
691 else
692 _eet_image_words_bigendian = 0;
693 }
694
695 {
696 unsigned char *d;
697 int *header;
698
699 d = malloc((w * h * 4) + (8 * 4));
700 if (!d)
701 return NULL;
702
703 header = (int *)d;
704 memset(d, 0, 32);
705
706 header[0] = 0xac1dfeed;
707 header[1] = w;
708 header[2] = h;
709 header[3] = alpha;
710
711 memcpy(d + 32, data, w * h * 4);
712
713 if (_eet_image_words_bigendian)
714 {
715 unsigned int i;
716
717 for (i = 0; i < ((w * h) + 8); i++) SWAP32(header[i]);
718 }
719
720 *size = ((w * h * 4) + (8 * 4));
721 return d;
722 }
723}
724
725static void *
726eet_data_image_lossless_compressed_convert(int *size,
727 const void *data,
728 unsigned int w,
729 unsigned int h,
730 int alpha,
731 int compression)
732{
733 if (_eet_image_words_bigendian == -1)
734 {
735 unsigned long int v;
736
737 v = htonl(0x12345678);
738 if (v == 0x12345678)
739 _eet_image_words_bigendian = 1;
740 else
741 _eet_image_words_bigendian = 0;
742 }
743
744 {
745 unsigned char *d;
746 unsigned char *comp;
747 int *header;
748 int ret;
749 uLongf buflen;
750
751 d = malloc((w * h * 4) + (8 * 4));
752 if (!d)
753 return NULL;
754
755 buflen = (((w * h * 101) / 100) + 3) * 4;
756 comp = malloc(buflen);
757 if (!comp)
758 {
759 free(d);
760 return NULL;
761 }
762
763 header = (int *)d;
764 memset(d, 0, 32);
765
766 header[0] = 0xac1dfeed;
767 header[1] = w;
768 header[2] = h;
769 header[3] = alpha;
770 header[4] = compression;
771 memcpy(d + 32, data, w * h * 4);
772
773 if (_eet_image_words_bigendian)
774 {
775 unsigned int i;
776
777 for (i = 0; i < ((w * h) + 8); i++) SWAP32(header[i]);
778 }
779
780 ret = compress2((Bytef *)comp, &buflen,
781 (Bytef *)(d + 32),
782 (uLong)(w * h * 4),
783 compression);
784 if (ret != Z_OK || buflen > (w * h * 4))
785 {
786 free(comp);
787 free(d);
788 *size = -1;
789 return NULL;
790 }
791
792 memcpy(d + 32, comp, buflen);
793 *size = (8 * 4) + buflen;
794 free(comp);
795 return d;
796 }
797}
798
799static void *
800eet_data_image_jpeg_convert(int *size,
801 const void *data,
802 unsigned int w,
803 unsigned int h,
804 int alpha,
805 int quality)
806{
807 struct jpeg_compress_struct cinfo;
808 struct _JPEG_error_mgr jerr;
809 const int *ptr;
810 void *d = NULL;
811 size_t sz = 0;
812 JSAMPROW *jbuf;
813 unsigned char *buf;
814
815 (void)alpha; /* unused */
816
817 buf = alloca(3 * w);
818
819 memset(&cinfo, 0, sizeof (struct jpeg_compress_struct));
820
821 cinfo.err = jpeg_std_error(&(jerr.pub));
822 jerr.pub.error_exit = _JPEGFatalErrorHandler;
823 jerr.pub.emit_message = _JPEGErrorHandler2;
824 jerr.pub.output_message = _JPEGErrorHandler;
825 if (setjmp(jerr.setjmp_buffer))
826 return NULL;
827
828 jpeg_create_compress(&cinfo);
829
830 if (eet_jpeg_membuf_dst(&cinfo, &d, &sz))
831 {
832 jpeg_destroy_compress(&cinfo);
833 return NULL;
834 }
835
836 cinfo.image_width = w;
837 cinfo.image_height = h;
838 cinfo.input_components = 3;
839 cinfo.in_color_space = JCS_RGB;
840 cinfo.optimize_coding = FALSE;
841 cinfo.dct_method = JDCT_ISLOW; // JDCT_FLOAT JDCT_IFAST(quality loss)
842 if (quality < 60) cinfo.dct_method = JDCT_IFAST;
843 jpeg_set_defaults(&cinfo);
844 jpeg_set_quality(&cinfo, quality, TRUE);
845
846 if (quality >= 90)
847 {
848 cinfo.comp_info[0].h_samp_factor = 1;
849 cinfo.comp_info[0].v_samp_factor = 1;
850 cinfo.comp_info[1].h_samp_factor = 1;
851 cinfo.comp_info[1].v_samp_factor = 1;
852 cinfo.comp_info[2].h_samp_factor = 1;
853 cinfo.comp_info[2].v_samp_factor = 1;
854 }
855
856 jpeg_start_compress(&cinfo, TRUE);
857
858 while (cinfo.next_scanline < cinfo.image_height)
859 {
860 unsigned int i, j;
861
862 /* convert scaline from ARGB to RGB packed */
863 ptr = ((const int *)data) + cinfo.next_scanline * w;
864 for (j = 0, i = 0; i < w; i++)
865 {
866 buf[j++] = ((*ptr) >> 16) & 0xff;
867 buf[j++] = ((*ptr) >> 8) & 0xff;
868 buf[j++] = ((*ptr)) & 0xff;
869 ptr++;
870 }
871 jbuf = (JSAMPROW *)(&buf);
872 jpeg_write_scanlines(&cinfo, jbuf, 1);
873 }
874
875 jpeg_finish_compress(&cinfo);
876 jpeg_destroy_compress(&cinfo);
877
878 *size = sz;
879 return d;
880}
881
882static void *
883eet_data_image_jpeg_alpha_convert(int *size,
884 const void *data,
885 unsigned int w,
886 unsigned int h,
887 int alpha,
888 int quality)
889{
890 unsigned char *d1, *d2;
891 unsigned char *d;
892 int *header;
893 int sz1, sz2;
894
895 (void)alpha; /* unused */
896
897 if (_eet_image_words_bigendian == -1)
898 {
899 unsigned long int v;
900
901 v = htonl(0x12345678);
902 if (v == 0x12345678)
903 _eet_image_words_bigendian = 1;
904 else
905 _eet_image_words_bigendian = 0;
906 }
907
908 {
909 const int *ptr;
910 void *dst = NULL;
911 size_t sz = 0;
912 struct _JPEG_error_mgr jerr;
913 JSAMPROW *jbuf;
914 struct jpeg_compress_struct cinfo;
915 unsigned char *buf;
916
917 buf = alloca(3 * w);
918
919 cinfo.err = jpeg_std_error(&(jerr.pub));
920 jerr.pub.error_exit = _JPEGFatalErrorHandler;
921 jerr.pub.emit_message = _JPEGErrorHandler2;
922 jerr.pub.output_message = _JPEGErrorHandler;
923 if (setjmp(jerr.setjmp_buffer))
924 return NULL;
925
926 jpeg_create_compress(&cinfo);
927 if (eet_jpeg_membuf_dst(&cinfo, &dst, &sz))
928 {
929 jpeg_destroy_compress(&cinfo);
930 return NULL;
931 }
932
933 cinfo.image_width = w;
934 cinfo.image_height = h;
935 cinfo.input_components = 3;
936 cinfo.in_color_space = JCS_RGB;
937 cinfo.optimize_coding = FALSE;
938 cinfo.dct_method = JDCT_ISLOW; // JDCT_FLOAT JDCT_IFAST(quality loss)
939 if (quality < 60) cinfo.dct_method = JDCT_IFAST;
940 jpeg_set_defaults(&cinfo);
941 jpeg_set_quality(&cinfo, quality, TRUE);
942 if (quality >= 90)
943 {
944 cinfo.comp_info[0].h_samp_factor = 1;
945 cinfo.comp_info[0].v_samp_factor = 1;
946 cinfo.comp_info[1].h_samp_factor = 1;
947 cinfo.comp_info[1].v_samp_factor = 1;
948 cinfo.comp_info[2].h_samp_factor = 1;
949 cinfo.comp_info[2].v_samp_factor = 1;
950 }
951
952 jpeg_start_compress(&cinfo, TRUE);
953
954 while (cinfo.next_scanline < cinfo.image_height)
955 {
956 unsigned int i, j;
957
958 ptr = ((const int *)data) + cinfo.next_scanline * w;
959 /* convert scaline from ARGB to RGB packed */
960 for (j = 0, i = 0; i < w; i++)
961 {
962 buf[j++] = ((*ptr) >> 16) & 0xff;
963 buf[j++] = ((*ptr) >> 8) & 0xff;
964 buf[j++] = ((*ptr)) & 0xff;
965 ptr++;
966 }
967 jbuf = (JSAMPROW *)(&buf);
968 jpeg_write_scanlines(&cinfo, jbuf, 1);
969 }
970
971 jpeg_finish_compress(&cinfo);
972 jpeg_destroy_compress(&cinfo);
973
974 d1 = dst;
975 sz1 = sz;
976 }
977 {
978 const int *ptr;
979 void *dst = NULL;
980 size_t sz = 0;
981 struct _JPEG_error_mgr jerr;
982 JSAMPROW *jbuf;
983 struct jpeg_compress_struct cinfo;
984 unsigned char *buf;
985
986 buf = alloca(3 * w);
987
988 cinfo.err = jpeg_std_error(&(jerr.pub));
989 jerr.pub.error_exit = _JPEGFatalErrorHandler;
990 jerr.pub.emit_message = _JPEGErrorHandler2;
991 jerr.pub.output_message = _JPEGErrorHandler;
992 if (setjmp(jerr.setjmp_buffer))
993 {
994 free(d1);
995 return NULL;
996 }
997
998 jpeg_create_compress(&cinfo);
999 if (eet_jpeg_membuf_dst(&cinfo, &dst, &sz))
1000 {
1001 jpeg_destroy_compress(&cinfo);
1002 free(d1);
1003 return NULL;
1004 }
1005
1006 cinfo.image_width = w;
1007 cinfo.image_height = h;
1008 cinfo.input_components = 1;
1009 cinfo.in_color_space = JCS_GRAYSCALE;
1010 jpeg_set_defaults(&cinfo);
1011 jpeg_set_quality(&cinfo, quality, TRUE);
1012 if (quality >= 90)
1013 {
1014 cinfo.comp_info[0].h_samp_factor = 1;
1015 cinfo.comp_info[0].v_samp_factor = 1;
1016 cinfo.comp_info[1].h_samp_factor = 1;
1017 cinfo.comp_info[1].v_samp_factor = 1;
1018 cinfo.comp_info[2].h_samp_factor = 1;
1019 cinfo.comp_info[2].v_samp_factor = 1;
1020 }
1021
1022 jpeg_start_compress(&cinfo, TRUE);
1023
1024 while (cinfo.next_scanline < cinfo.image_height)
1025 {
1026 unsigned int i, j;
1027
1028 ptr = ((const int *)data) + cinfo.next_scanline * w;
1029 /* convert scaline from ARGB to RGB packed */
1030 for (j = 0, i = 0; i < w; i++)
1031 {
1032 buf[j++] = ((*ptr) >> 24) & 0xff;
1033 ptr++;
1034 }
1035 jbuf = (JSAMPROW *)(&buf);
1036 jpeg_write_scanlines(&cinfo, jbuf, 1);
1037 }
1038
1039 jpeg_finish_compress(&cinfo);
1040 jpeg_destroy_compress(&cinfo);
1041
1042 d2 = dst;
1043 sz2 = sz;
1044 }
1045 d = malloc(12 + sz1 + sz2);
1046 if (!d)
1047 {
1048 free(d1);
1049 free(d2);
1050 return NULL;
1051 }
1052
1053 header = (int *)d;
1054 header[0] = 0xbeeff00d;
1055 header[1] = sz1;
1056 header[2] = sz2;
1057 if (_eet_image_words_bigendian)
1058 {
1059 int i;
1060
1061 for (i = 0; i < 3; i++) SWAP32(header[i]);
1062 }
1063
1064 memcpy(d + 12, d1, sz1);
1065 memcpy(d + 12 + sz1, d2, sz2);
1066
1067 free(d1);
1068 free(d2);
1069 *size = 12 + sz1 + sz2;
1070 return d;
1071}
1072
1073EAPI int
1074eet_data_image_write_cipher(Eet_File *ef,
1075 const char *name,
1076 const char *cipher_key,
1077 const void *data,
1078 unsigned int w,
1079 unsigned int h,
1080 int alpha,
1081 int comp,
1082 int quality,
1083 int lossy)
1084{
1085 void *d = NULL;
1086 int size = 0;
1087
1088 d = eet_data_image_encode(data, &size, w, h, alpha, comp, quality, lossy);
1089 if (d)
1090 {
1091 int v;
1092
1093 v = eet_write_cipher(ef, name, d, size, 0, cipher_key);
1094 free(d);
1095 return v;
1096 }
1097
1098 return 0;
1099}
1100
1101EAPI int
1102eet_data_image_write(Eet_File *ef,
1103 const char *name,
1104 const void *data,
1105 unsigned int w,
1106 unsigned int h,
1107 int alpha,
1108 int comp,
1109 int quality,
1110 int lossy)
1111{
1112 return eet_data_image_write_cipher(ef,
1113 name,
1114 NULL,
1115 data,
1116 w,
1117 h,
1118 alpha,
1119 comp,
1120 quality,
1121 lossy);
1122}
1123
1124EAPI void *
1125eet_data_image_read_cipher(Eet_File *ef,
1126 const char *name,
1127 const char *cipher_key,
1128 unsigned int *w,
1129 unsigned int *h,
1130 int *alpha,
1131 int *comp,
1132 int *quality,
1133 int *lossy)
1134{
1135 unsigned int *d = NULL;
1136 void *data = NULL;
1137 int free_data = 0;
1138 int size;
1139
1140 if (!cipher_key)
1141 data = (void *)eet_read_direct(ef, name, &size);
1142
1143 if (!data)
1144 {
1145 data = eet_read_cipher(ef, name, &size, cipher_key);
1146 free_data = 1;
1147 if (!data)
1148 return NULL;
1149 }
1150
1151 d = eet_data_image_decode(data, size, w, h, alpha, comp, quality, lossy);
1152
1153 if (free_data)
1154 free(data);
1155
1156 return d;
1157}
1158
1159EAPI void *
1160eet_data_image_read(Eet_File *ef,
1161 const char *name,
1162 unsigned int *w,
1163 unsigned int *h,
1164 int *alpha,
1165 int *comp,
1166 int *quality,
1167 int *lossy)
1168{
1169 return eet_data_image_read_cipher(ef, name, NULL, w, h, alpha,
1170 comp, quality, lossy);
1171}
1172
1173EAPI int
1174eet_data_image_read_to_surface_cipher(Eet_File *ef,
1175 const char *name,
1176 const char *cipher_key,
1177 unsigned int src_x,
1178 unsigned int src_y,
1179 unsigned int *d,
1180 unsigned int w,
1181 unsigned int h,
1182 unsigned int row_stride,
1183 int *alpha,
1184 int *comp,
1185 int *quality,
1186 int *lossy)
1187{
1188 void *data = NULL;
1189 int free_data = 0;
1190 int res = 1;
1191 int size;
1192
1193 if (!cipher_key)
1194 data = (void *)eet_read_direct(ef, name, &size);
1195
1196 if (!data)
1197 {
1198 data = eet_read_cipher(ef, name, &size, cipher_key);
1199 free_data = 1;
1200 if (!data)
1201 return 0;
1202 }
1203
1204 res = eet_data_image_decode_to_surface(data, size, src_x, src_y, d,
1205 w, h, row_stride, alpha,
1206 comp, quality, lossy);
1207
1208 if (free_data)
1209 free(data);
1210
1211 return res;
1212}
1213
1214EAPI int
1215eet_data_image_read_to_surface(Eet_File *ef,
1216 const char *name,
1217 unsigned int src_x,
1218 unsigned int src_y,
1219 unsigned int *d,
1220 unsigned int w,
1221 unsigned int h,
1222 unsigned int row_stride,
1223 int *alpha,
1224 int *comp,
1225 int *quality,
1226 int *lossy)
1227{
1228 return eet_data_image_read_to_surface_cipher(ef, name, NULL,
1229 src_x, src_y, d,
1230 w, h, row_stride,
1231 alpha, comp, quality,
1232 lossy);
1233}
1234
1235EAPI int
1236eet_data_image_header_read_cipher(Eet_File *ef,
1237 const char *name,
1238 const char *cipher_key,
1239 unsigned int *w,
1240 unsigned int *h,
1241 int *alpha,
1242 int *comp,
1243 int *quality,
1244 int *lossy)
1245{
1246 void *data = NULL;
1247 int size = 0;
1248 int free_data = 0;
1249 int d;
1250
1251 if (!cipher_key)
1252 data = (void *)eet_read_direct(ef, name, &size);
1253
1254 if (!data)
1255 {
1256 data = eet_read_cipher(ef, name, &size, cipher_key);
1257 free_data = 1;
1258 if (!data)
1259 return 0;
1260 }
1261
1262 d = eet_data_image_header_decode(data, size, w, h, alpha,
1263 comp, quality, lossy);
1264 if (free_data)
1265 free(data);
1266
1267 return d;
1268}
1269
1270EAPI int
1271eet_data_image_header_read(Eet_File *ef,
1272 const char *name,
1273 unsigned int *w,
1274 unsigned int *h,
1275 int *alpha,
1276 int *comp,
1277 int *quality,
1278 int *lossy)
1279{
1280 return eet_data_image_header_read_cipher(ef, name, NULL,
1281 w, h, alpha,
1282 comp, quality, lossy);
1283}
1284
1285EAPI void *
1286eet_data_image_encode_cipher(const void *data,
1287 const char *cipher_key,
1288 unsigned int w,
1289 unsigned int h,
1290 int alpha,
1291 int comp,
1292 int quality,
1293 int lossy,
1294 int *size_ret)
1295{
1296 void *d = NULL;
1297 void *ciphered_d = NULL;
1298 unsigned int ciphered_sz = 0;
1299 int size = 0;
1300
1301 if (lossy == 0)
1302 {
1303 if (comp > 0)
1304 d = eet_data_image_lossless_compressed_convert(&size, data,
1305 w, h, alpha, comp);
1306
1307 /* eet_data_image_lossless_compressed_convert will refuse to compress something
1308 if the result is bigger than the entry. */
1309 if (comp <= 0 || !d)
1310 d = eet_data_image_lossless_convert(&size, data, w, h, alpha);
1311 }
1312 else
1313 {
1314 if (!alpha)
1315 d = eet_data_image_jpeg_convert(&size, data, w, h, alpha, quality);
1316 else
1317 d = eet_data_image_jpeg_alpha_convert(&size, data,
1318 w, h, alpha, quality);
1319 }
1320
1321 if (cipher_key)
1322 {
1323 if(!eet_cipher(d, size, cipher_key, strlen(cipher_key), &ciphered_d,
1324 &ciphered_sz))
1325 {
1326 if (d)
1327 free(d);
1328
1329 d = ciphered_d;
1330 size = ciphered_sz;
1331 }
1332 else
1333 if (ciphered_d)
1334 free(ciphered_d);
1335 }
1336
1337 if (size_ret)
1338 *size_ret = size;
1339
1340 return d;
1341}
1342
1343EAPI void *
1344eet_data_image_encode(const void *data,
1345 int *size_ret,
1346 unsigned int w,
1347 unsigned int h,
1348 int alpha,
1349 int comp,
1350 int quality,
1351 int lossy)
1352{
1353 return eet_data_image_encode_cipher(data, NULL, w, h, alpha,
1354 comp, quality, lossy, size_ret);
1355}
1356
1357EAPI int
1358eet_data_image_header_decode_cipher(const void *data,
1359 const char *cipher_key,
1360 int size,
1361 unsigned int *w,
1362 unsigned int *h,
1363 int *alpha,
1364 int *comp,
1365 int *quality,
1366 int *lossy)
1367{
1368 int header[8];
1369 void *deciphered_d = NULL;
1370 unsigned int deciphered_sz = 0;
1371
1372 if (cipher_key)
1373 {
1374 if (!eet_decipher(data, size, cipher_key, strlen(cipher_key),
1375 &deciphered_d, &deciphered_sz))
1376 {
1377 data = deciphered_d;
1378 size = deciphered_sz;
1379 }
1380 else
1381 if (deciphered_d)
1382 free(deciphered_d);
1383 }
1384
1385 if (_eet_image_words_bigendian == -1)
1386 {
1387 unsigned long int v;
1388
1389 v = htonl(0x12345678);
1390 if (v == 0x12345678)
1391 _eet_image_words_bigendian = 1;
1392 else
1393 _eet_image_words_bigendian = 0;
1394 }
1395
1396 if (size < 32)
1397 return 0;
1398
1399 memcpy(header, data, 32);
1400 if (_eet_image_words_bigendian)
1401 {
1402 int i;
1403
1404 for (i = 0; i < 8; i++) SWAP32(header[i]);
1405 }
1406
1407 if ((unsigned)header[0] == 0xac1dfeed)
1408 {
1409 int iw, ih, al, cp;
1410
1411 iw = header[1];
1412 ih = header[2];
1413 al = header[3];
1414 cp = header[4];
1415 if ((iw < 1) || (ih < 1) || (iw > 8192) || (ih > 8192))
1416 return 0;
1417
1418 if ((cp == 0) && (size < ((iw * ih * 4) + 32)))
1419 return 0;
1420
1421 if (w)
1422 *w = iw;
1423
1424 if (h)
1425 *h = ih;
1426
1427 if (alpha)
1428 *alpha = al ? 1 : 0;
1429
1430 if (comp)
1431 *comp = cp;
1432
1433 if (lossy)
1434 *lossy = 0;
1435
1436 if (quality)
1437 *quality = 100;
1438
1439 return 1;
1440 }
1441 else if ((unsigned)header[0] == 0xbeeff00d)
1442 {
1443 unsigned int iw = 0, ih = 0;
1444 unsigned const char *dt;
1445 int sz1;
1446 int ok;
1447
1448 sz1 = header[1];
1449/* sz2 = header[2]; */
1450 dt = data;
1451 dt += 12;
1452 ok = eet_data_image_jpeg_header_decode(dt, sz1, &iw, &ih);
1453 if (ok)
1454 {
1455 if (w)
1456 *w = iw;
1457
1458 if (h)
1459 *h = ih;
1460
1461 if (alpha)
1462 *alpha = 1;
1463
1464 if (comp)
1465 *comp = 0;
1466
1467 if (lossy)
1468 *lossy = 1;
1469
1470 if (quality)
1471 *quality = 75;
1472
1473 return 1;
1474 }
1475 }
1476 else
1477 {
1478 unsigned int iw = 0, ih = 0;
1479 int ok;
1480
1481 ok = eet_data_image_jpeg_header_decode(data, size, &iw, &ih);
1482 if (ok)
1483 {
1484 if (w)
1485 *w = iw;
1486
1487 if (h)
1488 *h = ih;
1489
1490 if (alpha)
1491 *alpha = 0;
1492
1493 if (comp)
1494 *comp = 0;
1495
1496 if (lossy)
1497 *lossy = 1;
1498
1499 if (quality)
1500 *quality = 75;
1501
1502 return 1;
1503 }
1504 }
1505
1506 return 0;
1507}
1508
1509EAPI int
1510eet_data_image_header_decode(const void *data,
1511 int size,
1512 unsigned int *w,
1513 unsigned int *h,
1514 int *alpha,
1515 int *comp,
1516 int *quality,
1517 int *lossy)
1518{
1519 return eet_data_image_header_decode_cipher(data,
1520 NULL,
1521 size,
1522 w,
1523 h,
1524 alpha,
1525 comp,
1526 quality,
1527 lossy);
1528}
1529
1530static void
1531_eet_data_image_copy_buffer(const unsigned int *src,
1532 unsigned int src_x,
1533 unsigned int src_y,
1534 unsigned int src_w,
1535 unsigned int *dst,
1536 unsigned int w,
1537 unsigned int h,
1538 unsigned int row_stride)
1539{
1540 src += src_x + src_y * src_w;
1541
1542 if (row_stride == src_w * 4 && w == src_w)
1543 memcpy(dst, src, row_stride * h);
1544 else
1545 {
1546 unsigned int *over = dst;
1547 unsigned int y;
1548
1549 for (y = 0; y < h; ++y, src += src_w, over += row_stride)
1550 memcpy(over, src, w * 4);
1551 }
1552}
1553
1554static int
1555_eet_data_image_decode_inside(const void *data,
1556 int size,
1557 unsigned int src_x,
1558 unsigned int src_y,
1559 unsigned int src_w,
1560 unsigned int src_h,
1561 unsigned int *d,
1562 unsigned int w,
1563 unsigned int h,
1564 unsigned int row_stride,
1565 int alpha,
1566 int comp,
1567 int quality,
1568 int lossy)
1569{
1570 if (lossy == 0 && quality == 100)
1571 {
1572 unsigned int *body;
1573
1574 body = ((unsigned int *)data) + 8;
1575 if (!comp)
1576 _eet_data_image_copy_buffer(body, src_x, src_y, src_w, d,
1577 w, h, row_stride);
1578 else
1579 {
1580 if (src_h == h && src_w == w && row_stride == src_w * 4)
1581 {
1582 uLongf dlen;
1583
1584 dlen = w * h * 4;
1585 uncompress((Bytef *)d, &dlen, (Bytef *)body,
1586 (uLongf)(size - 32));
1587 }
1588 else
1589 {
1590 Bytef *dtmp;
1591 uLongf dlen = src_w * src_h * 4;
1592
1593 /* FIXME: This could create a huge alloc. So compressed
1594 data and tile could not always work. */
1595 dtmp = malloc(dlen);
1596 if (!dtmp)
1597 return 0;
1598
1599 uncompress(dtmp, &dlen, (Bytef *)body, (uLongf)(size - 32));
1600
1601 _eet_data_image_copy_buffer((unsigned int *)dtmp,
1602 src_x, src_y, src_w, d,
1603 w, h, row_stride);
1604
1605 free(dtmp);
1606 }
1607 }
1608
1609 /* Fix swapiness. */
1610 if (_eet_image_words_bigendian)
1611 {
1612 unsigned int x;
1613
1614 for (x = 0; x < (w * h); x++) SWAP32(d[x]);
1615 }
1616 }
1617 else if (comp == 0 && lossy == 1)
1618 {
1619 if (alpha)
1620 {
1621 unsigned const char *dt;
1622 int header[8];
1623 int sz1, sz2;
1624
1625 memcpy(header, data, 32);
1626 if (_eet_image_words_bigendian)
1627 {
1628 int i;
1629
1630 for (i = 0; i < 8; i++) SWAP32(header[i]);
1631 }
1632
1633 sz1 = header[1];
1634 sz2 = header[2];
1635 dt = data;
1636 dt += 12;
1637
1638 if (eet_data_image_jpeg_rgb_decode(dt, sz1, src_x, src_y, d, w, h,
1639 row_stride))
1640 {
1641 dt += sz1;
1642 if (!eet_data_image_jpeg_alpha_decode(dt, sz2, src_x, src_y,
1643 d, w, h, row_stride))
1644 return 0;
1645 }
1646 }
1647 else if (!eet_data_image_jpeg_rgb_decode(data, size, src_x, src_y, d, w,
1648 h, row_stride))
1649 return 0;
1650 }
1651 else
1652 abort();
1653
1654 return 1;
1655}
1656
1657EAPI void *
1658eet_data_image_decode_cipher(const void *data,
1659 const char *cipher_key,
1660 int size,
1661 unsigned int *w,
1662 unsigned int *h,
1663 int *alpha,
1664 int *comp,
1665 int *quality,
1666 int *lossy)
1667{
1668 unsigned int *d = NULL;
1669 unsigned int iw, ih;
1670 int ialpha, icompress, iquality, ilossy;
1671 void *deciphered_d = NULL;
1672 unsigned int deciphered_sz = 0;
1673
1674 if (cipher_key)
1675 {
1676 if (!eet_decipher(data, size, cipher_key, strlen(cipher_key),
1677 &deciphered_d, &deciphered_sz))
1678 {
1679 data = deciphered_d;
1680 size = deciphered_sz;
1681 }
1682 else
1683 if (deciphered_d)
1684 free(deciphered_d);
1685 }
1686
1687 /* All check are done during header decode, this simplify the code a lot. */
1688 if (!eet_data_image_header_decode(data, size, &iw, &ih, &ialpha, &icompress,
1689 &iquality, &ilossy))
1690 return NULL;
1691
1692 d = malloc(iw * ih * 4);
1693 if (!d)
1694 return NULL;
1695
1696 if (!_eet_data_image_decode_inside(data, size, 0, 0, iw, ih, d, iw, ih, iw *
1697 4, ialpha, icompress, iquality, ilossy))
1698 {
1699 free(d);
1700 return NULL;
1701 }
1702
1703 if (w)
1704 *w = iw;
1705
1706 if (h)
1707 *h = ih;
1708
1709 if (alpha)
1710 *alpha = ialpha;
1711
1712 if (comp)
1713 *comp = icompress;
1714
1715 if (quality)
1716 *quality = iquality;
1717
1718 if (lossy)
1719 *lossy = ilossy;
1720
1721 return d;
1722}
1723
1724EAPI void *
1725eet_data_image_decode(const void *data,
1726 int size,
1727 unsigned int *w,
1728 unsigned int *h,
1729 int *alpha,
1730 int *comp,
1731 int *quality,
1732 int *lossy)
1733{
1734 return eet_data_image_decode_cipher(data, NULL, size, w, h,
1735 alpha, comp, quality, lossy);
1736}
1737
1738EAPI int
1739eet_data_image_decode_to_surface_cipher(const void *data,
1740 const char *cipher_key,
1741 int size,
1742 unsigned int src_x,
1743 unsigned int src_y,
1744 unsigned int *d,
1745 unsigned int w,
1746 unsigned int h,
1747 unsigned int row_stride,
1748 int *alpha,
1749 int *comp,
1750 int *quality,
1751 int *lossy)
1752{
1753 unsigned int iw, ih;
1754 int ialpha, icompress, iquality, ilossy;
1755 void *deciphered_d = NULL;
1756 unsigned int deciphered_sz = 0;
1757
1758 if (cipher_key)
1759 {
1760 if (!eet_decipher(data, size, cipher_key, strlen(cipher_key),
1761 &deciphered_d, &deciphered_sz))
1762 {
1763 data = deciphered_d;
1764 size = deciphered_sz;
1765 }
1766 else
1767 if (deciphered_d)
1768 free(deciphered_d);
1769 }
1770
1771 /* All check are done during header decode, this simplify the code a lot. */
1772 if (!eet_data_image_header_decode(data, size, &iw, &ih, &ialpha, &icompress,
1773 &iquality, &ilossy))
1774 return 0;
1775
1776 if (!d)
1777 return 0;
1778
1779 if (w * 4 > row_stride)
1780 return 0;
1781
1782 if (w > iw || h > ih)
1783 return 0;
1784
1785 if (!_eet_data_image_decode_inside(data, size, src_x, src_y, iw, ih, d, w, h,
1786 row_stride, ialpha, icompress, iquality,
1787 ilossy))
1788 return 0;
1789
1790 if (alpha)
1791 *alpha = ialpha;
1792
1793 if (comp)
1794 *comp = icompress;
1795
1796 if (quality)
1797 *quality = iquality;
1798
1799 if (lossy)
1800 *lossy = ilossy;
1801
1802 return 1;
1803}
1804
1805EAPI int
1806eet_data_image_decode_to_surface(const void *data,
1807 int size,
1808 unsigned int src_x,
1809 unsigned int src_y,
1810 unsigned int *d,
1811 unsigned int w,
1812 unsigned int h,
1813 unsigned int row_stride,
1814 int *alpha,
1815 int *comp,
1816 int *quality,
1817 int *lossy)
1818{
1819 return eet_data_image_decode_to_surface_cipher(data, NULL, size,
1820 src_x, src_y, d,
1821 w, h, row_stride,
1822 alpha, comp, quality,
1823 lossy);
1824}
1825