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