2 #define _GNU_SOURCE /* need this for fmemopen & open_memstream */
10 #include <netinet/in.h>
21 * rotuines for doing data -> struct and struct -> data conversion
41 * multiple entries ordered as...
43 * fixed size array [ of basic types ]
44 * variable size array [ of basic types ]
45 * linked list [ of basic types ]
46 * hash table [ of basic types ]
48 * need to provide builder/accessor funcs for:
60 typedef struct _Eet_Data_Element Eet_Data_Element;
61 typedef struct _Eet_Data_Basic_Type_Decoder Eet_Data_Basic_Type_Decoder;
62 typedef struct _Eet_Data_Chunk Eet_Data_Chunk;
63 typedef struct _Eet_Data_Stream Eet_Data_Stream;
64 typedef struct _JPEG_error_mgr *emptr;
68 struct _Eet_Data_Basic_Type_Decoder
71 int (*get) (void *src, void *src_end, void *dest);
72 void *(*put) (void *src, int *size_ret);
75 struct _Eet_Data_Chunk
82 struct _Eet_Data_Stream
89 struct _Eet_Data_Descriptor
94 void *(*list_next) (void *l);
95 void *(*list_append) (void *l, void *d);
96 void *(*list_data) (void *l);
97 void (*hash_foreach) (void *h, int (*func) (void *h, const char *k, void *dt, void *fdt), void *fdt);
98 void *(*hash_add) (void *h, const char *k, void *d);
102 Eet_Data_Element *set;
106 struct _Eet_Data_Element
114 Eet_Data_Descriptor *subtype;
117 struct _JPEG_error_mgr
119 struct jpeg_error_mgr pub;
120 jmp_buf setjmp_buffer;
125 static void _JPEGFatalErrorHandler(j_common_ptr cinfo);
126 static void _JPEGErrorHandler(j_common_ptr cinfo);
127 static void _JPEGErrorHandler2(j_common_ptr cinfo, int msg_level);
129 static void *eet_data_image_jpeg_rgb_decode(void *data, int size, int *w, int *h);
130 static void *eet_data_image_jpeg_alpha_decode(void *data, int size, unsigned int *d, int *w, int *h);
131 static void *eet_data_image_lossless_convert(int *size, void *data, int w, int h, int alpha);
132 static void *eet_data_image_lossless_compressed_convert(int *size, void *data, int w, int h, int alpha, int compression);
133 static void *eet_data_image_jpeg_convert(int *size, void *data, int w, int h, int alpha, int quality);
134 static void *eet_data_image_jpeg_alpha_convert(int *size, void *data, int w, int h, int alpha, int quality);
136 static int eet_data_get_char(void *src, void *src_end, void *dest);
137 static void *eet_data_put_char(void *src, int *size_ret);
138 static int eet_data_get_short(void *src, void *src_end, void *dest);
139 static void *eet_data_put_short(void *src, int *size_ret);
140 static int eet_data_get_int(void *src, void *src_end, void *dest);
141 static void *eet_data_put_int(void *src, int *size_ret);
142 static int eet_data_get_long_long(void *src, void *src_end, void *dest);
143 static void *eet_data_put_long_long(void *src, int *size_ret);
144 static int eet_data_get_float(void *src, void *src_end, void *dest);
145 static void *eet_data_put_float(void *src, int *size_ret);
146 static int eet_data_get_double(void *src, void *src_end, void *dest);
147 static void *eet_data_put_double(void *src, int *size_ret);
148 static int eet_data_get_string(void *src, void *src_end, void *dest);
149 static void *eet_data_put_string(void *src, int *size_ret);
151 static int eet_data_get_type(int type, void *src, void *src_end, void *dest);
152 static void *eet_data_put_type(int type, void *src, int *size_ret);
154 static Eet_Data_Chunk *eet_data_chunk_get(void *src, int size);
155 static Eet_Data_Chunk *eet_data_chunk_new(void *data, int size, char *name);
156 static void eet_data_chunk_free(Eet_Data_Chunk *chnk);
158 static Eet_Data_Stream *eet_data_stream_new(void);
159 static void eet_data_stream_write(Eet_Data_Stream *ds, void *data, int size);
160 static void eet_data_stream_free(Eet_Data_Stream *ds);
162 static void eet_data_chunk_put(Eet_Data_Chunk *chnk, Eet_Data_Stream *ds);
166 const Eet_Data_Basic_Type_Decoder eet_coder[] =
168 {sizeof(char), eet_data_get_char, eet_data_put_char },
169 {sizeof(short), eet_data_get_short, eet_data_put_short },
170 {sizeof(int), eet_data_get_int, eet_data_put_int },
171 {sizeof(long long), eet_data_get_long_long, eet_data_put_long_long},
172 {sizeof(float), eet_data_get_float, eet_data_put_float },
173 {sizeof(double), eet_data_get_double, eet_data_put_double },
174 {sizeof(char), eet_data_get_char, eet_data_put_char },
175 {sizeof(short), eet_data_get_short, eet_data_put_short },
176 {sizeof(int), eet_data_get_int, eet_data_put_int },
177 {sizeof(long long), eet_data_get_long_long, eet_data_put_long_long},
178 {sizeof(char *), eet_data_get_string, eet_data_put_string }
181 static int words_bigendian = -1;
185 #define SWAP64(x) (x) = \
186 ((((x) & 0x00000000000000ff ) << 56) |\
187 (((x) & 0x000000000000ff00 ) << 40) |\
188 (((x) & 0x0000000000ff0000 ) << 24) |\
189 (((x) & 0x00000000ff000000 ) << 8) |\
190 (((x) & 0x000000ff00000000 ) >> 8) |\
191 (((x) & 0x0000ff0000000000 ) >> 24) |\
192 (((x) & 0x00ff000000000000 ) >> 40) |\
193 (((x) & 0xff00000000000000 ) >> 56))
194 #define SWAP32(x) (x) = \
195 ((((x) & 0x000000ff ) << 24) |\
196 (((x) & 0x0000ff00 ) << 8) |\
197 (((x) & 0x00ff0000 ) >> 8) |\
198 (((x) & 0xff000000 ) >> 24))
199 #define SWAP16(x) (x) = \
200 ((((x) & 0x00ff ) << 8) |\
201 (((x) & 0xff00 ) >> 8))
204 #define CONV16(x) {if (words_bigendian) SWAP16(x);}
205 #define CONV32(x) {if (words_bigendian) SWAP32(x);}
206 #define CONV64(x) {if (words_bigendian) SWAP64(x);}
211 _JPEGFatalErrorHandler(j_common_ptr cinfo)
215 errmgr = (emptr) cinfo->err;
216 /* cinfo->err->output_message(cinfo);*/
217 longjmp(errmgr->setjmp_buffer, 1);
222 _JPEGErrorHandler(j_common_ptr cinfo)
226 errmgr = (emptr) cinfo->err;
227 /* cinfo->err->output_message(cinfo);*/
228 /* longjmp(errmgr->setjmp_buffer, 1);*/
233 _JPEGErrorHandler2(j_common_ptr cinfo, int msg_level)
237 errmgr = (emptr) cinfo->err;
238 /* cinfo->err->output_message(cinfo);*/
239 /* longjmp(errmgr->setjmp_buffer, 1);*/
245 eet_data_image_jpeg_rgb_decode(void *data, int size, int *w, int *h)
248 struct jpeg_decompress_struct cinfo;
249 struct _JPEG_error_mgr jerr;
250 unsigned char *ptr, *line[16], *tdata;
252 int x, y, l, i, scans, count, prevy;
255 f = fmemopen(data, (size_t)size, "r");
257 cinfo.err = jpeg_std_error(&(jerr.pub));
258 jerr.pub.error_exit = _JPEGFatalErrorHandler;
259 jerr.pub.emit_message = _JPEGErrorHandler2;
260 jerr.pub.output_message = _JPEGErrorHandler;
261 if (setjmp(jerr.setjmp_buffer))
263 jpeg_destroy_decompress(&cinfo);
267 jpeg_create_decompress(&cinfo);
268 jpeg_stdio_src(&cinfo, f);
269 jpeg_read_header(&cinfo, TRUE);
270 cinfo.do_fancy_upsampling = FALSE;
271 cinfo.do_block_smoothing = FALSE;
272 jpeg_start_decompress(&cinfo);
275 *w = cinfo.output_width;
276 *h = cinfo.output_height;
277 /* end head decoding */
279 if (cinfo.rec_outbuf_height > 16)
281 jpeg_destroy_decompress(&cinfo);
285 tdata = malloc((*w) * 16 * 3);
288 jpeg_destroy_decompress(&cinfo);
292 d = malloc((*w) * (*h) * 4);
296 jpeg_destroy_decompress(&cinfo);
303 if (cinfo.output_components == 3)
305 for (i = 0; i < cinfo.rec_outbuf_height; i++)
306 line[i] = tdata + (i * (*w) * 3);
307 for (l = 0; l < (*h); l += cinfo.rec_outbuf_height)
309 jpeg_read_scanlines(&cinfo, line, cinfo.rec_outbuf_height);
310 scans = cinfo.rec_outbuf_height;
311 if (((*h) - l) < scans) scans = (*h) - l;
313 for (y = 0; y < scans; y++)
315 for (x = 0; x < (*w); x++)
318 (0xff000000) | ((ptr[0]) << 16) | ((ptr[1]) << 8) | (ptr[2]);
325 else if (cinfo.output_components == 1)
327 for (i = 0; i < cinfo.rec_outbuf_height; i++)
328 line[i] = tdata + (i * (*w));
329 for (l = 0; l < (*h); l += cinfo.rec_outbuf_height)
331 jpeg_read_scanlines(&cinfo, line, cinfo.rec_outbuf_height);
332 scans = cinfo.rec_outbuf_height;
333 if (((*h) - l) < scans) scans = (*h) - l;
335 for (y = 0; y < scans; y++)
337 for (x = 0; x < (*w); x++)
340 (0xff000000) | ((ptr[0]) << 16) | ((ptr[0]) << 8) | (ptr[0]);
349 /* end data decoding */
350 jpeg_finish_decompress(&cinfo);
351 jpeg_destroy_decompress(&cinfo);
356 eet_data_image_jpeg_alpha_decode(void *data, int size, unsigned int *d, int *w, int *h)
358 struct jpeg_decompress_struct cinfo;
359 struct _JPEG_error_mgr jerr;
360 unsigned char *ptr, *line[16], *tdata;
362 int x, y, l, i, scans, count, prevy;
365 f = fmemopen(data, (size_t)size, "r");
367 cinfo.err = jpeg_std_error(&(jerr.pub));
368 jerr.pub.error_exit = _JPEGFatalErrorHandler;
369 jerr.pub.emit_message = _JPEGErrorHandler2;
370 jerr.pub.output_message = _JPEGErrorHandler;
371 if (setjmp(jerr.setjmp_buffer))
373 jpeg_destroy_decompress(&cinfo);
377 jpeg_create_decompress(&cinfo);
378 jpeg_stdio_src(&cinfo, f);
379 jpeg_read_header(&cinfo, TRUE);
380 cinfo.do_fancy_upsampling = FALSE;
381 cinfo.do_block_smoothing = FALSE;
382 jpeg_start_decompress(&cinfo);
385 if ((*w) != cinfo.output_width)
387 jpeg_destroy_decompress(&cinfo);
391 if ((*h) != cinfo.output_height)
393 jpeg_destroy_decompress(&cinfo);
397 *w = cinfo.output_width;
398 *h = cinfo.output_height;
399 /* end head decoding */
401 if (cinfo.rec_outbuf_height > 16)
403 jpeg_destroy_decompress(&cinfo);
407 tdata = malloc((*w) * 16 * 3);
410 jpeg_destroy_decompress(&cinfo);
417 if (cinfo.output_components == 3)
419 for (i = 0; i < cinfo.rec_outbuf_height; i++)
420 line[i] = tdata + (i * (*w) * 3);
421 for (l = 0; l < (*h); l += cinfo.rec_outbuf_height)
423 jpeg_read_scanlines(&cinfo, line, cinfo.rec_outbuf_height);
424 scans = cinfo.rec_outbuf_height;
425 if (((*h) - l) < scans) scans = (*h) - l;
427 for (y = 0; y < scans; y++)
429 for (x = 0; x < (*w); x++)
432 ((*ptr2) & 0x00ffffff) |
433 (((ptr[0] + ptr[1] + ptr[2]) / 3) << 24);
440 else if (cinfo.output_components == 1)
442 for (i = 0; i < cinfo.rec_outbuf_height; i++)
443 line[i] = tdata + (i * (*w));
444 for (l = 0; l < (*h); l += cinfo.rec_outbuf_height)
446 jpeg_read_scanlines(&cinfo, line, cinfo.rec_outbuf_height);
447 scans = cinfo.rec_outbuf_height;
448 if (((*h) - l) < scans) scans = (*h) - l;
450 for (y = 0; y < scans; y++)
452 for (x = 0; x < (*w); x++)
455 ((*ptr2) & 0x00ffffff) |
465 /* end data decoding */
466 jpeg_finish_decompress(&cinfo);
467 jpeg_destroy_decompress(&cinfo);
472 eet_data_image_lossless_convert(int *size, void *data, int w, int h, int alpha)
474 if (words_bigendian == -1)
478 v = htonl(0x12345678);
479 if (v == 0x12345678) words_bigendian = 1;
480 else words_bigendian = 0;
486 d = malloc((w * h * 4) + (8 * 4));
489 header[0] = 0xac1dfeed;
494 memcpy(d + 32, data, w * h * 4);
500 for (i = 0; i < ((w * h) + 8); i++) SWAP32(header[i]);
502 *size = ((w * h * 4) + (8 * 4));
508 eet_data_image_lossless_compressed_convert(int *size, void *data, int w, int h, int alpha, int compression)
510 if (words_bigendian == -1)
514 v = htonl(0x12345678);
515 if (v == 0x12345678) words_bigendian = 1;
516 else words_bigendian = 0;
526 d = malloc((w * h * 4) + (8 * 4));
528 buflen = (((w * h * 101) / 100) + 3) * 4;
529 comp = malloc(buflen);
536 header[0] = 0xac1dfeed;
540 header[4] = compression;
541 memcpy(d + 32, data, w * h * 4);
547 for (i = 0; i < ((w * h) + 8); i++) SWAP32(header[i]);
549 ret = compress2((Bytef *)comp, &buflen,
553 if (buflen > (w * h * 4))
556 *size = ((w * h * 4) + (8 * 4));
559 memcpy(d + 32, comp, buflen);
560 *size = (8 * 4) + buflen;
567 eet_data_image_jpeg_convert(int *size, void *data, int w, int h, int alpha, int quality)
572 struct _JPEG_error_mgr jerr;
574 struct jpeg_compress_struct cinfo;
578 f = open_memstream(&d, &sz);
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))
595 jpeg_destroy_compress(&cinfo);
601 jpeg_create_compress(&cinfo);
602 jpeg_stdio_dest(&cinfo, f);
603 cinfo.image_width = w;
604 cinfo.image_height = h;
605 cinfo.input_components = 3;
606 cinfo.in_color_space = JCS_RGB;
607 jpeg_set_defaults(&cinfo);
608 jpeg_set_quality(&cinfo, quality, TRUE);
609 jpeg_start_compress(&cinfo, TRUE);
612 while (cinfo.next_scanline < cinfo.image_height)
616 /* convert scaline from ARGB to RGB packed */
617 for (j = 0, i = 0; i < w; i++)
619 buf[j++] = ((*ptr) >> 16) & 0xff;
620 buf[j++] = ((*ptr) >> 8) & 0xff;
621 buf[j++] = ((*ptr)) & 0xff;
624 jbuf = (JSAMPROW *) (&buf);
625 jpeg_write_scanlines(&cinfo, jbuf, 1);
628 jpeg_finish_compress(&cinfo);
629 jpeg_destroy_compress(&cinfo);
638 eet_data_image_jpeg_alpha_convert(int *size, void *data, int w, int h, int alpha, int quality)
640 unsigned char *d1, *d2;
645 if (words_bigendian == -1)
649 v = htonl(0x12345678);
650 if (v == 0x12345678) words_bigendian = 1;
651 else words_bigendian = 0;
658 struct _JPEG_error_mgr jerr;
660 struct jpeg_compress_struct cinfo;
664 f = open_memstream(&d, &sz);
675 cinfo.err = jpeg_std_error(&(jerr.pub));
676 jerr.pub.error_exit = _JPEGFatalErrorHandler;
677 jerr.pub.emit_message = _JPEGErrorHandler2;
678 jerr.pub.output_message = _JPEGErrorHandler;
679 if (setjmp(jerr.setjmp_buffer))
681 jpeg_destroy_compress(&cinfo);
687 jpeg_create_compress(&cinfo);
688 jpeg_stdio_dest(&cinfo, f);
689 cinfo.image_width = w;
690 cinfo.image_height = h;
691 cinfo.input_components = 3;
692 cinfo.in_color_space = JCS_RGB;
693 jpeg_set_defaults(&cinfo);
694 jpeg_set_quality(&cinfo, quality, TRUE);
695 jpeg_start_compress(&cinfo, TRUE);
698 while (cinfo.next_scanline < cinfo.image_height)
702 /* convert scaline from ARGB to RGB packed */
703 for (j = 0, i = 0; i < w; i++)
705 buf[j++] = ((*ptr) >> 16) & 0xff;
706 buf[j++] = ((*ptr) >> 8) & 0xff;
707 buf[j++] = ((*ptr)) & 0xff;
710 jbuf = (JSAMPROW *) (&buf);
711 jpeg_write_scanlines(&cinfo, jbuf, 1);
714 jpeg_finish_compress(&cinfo);
715 jpeg_destroy_compress(&cinfo);
726 struct _JPEG_error_mgr jerr;
728 struct jpeg_compress_struct cinfo;
732 f = open_memstream(&d, &sz);
748 cinfo.err = jpeg_std_error(&(jerr.pub));
749 jerr.pub.error_exit = _JPEGFatalErrorHandler;
750 jerr.pub.emit_message = _JPEGErrorHandler2;
751 jerr.pub.output_message = _JPEGErrorHandler;
752 if (setjmp(jerr.setjmp_buffer))
754 jpeg_destroy_compress(&cinfo);
761 jpeg_create_compress(&cinfo);
762 jpeg_stdio_dest(&cinfo, f);
763 cinfo.image_width = w;
764 cinfo.image_height = h;
765 cinfo.input_components = 1;
766 cinfo.in_color_space = JCS_GRAYSCALE;
767 jpeg_set_defaults(&cinfo);
768 jpeg_set_quality(&cinfo, quality, TRUE);
769 jpeg_start_compress(&cinfo, TRUE);
772 while (cinfo.next_scanline < cinfo.image_height)
776 /* convert scaline from ARGB to RGB packed */
777 for (j = 0, i = 0; i < w; i++)
779 buf[j++] = ((*ptr) >> 24) & 0xff;
782 jbuf = (JSAMPROW *) (&buf);
783 jpeg_write_scanlines(&cinfo, jbuf, 1);
786 jpeg_finish_compress(&cinfo);
787 jpeg_destroy_compress(&cinfo);
794 d = malloc(12 + sz1 + sz2);
802 header[0] = 0xbeeff00d;
809 for (i = 0; i < ((w * h) + 3); i++) SWAP32(header[i]);
811 memcpy(d + 12, d1, sz1);
812 memcpy(d + 12 + sz1, d2, sz2);
816 *size = 12 + sz1 + sz2;
823 eet_data_get_char(void *src, void *src_end, void *dst)
827 if ((src + sizeof(char)) > src_end) return -1;
836 eet_data_put_char(void *src, int *size_ret)
840 d = (char *)malloc(sizeof(char));
845 *size_ret = sizeof(char);
851 eet_data_get_short(void *src, void *src_end, void *dst)
856 if ((src + sizeof(short)) > src_end) return -1;
859 /* alignment fixup */
860 if ((int)s & (sizeof(short) - 1))
862 memcpy(&tmp, s, sizeof(short));
867 return sizeof(short);
871 eet_data_put_short(void *src, int *size_ret)
875 d = (short *)malloc(sizeof(short));
880 *size_ret = sizeof(short);
886 eet_data_get_int(void *src, void *src_end, void *dst)
891 if ((src + sizeof(int)) > src_end) return -1;
894 /* alignment fixup */
895 if ((int)s & (sizeof(int) - 1))
897 memcpy(&tmp, s, sizeof(int));
906 eet_data_put_int(void *src, int *size_ret)
910 d = (int *)malloc(sizeof(int));
915 *size_ret = sizeof(int);
921 eet_data_get_long_long(void *src, void *src_end, void *dst)
926 if ((src + sizeof(long long)) > src_end) return -1;
927 s = (long long *)src;
928 d = (long long *)dst;
929 /* alignment fixup */
930 if ((int)s & (sizeof(long long) - 1))
932 memcpy(&tmp, s, sizeof(long long));
937 return sizeof(long long);
941 eet_data_put_long_long(void *src, int *size_ret)
945 d = (long long *)malloc(sizeof(long long));
947 s = (long long *)src;
950 *size_ret = sizeof(long long);
956 eet_data_get_string(void *src, void *src_end, void *dst)
965 while ((p < (char *)src_end) && (*p != 0)) {len++; p++;}
966 *d = malloc(len + 1);
967 if (!(*d)) return -1;
974 eet_data_put_string(void *src, int *size_ret)
980 s = (char *)(*((char **)src));
991 eet_data_get_float(void *src, void *src_end, void *dst)
994 char *s, *str, *p, *prev_locale;
1001 while ((p < (char *)src_end) && (*p != 0)) {len++; p++;}
1002 str = malloc(len + 1);
1003 if (!str) return -1;
1004 memcpy(str, s, len);
1007 prev_locale = setlocale(LC_NUMERIC, "C");
1008 *d = (float)atof(str);
1009 if (prev_locale) setlocale(LC_NUMERIC, prev_locale);
1016 eet_data_put_float(void *src, int *size_ret)
1019 char *d, buf[64], *prev_locale;
1023 prev_locale = setlocale(LC_NUMERIC, "C");
1024 snprintf(buf, sizeof(buf), "%16.16f", (double)(*s));
1025 if (prev_locale) setlocale(LC_NUMERIC, prev_locale);
1027 d = malloc(len + 1);
1028 if (!d) return NULL;
1030 *size_ret = len + 1;
1036 eet_data_get_double(void *src, void *src_end, void *dst)
1039 char *s, *str, *p, *prev_locale;
1046 while ((p < (char *)src_end) && (*p != 0)) {len++; p++;}
1047 str = malloc(len + 1);
1048 if (!str) return -1;
1049 memcpy(str, s, len);
1052 prev_locale = setlocale(LC_NUMERIC, "C");
1053 *d = (double)atof(str);
1054 if (prev_locale) setlocale(LC_NUMERIC, prev_locale);
1061 eet_data_put_double(void *src, int *size_ret)
1064 char *d, buf[128], *prev_locale;
1068 prev_locale = setlocale(LC_NUMERIC, "C");
1069 snprintf(buf, sizeof(buf), "%32.32f", (double)(*s));
1070 if (prev_locale) setlocale(LC_NUMERIC, prev_locale);
1072 d = malloc(len + 1);
1073 if (!d) return NULL;
1075 *size_ret = len + 1;
1080 eet_data_get_type(int type, void *src, void *src_end, void *dest)
1084 ret = eet_coder[type - 1].get(src, src_end, dest);
1089 eet_data_put_type(int type, void *src, int *size_ret)
1093 ret = eet_coder[type - 1].put(src, size_ret);
1100 * int = chunk size (including magic string);
1101 * char[] = chuck magic/name string (0 byte terminated);
1102 * ... sub-chunks (a chunk can contain chuncks recusrively) ...
1104 * ... payload data ...
1108 static Eet_Data_Chunk *
1109 eet_data_chunk_get(void *src, int size)
1111 Eet_Data_Chunk *chnk;
1115 if (!src) return NULL;
1116 if (size <= 8) return NULL;
1118 chnk = calloc(1, sizeof(Eet_Data_Chunk));
1119 if (!chnk) return NULL;
1122 if ((s[0] != 'C') || (s[1] != 'H') || (s[2] != 'n') || (s[3] != 'K'))
1127 ret1 = eet_data_get_type(EET_T_INT, (void *)(s + 4), (void *)(s + size), &(chnk->size));
1133 if ((chnk->size < 0) || ((chnk->size + 8) > size))
1138 ret2 = eet_data_get_type(EET_T_STRING, (void *)(s + 8), (void *)(s + size), &(chnk->name));
1144 chnk->data = src + 4 + ret1 + ret2;
1149 static Eet_Data_Chunk *
1150 eet_data_chunk_new(void *data, int size, char *name)
1152 Eet_Data_Chunk *chnk;
1154 if (!name) return NULL;
1155 chnk = calloc(1, sizeof(Eet_Data_Chunk));
1156 if (!chnk) return NULL;
1158 chnk->name = strdup(name);
1166 eet_data_chunk_free(Eet_Data_Chunk *chnk)
1168 if (chnk->name) free(chnk->name);
1172 static Eet_Data_Stream *
1173 eet_data_stream_new(void)
1175 Eet_Data_Stream *ds;
1177 ds = calloc(1, sizeof(Eet_Data_Stream));
1178 if (!ds) return NULL;
1183 eet_data_stream_free(Eet_Data_Stream *ds)
1185 if (ds->data) free(ds->data);
1190 eet_data_stream_write(Eet_Data_Stream *ds, void *data, int size)
1194 if ((ds->pos + size) > ds->size)
1196 ds->data = realloc(ds->data, ds->size + size + 256);
1203 ds->size = ds->size + size + 256;
1206 memcpy(p + ds->pos, data, size);
1211 eet_data_chunk_put(Eet_Data_Chunk *chnk, Eet_Data_Stream *ds)
1217 if (!chnk->data) return;
1219 eet_data_stream_write(ds, "CHnK", 4);
1220 /* size of chunk payload data + name */
1221 s = strlen(chnk->name) + 1 + chnk->size;
1222 size = eet_data_put_int(&s, &size_ret);
1225 eet_data_stream_write(ds, size, size_ret);
1228 /* write chunk name */
1229 eet_data_stream_write(ds, chnk->name, strlen(chnk->name) + 1);
1231 eet_data_stream_write(ds, chnk->data, chnk->size);
1237 eet_data_image_write(Eet_File *ef, char *name,
1238 void *data, int w, int h, int alpha,
1239 int compress, int quality, int lossy)
1244 d = eet_data_image_encode(data, &size, w, h, alpha, compress, quality, lossy);
1249 v = eet_write(ef, name, d, size, 0);
1257 eet_data_image_read(Eet_File *ef, char *name,
1258 int *w, int *h, int *alpha,
1259 int *compress, int *quality, int *lossy)
1263 unsigned int *d = NULL;
1266 data = eet_read(ef, name, &size);
1267 if (!data) return NULL;
1268 d = eet_data_image_decode(data, size, w, h, alpha, compress, quality, lossy);
1274 eet_data_image_encode(void *data, int *size_ret, int w, int h, int alpha, int compress, int quality, int lossy)
1282 d = eet_data_image_lossless_convert(&size, data, w, h, alpha);
1284 d = eet_data_image_lossless_compressed_convert(&size, data, w, h, alpha, compress);
1289 d = eet_data_image_jpeg_convert(&size, data, w, h, alpha, quality);
1291 d = eet_data_image_jpeg_alpha_convert(&size, data, w, h, alpha, quality);
1293 if (size_ret) *size_ret = size;
1298 eet_data_image_decode(void *data, int size, int *w, int *h, int *alpha, int *compress, int *quality, int *lossy)
1300 unsigned int *d = NULL;
1303 if (words_bigendian == -1)
1305 unsigned long int v;
1307 v = htonl(0x12345678);
1308 if (v == 0x12345678) words_bigendian = 1;
1309 else words_bigendian = 0;
1312 if (size < 32) return NULL;
1314 memcpy(header, data, 32);
1315 if (words_bigendian)
1319 for (i = 0; i < 8; i++) SWAP32(header[i]);
1321 if (header[0] == 0xac1dfeed)
1330 if ((iw > 8192) || (ih > 8192)) return NULL;
1331 if ((cp == 0) && (size < ((iw * ih * 4) + 32))) return NULL;
1332 body = ((unsigned int *)data) + 8;
1333 d = malloc(iw * ih * 4);
1334 if (!d) return NULL;
1337 memcpy(d, body, iw * ih * 4);
1338 if (words_bigendian)
1342 for (x = 0; x < (iw * ih); x++) SWAP32(d[x]);
1350 uncompress((Bytef *)d, &dlen, (Bytef *)body,
1351 (uLongf)(size - 32));
1352 if (words_bigendian)
1356 for (x = 0; x < (iw * ih); x++) SWAP32(d[x]);
1363 if (alpha) *alpha = al;
1364 if (compress) *compress = cp;
1365 if (lossy) *lossy = 0;
1366 if (quality) *quality = 100;
1369 else if (header[0] == 0xbeeff00d)
1379 d = eet_data_image_jpeg_rgb_decode(dt, sz1, &iw, &ih);
1383 eet_data_image_jpeg_alpha_decode(dt, sz2, d, &iw, &ih);
1389 if (alpha) *alpha = 1;
1390 if (compress) *compress = 0;
1391 if (lossy) *lossy = 1;
1392 if (quality) *quality = 75;
1399 d = eet_data_image_jpeg_rgb_decode(data, size, &iw, &ih);
1404 if (alpha) *alpha = 0;
1405 if (compress) *compress = 0;
1406 if (lossy) *lossy = 1;
1407 if (quality) *quality = 75;
1413 Eet_Data_Descriptor *
1414 eet_data_descriptor_new(char *name,
1416 void *(*func_list_next) (void *l),
1417 void *(*func_list_append) (void *l, void *d),
1418 void *(*func_list_data) (void *l),
1419 void (*func_hash_foreach) (void *h, int (*func) (void *h, const char *k, void *dt, void *fdt), void *fdt),
1420 void *(*func_hash_add) (void *h, const char *k, void *d))
1422 Eet_Data_Descriptor *edd;
1424 edd = calloc(1, sizeof(Eet_Data_Descriptor));
1425 edd->name = strdup(name);
1427 edd->func.list_next = func_list_next;
1428 edd->func.list_append = func_list_append;
1429 edd->func.list_data = func_list_data;
1430 edd->func.hash_foreach = func_hash_foreach;
1431 edd->func.hash_add = func_hash_add;
1436 eet_data_descriptor_free(Eet_Data_Descriptor *edd)
1440 if (edd->name) free(edd->name);
1441 for (i = 0; i < edd->elements.num; i++)
1443 if (edd->elements.set[i].name) free(edd->elements.set[i].name);
1444 if (edd->elements.set[i].counter_name) free(edd->elements.set[i].counter_name);
1446 if (edd->elements.set) free(edd->elements.set);
1451 eet_data_descriptor_element_add(Eet_Data_Descriptor *edd, char *name, int type,
1454 int count, char *counter_name,
1455 Eet_Data_Descriptor *subtype)
1457 Eet_Data_Element *ede;
1459 edd->elements.num++;
1460 edd->elements.set = realloc(edd->elements.set, edd->elements.num * sizeof(Eet_Data_Element));
1461 if (!edd->elements.set) return;
1462 ede = &(edd->elements.set[edd->elements.num - 1]);
1463 ede->name = strdup(name);
1465 ede->group_type = group_type;
1466 ede->offset = offset;
1469 ede->counter_name = strdup(counter_name);
1470 else ede->counter_name = NULL;
1471 ede->subtype = subtype;
1475 eet_data_read(Eet_File *ef, Eet_Data_Descriptor *edd, char *name)
1481 data = eet_read(ef, name, &size);
1482 if (!data) return NULL;
1483 data_dec = eet_data_descriptor_decode(edd, data, size);
1489 eet_data_write(Eet_File *ef, Eet_Data_Descriptor *edd, char *name, void *data, int compress)
1495 data_enc = eet_data_descriptor_encode(edd, data, &size);
1496 if (!data_enc) return 0;
1497 val = eet_write(ef, name, data_enc, size, compress);
1503 eet_data_descriptor_decode(Eet_Data_Descriptor *edd,
1510 Eet_Data_Chunk *chnk;
1512 if (words_bigendian == -1)
1514 unsigned long int v;
1516 v = htonl(0x12345678);
1517 if (v == 0x12345678) words_bigendian = 1;
1518 else words_bigendian = 0;
1521 data = calloc(1, edd->size);
1522 if (!data) return NULL;
1523 chnk = eet_data_chunk_get(data_in, size_in);
1529 if (strcmp(chnk->name, edd->name))
1531 eet_data_chunk_free(chnk);
1536 size = size_in - (4 + 4 + strlen(chnk->name) + 1);
1539 Eet_Data_Chunk *echnk;
1542 /* get next data chunk */
1543 echnk = eet_data_chunk_get(p, size);
1546 /* FIXME: partially built data struct - leak!!!! */
1548 eet_data_chunk_free(chnk);
1551 for (i = 0; i < edd->elements.num; i++)
1553 Eet_Data_Element *ede;
1555 ede = &(edd->elements.set[i]);
1556 if (!strcmp(echnk->name, ede->name))
1558 if (ede->group_type == EET_G_UNKNOWN)
1563 if ((ede->type >= EET_T_CHAR) &&
1564 (ede->type <= EET_T_STRING))
1566 ret = eet_data_get_type(ede->type,
1568 ((char *)echnk->data) + echnk->size,
1569 ((char *)data) + ede->offset);
1571 else if (ede->subtype)
1575 data_ret = eet_data_descriptor_decode(ede->subtype,
1578 ptr = (void **)(((char *)data) + ede->offset);
1579 *ptr = (void *)data_ret;
1584 switch (ede->group_type)
1587 case EET_G_VAR_ARRAY:
1589 printf("ARRAY TYPE NOT IMPLIMENTED YET!!!\n");
1599 ptr = (void **)(((char *)data) + ede->offset);
1602 if ((ede->type >= EET_T_CHAR) &&
1603 (ede->type <= EET_T_STRING))
1605 data_ret = calloc(1, eet_coder[ede->type].size);
1608 ret = eet_data_get_type(ede->type,
1610 ((char *)echnk->data) + echnk->size,
1619 else if (ede->subtype)
1621 data_ret = eet_data_descriptor_decode(ede->subtype,
1627 list = edd->func.list_append(list, data_ret);
1633 printf("HASH TYPE NOT IMPLIMENTED YET!!!\n");
1642 /* advance to next chunk */
1643 p += (4 + 4 + strlen(echnk->name) + 1 + echnk->size);
1644 size -= (4 + 4 + strlen(echnk->name) + 1 + echnk->size);
1645 eet_data_chunk_free(echnk);
1647 eet_data_chunk_free(chnk);
1652 eet_data_descriptor_encode(Eet_Data_Descriptor *edd,
1656 Eet_Data_Chunk *chnk;
1657 Eet_Data_Stream *ds;
1662 if (words_bigendian == -1)
1664 unsigned long int v;
1666 v = htonl(0x12345678);
1667 if (v == 0x12345678) words_bigendian = 1;
1668 else words_bigendian = 0;
1671 ds = eet_data_stream_new();
1672 for (i = 0; i < edd->elements.num; i++)
1674 Eet_Data_Element *ede;
1675 Eet_Data_Chunk *echnk;
1679 ede = &(edd->elements.set[i]);
1681 if (ede->group_type == EET_G_UNKNOWN)
1683 if ((ede->type >= EET_T_CHAR) &&
1684 (ede->type <= EET_T_STRING))
1685 data = eet_data_put_type(ede->type,
1686 ((char *)data_in) + ede->offset,
1688 else if (ede->subtype)
1689 data = eet_data_descriptor_encode(ede->subtype,
1690 *((char **)(((char *)data_in) + ede->offset)),
1694 echnk = eet_data_chunk_new(data, size, ede->name);
1695 eet_data_chunk_put(echnk, ds);
1696 eet_data_chunk_free(echnk);
1703 switch (ede->group_type)
1706 case EET_G_VAR_ARRAY:
1708 printf("ARRAY TYPE NOT IMPLIMENTED YET!!!\n");
1715 l = *((void **)(((char *)data_in) + ede->offset));
1716 for (; l; l = edd->func.list_next(l))
1718 if ((ede->type >= EET_T_CHAR) &&
1719 (ede->type <= EET_T_STRING))
1720 data = eet_data_put_type(ede->type,
1721 edd->func.list_data(l),
1723 else if (ede->subtype)
1724 data = eet_data_descriptor_encode(ede->subtype,
1725 edd->func.list_data(l),
1729 echnk = eet_data_chunk_new(data, size, ede->name);
1730 eet_data_chunk_put(echnk, ds);
1731 eet_data_chunk_free(echnk);
1740 printf("HASH TYPE NOT IMPLIMENTED YET!!!\n");
1748 chnk = eet_data_chunk_new(ds->data, ds->pos, edd->name);
1751 eet_data_stream_free(ds);
1753 ds = eet_data_stream_new();
1754 eet_data_chunk_put(chnk, ds);
1760 eet_data_stream_free(ds);
1762 eet_data_chunk_free(chnk);