OSDN Git Service

Once more, Allow building with either giflib 4.2 or 5.0.
[swfed/swfed.git] / src / swf_tag_sprite.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_tag_sprite.h"
11 #include "swf_object.h"
12
13 swf_tag_detail_handler_t sprite_detail_handler;
14
15 swf_tag_detail_handler_t *
16 swf_tag_sprite_detail_handler(void) {
17     sprite_detail_handler.create   = swf_tag_sprite_create_detail;
18     sprite_detail_handler.input    = swf_tag_sprite_input_detail;
19     sprite_detail_handler.get_cid  = swf_tag_sprite_get_cid_detail;
20     sprite_detail_handler.replace_cid = swf_tag_sprite_replace_cid_detail;
21     sprite_detail_handler.output   = swf_tag_sprite_output_detail;
22     sprite_detail_handler.print    = swf_tag_sprite_print_detail;
23     sprite_detail_handler.destroy  = swf_tag_sprite_destroy_detail;
24     return &sprite_detail_handler;
25 }
26
27 void *
28 swf_tag_sprite_create_detail(void) {
29     swf_tag_sprite_detail_t *swf_tag_sprite;
30     swf_tag_sprite = calloc(sizeof(*swf_tag_sprite), 1);
31     if (swf_tag_sprite == NULL) {
32         fprintf(stderr, "ERROR: swf_tag_sprite_create_detail: can't calloc\n");
33         return NULL;
34     }
35     return swf_tag_sprite;
36 }
37
38 int
39 swf_tag_sprite_input_detail(swf_tag_t *tag, struct swf_object_ *swf) {
40     swf_tag_sprite_detail_t *swf_tag_sprite = tag->detail;
41     unsigned char *data  = tag->data;
42     unsigned long length = tag->length;
43     bitstream_t *bs;
44     swf_tag_t *tag_in_sprite, *prev_tag;
45     (void) swf;
46     if (swf_tag_sprite == NULL) {
47         fprintf(stderr, "ERROR: swf_tag_sprite_input_detail: swf_tag_sprite == NULL\n");
48         return 1;
49     }
50     bs = bitstream_open();
51     bitstream_input(bs, data, length);
52     swf_tag_sprite->sprite_id = bitstream_getbytesLE(bs, 2);
53     swf_tag_sprite->frame_count = bitstream_getbytesLE(bs, 2);
54     //
55
56     prev_tag = NULL;
57     while(1) {
58         long pos;
59         pos = bitstream_getbytepos(bs);
60         if ((pos == -1) || ((long) length <= pos)) {
61             break;
62         }
63         tag_in_sprite = swf_tag_create(bs);
64         if (tag_in_sprite == NULL) {
65             fprintf(stderr, "swf_object_input: swf_tag_create failed\n");
66             break;
67         }
68         if (prev_tag == NULL) {
69             swf_tag_sprite->tag = tag_in_sprite;
70             tag_in_sprite->prev = NULL;
71         } else {
72             prev_tag->next = tag_in_sprite;
73             tag_in_sprite->prev = prev_tag;
74         }
75         tag_in_sprite->next = NULL;
76         prev_tag = tag_in_sprite;
77     }
78     bitstream_close(bs);
79     return 0;
80 }
81
82 int swf_tag_sprite_get_cid_detail(swf_tag_t *tag) {
83     unsigned char *data = tag->data;
84     if (tag->detail) {
85         swf_tag_sprite_detail_t *swf_tag_sprite = (swf_tag_sprite_detail_t *) tag->detail;
86         return swf_tag_sprite->sprite_id;
87     }
88     if (data == NULL) {
89         fprintf(stderr, "swf_tag_sprite_get_cid_detail: data == NULL\n");
90         return -1;
91     }
92     return GetUShortLE(data); // sprite_id;
93 }
94
95 int swf_tag_sprite_replace_cid_detail(swf_tag_t *tag, int id) {
96     unsigned char *data = tag->data;
97     if (tag->detail) {
98         swf_tag_sprite_detail_t *swf_tag_sprite = (swf_tag_sprite_detail_t *) tag->detail;
99         swf_tag_sprite->sprite_id = id;
100     }
101     if (data) {
102         PutUShortLE(data, id);
103     }        
104     return 0; // always 0
105 }
106
107 unsigned char *
108 swf_tag_sprite_output_detail(swf_tag_t *tag, unsigned long *length,
109                            struct swf_object_ *swf) {
110     swf_tag_sprite_detail_t *swf_tag_sprite = (swf_tag_sprite_detail_t *) tag->detail;
111     bitstream_t *bs;
112     unsigned char *data;
113     swf_tag_t *_tag;
114     *length = 0;
115     bs = bitstream_open();
116     bitstream_putbytesLE(bs, swf_tag_sprite->sprite_id, 2);
117     bitstream_putbytesLE(bs, swf_tag_sprite->frame_count, 2);
118     for (_tag=swf_tag_sprite->tag ; _tag ; _tag=_tag->next) {
119         swf_tag_build(bs, _tag, swf);
120     }
121     data = bitstream_steal(bs, length);
122     bitstream_close(bs);
123     return data;
124 }
125
126 void
127 swf_tag_sprite_print_detail(swf_tag_t *tag,
128                             struct swf_object_ *swf,
129                             int indent_depth) {
130     swf_tag_sprite_detail_t *swf_tag_sprite = (swf_tag_sprite_detail_t *) tag->detail;
131     int i;
132     swf_tag_t *_tag;
133     print_indent(indent_depth);
134     printf("sprite_id=%d\n", swf_tag_sprite->sprite_id);
135     print_indent(indent_depth);
136     printf("frame_count=%d\n", swf_tag_sprite->frame_count);
137     _tag = swf_tag_sprite->tag;
138     for (i=0 ; _tag ; i++) {
139         print_indent(indent_depth);
140         printf("  [%d] ", i);
141         swf_tag_print(_tag, swf, indent_depth + 1);
142         if (_tag->code == 0) { // END Tag
143             break;
144         }
145         _tag = _tag->next;
146     }
147     return ;
148 }
149
150 void
151 swf_tag_sprite_destroy_detail(swf_tag_t *tag) {
152     swf_tag_sprite_detail_t *swf_tag_sprite = (swf_tag_sprite_detail_t *) tag->detail;
153     if (swf_tag_sprite) {
154         swf_tag_t *t, *next_tag;
155         for (t = swf_tag_sprite->tag ; t ; t = next_tag) {
156             next_tag = t->next;
157             swf_tag_destroy(t);
158         }
159         free(swf_tag_sprite);
160         tag->detail = NULL;
161     }
162     return ;
163 }