OSDN Git Service

delete png_set_gAMA
[swfed/swfed.git] / src / swf_tag_shape.c
1 /*
2   +----------------------------------------------------------------------+
3   | Author: yoya@awm.jp                                                  |
4   +----------------------------------------------------------------------+
5 */
6
7 #include <stdio.h>
8 #include <string.h>
9 #include "bitstream.h"
10 #include "swf_shape_record.h"
11 #include "swf_tag_shape.h"
12 #include "swf_object.h"
13
14 swf_tag_detail_handler_t shape_detail_handler;
15
16 swf_tag_detail_handler_t *
17 swf_tag_shape_detail_handler(void) {
18     shape_detail_handler.create   = swf_tag_shape_create_detail;
19     shape_detail_handler.input    = swf_tag_shape_input_detail;
20     shape_detail_handler.get_cid  = swf_tag_shape_get_cid_detail;
21     shape_detail_handler.replace_cid = swf_tag_shape_replace_cid_detail;
22     shape_detail_handler.output   = swf_tag_shape_output_detail;
23     shape_detail_handler.print    = swf_tag_shape_print_detail;
24     shape_detail_handler.destroy  = swf_tag_shape_destroy_detail;
25     return &shape_detail_handler;
26 }
27
28 swf_tag_detail_handler_t *
29 swf_tag_shape_cid_handler(void) {
30     shape_detail_handler.create   = NULL;
31     shape_detail_handler.input    = NULL;
32     shape_detail_handler.get_cid     = swf_tag_shape_get_cid_detail;
33     shape_detail_handler.replace_cid = swf_tag_shape_replace_cid_detail;
34     shape_detail_handler.output   = NULL;
35     shape_detail_handler.print    = NULL;
36     shape_detail_handler.destroy  = NULL;
37     return &shape_detail_handler;
38 }
39
40 void *
41 swf_tag_shape_create_detail(void) {
42     swf_tag_shape_detail_t *swf_tag_shape;
43     swf_tag_shape = calloc(sizeof(*swf_tag_shape), 1);
44     if (swf_tag_shape == NULL) {
45         fprintf(stderr, "ERROR: swf_tag_shape_create_detail: can't calloc\n");
46         return NULL;
47     }
48     return swf_tag_shape;
49 }
50
51 int
52 swf_tag_shape_input_detail(swf_tag_t *tag, struct swf_object_ *swf) {
53     swf_tag_shape_detail_t *swf_tag_shape = tag->detail;
54     unsigned char *data  = tag->data;
55     unsigned long length = tag->length;
56     bitstream_t *bs;
57     int ret;
58     (void) swf;
59     if (swf_tag_shape == NULL) {
60         fprintf(stderr, "ERROR: swf_tag_shape_input_detail: swf_tag_shape == NULL\n");
61         return 1;
62     }
63     // parse context
64     swf_tag_shape->_current_x = 0;
65     swf_tag_shape->_current_y = 0;
66     swf_tag_shape->_parse_condition = 0;
67
68     bs = bitstream_open();
69     bitstream_input(bs, data, length);
70     
71     swf_tag_shape->shape_id = bitstream_getbytesLE(bs, 2);
72     ret = swf_rect_parse(bs, &(swf_tag_shape->rect));
73     if (ret) {
74         fprintf(stderr, "ERROR: swf_tag_shape_input_detail: swf_tag_shape->rect parse failed. shape_id=%d\n", swf_tag_shape->shape_id);
75         bitstream_close(bs);
76         return ret;
77     }
78
79     // DefineMorphShape, DefineMorphShape2
80     swf_tag_shape->is_morph = (tag->code == 46) || (tag->code == 84);
81     // DefineShape4, DefineMorphShape2
82     swf_tag_shape->has_strokes = (tag->code == 83) || (tag->code == 84);
83
84     if (swf_tag_shape->is_morph) {
85         ret = swf_rect_parse(bs, &(swf_tag_shape->rect_morph));
86         if (ret) {
87             fprintf(stderr, "ERROR: swf_tag_shape_input_detail: swf_tag_shape->rect_morph parse failed. shape_id=%d\n", swf_tag_shape->shape_id);
88             bitstream_close(bs);
89             return ret;
90         }
91     }
92     if (swf_tag_shape->has_strokes) {
93         ret = swf_rect_parse(bs, &(swf_tag_shape->stroke_rect));
94         if (ret) {
95             fprintf(stderr, "ERROR: swf_tag_shape_input_detail: swf_tag_shape->stroke_rect parse failed. shape_id=%d\n", swf_tag_shape->shape_id);
96             bitstream_close(bs);
97             return ret;
98         }
99         if (swf_tag_shape->is_morph) {
100             ret = swf_rect_parse(bs, &(swf_tag_shape->stroke_rect_morph));
101             if (ret) {
102                 fprintf(stderr, "ERROR: swf_tag_shape_input_detail: swf_tag_shape->stroke_rect_morph parse failed. shape_id=%d\n", swf_tag_shape->shape_id);
103                 bitstream_close(bs);
104                 return ret;
105             }
106         }
107         swf_tag_shape->define_shape_reserved = bitstream_getbits(bs, 6);
108         swf_tag_shape->define_shape_non_scaling_strokes = bitstream_getbits(bs, 1);
109         swf_tag_shape->define_shape_scaling_strokes = bitstream_getbits(bs, 1);
110     }
111     if (swf_tag_shape->is_morph) {
112         bitstream_align(bs);
113         swf_tag_shape->offset_morph = bitstream_getbytesLE(bs, 4);
114         ret = swf_morph_shape_with_style_parse(bs, &swf_tag_shape->morph_shape_with_style, tag);
115         if (ret) {
116             fprintf(stderr, "ERROR: swf_tag_shape_input_detail: swf_shape_with_style_parse swf_tag_shape->morph_shape_with_style failed. shape_id=%d\n", swf_tag_shape->shape_id);
117                 bitstream_close(bs);
118             return ret;
119         }
120     } else {
121         ret = swf_shape_with_style_parse(bs, &swf_tag_shape->shape_with_style, tag);
122         if (ret) {
123             fprintf(stderr, "ERROR: swf_tag_shape_input_detail: swf_shape_with_style_parse swf_tag_shape->shape_with_style failed. shape_id=%d\n", swf_tag_shape->shape_id);
124                 bitstream_close(bs);
125             return ret;
126         }
127     }
128     
129     bitstream_close(bs);
130     return 0;
131 }
132
133 int swf_tag_shape_get_cid_detail(swf_tag_t *tag) {
134     unsigned char *data = tag->data;
135     if (tag->detail) {
136         swf_tag_shape_detail_t *swf_tag_shape = (swf_tag_shape_detail_t *) tag->detail;
137         return swf_tag_shape->shape_id;
138     }
139     if (data == NULL) {
140         fprintf(stderr, "swf_tag_shape_get_cid_detail: data == NULL\n");
141         return -1;
142     }
143     return GetUShortLE(data); // shape_id;
144 }
145
146 int swf_tag_shape_replace_cid_detail(swf_tag_t *tag, int id) {
147     unsigned char *data = tag->data;
148     if (tag->detail) {
149         swf_tag_shape_detail_t *swf_tag_shape = (swf_tag_shape_detail_t *) tag->detail;
150         swf_tag_shape->shape_id = id;
151     }
152     if (data) {
153         PutUShortLE(data, id);
154     }
155     return 0; // always 0
156 }
157
158 static swf_shape_record_t *
159 _swf_tag_shape_search_new_style_in_shape_records(swf_shape_record_t *shape_records) {
160     for ( ; shape_records ; shape_records = shape_records->next) {
161         if ((shape_records->first_6bits) && 
162             ((shape_records->first_6bits & 0x20) == 0)) {
163             if (shape_records->shape.shape_setup.shape_has_new_styles) {
164                 break;
165             }
166         }
167     }
168     return shape_records;
169 }
170
171 int *
172 swf_tag_shape_bitmap_get_refcid_list(swf_tag_t *tag, int *cid_list_num) {
173     swf_tag_shape_detail_t *swf_tag_shape;
174     int i, ret;
175     int *cid_list, cid_list_alloc;
176     swf_styles_t *styles = NULL;
177     swf_shape_record_t *shape_records = NULL;
178
179     if (tag == NULL) {
180         fprintf(stderr, "swf_tag_shape_bitmap_get_refcid: tag == NULL\n");
181         return NULL;
182     }
183     if (! isShapeTag(tag->code)) {
184         fprintf(stderr, "swf_tag_shape_bitmap_get_refcid: ! isShapeTag(%d)\n",
185                 tag->code);
186         return NULL;
187     }
188     if (tag->detail == NULL) {
189         tag->detail = swf_tag_shape_create_detail();
190         swf_tag_shape = (swf_tag_shape_detail_t *) tag->detail;
191         //        swf_tag_shape->_parse_condition = SWF_TAG_SHAPE_PARSE_CONDITION_BITMAP;
192         ret = swf_tag_shape_input_detail(tag, NULL);
193         if (ret) {
194             swf_tag_shape_destroy_detail(tag);
195             return NULL; // no shape bitmap
196         }
197     } else {
198         swf_tag_shape = (swf_tag_shape_detail_t *) tag->detail;
199     }
200     //
201     *cid_list_num = 0;
202     cid_list_alloc = 10;
203     cid_list = malloc(sizeof(int) * cid_list_alloc);
204
205     if (tag->code == 46) { // DefineMorphShape
206         styles = &(swf_tag_shape->morph_shape_with_style.styles);
207         shape_records = &(swf_tag_shape->morph_shape_with_style.shape_records);
208     } else {
209         styles = &(swf_tag_shape->shape_with_style.styles);
210         shape_records = &(swf_tag_shape->shape_with_style.shape_records);
211     }
212     while (1) {
213         for (i = 0 ; i < styles->fill_styles.count ; i++) {
214             swf_fill_style_t *fill_style;
215             fill_style = &(styles->fill_styles.fill_style[i]);
216             if (fill_style == NULL) {
217                 fprintf(stderr, "swf_tag_shape_bitmap_get_refcid: fill_style == NULL i=%d\n", i);
218                 free(cid_list);
219                 return NULL; // Illegal!!!
220             }
221             switch (fill_style->type) {
222                 void *tmp;
223               case 0x40: // tilled  bitmap fill with smoothed edges
224               case 0x41: // clipped bitmap fill with smoothed edges
225               case 0x42: // tilled  bitmap fill with hard edges
226               case 0x43: // clipped bitmap fill with hard edges
227                 if (fill_style->bitmap.bitmap_ref != 0xffff) {
228                     if (cid_list_alloc <= *cid_list_num) {
229                         cid_list_alloc *= 2;
230                         tmp = realloc(cid_list, cid_list_alloc);
231                         if (tmp == NULL) {
232                             fprintf(stderr, "swf_tag_shape_bitmap_get_refcid_list: Can't realloc memory (%p, %d)\n", cid_list, cid_list_alloc);
233                             free(cid_list);
234                             return NULL;
235                         }
236                         cid_list = tmp;
237                     }
238                     cid_list[*cid_list_num] = fill_style->bitmap.bitmap_ref;
239                     *cid_list_num  = (*cid_list_num) + 1;
240                 }
241                 break;
242               default:
243                 break;
244             }
245         }
246         // new style を探す
247         shape_records = _swf_tag_shape_search_new_style_in_shape_records(shape_records);
248         
249         if (shape_records) {
250             styles = &(shape_records->shape.shape_setup.styles);
251             shape_records = shape_records->next; // next
252         } else {
253             break; // finish
254         }
255     }
256     
257     if (*cid_list_num == 0) {
258         free(cid_list);
259         return NULL;
260     }
261     return cid_list; // not found
262 }
263
264 int swf_tag_shape_bitmap_replace_refcid_list(swf_tag_t *tag, int from_cid, int to_cid) {
265     swf_tag_shape_detail_t *swf_tag_shape;
266     int i, ret;
267     swf_styles_t *styles = NULL;
268     swf_shape_record_t *shape_records = NULL;
269     int morph_shape_check = 0;
270     if (tag == NULL) {
271         fprintf(stderr, "swf_tag_shape_bitmap_replace_refcid: tag == NULL\n");
272         return 1;
273     }
274     if (! isShapeTag(tag->code)) {
275         fprintf(stderr, "swf_tag_shape_bitmap_replace_refcid: ! isShapeTag(%d)\n",
276                 tag->code);
277         return 1;
278     }
279     if (tag->detail == NULL) {
280         tag->detail = swf_tag_shape_create_detail();
281         swf_tag_shape = (swf_tag_shape_detail_t *) tag->detail;
282 //        swf_tag_shape->_parse_condition = SWF_TAG_SHAPE_PARSE_CONDITION_BITMAP;
283         ret = swf_tag_shape_input_detail(tag, NULL);
284         if (ret) {
285             swf_tag_shape_destroy_detail(tag);
286             return 1; // no shape bitmap
287         }
288     } else {
289         swf_tag_shape = (swf_tag_shape_detail_t *) tag->detail;
290     }
291     
292     if (tag->code == 46) { // DefineMorphShape
293         morph_shape_check = 1;
294         styles = &(swf_tag_shape->morph_shape_with_style.styles);
295         shape_records = &(swf_tag_shape->morph_shape_with_style.shape_records);
296 //        shape_records = &(swf_tag_shape->morph_shape_with_style.shape_records_morph);
297     } else {
298         styles = &(swf_tag_shape->shape_with_style.styles);
299         shape_records = &(swf_tag_shape->shape_with_style.shape_records);
300     }
301     while (1) {
302         for (i = 0 ; i < styles->fill_styles.count ; i++) {
303             swf_fill_style_t *fill_style;
304             fill_style = &(styles->fill_styles.fill_style[i]);
305             if (fill_style == NULL) {
306                 fprintf(stderr, "swf_tag_shape_bitmap_replace_refcid: fill_style == NULL i=%d\n", i);
307                 return 1; // Illegal!!!
308             }
309             switch (fill_style->type) {
310               case 0x40: // tilled  bitmap fill with smoothed edges
311               case 0x41: // clipped bitmap fill with smoothed edges
312               case 0x42: // tilled  bitmap fill with hard edges
313               case 0x43: // clipped bitmap fill with hard edges
314                 if (fill_style->bitmap.bitmap_ref == from_cid) {
315                     fill_style->bitmap.bitmap_ref = to_cid;
316                     if (tag->data) {
317                         // 内容が変わったので元データは削除
318                         free(tag->data);
319                         tag->data = NULL;
320                     }
321                     return 0; // success!
322                 }
323                 break;
324               default:
325                 break;
326             }
327         }
328         // new style を探す
329         for ( ; shape_records ; shape_records = shape_records->next) {
330             if ((shape_records->first_6bits) && 
331                 ((shape_records->first_6bits & 0x20) == 0)) {
332                 if (shape_records->shape.shape_setup.shape_has_new_styles) {
333                     styles = &(shape_records->shape.shape_setup.styles);
334                     break;
335                 }
336             }
337         }
338         shape_records = _swf_tag_shape_search_new_style_in_shape_records(shape_records);
339
340         if (shape_records) {
341             styles = &(shape_records->shape.shape_setup.styles);
342             shape_records = shape_records->next; // next
343         } else {
344             morph_shape_check = 0;
345             if (morph_shape_check) {        
346                 shape_records = &(swf_tag_shape->morph_shape_with_style.shape_records);
347                 shape_records = _swf_tag_shape_search_new_style_in_shape_records(shape_records);
348                 if (shape_records) {
349                     styles = &(shape_records->shape.shape_setup.styles);
350                     morph_shape_check = 0;
351                 } else {
352                     break; // finish
353                 }
354             } else {
355                 break; // finish
356             }
357         }
358     }
359     return 1; // not found
360 }
361
362 unsigned char *
363 swf_tag_shape_output_detail(swf_tag_t *tag, unsigned long *length,
364                            struct swf_object_ *swf) {
365     swf_tag_shape_detail_t *swf_tag_shape = (swf_tag_shape_detail_t *) tag->detail;
366     bitstream_t *bs;
367     unsigned char *data;
368     int ret;
369     (void) swf;
370     long offset_of_offset_morph = 0;
371     long tmp_offset_byte = 0;
372     long tmp_offset_bit = 0;
373     *length = 0;
374     // build context
375     swf_tag_shape->_current_fill_style_num = 0;
376     swf_tag_shape->_current_line_style_num = 0;
377     swf_tag_shape->_current_x = 0;
378     swf_tag_shape->_current_y = 0;
379
380     //
381     bs = bitstream_open();
382     bitstream_putbytesLE(bs, swf_tag_shape->shape_id, 2);
383     swf_rect_build(bs, &(swf_tag_shape->rect));
384     
385     // DefineMorphShape, DefineMorphShape2
386     swf_tag_shape->is_morph = (tag->code == 46) || (tag->code == 84);
387     // DefineShape4, DefineMorphShape2
388     swf_tag_shape->has_strokes = (tag->code == 83) || (tag->code == 84);
389     
390     if (swf_tag_shape->is_morph) {
391         ret = swf_rect_build(bs, &(swf_tag_shape->rect_morph));
392         if (ret) {
393             fprintf(stderr, "ERROR: swf_tag_shape_output_detail: swf_tag_shape->rect_morph build failed\n");
394             bitstream_close(bs);
395             return NULL;
396         }
397     }
398     if (swf_tag_shape->has_strokes) {
399         ret = swf_rect_build(bs, &(swf_tag_shape->stroke_rect));
400         if (ret) {
401             fprintf(stderr, "ERROR: swf_tag_shape_input_detail: swf_tag_shape->stroke_rect build failed\n");
402             bitstream_close(bs);
403             return NULL;
404         }
405         if (swf_tag_shape->is_morph) {
406             ret = swf_rect_build(bs, &(swf_tag_shape->stroke_rect_morph));
407             if (ret) {
408                 fprintf(stderr, "ERROR: swf_tag_shape_input_detail: swf_tag_shape->stroke_rect_morph build failed\n");
409                 bitstream_close(bs);
410                 return NULL;
411             }
412         }
413         bitstream_putbits(bs, 6, swf_tag_shape->define_shape_reserved );
414         bitstream_putbits(bs, 1, swf_tag_shape->define_shape_non_scaling_strokes );
415         bitstream_putbits(bs, 1, swf_tag_shape->define_shape_scaling_strokes);
416     }
417     if (swf_tag_shape->is_morph) {
418         bitstream_align(bs);
419         // 後で上書きするので、offset を覚えておく
420         offset_of_offset_morph = bitstream_getbytepos(bs);
421         bitstream_putbytesLE(bs, swf_tag_shape->offset_morph, 4);
422         swf_morph_shape_with_style_build(bs, &swf_tag_shape->morph_shape_with_style, tag);
423         // offset_morph のフィールドに戻って上書きする
424         // offset_morph の後ろからの offset 差なので、- 4 する
425         swf_tag_shape->offset_morph = swf_tag_shape->morph_shape_with_style.offset_of_end_edges - offset_of_offset_morph - 4;
426         tmp_offset_byte = bitstream_getbytepos(bs); // offset を退避
427         tmp_offset_bit = bitstream_getbitpos(bs);
428         bitstream_setpos(bs, offset_of_offset_morph, 0);
429         bitstream_putbytesLE(bs, swf_tag_shape->offset_morph , 4);
430         bitstream_setpos(bs, tmp_offset_byte, tmp_offset_bit); // 元に戻す
431     } else {
432         ret = swf_shape_with_style_build(bs, &swf_tag_shape->shape_with_style, tag);
433         if (ret) {
434             fprintf(stderr, "swf_tag_shape_output_detail: swf_shape_with_style_build failed\n");
435             bitstream_close(bs);
436             return NULL;
437         }
438     }
439     
440     data = bitstream_steal(bs, length);
441     bitstream_close(bs);
442     return data;
443 }
444
445 void
446 swf_tag_shape_print_detail(swf_tag_t *tag,
447                            struct swf_object_ *swf, int indent_depth) {
448     swf_tag_shape_detail_t *swf_tag_shape = (swf_tag_shape_detail_t *) tag->detail;
449     (void) swf;
450     print_indent(indent_depth);
451     printf("shape_id=%d\n", swf_tag_shape->shape_id);
452     swf_rect_print(&(swf_tag_shape->rect), indent_depth);
453 //    print_indent(indent_depth);
454 //    printf("is_morph=%d has_strokes=%d\n",
455 //           swf_tag_shape->is_morph, swf_tag_shape->has_strokes);
456     if (swf_tag_shape->is_morph) {
457         swf_rect_print(&(swf_tag_shape->rect_morph), indent_depth);
458     }
459     if (swf_tag_shape->has_strokes) {
460         swf_rect_print(&(swf_tag_shape->stroke_rect), indent_depth);
461         if (swf_tag_shape->is_morph) {
462             swf_rect_print(&(swf_tag_shape->stroke_rect_morph), indent_depth);
463         }
464         print_indent(indent_depth);
465         printf("define_shape_non_scaling_strokes=%d define_shape_scaling_strokes=%d\n",
466                swf_tag_shape->define_shape_non_scaling_strokes,
467                swf_tag_shape->define_shape_scaling_strokes);
468     }
469     if (swf_tag_shape->is_morph) {
470         print_indent(indent_depth);
471         printf("offset_morph=%lu\n", swf_tag_shape->offset_morph);
472         swf_morph_shape_with_style_print(&swf_tag_shape->morph_shape_with_style,
473                                          indent_depth, tag);
474     } else {
475         swf_shape_with_style_print(&swf_tag_shape->shape_with_style,
476                                    indent_depth, tag);
477     }
478     return ;
479 }
480
481 void
482 swf_tag_shape_destroy_detail(swf_tag_t *tag) {
483     swf_tag_shape_detail_t *swf_tag_shape = (swf_tag_shape_detail_t *) tag->detail;
484     if (swf_tag_shape) {
485         swf_morph_shape_with_style_delete(&(swf_tag_shape->morph_shape_with_style));
486         swf_shape_with_style_delete(&(swf_tag_shape->shape_with_style));
487         free(swf_tag_shape);
488         tag->detail = NULL;
489     }
490     return ;
491 }
492
493 int
494 swf_tag_shape_apply_matrix_factor(void *detail, int shape_id,
495                                   double scale_x, double scale_y,
496                                   double rotate_rad,
497                                   signed int trans_x,
498                                   signed int trans_y) {
499     int i;
500     swf_tag_shape_detail_t *swf_tag_shape = (swf_tag_shape_detail_t *) detail;
501     if (detail == NULL) {
502         fprintf(stderr, "swf_tag_shape_apply_matrix_factor: detail == NULL\n");
503         return 1;
504     }
505     swf_fill_style_t *fill_style;
506     if (shape_id != swf_tag_shape->shape_id) {
507         return 1;
508     }
509     for (i = 0 ; i < swf_tag_shape->shape_with_style.styles.fill_styles.count ; i++) {
510         fill_style = &(swf_tag_shape->shape_with_style.styles.fill_styles.fill_style[i]);
511         switch (fill_style->type) {
512           case 0x10: // linear gradient fill
513           case 0x12: // radial gradient fill
514           case 0x13: // focal  gradient fill
515               swf_matrix_apply_factor(&(fill_style->gradient.gradient_matrix), scale_x, scale_y,
516                                       rotate_rad, trans_x, trans_y);
517               break;
518           case 0x40: // tilled  bitmap fill with smoothed edges
519           case 0x41: // clipped bitmap fill with smoothed edges
520           case 0x42: // tilled  bitmap fill with hard edges
521           case 0x43: // clipped bitmap fill with hard edges
522               swf_matrix_apply_factor(&(fill_style->bitmap.bitmap_matrix),
523                                       scale_x, scale_y, rotate_rad,
524                                       trans_x, trans_y);
525               break;
526           default:
527             fprintf(stderr, "swf_tag_shape_apply_matrix_factor: unknown fill_style->type=%d\n",
528                     fill_style->type);
529             return 1;
530         }
531     }
532     return 0;
533 }
534
535 int
536 swf_tag_shape_apply_rect_factor(void *detail, int shape_id,
537                                 double scale_x, double scale_y,
538                                 signed int trans_x,
539                                 signed int trans_y) {
540 //    int i;
541     swf_tag_shape_detail_t *swf_tag_shape = (swf_tag_shape_detail_t *) detail;
542     if (detail == NULL) {
543         fprintf(stderr, "swf_tag_shape_apply_rect_factor: detail == NULL\n");
544         return 1;
545     }
546     if (shape_id != swf_tag_shape->shape_id) {
547         return 1;
548     }
549     swf_rect_apply_factor(&(swf_tag_shape->rect),
550                           scale_x, scale_y, trans_x, trans_y);
551     
552     swf_shape_record_edge_apply_factor(&(swf_tag_shape->shape_with_style.shape_records),
553                                        scale_x, scale_y, trans_x, trans_y);
554     return 0;
555 }
556
557 int
558 swf_tag_shape_apply_type_tilled(void *detail, int shape_id) {
559     int i, count;
560     swf_tag_shape_detail_t *swf_tag_shape = (swf_tag_shape_detail_t *) detail;
561     if (detail == NULL) {
562         fprintf(stderr, "swf_tag_shape_apply_type_tilled: detail == NULL\n");
563         return 1;
564     }
565     if (shape_id != swf_tag_shape->shape_id) {
566         fprintf(stderr, "swf_tag_shape_apply_type_tilled: shape_id(%d) != shape->shape_id(%d)\n",
567               shape_id, swf_tag_shape->shape_id);
568         return 1;
569     }
570     count = swf_tag_shape->shape_with_style.styles.fill_styles.count;
571     for (i = 0 ; i < count ; i++) {
572         swf_fill_style_t *fill_style = &(swf_tag_shape->shape_with_style.styles.fill_styles.fill_style[i]);
573         switch (fill_style->type) {
574           case 0x41: // clipped bitmap fill with smoothed edges
575             fill_style->type = 0x40; // tilled  bitmap fill with smoothed edges
576             break;
577           case 0x43: // clipped bitmap fill with hard edges
578             fill_style->type = 0x42; // tilled  bitmap fill with hard edges
579             break;
580         }
581     }
582     return 0;
583 }
584