OSDN Git Service

create_detail を create_detail(=calloc)と input_detail(=parse)に分解
[swfed/swfed.git] / src / swf_tag_sound.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_sound.h"
11 #include "swf_object.h"
12
13 swf_tag_detail_handler_t sound_detail_handler;
14
15 swf_tag_detail_handler_t *
16 swf_tag_sound_detail_handler(void) {
17     sound_detail_handler.create   = swf_tag_sound_create_detail;
18     sound_detail_handler.input    = swf_tag_sound_input_detail;
19     sound_detail_handler.identity = swf_tag_sound_identity_detail;
20     sound_detail_handler.output   = swf_tag_sound_output_detail;
21     sound_detail_handler.print    = swf_tag_sound_print_detail;
22     sound_detail_handler.destroy  = swf_tag_sound_destroy_detail;
23     return &sound_detail_handler;
24 }
25
26 void *
27 swf_tag_sound_create_detail(void) {
28     swf_tag_sound_detail_t *swf_tag_sound;
29     swf_tag_sound = calloc(sizeof(*swf_tag_sound), 1);
30     if (swf_tag_sound == NULL) {
31         fprintf(stderr, "ERROR: swf_tag_sound_create_detail: can't calloc\n");
32         return NULL;
33     }
34 }
35
36 int
37 swf_tag_sound_input_detail(unsigned char *data, unsigned long length,
38                             swf_tag_t *tag,
39                             struct swf_object_ *swf) {
40     swf_tag_sound_detail_t *swf_tag_sound;
41     bitstream_t *bs;
42     unsigned long sound_data_len;
43     unsigned char *sound_data_ref;
44     (void) tag;
45     (void) swf;
46     swf_tag_sound = tag->detail;
47     if (swf_tag_sound == NULL) {
48         fprintf(stderr, "ERROR: swf_tag_sound_input_detail: swf_tag_sound == NULL\n");
49         return 1;
50     }
51     bs = bitstream_open();
52     bitstream_input(bs, data, length);
53     swf_tag_sound->sound_id = bitstream_getbytesLE(bs, 2);
54     swf_tag_sound->sound_format    = bitstream_getbits(bs, 4);
55     swf_tag_sound->sound_rate      = bitstream_getbits(bs, 2);
56     swf_tag_sound->sound_is_16bits = bitstream_getbit(bs);
57     swf_tag_sound->sound_is_stereo = bitstream_getbit(bs);
58     swf_tag_sound->sound_samples_count = bitstream_getbytesLE(bs, 4);
59     sound_data_len = bitstream_length(bs) - bitstream_getbytepos(bs);
60     swf_tag_sound->sound_data = malloc(sound_data_len);
61     if (swf_tag_sound->sound_data == NULL) {
62         fprintf(stderr, "swf_tag_sound_create_detail: swf_tag_sound->sound_data == NULL at line(%d): sound_data_len=%lu\n",
63                 __LINE__, sound_data_len);
64         bitstream_close(bs);
65         return 1;
66     }
67     sound_data_ref = bitstream_buffer(bs, bitstream_getbytepos(bs));
68     memcpy(swf_tag_sound->sound_data, sound_data_ref, sound_data_len);
69     swf_tag_sound->sound_data_len = sound_data_len;
70     bitstream_close(bs);
71     return 0;
72 }
73
74 int
75 swf_tag_sound_identity_detail(unsigned char *data, int id, swf_tag_t *tag) {
76     int sound_id;
77     if (tag->detail) {
78         swf_tag_sound_detail_t *swf_tag_sound = (swf_tag_sound_detail_t *) tag->detail;        
79         if (swf_tag_sound->sound_id == id) {
80             return 0;
81         }        
82         return 1;
83     }
84     if (data == NULL) {
85         fprintf(stderr, "swf_tag_sound_identity_detail: data==NULL\n");
86         return 1;
87     }
88     sound_id = GetUShortLE(data);
89     if (id == sound_id) {
90         return 0;
91     }        
92     return 1;
93 }
94
95 unsigned char *
96 swf_tag_sound_output_detail(void *detail, unsigned long *length,
97                            swf_tag_t *tag,
98                            struct swf_object_ *swf) {
99     swf_tag_sound_detail_t *swf_tag_sound = (swf_tag_sound_detail_t *) detail;
100     bitstream_t *bs;
101     unsigned char *data;
102     (void) tag;
103     (void) swf;
104     *length = 0;
105     bs = bitstream_open();
106     bitstream_putbytesLE(bs, swf_tag_sound->sound_id, 2);
107     bitstream_putbits(bs, swf_tag_sound->sound_format, 4);
108     bitstream_putbits(bs, swf_tag_sound->sound_rate, 2);
109     bitstream_putbit(bs, swf_tag_sound->sound_is_16bits);
110     bitstream_putbit(bs, swf_tag_sound->sound_is_stereo);
111     bitstream_putbytesLE(bs, swf_tag_sound->sound_samples_count, 4);
112     bitstream_putstring(bs, swf_tag_sound->sound_data,
113                         swf_tag_sound->sound_data_len);
114     data = bitstream_steal(bs, length);
115     bitstream_close(bs);
116     return data;
117 }
118
119 void
120 swf_tag_sound_print_detail(void *detail,
121                           swf_tag_t *tag,
122                           struct swf_object_ *swf) {
123     swf_tag_sound_detail_t *swf_tag_sound = (swf_tag_sound_detail_t *) detail;
124     char *format_name = "Unknown";
125     (void) tag;
126     (void) swf;
127     switch(swf_tag_sound->sound_format & 0x0f) {
128     case 0:
129         format_name = "Raw";
130         break;
131     case 1:
132         format_name = "ADPCM";
133         break;
134     case 2:
135         format_name = "MP3";
136         break;
137     case 3:
138         format_name = "Uncompressed";
139         break;
140     case 6:
141         format_name = "Nellymoser";
142         break;
143         
144     }
145     printf("\tsound_id=%d\n", swf_tag_sound->sound_id);
146     
147     printf("\tformat=%u(%s) rate=%u is_16bits=%u is_stereo=%u samples_count=%lu\n",
148            swf_tag_sound->sound_format & 0x0f, format_name,
149            swf_tag_sound->sound_rate  & 0x03,
150            swf_tag_sound->sound_is_16bits?1:0,
151            swf_tag_sound->sound_is_stereo?1:0,
152            swf_tag_sound->sound_samples_count);
153     printf("\tsound_data(length=%lu)\n",
154            swf_tag_sound->sound_data_len);
155     return ;
156 }
157
158 void
159 swf_tag_sound_destroy_detail(void *detail) {
160     swf_tag_sound_detail_t *swf_tag_sound = (swf_tag_sound_detail_t *) detail;
161     if (swf_tag_sound) {
162         free(swf_tag_sound->sound_data);
163         swf_tag_sound->sound_data = NULL;
164         free(swf_tag_sound);
165     }
166     return ;
167 }
168
169 unsigned char *
170 swf_tag_sound_get_sound_data(void *detail, unsigned long *length,
171                            int sound_id) {
172     swf_tag_sound_detail_t *swf_tag_sound = (swf_tag_sound_detail_t *) detail;
173     unsigned char *data;
174     *length = 0;
175     if (detail == NULL) {
176         fprintf(stderr, "swf_tag_sound_get_sound_data: detail == NULL\n");
177         return NULL;
178     }
179     if (swf_tag_sound->sound_id != sound_id) {
180         return NULL;
181     }
182     *length = swf_tag_sound->sound_data_len;
183     data = malloc(*length);
184     memcpy(data, swf_tag_sound->sound_data, *length);
185     return data;
186 }
187
188 int
189 swf_tag_sound_replace_mp3_data(void *detail, int sound_id,
190                                unsigned char *mp3_data,
191                                unsigned long mp3_data_len) {
192     (void) detail;
193     (void) sound_id;
194     (void) mp3_data;
195     (void) mp3_data_len;
196         // dummy
197     return -1;
198 }
199
200 int
201 swf_tag_sound_replace_melo_data(void *detail, int sound_id,
202                                 unsigned char *melo_data,
203                                 unsigned long melo_data_len) {
204     swf_tag_sound_detail_t *swf_tag_sound = (swf_tag_sound_detail_t *) detail;
205     (void) melo_data;
206     (void) melo_data_len;
207     swf_tag_sound->sound_id = sound_id;
208     swf_tag_sound->sound_format = 15;
209     swf_tag_sound->sound_rate = 0;
210     swf_tag_sound->sound_is_16bits = 0;
211     swf_tag_sound->sound_is_stereo = 0;
212     swf_tag_sound->sound_samples_count = 0;
213     free(swf_tag_sound->sound_data);
214     swf_tag_sound->sound_data = malloc(melo_data_len);
215     if (swf_tag_sound->sound_data == NULL) {
216         fprintf(stderr, "swf_tag_sound_replace_melo_data: swf_tag_sound->sound_data == NULL\n");
217         return 1;
218     }
219     memcpy(swf_tag_sound->sound_data, melo_data, melo_data_len);
220     swf_tag_sound->sound_data_len = melo_data_len;
221         // dummy
222     return 0;
223 }