OSDN Git Service

test for replaceBitmapData Lossless with alpha0
[swfed/swfed.git] / src / swf_shape_record.c
1 #include <stdio.h>
2 #include "bitstream.h"
3 #include "swf_shape_record.h"
4
5 int
6 swf_shape_record_parse(bitstream_t *bs, swf_shape_record_t *shape_record,
7                        swf_tag_t *tag) {
8     int first_bit, next_5bits;
9     swf_shape_record_t *current_record = shape_record;
10     int limit;
11     for (limit = 1; current_record ; limit ++) {
12         int ret;
13         current_record->next = NULL; // stopper
14         ret = bitstream_getbits(bs, 6);
15         if (ret == -1) {
16             fprintf(stderr, "swf_shape_record_parse: bitstream_getbits failed at L%d\n", __LINE__);
17             return ret;
18         }
19         current_record->first_6bits = ret;
20         first_bit = (current_record->first_6bits >> 5) & 1;
21         next_5bits = current_record->first_6bits & 0x1f;
22         bitstream_incrpos(bs, 0, -6); // 6 bit back
23         if ((first_bit == 0) && (next_5bits == 0)) {
24             ret = swf_shape_record_end_parse(bs, &(current_record->shape.shape_end));
25             if (ret) {
26                 fprintf(stderr, "swf_shape_record_parse: swf_shape_record_end_parse at L%d\n", __LINE__);
27                 return ret;
28             }
29             break; // end
30         } if (first_bit == 0) {
31             ret = swf_shape_record_setup_parse(bs, &(current_record->shape.shape_setup),
32                                          tag);
33             if (ret) {
34                 fprintf(stderr, "swf_shape_record_parse: swf_shape_record_setup_parse at L%d\n", __LINE__);
35                 return ret;
36             }
37 } else {
38             ret = swf_shape_record_edge_parse(bs, &(current_record->shape.shape_edge), tag);
39             if (ret) {
40                 fprintf(stderr, "swf_shape_record_parse: swf_shape_record_edge_parse at L%d\n", __LINE__);
41                 return ret;
42             }
43
44         }
45         if (100000 <= limit) { // XXX 100000???
46             current_record->next = NULL;
47             fprintf(stderr, "swf_shape_record_parse: limit(%d) over\n", limit);
48             return 1;
49         }
50         current_record->next = calloc(1, sizeof(swf_shape_record_t));
51         current_record = current_record->next;
52     }
53     return 0;
54 }
55
56 int
57 swf_shape_record_build(bitstream_t *bs, swf_shape_record_t *shape_record,
58                        swf_tag_t *tag) {
59     int first_bit, next_5bits;
60     swf_shape_record_t *current_record = shape_record;
61     while (current_record) {
62         first_bit = (current_record->first_6bits >> 5) & 1;
63         next_5bits = current_record->first_6bits & 0x1f;
64         if ((first_bit == 0) && (next_5bits == 0)) {
65             swf_shape_record_end_build(bs, &(current_record->shape.shape_end));
66             break;
67         } if (first_bit == 0) {
68             swf_shape_record_setup_build(bs, &(current_record->shape.shape_setup),
69                                          tag);
70         } else {
71             swf_shape_record_edge_build(bs, &(current_record->shape.shape_edge), tag);
72         }
73         current_record = current_record->next;
74     }
75     return 0;
76 }
77
78 int
79 swf_shape_record_print(swf_shape_record_t *shape_record, int indent_depth,
80                        swf_tag_t *tag) {
81     int first_bit, next_5bits;
82     swf_shape_record_t *current_record = shape_record;
83     int i;
84     for (i = 0 ; current_record ; i++) {
85         first_bit = (current_record->first_6bits >> 5) & 1;
86         next_5bits = current_record->first_6bits & 0x1f;
87         print_indent(indent_depth);
88         printf("shape_record [%d]  ", i);
89         if ((first_bit == 0) && (next_5bits == 0)) {
90             printf("end\n");
91             swf_shape_record_end_print(indent_depth + 1);
92             break;
93         } if (first_bit == 0) {
94             printf("setup\n");
95             swf_shape_record_setup_print(&(current_record->shape.shape_setup),
96                                          indent_depth + 1, tag);
97         } else {
98             printf("edge\n");
99             swf_shape_record_edge_print(&(current_record->shape.shape_edge),
100                                         indent_depth + 1);
101         }
102         current_record = current_record->next;
103     }
104     return 0;
105 }
106
107 int
108 swf_shape_record_delete(swf_shape_record_t *shape_record) {
109     swf_shape_record_t *current, *next;
110     int first_bit, next_5bits;
111     
112     first_bit = (shape_record->first_6bits >> 5) & 1;
113     next_5bits = shape_record->first_6bits & 0x1f;
114
115     if ((first_bit == 0) && (next_5bits != 0)) {
116         swf_shape_record_setup_delete(&(shape_record->shape.shape_setup));
117     }
118
119     current = shape_record->next;
120     while (current) {
121         first_bit = (current->first_6bits >> 5) & 1;
122         next_5bits = current->first_6bits & 0x1f;
123         if ((first_bit == 0) && (next_5bits != 0)) {
124             swf_shape_record_setup_delete(&(current->shape.shape_setup));
125         }
126         next = current->next;
127         free(current);
128         current = next;
129     }
130     return 0;
131 }
132
133 int
134 swf_shape_record_edge_apply_factor(swf_shape_record_t *shape_record,
135                                    double scale_x, double scale_y,
136                                    signed trans_x, signed trans_y) {
137     int first_bit, next_5bits;
138     swf_shape_record_t *current_record;
139
140     // top-left base adjust
141     signed min_x = SWF_TWIPS*10000, min_y = SWF_TWIPS*10000;
142     for (current_record = shape_record ; current_record ; current_record = current_record->next) {
143         first_bit = (current_record->first_6bits >> 5) & 1;
144         next_5bits = current_record->first_6bits & 0x1f;
145         if (first_bit) { // edge
146             swf_shape_record_edge_t *edge = &(current_record->shape.shape_edge);
147             min_x = (edge->shape_x<min_x)?edge->shape_x:min_x;
148             min_y = (edge->shape_y<min_y)?edge->shape_y:min_y;
149         } else if (next_5bits) { // setup
150             swf_shape_record_setup_t *setup = &(current_record->shape.shape_setup);
151             min_x = (setup->shape_move_x<min_x)?setup->shape_move_x:min_x;
152             min_y = (setup->shape_move_y<min_y)?setup->shape_move_y:min_y;
153         } else { // end
154             break;
155         }
156     }
157     // scale and trans
158     for (current_record = shape_record ; current_record ; current_record = current_record->next) {
159         first_bit = (current_record->first_6bits >> 5) & 1;
160         next_5bits = current_record->first_6bits & 0x1f;
161         if (first_bit) { // edge
162             swf_shape_record_edge_t *edge = &(current_record->shape.shape_edge);
163             edge->shape_x = (edge->shape_x - min_x) * scale_x + min_x + trans_x * SWF_TWIPS;
164             edge->shape_y = (edge->shape_y - min_y) * scale_y + min_y + trans_y * SWF_TWIPS;
165         } else if (next_5bits) { // setup
166             swf_shape_record_setup_t *setup = &(current_record->shape.shape_setup);
167             setup->shape_move_x = (setup->shape_move_x - min_x) * scale_x + min_x + trans_x * SWF_TWIPS;
168             setup->shape_move_y = (setup->shape_move_y - min_y) * scale_y + min_y + trans_y * SWF_TWIPS;
169         } else { // end
170             break;
171         }
172     }
173     return 0;
174 }