2 +----------------------------------------------------------------------+
3 | Author: yoya@awm.jp |
4 +----------------------------------------------------------------------+
9 #include <string.h> /* memcpy */
11 #include "bitstream.h"
12 #include "swf_define.h"
13 #include "swf_tag_jpeg.h"
14 #include "swf_object.h"
15 // #include "swf_tag.h"
17 #include "jpeg_segment.h"
18 #include "bitmap_util.h"
20 swf_tag_detail_handler_t jpeg_detail_handler;
21 swf_tag_detail_handler_t jpegt_detail_handler;
22 swf_tag_detail_handler_t jpeg3_detail_handler;
24 swf_tag_detail_handler_t *swf_tag_jpeg_detail_handler(void) {
25 jpeg_detail_handler.create = swf_tag_jpeg_create_detail;
26 jpeg_detail_handler.input = swf_tag_jpeg_input_detail;
27 jpeg_detail_handler.get_cid = swf_tag_jpeg_get_cid_detail;
28 jpeg_detail_handler.replace_cid = swf_tag_jpeg_replace_cid_detail;
29 jpeg_detail_handler.output = swf_tag_jpeg_output_detail;
30 jpeg_detail_handler.print = swf_tag_jpeg_print_detail;
31 jpeg_detail_handler.destroy = swf_tag_jpeg_destroy_detail;
32 return &jpeg_detail_handler;
35 swf_tag_detail_handler_t *swf_tag_jpegt_detail_handler(void) {
36 jpegt_detail_handler.create = swf_tag_jpeg_create_detail;
37 jpegt_detail_handler.input = swf_tag_jpegt_input_detail;
38 jpegt_detail_handler.get_cid = NULL;
39 jpegt_detail_handler.replace_cid = NULL;
40 jpegt_detail_handler.output = swf_tag_jpegt_output_detail;
41 jpegt_detail_handler.print = swf_tag_jpeg_print_detail;
42 jpegt_detail_handler.destroy = swf_tag_jpeg_destroy_detail;
43 return &jpegt_detail_handler;
46 swf_tag_detail_handler_t *swf_tag_jpeg3_detail_handler(void) {
47 jpeg3_detail_handler.create = swf_tag_jpeg_create_detail;
48 jpeg3_detail_handler.input = swf_tag_jpeg3_input_detail;
49 jpeg3_detail_handler.get_cid = swf_tag_jpeg_get_cid_detail;
50 jpeg3_detail_handler.replace_cid = swf_tag_jpeg_replace_cid_detail;
51 jpeg3_detail_handler.output = swf_tag_jpeg3_output_detail;
52 jpeg3_detail_handler.print = swf_tag_jpeg_print_detail;
53 jpeg3_detail_handler.destroy = swf_tag_jpeg_destroy_detail;
54 return &jpeg3_detail_handler;
58 swf_tag_jpeg_create_detail(void) {
59 swf_tag_jpeg_detail_t *swf_tag_jpeg;
60 swf_tag_jpeg = calloc(sizeof(*swf_tag_jpeg), 1);
61 if (swf_tag_jpeg == NULL) {
62 fprintf(stderr, "ERROR: swf_tag_jpeg_create_detail: can't calloc\n");
65 swf_tag_jpeg->image_id = 0;
66 swf_tag_jpeg->jpeg_data = NULL;
67 swf_tag_jpeg->jpeg_data_len = 0;
68 swf_tag_jpeg->offset_to_alpha = 0;
69 swf_tag_jpeg->alpha_data = NULL;
70 swf_tag_jpeg->alpha_data_len = 0;
71 return (void *) swf_tag_jpeg;
75 swf_tag_jpeg_input_detail(swf_tag_t *tag,
76 struct swf_object_ *swf) {
77 swf_tag_jpeg_detail_t *swf_tag_jpeg = NULL;
78 unsigned char *data = NULL;
80 bitstream_t *bs = NULL;
83 fprintf(stderr, "ERROR: swf_tag_jpeg_input_detail: swf_tag_jpeg == NULL\n");
86 swf_tag_jpeg = tag->detail;
89 if (swf_tag_jpeg == NULL) {
90 fprintf(stderr, "ERROR: swf_tag_jpeg_input_detail: swf_tag_jpeg == NULL\n");
93 bs = bitstream_open();
94 bitstream_input(bs, data, length);
95 swf_tag_jpeg->image_id = bitstream_getbytesLE(bs, 2);
96 swf_tag_jpeg->jpeg_data = bitstream_output_sub(bs, 2, length - 2);
97 swf_tag_jpeg->jpeg_data_len = length - 2;
98 swf_tag_jpeg->alpha_data = NULL;
99 swf_tag_jpeg->alpha_data_len = 0;
105 swf_tag_jpegt_input_detail(swf_tag_t *tag,
106 struct swf_object_ *swf) {
107 swf_tag_jpeg_detail_t *swf_tag_jpeg = NULL;
108 unsigned char *data = NULL;
109 unsigned long length;
112 fprintf(stderr, "ERROR: swf_tag_jpegt_input_detail: tag == NULL\n");
115 swf_tag_jpeg = tag->detail;
117 length = tag->length;
118 if (swf_tag_jpeg == NULL) {
119 fprintf(stderr, "ERROR: swf_tag_jpegt_input_detail: swf_tag_jpeg == NULL\n");
122 swf_tag_jpeg->image_id = -1; // no id
123 swf_tag_jpeg->jpeg_data = (unsigned char *) malloc(length);
124 memcpy(swf_tag_jpeg->jpeg_data, data, length);
125 swf_tag_jpeg->jpeg_data_len = length;
126 swf_tag_jpeg->alpha_data = NULL;
127 swf_tag_jpeg->alpha_data_len = 0;
132 swf_tag_jpeg3_input_detail(swf_tag_t *tag,
133 struct swf_object_ *swf) {
134 swf_tag_jpeg_detail_t *swf_tag_jpeg = NULL;
135 unsigned char *data = NULL;
136 unsigned long length;
137 unsigned long offset_to_alpha;
138 bitstream_t *bs = NULL;
139 unsigned long offset, alpha_data_len;
140 unsigned char *old_buff_ref = NULL, *new_buff = NULL;
141 unsigned long origsize;
145 fprintf(stderr, "swf_tag_jpeg3_input_detail: tag == NULL\n");
148 swf_tag_jpeg = tag->detail;
150 length = tag->length;
151 if (swf_tag_jpeg == NULL) {
152 fprintf(stderr, "ERROR: swf_tag_jpeg3_input_detail: swf_tag_jpeg == NULL\n");
155 bs = bitstream_open();
156 bitstream_input(bs, data, length);
157 swf_tag_jpeg->image_id = bitstream_getbytesLE(bs, 2);
158 offset_to_alpha = bitstream_getbytesLE(bs, 4);
159 swf_tag_jpeg->offset_to_alpha = offset_to_alpha;
160 swf_tag_jpeg->jpeg_data = bitstream_output_sub(bs, 2 + 4 , offset_to_alpha);
161 if (swf_tag_jpeg->jpeg_data == NULL) {
164 fprintf(stderr, "swf_tag_jpeg3_create_detail: swf_tag_jpeg->jpeg_data\n");
168 swf_tag_jpeg->jpeg_data_len = offset_to_alpha;
169 offset = 2 + 4 + offset_to_alpha;
170 alpha_data_len = length - offset;
171 // TODO: analyze jpeg and get width and height
172 origsize = 512 * alpha_data_len; // XXX greater than jpeg1,2
174 new_buff = malloc(origsize); // enough size?
175 old_buff_ref = bitstream_buffer(bs, offset);
176 result = uncompress(new_buff, &origsize, old_buff_ref, alpha_data_len);
177 if (result == Z_BUF_ERROR) { // XXX
179 new_buff = realloc(new_buff, origsize); // enough size?
180 if (new_buff == NULL) {
183 fprintf(stderr, "swf_tag_jpeg3_create_detail: realloc(%p, %lu) failed\n", new_buff, origsize);
186 result = uncompress(new_buff, &origsize, old_buff_ref, alpha_data_len);
188 if (result == Z_OK) {
189 swf_tag_jpeg->alpha_data = realloc(new_buff, origsize);
190 swf_tag_jpeg->alpha_data_len = origsize;
192 if (result == Z_MEM_ERROR) {
193 fprintf(stderr, "swf_tag_jpeg3_create_detail: uncompress: Z_MEM_ERROR: can't malloc\n");
194 } else if (result == Z_BUF_ERROR) {
195 fprintf(stderr, "swf_tag_jpeg3_create_detail: uncompress: Z_BUF_ERROR: not enough buff size\n");
196 } else if (result == Z_DATA_ERROR) {
197 fprintf(stderr, "swf_tag_jpeg3_create_detail: uncompress: Z_DATA_ERROR: corrupted or imcomplete data\n");
199 fprintf(stderr, "swf_tag_jpeg3_create_detail: uncompress: failed by unknown reason (%d)\n", result);
208 swf_tag_jpeg_get_cid_detail(swf_tag_t *tag) {
209 unsigned char *data = NULL;
212 fprintf(stderr, "swf_tag_jpeg_get_cid_detail: tag == NULL\n");
217 swf_tag_jpeg_detail_t *swf_tag_jpeg = (swf_tag_jpeg_detail_t *) tag->detail;
218 return swf_tag_jpeg->image_id;
221 fprintf(stderr, "swf_tag_jpeg_get_cid_detail: data==NULL\n");
224 return GetUShortLE(data); // image_id;
228 swf_tag_jpeg_replace_cid_detail(swf_tag_t *tag, int image_id) {
229 unsigned char *data = NULL;
231 fprintf(stderr, "swf_tag_jpeg_replace_cid_detail: tag == NULL\n");
236 swf_tag_jpeg_detail_t *swf_tag_jpeg = (swf_tag_jpeg_detail_t *) tag->detail;
237 swf_tag_jpeg->image_id = image_id;
240 PutUShortLE(data, image_id);
246 swf_tag_jpeg_output_detail(swf_tag_t *tag, unsigned long *length,
247 struct swf_object_ *swf) {
248 swf_tag_jpeg_detail_t *swf_tag_jpeg = NULL;
249 bitstream_t *bs = NULL;
250 unsigned char *data = NULL;
253 fprintf(stderr, "swf_tag_jpeg_output_detail: tag == NULL\n");
256 swf_tag_jpeg = (swf_tag_jpeg_detail_t *) tag->detail;
258 bs = bitstream_open();
259 bitstream_putbytesLE(bs, swf_tag_jpeg->image_id, 2);
260 bitstream_putstring(bs, swf_tag_jpeg->jpeg_data, swf_tag_jpeg->jpeg_data_len);
261 data = bitstream_steal(bs, length);
267 swf_tag_jpegt_output_detail(swf_tag_t *tag, unsigned long *length,
268 struct swf_object_ *swf) {
269 swf_tag_jpeg_detail_t *swf_tag_jpeg = NULL;
270 bitstream_t *bs = NULL;
271 unsigned char *data = NULL;
274 fprintf(stderr, "swf_tag_jpegt_output_detail: tag == NULL\n");
277 if (length == NULL) {
278 fprintf(stderr, "swf_tag_jpegt_output_detail: length == NULL\n");
282 swf_tag_jpeg = (swf_tag_jpeg_detail_t *) tag->detail;
283 bs = bitstream_open();
284 bitstream_putstring(bs, swf_tag_jpeg->jpeg_data, swf_tag_jpeg->jpeg_data_len);
285 data = bitstream_steal(bs, length);
291 swf_tag_jpeg3_output_detail(swf_tag_t *tag, unsigned long *length,
292 struct swf_object_ *swf) {
293 swf_tag_jpeg_detail_t *swf_tag_jpeg = NULL;
294 bitstream_t *bs = NULL;
295 unsigned char *data = NULL, *new_buff = NULL;
296 unsigned long offset_to_alpha;
297 unsigned long compsize, old_size;
300 fprintf(stderr, "swf_tag_jpeg3_output_detail: tag == NULL\n");
303 fprintf(stderr, "swf_tag_jpeg3_output_detail: swf == NULL\n");
305 if (length == NULL) {
306 fprintf(stderr, "swf_tag_jpeg3_output_detail: length == NULL\n");
308 swf_tag_jpeg = (swf_tag_jpeg_detail_t *) tag->detail;
310 bs = bitstream_open();
311 bitstream_putbytesLE(bs, swf_tag_jpeg->image_id, 2);
312 bitstream_putbytesLE(bs, swf_tag_jpeg->jpeg_data_len, 4);
313 bitstream_putstring(bs, swf_tag_jpeg->jpeg_data, swf_tag_jpeg->jpeg_data_len);
314 offset_to_alpha = swf_tag_jpeg->jpeg_data_len;
315 old_size = swf_tag_jpeg->alpha_data_len;
316 compsize = old_size * 1.001 + 12; // increasing, rarely situation
317 new_buff = malloc(compsize);
318 // result = compress2(new_buff, &compsize, swf_tag_jpeg->alpha_data, old_size, swf->compress_level);
319 result = compress2(new_buff, &compsize, swf_tag_jpeg->alpha_data, old_size, swf->compress_level);
320 if (result != Z_OK) {
321 if (result == Z_MEM_ERROR) {
322 fprintf(stderr, "swf_tag_jpeg_output_detail: compress Z_MEM_ERROR: can't malloc\n");
323 } else if (result == Z_BUF_ERROR) {
324 fprintf(stderr, "swf_tag_jpeg_output_detail: compress Z_BUF_ERROR: not enough buff size\n");
326 fprintf(stderr, "swf_tag_jpeg_output_detail: compress failed by unknown reason\n");
330 return NULL; // FAILURE
332 bitstream_putstring(bs, new_buff, compsize);
334 data = bitstream_steal(bs, length);
340 swf_tag_jpeg_print_detail(swf_tag_t *tag,
341 struct swf_object_ *swf, int indent_depth) {
342 swf_tag_jpeg_detail_t *swf_tag_jpeg = NULL;
343 jpeg_segment_t *jpeg_seg = NULL;
344 jpeg_segment_node_t *node = NULL;
347 fprintf(stderr, "swf_tag_jpeg_print_detail: tag == NULL\n");
350 swf_tag_jpeg = (swf_tag_jpeg_detail_t *) tag->detail;
351 if (swf_tag_jpeg == NULL) {
352 fprintf(stderr, "swf_tag_jpeg_print_detail: swf_tag_jpeg == NULL\n");
356 print_indent(indent_depth);
357 if (swf_tag_jpeg->image_id == -1) {
358 printf("jpeg_data_size=%lu\n", swf_tag_jpeg->jpeg_data_len);
360 printf("image_id=%d jpeg_data_size=%lu\n",
361 swf_tag_jpeg->image_id, swf_tag_jpeg->jpeg_data_len);
363 jpeg_seg = jpeg_segment_parse(swf_tag_jpeg->jpeg_data,
364 swf_tag_jpeg->jpeg_data_len, SWFED_JPEG_RST_SCAN_SWFJPEG);
366 int ret, width = 0, height = 0;
368 ret = jpeg_size_segment(jpeg_seg, &width, &height);
370 print_indent(indent_depth + 1);
371 printf("(width, height)=(%d, %d)\n", width, height);
374 for (node=jpeg_seg->head ; node ; node=node->next) {
375 char *name = jpeg_segment_get_marker_name(node->marker);
376 print_indent(indent_depth + 1);
377 printf("%s(0x%02X): len=%lu\n", name?name:"Unknwon",
378 node->marker, node->data_len);
380 jpeg_segment_destroy(jpeg_seg);
382 unsigned char *data = swf_tag_jpeg->jpeg_data;
383 print_indent(indent_depth + 1);
384 printf("(invalid jpeg data: %02x %02x %02x %02x ...)\n",
385 data[0]&0xff, data[1]&0xff, data[2]&0xff, data[3]&0xff);
387 if (swf_tag_jpeg->alpha_data) {
388 print_indent(indent_depth);
389 printf("alpha_data_size=%lu\n",
390 swf_tag_jpeg->alpha_data_len);
395 swf_tag_jpeg_destroy_detail(swf_tag_t *tag) {
396 swf_tag_jpeg_detail_t *swf_tag_jpeg = NULL;
398 fprintf(stderr, "swf_tag_jpeg_destroy_detail: tag == NULL\n");
401 swf_tag_jpeg = (swf_tag_jpeg_detail_t *) tag->detail;
403 free(swf_tag_jpeg->jpeg_data);
404 free(swf_tag_jpeg->alpha_data);
405 swf_tag_jpeg->jpeg_data = NULL;
406 swf_tag_jpeg->alpha_data = NULL;
414 swf_tag_jpeg_get_jpeg_data(void *detail,
415 unsigned long *length,
417 unsigned char *jpeg_table_data,
418 unsigned long jpeg_table_data_len) {
419 swf_tag_jpeg_detail_t *swf_tag_jpeg = (swf_tag_jpeg_detail_t *) detail;
421 if (detail == NULL) {
422 fprintf(stderr, "swf_tag_jpeg_get_jpeg_data: detail == NULL\n");
424 if (length == NULL) {
425 fprintf(stderr, "swf_tag_jpeg_get_jpeg_data: length == NULL\n");
428 if (swf_tag_jpeg->image_id != image_id) {
431 if (swf_tag_jpeg->jpeg_data_len == 0) {
432 fprintf(stderr, "swf_tag_jpeg_get_jpeg_data: swf_tag_jpeg->jpeg_data_len\n");
435 data = jpegconv_swf2std(swf_tag_jpeg->jpeg_data,
436 swf_tag_jpeg->jpeg_data_len,
439 jpeg_table_data_len);
443 unsigned char *swf_tag_jpeg_get_alpha_data(void *detail, unsigned long *length, int image_id) {
444 swf_tag_jpeg_detail_t *swf_tag_jpeg = (swf_tag_jpeg_detail_t *) detail;
445 unsigned char *data = NULL;
446 if (detail == NULL) {
447 fprintf(stderr, "swf_tag_jpeg_get_alpha_data: detail == NULL\n");
450 if (length == NULL) {
451 fprintf(stderr, "swf_tag_jpeg_get_alpha_data: length == NULL\n");
456 if (swf_tag_jpeg->image_id != image_id) {
459 *length = swf_tag_jpeg->alpha_data_len;
463 data = malloc(*length);
464 memcpy(data, swf_tag_jpeg->alpha_data, *length);
469 swf_tag_jpeg_replace_jpeg_data(void *detail, int image_id,
470 unsigned char *jpeg_data,
471 unsigned long jpeg_data_len,
472 unsigned char *alpha_data,
473 unsigned long alpha_data_len,
475 swf_tag_jpeg_detail_t *swf_tag_jpeg = (swf_tag_jpeg_detail_t *) detail;
476 if (detail == NULL) {
477 fprintf(stderr, "swf_tag_jpeg_replace_jpeg_data: detail == NULL\n");
480 swf_tag_jpeg->image_id = image_id;
481 if (tag->code == 6) { // DefineBitsJPEG
482 if (jpeg_data && jpeg_data_len) { // fail safe
483 free(swf_tag_jpeg->jpeg_data);
484 swf_tag_jpeg->jpeg_data = malloc(jpeg_data_len);
485 memcpy(swf_tag_jpeg->jpeg_data, jpeg_data, jpeg_data_len);
486 swf_tag_jpeg->jpeg_data_len = jpeg_data_len;
489 if (jpeg_data && jpeg_data_len) {
490 unsigned long length;
491 free(swf_tag_jpeg->jpeg_data);
492 swf_tag_jpeg->jpeg_data = jpegconv_std2swf(jpeg_data, jpeg_data_len,
494 if (swf_tag_jpeg->jpeg_data == NULL) {
495 fprintf(stderr, "swf_tag_jpeg_replace_jpeg_data: failed to jpegconv_std2swf\n");
498 swf_tag_jpeg->jpeg_data_len = length;
500 if (alpha_data && alpha_data_len) {
501 free(swf_tag_jpeg->alpha_data);
502 swf_tag_jpeg->alpha_data = malloc(alpha_data_len);
503 memcpy(swf_tag_jpeg->alpha_data, alpha_data, alpha_data_len);
504 swf_tag_jpeg->alpha_data_len = alpha_data_len;
511 swf_tag_jpeg_replace_bitmap_data(void *detail, int image_id,
512 unsigned char *bitmap_data,
513 unsigned long bitmap_data_len,
515 swf_tag_jpeg_detail_t *swf_tag_jpeg = (swf_tag_jpeg_detail_t *) detail;
516 if (detail == NULL) {
517 fprintf(stderr, "swf_tag_jpeg_replace_jpeg_data: detail == NULL\n");
520 swf_tag_jpeg->image_id = image_id;
521 tag->code = 21; // DefineBitsJPEG2
522 if (bitmap_data && bitmap_data_len) { // fail safe
523 free(swf_tag_jpeg->jpeg_data);
524 swf_tag_jpeg->jpeg_data = malloc(bitmap_data_len);
525 memcpy(swf_tag_jpeg->jpeg_data, bitmap_data, bitmap_data_len);
526 swf_tag_jpeg->jpeg_data_len = bitmap_data_len;
528 fprintf(stderr, "swf_tag_jpeg_replace_bitmap_data: jpeg_data == NULL or jpeg_data_len == 0\n");
531 free(swf_tag_jpeg->alpha_data);
532 swf_tag_jpeg->alpha_data = NULL;
533 swf_tag_jpeg->alpha_data_len = 0;