OSDN Git Service

test for replaceBitmapData Lossless with alpha0
[swfed/swfed.git] / src / swf_tag_lossless.c
1 /* 
2   +----------------------------------------------------------------------+
3   | Author: yoya@awm.jp                                                  |
4   +----------------------------------------------------------------------+
5 */
6
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <string.h> /* strndup */
10 #include <zlib.h>
11 #include "bitstream.h"
12 #include "swf_define.h"
13 #include "swf_tag_lossless.h"
14 #include "swf_object.h"
15 #include "swf_png.h"
16 #include "swf_gif.h"
17
18 swf_tag_detail_handler_t lossless_detail_handler;
19
20 swf_tag_detail_handler_t *swf_tag_lossless_detail_handler(void) {
21     lossless_detail_handler.create   = swf_tag_lossless_create_detail;
22     lossless_detail_handler.input    = swf_tag_lossless_input_detail;
23     lossless_detail_handler.get_cid  = swf_tag_lossless_get_cid_detail;
24     lossless_detail_handler.replace_cid = swf_tag_lossless_replace_cid_detail;
25     lossless_detail_handler.output   = swf_tag_lossless_output_detail;
26     lossless_detail_handler.print    = swf_tag_lossless_print_detail;
27     lossless_detail_handler.destroy  = swf_tag_lossless_destroy_detail;
28     return &lossless_detail_handler;
29 }
30
31 void *
32 swf_tag_lossless_create_detail(void) {
33     swf_tag_lossless_detail_t *swf_tag_lossless;
34     swf_tag_lossless = calloc(sizeof(*swf_tag_lossless), 1);
35     if (swf_tag_lossless == NULL) {
36         fprintf(stderr, "swf_tag_lossless_create_detail: can't calloc swf_tag_lossless\n");
37         return NULL;
38     }
39     swf_tag_lossless->image_id = 0;
40     swf_tag_lossless->format = 0;
41     swf_tag_lossless->width  = 0;
42     swf_tag_lossless->height = 0;
43     swf_tag_lossless->colormap_count = 0;
44     swf_tag_lossless->colormap  = NULL;
45     swf_tag_lossless->colormap2 = NULL;
46     swf_tag_lossless->indices   = NULL;
47     swf_tag_lossless->bitmap  = NULL;
48     swf_tag_lossless->bitmap2 = NULL;
49     return swf_tag_lossless;
50 }
51
52 int
53 swf_tag_lossless_input_detail(swf_tag_t *tag,
54                               struct swf_object_ *swf) {
55     swf_tag_lossless_detail_t *swf_tag_lossless = NULL;
56     unsigned char *data = NULL;
57     unsigned long length;
58     bitstream_t *bs = NULL, *bs2 = NULL;
59     unsigned long i;
60     unsigned char *tmp_buff = NULL, *old_buff_ref = NULL;
61     unsigned long origsize, old_size, offset;
62     int result;
63     (void) swf;
64     if (tag == NULL) {
65         fprintf(stderr, "swf_tag_lossless_input_detail: tag == NULL\n");
66         return 1;
67     }
68     if (tag->detail == NULL) {
69         fprintf(stderr, "swf_tag_lossless_input_detail: tag->detail== NULL\n");
70         return 1;
71     }
72     swf_tag_lossless = tag->detail;
73     data = tag->data;
74     length = tag->length;
75
76     bs = bitstream_open();
77     bitstream_input(bs, data, length);
78     swf_tag_lossless->image_id = bitstream_getbytesLE(bs, 2);
79     swf_tag_lossless->format = bitstream_getbyte(bs);
80     swf_tag_lossless->width = bitstream_getbytesLE(bs, 2);
81     swf_tag_lossless->height = bitstream_getbytesLE(bs, 2);
82     if (swf_tag_lossless->format == 3) {
83         unsigned long indices_len;
84         int bytes_per_color;
85         swf_tag_lossless->colormap_count = bitstream_getbyte(bs) + 1;
86         indices_len = ((swf_tag_lossless->width + 3) & -4) * swf_tag_lossless->height;
87         if (tag->code == 20) { // Lossless => rgb (3 bytes)
88             bytes_per_color = 3;
89         } else { // Lossless2 => rgba (4 bytes)
90             bytes_per_color = 4;
91         }
92         origsize = bytes_per_color * swf_tag_lossless->colormap_count + indices_len;
93         tmp_buff = malloc(origsize);
94         offset = bitstream_getbytepos(bs);
95         old_buff_ref = bitstream_buffer(bs, offset);
96         old_size = bitstream_length(bs) - offset;
97         result = uncompress(tmp_buff, &origsize, old_buff_ref, old_size);
98         if (result != Z_OK) {
99             if (result == Z_MEM_ERROR) {
100                 fprintf(stderr, "swf_tag_lossless_input_detaill: uncompress: Z_MEM_ERROR: can't malloc at line(%d)\n", __LINE__);
101             } else if (result == Z_BUF_ERROR) {
102                 fprintf(stderr, "swf_tag_lossless_input_detail: uncompress: Z_BUF_ERROR: not enough buff size at line(%d)\n", __LINE__);
103             } else if (result == Z_DATA_ERROR) {
104                 fprintf(stderr, "swf_tag_lossless_input_detail: uncompress: Z_DATA_ERROR: corrupted or imcomplete data at line(%d)\n", __LINE__);
105             } else {
106                 fprintf(stderr, "swf_tag_lossless_input_detail: uncompress: failed byunknown reason (%d) at line(%d)\n", result, __LINE__);
107             }
108             free(tmp_buff);
109             bitstream_close(bs);
110             return 1;
111         }
112         if (indices_len != origsize - bytes_per_color * swf_tag_lossless->colormap_count) {
113             fprintf(stderr, "swf_tag_lossless_input_detail: indices_len(%lu) != origsize(%lu) - %d * swf_tag_lossless->colormap_count(%d) at line(%d)\n",
114                     indices_len, origsize, bytes_per_color,
115                     swf_tag_lossless->colormap_count, __LINE__);
116             free(tmp_buff);
117             bitstream_close(bs);
118             return 1;
119         }
120         bs2 = bitstream_open();
121         bitstream_input(bs2, tmp_buff, origsize);
122         if (tag->code == 20) { // Lossless
123             swf_tag_lossless->colormap = malloc(sizeof(swf_rgb_t) * swf_tag_lossless->colormap_count);
124             for (i=0 ; i < swf_tag_lossless->colormap_count ; i++) {
125                 swf_rgb_t *rgb = swf_tag_lossless->colormap + i;
126                 swf_rgb_parse(bs2, rgb);
127             }
128         } else { // tag == 36 (Lossless2)
129             swf_tag_lossless->colormap2 = malloc(sizeof(swf_rgba_t) * swf_tag_lossless->colormap_count);
130             for (i=0 ; i < swf_tag_lossless->colormap_count ; i++) {
131                 swf_rgba_t *rgba = swf_tag_lossless->colormap2 + i;
132                 swf_rgba_parse(bs2, rgba);
133             }
134         }
135         swf_tag_lossless->indices = malloc(indices_len);
136         bitstream_getstring(bs2, swf_tag_lossless->indices, indices_len);
137         bitstream_close(bs2);
138         free(tmp_buff);
139     } else { // format != 3
140         unsigned long bitmap_count;
141         bitmap_count = swf_tag_lossless->width * swf_tag_lossless->height;
142         origsize = 4 * bitmap_count; // xrgb or argb (4 bytes)
143         tmp_buff = malloc(origsize);
144         offset = bitstream_getbytepos(bs);
145         old_buff_ref = bitstream_buffer(bs, offset);
146         old_size = bitstream_length(bs) - offset;
147         result = uncompress(tmp_buff, &origsize, old_buff_ref, old_size);
148         if (result != Z_OK) {
149             if (result == Z_MEM_ERROR) {
150                 fprintf(stderr, "swf_tag_lossless_input_detail: uncompress: Z_MEM_ERROR: can't malloc (origsize=%lu, old_size=%lu) at line(%d)\n",
151                         origsize, old_size, __LINE__);
152             } else if (result == Z_BUF_ERROR) {
153                 fprintf(stderr, "swf_tag_lossless_input_detail: uncompress: Z_BUF_ERROR: not enough buff size(origsize=%lu, old_size=%lu) at line(%d)\n",
154                         origsize, old_size, __LINE__);
155             } else if (result == Z_DATA_ERROR) {
156                 fprintf(stderr, "swf_tag_lossless_input_detail: uncompress: Z_DATA_ERROR: corrupted or imcomplete data at line(%d)\n", __LINE__);
157             } else {
158                 fprintf(stderr, "swf_tag_lossless_input_detail: uncompress: failed byunknown reason (%d) at line(%d)\n", result, __LINE__);
159             }
160             free(tmp_buff);
161             bitstream_close(bs);
162             return 1;
163         }
164         bs2 = bitstream_open();
165         bitstream_input(bs2, tmp_buff, origsize);
166         if (tag->code == 20) { // Lossless
167             swf_tag_lossless->bitmap = malloc(bitmap_count * sizeof(swf_xrgb_t));
168             for (i=0 ; i < bitmap_count ; i++) {
169                 swf_xrgb_t *xrgb = swf_tag_lossless->bitmap + i;
170                 swf_xrgb_parse(bs2, xrgb);
171             }
172         } else { // tag == 36 (Lossless2)
173             swf_tag_lossless->bitmap2 = malloc(bitmap_count * sizeof(swf_argb_t));
174             for (i=0 ; i < bitmap_count ; i++) {
175                 swf_argb_t *argb = swf_tag_lossless->bitmap2 + i;
176                 swf_argb_parse(bs2, argb);
177             }
178         }
179         bitstream_close(bs2);
180         free(tmp_buff);
181     }
182     bitstream_close(bs);
183     return 0;
184
185 }
186
187 int
188 swf_tag_lossless_get_cid_detail(swf_tag_t *tag) {
189     unsigned char *data = NULL;
190     if (tag == NULL) {
191         fprintf(stderr, "swf_tag_lossless_get_cid_detail: tag == NULL\n");
192         return 1;
193     }
194     data = tag->data;
195     if (tag->detail) {
196         swf_tag_lossless_detail_t *swf_tag_lossless = (swf_tag_lossless_detail_t *) tag->detail;
197         return swf_tag_lossless->image_id;
198     }
199     if (data == NULL) {
200         fprintf(stderr, "swf_tag_lossless_get_cid_detail: data==NULL at line(%d)\n", __LINE__);
201         return -1;
202     }
203     return GetUShortLE(data); // image_id;
204 }
205
206 int
207 swf_tag_lossless_replace_cid_detail(swf_tag_t *tag, int id) {
208     unsigned char *data = NULL;
209     if (tag == NULL) {
210         fprintf(stderr, "swf_tag_lossless_replace_cid_detail: tag == NULL\n");
211         return 1;
212     }
213     data = tag->data;
214     if (tag->detail) {
215         swf_tag_lossless_detail_t *swf_tag_lossless = (swf_tag_lossless_detail_t *) tag->detail;
216         swf_tag_lossless->image_id = id;
217     }
218     if (data) {
219         PutUShortLE(data, id);
220     }
221     return 0; // always 0
222 }
223
224 unsigned char *
225 swf_tag_lossless_output_detail(swf_tag_t *tag, unsigned long *length,
226                                struct swf_object_ *swf) {
227     swf_tag_lossless_detail_t *swf_tag_lossless = (swf_tag_lossless_detail_t *) tag->detail;
228     bitstream_t *bs = NULL, *bs2 = NULL;
229     unsigned char *data = NULL;
230     unsigned long i;
231     unsigned char *tmp_buff = NULL, *old_buff_ref = NULL;
232     unsigned long compsize, old_size;
233     int result;
234     if (tag == NULL) {
235         fprintf(stderr, "swf_tag_lossless_output_detail: tag == NULL\n");
236         return NULL;
237     }
238     if (swf == NULL) {
239         fprintf(stderr, "swf_tag_lossless_output_detail: swf == NULL\n");
240         return NULL;
241     }
242     if (length == NULL) {
243         fprintf(stderr, "swf_tag_lossless_output_detail: length == NULL\n");
244         return NULL;
245     }
246
247     *length = 0;
248     bs = bitstream_open();
249     bitstream_putbytesLE(bs, swf_tag_lossless->image_id, 2);
250     bitstream_putbyte(bs, swf_tag_lossless->format);
251     bitstream_putbytesLE(bs, swf_tag_lossless->width, 2);
252     bitstream_putbytesLE(bs, swf_tag_lossless->height, 2);
253     if (swf_tag_lossless->format == 3) {
254         unsigned long indices_len;
255         bitstream_putbyte(bs, swf_tag_lossless->colormap_count - 1); /* XXX */
256         bs2 = bitstream_open();
257         if (tag->code == 20) { // Lossless
258             for (i=0 ; i < swf_tag_lossless->colormap_count ; i++) {
259                 swf_rgb_t *rgb = swf_tag_lossless->colormap + i;
260                 swf_rgb_build(bs2, rgb);
261             }
262         } else { // tag == 36 (Lossless2)
263             for (i=0 ; i < swf_tag_lossless->colormap_count ; i++) {
264                 swf_rgba_t *rgba = swf_tag_lossless->colormap2 + i;
265                 swf_rgba_build(bs2, rgba);
266             }
267         }
268         indices_len = ((swf_tag_lossless->width + 3) & -4) * swf_tag_lossless->height;
269         bitstream_putstring(bs2, swf_tag_lossless->indices,
270                             indices_len);
271         old_buff_ref = bitstream_buffer(bs2, 0);
272         old_size = bitstream_length(bs2);
273         compsize = old_size * 1.001 + 12; // increasing, rarely situation
274         tmp_buff = malloc(compsize);
275         result = compress2(tmp_buff, &compsize, old_buff_ref, old_size, swf->compress_level);
276         if (result != Z_OK) {
277             if (result == Z_MEM_ERROR) {
278                 fprintf(stderr, "swf_tag_lossless_output_detail: compress Z_MEM_ERROR: can't malloc\n");
279             } else if (result == Z_BUF_ERROR) {
280                 fprintf(stderr, "swf_tag_lossless_output_detail: compress Z_BUF_ERROR: not enough buff size\n");
281             } else {
282                 fprintf(stderr, "swf_tag_lossless_output_detail: compress failed by unknown reason\n");
283             }
284             bitstream_close(bs2);
285             bitstream_close(bs);
286             free(tmp_buff);
287             return NULL; // FAILURE
288         }
289         bitstream_putstring(bs, tmp_buff, compsize);
290         bitstream_close(bs2);
291         free(tmp_buff);
292         } else { // format == 4 or format == 5
293         unsigned long bitmap_size;
294         bs2 = bitstream_open();
295         if (tag->code == 20) { // Lossless
296             bitmap_size = swf_tag_lossless->width * swf_tag_lossless->height;
297             if (swf_tag_lossless->format == 4) {
298                 int x, y;
299                 int width_padding = (swf_tag_lossless->width%2)?1:0;
300                 i = 0;
301                 for (y = 0 ; y < swf_tag_lossless->height ; y++) {
302                     for (x = 0 ; x < swf_tag_lossless->width ; x++) {
303                         swf_xrgb_t *xrgb = swf_tag_lossless->bitmap + i;
304                         bitstream_putbit(bs2, 0);
305                         bitstream_putbits(bs2, xrgb->red >> 3, 5);
306                         bitstream_putbits(bs2, xrgb->green >> 3, 5);
307                         bitstream_putbits(bs2, xrgb->blue >> 3, 5);
308                         i++;
309                     }
310                     if (width_padding) {
311                         bitstream_putstring(bs2, (unsigned char *)"\0\0", 2);
312                     }
313                 }
314             }  else {
315                 for (i=0 ; i < bitmap_size ; i++) {
316                     swf_xrgb_t *xrgb = swf_tag_lossless->bitmap + i;
317                     swf_xrgb_build(bs2, xrgb);
318                 }
319             }
320         } else { // tag == 36 (Lossless2)
321             bitmap_size = swf_tag_lossless->width * swf_tag_lossless->height;
322             for (i=0 ; i < bitmap_size ; i++) {
323                 swf_argb_t *argb = swf_tag_lossless->bitmap2 + i;
324                 swf_argb_build(bs2, argb);
325             }
326         }
327         old_buff_ref = bitstream_buffer(bs2, 0);
328         old_size = bitstream_length(bs2);
329         compsize = old_size * 1.001 + 12; // increasing, rarely situation
330         tmp_buff = malloc(compsize);
331         result = compress2(tmp_buff, &compsize, old_buff_ref, old_size, swf->compress_level);
332         if (result != Z_OK) {
333             if (result == Z_MEM_ERROR) {
334                 fprintf(stderr, "swf_tag_lossless_output_detail: compress Z_MEM_ERROR: can't malloc\n");
335             } else if (result == Z_BUF_ERROR) {
336                 fprintf(stderr, "swf_tag_lossless_output_detail: compress Z_BUF_ERROR: not enough buff size\n");
337             } else {
338                 fprintf(stderr, "swf_tag_lossless_output_detail: compress failed by unknown reason\n");
339             }
340             bitstream_close(bs2);
341             bitstream_close(bs);
342             free(tmp_buff);
343             return NULL; // FAILURE
344         }
345         bitstream_putstring(bs, tmp_buff, compsize);
346         bitstream_close(bs2);
347         free(tmp_buff);
348     }
349     data = bitstream_steal(bs, length);
350     bitstream_close(bs);
351     return data;
352 }
353
354 void
355 swf_tag_lossless_print_detail(swf_tag_t *tag,
356                               struct swf_object_ *swf, int indent_depth) {
357     swf_tag_lossless_detail_t *swf_tag_lossless = NULL;
358     (void) swf;
359     if (tag == NULL) {
360         fprintf(stderr, "swf_tag_lossless_print_detail: tag == NULL\n");
361         return ;
362     }
363     if (tag->detail == NULL) {
364         fprintf(stderr, "swf_tag_lossless_print_detail: tag->detail == NULL\n");
365         return ;
366     }
367     swf_tag_lossless = (swf_tag_lossless_detail_t *) tag->detail;
368     print_indent(indent_depth);
369     printf("image_id=%d  format=%d  width=%u  height=%u\n",
370            swf_tag_lossless->image_id, swf_tag_lossless->format,
371            swf_tag_lossless->width, swf_tag_lossless->height);
372     if (swf_tag_lossless->colormap ||
373         swf_tag_lossless->colormap2) {
374         print_indent(indent_depth);
375         printf("colormap_count=%d",
376                swf_tag_lossless->colormap_count);
377         if (swf_tag_lossless->colormap) {
378             printf("  rgb colormap exists");
379         } else {
380             printf("  rgba colormap exists");
381         }
382         if (swf_tag_lossless->indices) {
383             printf("  indices exists");
384         }
385         printf("\n");
386     }
387     if (swf_tag_lossless->bitmap) {
388         print_indent(indent_depth);
389         printf("xrgb bitmap exists\n");
390     }
391     if (swf_tag_lossless->bitmap2) {
392         print_indent(indent_depth);
393         printf("argb bitmap exists\n");
394     }
395 }
396
397 void
398 swf_tag_lossless_destroy_detail(swf_tag_t *tag) {
399     swf_tag_lossless_detail_t *swf_tag_lossless;
400     if (tag == NULL) {
401         fprintf(stderr, "swf_tag_lossless_destroy_detail: tag == NULL\n");
402         return ;
403     }
404     swf_tag_lossless = (swf_tag_lossless_detail_t *) tag->detail;
405     if (swf_tag_lossless) {
406         free(swf_tag_lossless->colormap);
407         free(swf_tag_lossless->colormap2);
408         free(swf_tag_lossless->indices);
409         free(swf_tag_lossless->bitmap);
410         free(swf_tag_lossless->bitmap2);
411         swf_tag_lossless->colormap = NULL;
412         swf_tag_lossless->colormap2 = NULL;
413         swf_tag_lossless->indices = NULL;
414         swf_tag_lossless->bitmap = NULL;
415         swf_tag_lossless->bitmap2 = NULL;
416         free(swf_tag_lossless);
417         tag->detail = NULL;
418     }
419     return ;
420 }
421
422 #ifdef HAVE_PNG
423
424 unsigned char *swf_tag_lossless_get_png_data(void *detail,
425                                              unsigned long *length,
426                                              int image_id,
427                                              swf_tag_t *tag) {
428     swf_tag_lossless_detail_t *swf_tag_lossless = (swf_tag_lossless_detail_t *) detail;
429     unsigned char *data = NULL;
430     void *index_data = NULL;
431     void *image_data = NULL;
432     *length = 0;
433     if (detail == NULL) {
434         fprintf(stderr, "swf_tag_lossless_get_lossless_data: detail == NULL at line(%d)\n", __LINE__);
435         return NULL;
436     }
437     if (length == NULL) {
438         fprintf(stderr, "swf_tag_lossless_get_lossless_data: length == NULL at line(%d)\n", __LINE__);
439         return NULL;
440     }
441     if (swf_tag_lossless->image_id != image_id) {
442         return NULL;
443     }
444     if ((swf_tag_lossless->format != 3) && (swf_tag_lossless->format != 5)) {
445         fprintf(stderr, "swf_tag_lossless_get_lossless_data: format=%d not implemented yet\n",
446                 swf_tag_lossless->format);
447         return NULL;
448     }
449     if (tag->code == 20) {
450         if (swf_tag_lossless->format == 3) {
451             index_data = (void *) swf_tag_lossless->colormap;
452             image_data = (void *) swf_tag_lossless->indices;
453         } else {
454             image_data = (void *) swf_tag_lossless->bitmap;
455         }
456     } else { // 36
457         if (swf_tag_lossless->format == 3) {
458             index_data = (void *) swf_tag_lossless->colormap2;
459             image_data = (void *) swf_tag_lossless->indices;
460         } else {
461             image_data = (void *) swf_tag_lossless->bitmap2;
462         }
463     }
464     if (image_data == NULL) {
465         fprintf(stderr, "swf_tag_lossless_get_lossless_data: image_data == NULL at line(%d)\n", __LINE__);
466         return NULL;
467     }
468     data = pngconv_lossless2png(image_data,
469                                 swf_tag_lossless->width,
470                                 swf_tag_lossless->height,
471                                 index_data,
472                                 swf_tag_lossless->colormap_count,
473                                 tag->code, swf_tag_lossless->format,
474                                 length);
475     return data;
476 }
477
478 int
479 swf_tag_lossless_replace_png_data(void *detail, int image_id,
480                                   unsigned char *png_data,
481                                   unsigned long png_data_len,
482                                   int rgb15, swf_tag_t *tag) {
483     int tag_no, format;
484     unsigned short width, height;
485     unsigned char *result_data = NULL;
486     void *colormap = NULL;
487     int colormap_count = 0;
488     swf_tag_lossless_detail_t *swf_tag_lossless = (swf_tag_lossless_detail_t *) detail;
489     if (detail == NULL) {
490         fprintf(stderr, "swf_tag_lossess_replace_png_data: detail == NULL at line(%d)\n", __LINE__);
491         return 1;
492     }
493     if (png_data == NULL) {
494         fprintf(stderr, "swf_tag_lossess_replace_png_data: png_data == NULL at line(%d)\n", __LINE__);
495         return 1;
496     }
497     swf_tag_lossless->image_id = image_id;
498     result_data = pngconv_png2lossless(png_data, png_data_len,
499                                        &tag_no, &format,
500                                        &width, &height,
501                                        &colormap, &colormap_count, rgb15);
502
503     if (result_data == NULL) {
504         fprintf(stderr, "swf_tag_lossess_replace_png_data: pngconv_png2lossless failed at line(%d)\n", __LINE__);
505         return 1;
506     }
507     tag->code = tag_no;
508     swf_tag_lossless->format = format;
509     swf_tag_lossless->width  = width;
510     swf_tag_lossless->height = height;
511     if (format == 3) {
512         free(swf_tag_lossless->colormap);
513         free(swf_tag_lossless->colormap2);
514         free(swf_tag_lossless->indices);
515         free(swf_tag_lossless->bitmap);
516         free(swf_tag_lossless->bitmap2);
517         swf_tag_lossless->colormap = NULL;
518         swf_tag_lossless->colormap2 = NULL;
519         swf_tag_lossless->indices = NULL;
520         swf_tag_lossless->bitmap = NULL;
521         swf_tag_lossless->bitmap2 = NULL;
522         if (tag_no == 20) {
523             swf_tag_lossless->colormap = (swf_rgb_t*) colormap;
524         } else if (tag_no == 36) {
525             swf_tag_lossless->colormap2 = (swf_rgba_t*) colormap;
526         } else {
527             fprintf(stderr, "swf_tag_lossess_replace_png_data: internal error tag_no(%d) at line(%d).\n", tag_no, __LINE__);
528             return 1;
529         }
530         swf_tag_lossless->colormap_count = colormap_count;
531         swf_tag_lossless->indices = (unsigned char *) result_data;
532     } else if ((format == 4) || (format == 5)) {
533         free(swf_tag_lossless->colormap);
534         free(swf_tag_lossless->colormap2);
535         free(swf_tag_lossless->indices);
536         free(swf_tag_lossless->bitmap);
537         free(swf_tag_lossless->bitmap2);
538         swf_tag_lossless->colormap = NULL;
539         swf_tag_lossless->colormap2 = NULL;
540         swf_tag_lossless->indices = NULL;
541         swf_tag_lossless->bitmap = NULL;
542         swf_tag_lossless->bitmap2 = NULL;
543         if (tag_no == 20) {
544             swf_tag_lossless->bitmap = (swf_xrgb_t*) result_data;
545         } else if (tag_no == 36) {
546             swf_tag_lossless->bitmap2 = (swf_argb_t*) result_data;
547         } else {
548             fprintf(stderr, "swf_tag_lossless_replace_png_data: internal error tag_no(%d) at line(%d).\n", tag_no, __LINE__);
549             return 1;
550         }
551     } else {
552         fprintf(stderr, "swf_tag_lossless_replace_png_data: format(%d) not implemented yet. at line(%d)\n", format, __LINE__);
553         return 1;
554     }
555     return 0;
556 }
557
558 #endif /* HAVE_PNG */
559
560 #ifdef HAVE_GIF
561
562 int
563 swf_tag_lossless_replace_gif_data(void *detail, int image_id,
564                                   unsigned char *gif_data,
565                                   unsigned long gif_data_len, swf_tag_t *tag) {
566     int tag_no, format;
567     unsigned short width, height;
568     unsigned char *result_data = NULL;
569     void *colormap = NULL;
570     int colormap_count = 0;
571     swf_tag_lossless_detail_t *swf_tag_lossless = (swf_tag_lossless_detail_t *) detail;
572     if (detail == NULL) {
573         fprintf(stderr, "swf_tag_lossless_replace_gif_data: detail == NULL at line(%d)\n", __LINE__);
574         return 1;
575     }
576     if (gif_data == NULL) {
577         fprintf(stderr, "swf_tag_lossless_replace_gif_data: gif_data == NULL at line(%d)\n", __LINE__);
578         return 1;
579     }
580     swf_tag_lossless->image_id = image_id;
581     result_data = gifconv_gif2lossless(gif_data, gif_data_len,
582                                        &tag_no, &format,
583                                        &width, &height,
584                                        &colormap, &colormap_count);
585
586     if (result_data == NULL) {
587         fprintf(stderr, "swf_tag_lossless_replace_gif_data: gifconv_gif2lossless failed at line(%d)\n", __LINE__);
588         return 1;
589     }
590     tag->code = tag_no;
591     swf_tag_lossless->format = format;
592     swf_tag_lossless->width  = width;
593     swf_tag_lossless->height = height;
594     if (format == 3) {
595         free(swf_tag_lossless->colormap);
596         free(swf_tag_lossless->colormap2);
597         free(swf_tag_lossless->indices);
598         free(swf_tag_lossless->bitmap);
599         free(swf_tag_lossless->bitmap2);
600         swf_tag_lossless->colormap = NULL;
601         swf_tag_lossless->colormap2 = NULL;
602         swf_tag_lossless->indices = NULL;
603         swf_tag_lossless->bitmap = NULL;
604         swf_tag_lossless->bitmap2 = NULL;
605         if (tag_no == 20) {
606             swf_tag_lossless->colormap = (swf_rgb_t*) colormap;
607         } else if (tag_no == 36) {
608             swf_tag_lossless->colormap2 = (swf_rgba_t*) colormap;
609         } else {
610             fprintf(stderr, "swf_tag_lossless_replace_gif_data: internal error tag_no(%d) at line(%d).\n", tag_no, __LINE__);
611             return 1;
612         }
613         swf_tag_lossless->colormap_count = colormap_count;
614         swf_tag_lossless->indices = (unsigned char *) result_data;
615     } else {
616         fprintf(stderr, "swf_tag_lossless_replace_gif_data: format(%d) not implemented yet. at line(%d)\n", format, __LINE__);
617         return 1;
618     }
619     return 0;
620 }
621
622 #endif /* HAVE_GIF */