Mercurial > libavformat.hg
comparison wc3movie.c @ 4852:ecf9f13948f1 libavformat
Use get_le32/get_be32 in wc3movie demuxer instead of reading everything into
a buffer first.
author | reimar |
---|---|
date | Sat, 11 Apr 2009 18:58:55 +0000 |
parents | a9a2c60d0e84 |
children | 74342058fc9d |
comparison
equal
deleted
inserted
replaced
4851:dcd4702bcc21 | 4852:ecf9f13948f1 |
---|---|
27 * http://www.pcisys.net/~melanson/codecs/ | 27 * http://www.pcisys.net/~melanson/codecs/ |
28 */ | 28 */ |
29 | 29 |
30 #include "libavutil/intreadwrite.h" | 30 #include "libavutil/intreadwrite.h" |
31 #include "avformat.h" | 31 #include "avformat.h" |
32 | |
33 #define WC3_PREAMBLE_SIZE 8 | |
34 | 32 |
35 #define FORM_TAG MKTAG('F', 'O', 'R', 'M') | 33 #define FORM_TAG MKTAG('F', 'O', 'R', 'M') |
36 #define MOVE_TAG MKTAG('M', 'O', 'V', 'E') | 34 #define MOVE_TAG MKTAG('M', 'O', 'V', 'E') |
37 #define PC__TAG MKTAG('_', 'P', 'C', '_') | 35 #define PC__TAG MKTAG('_', 'P', 'C', '_') |
38 #define SOND_TAG MKTAG('S', 'O', 'N', 'D') | 36 #define SOND_TAG MKTAG('S', 'O', 'N', 'D') |
129 Wc3DemuxContext *wc3 = s->priv_data; | 127 Wc3DemuxContext *wc3 = s->priv_data; |
130 ByteIOContext *pb = s->pb; | 128 ByteIOContext *pb = s->pb; |
131 unsigned int fourcc_tag; | 129 unsigned int fourcc_tag; |
132 unsigned int size; | 130 unsigned int size; |
133 AVStream *st; | 131 AVStream *st; |
134 unsigned char preamble[WC3_PREAMBLE_SIZE]; | |
135 char buffer[513]; | 132 char buffer[513]; |
136 int ret = 0; | 133 int ret = 0; |
137 int current_palette = 0; | 134 int current_palette = 0; |
138 int bytes_to_read; | 135 int bytes_to_read; |
139 int i; | 136 int i; |
150 /* skip the first 3 32-bit numbers */ | 147 /* skip the first 3 32-bit numbers */ |
151 url_fseek(pb, 12, SEEK_CUR); | 148 url_fseek(pb, 12, SEEK_CUR); |
152 | 149 |
153 /* traverse through the chunks and load the header information before | 150 /* traverse through the chunks and load the header information before |
154 * the first BRCH tag */ | 151 * the first BRCH tag */ |
155 if ((ret = get_buffer(pb, preamble, WC3_PREAMBLE_SIZE)) != | 152 fourcc_tag = get_le32(pb); |
156 WC3_PREAMBLE_SIZE) | 153 size = (get_be32(pb) + 1) & (~1); |
157 return AVERROR(EIO); | |
158 fourcc_tag = AV_RL32(&preamble[0]); | |
159 size = (AV_RB32(&preamble[4]) + 1) & (~1); | |
160 | 154 |
161 do { | 155 do { |
162 switch (fourcc_tag) { | 156 switch (fourcc_tag) { |
163 | 157 |
164 case SOND_TAG: | 158 case SOND_TAG: |
168 break; | 162 break; |
169 | 163 |
170 case PC__TAG: | 164 case PC__TAG: |
171 /* need the number of palettes */ | 165 /* need the number of palettes */ |
172 url_fseek(pb, 8, SEEK_CUR); | 166 url_fseek(pb, 8, SEEK_CUR); |
173 if ((ret = get_buffer(pb, preamble, 4)) != 4) | 167 wc3->palette_count = get_le32(pb); |
174 return AVERROR(EIO); | |
175 wc3->palette_count = AV_RL32(&preamble[0]); | |
176 if((unsigned)wc3->palette_count >= UINT_MAX / PALETTE_SIZE){ | 168 if((unsigned)wc3->palette_count >= UINT_MAX / PALETTE_SIZE){ |
177 wc3->palette_count= 0; | 169 wc3->palette_count= 0; |
178 return -1; | 170 return -1; |
179 } | 171 } |
180 wc3->palettes = av_malloc(wc3->palette_count * PALETTE_SIZE); | 172 wc3->palettes = av_malloc(wc3->palette_count * PALETTE_SIZE); |
192 av_metadata_set(&s->metadata, "title", buffer); | 184 av_metadata_set(&s->metadata, "title", buffer); |
193 break; | 185 break; |
194 | 186 |
195 case SIZE_TAG: | 187 case SIZE_TAG: |
196 /* video resolution override */ | 188 /* video resolution override */ |
197 if ((ret = get_buffer(pb, preamble, WC3_PREAMBLE_SIZE)) != | 189 wc3->width = get_le32(pb); |
198 WC3_PREAMBLE_SIZE) | 190 wc3->height = get_le32(pb); |
199 return AVERROR(EIO); | |
200 wc3->width = AV_RL32(&preamble[0]); | |
201 wc3->height = AV_RL32(&preamble[4]); | |
202 break; | 191 break; |
203 | 192 |
204 case PALT_TAG: | 193 case PALT_TAG: |
205 /* one of several palettes */ | 194 /* one of several palettes */ |
206 if ((unsigned)current_palette >= wc3->palette_count) | 195 if ((unsigned)current_palette >= wc3->palette_count) |
222 current_palette++; | 211 current_palette++; |
223 break; | 212 break; |
224 | 213 |
225 default: | 214 default: |
226 av_log(s, AV_LOG_ERROR, " unrecognized WC3 chunk: %c%c%c%c (0x%02X%02X%02X%02X)\n", | 215 av_log(s, AV_LOG_ERROR, " unrecognized WC3 chunk: %c%c%c%c (0x%02X%02X%02X%02X)\n", |
227 preamble[0], preamble[1], preamble[2], preamble[3], | 216 (char)fourcc_tag, (char)(fourcc_tag >> 8), (char)(fourcc_tag >> 16), (char)(fourcc_tag >> 24), |
228 preamble[0], preamble[1], preamble[2], preamble[3]); | 217 (char)fourcc_tag, (char)(fourcc_tag >> 8), (char)(fourcc_tag >> 16), (char)(fourcc_tag >> 24)); |
229 return AVERROR_INVALIDDATA; | 218 return AVERROR_INVALIDDATA; |
230 break; | 219 break; |
231 } | 220 } |
232 | 221 |
233 if ((ret = get_buffer(pb, preamble, WC3_PREAMBLE_SIZE)) != | 222 fourcc_tag = get_le32(pb); |
234 WC3_PREAMBLE_SIZE) | 223 /* chunk sizes are 16-bit aligned */ |
224 size = (get_be32(pb) + 1) & (~1); | |
225 if (url_feof(pb)) | |
235 return AVERROR(EIO); | 226 return AVERROR(EIO); |
236 fourcc_tag = AV_RL32(&preamble[0]); | |
237 /* chunk sizes are 16-bit aligned */ | |
238 size = (AV_RB32(&preamble[4]) + 1) & (~1); | |
239 | 227 |
240 } while (fourcc_tag != BRCH_TAG); | 228 } while (fourcc_tag != BRCH_TAG); |
241 | 229 |
242 /* initialize the decoder streams */ | 230 /* initialize the decoder streams */ |
243 st = av_new_stream(s, 0); | 231 st = av_new_stream(s, 0); |
279 ByteIOContext *pb = s->pb; | 267 ByteIOContext *pb = s->pb; |
280 unsigned int fourcc_tag; | 268 unsigned int fourcc_tag; |
281 unsigned int size; | 269 unsigned int size; |
282 int packet_read = 0; | 270 int packet_read = 0; |
283 int ret = 0; | 271 int ret = 0; |
284 unsigned char preamble[WC3_PREAMBLE_SIZE]; | |
285 unsigned char text[1024]; | 272 unsigned char text[1024]; |
286 unsigned int palette_number; | 273 unsigned int palette_number; |
287 int i; | 274 int i; |
288 unsigned char r, g, b; | 275 unsigned char r, g, b; |
289 int base_palette_index; | 276 int base_palette_index; |
290 | 277 |
291 while (!packet_read) { | 278 while (!packet_read) { |
292 | 279 |
293 /* get the next chunk preamble */ | 280 fourcc_tag = get_le32(pb); |
294 if ((ret = get_buffer(pb, preamble, WC3_PREAMBLE_SIZE)) != | 281 /* chunk sizes are 16-bit aligned */ |
295 WC3_PREAMBLE_SIZE) | 282 size = (get_be32(pb) + 1) & (~1); |
283 if (url_feof(pb)) | |
296 return AVERROR(EIO); | 284 return AVERROR(EIO); |
297 | |
298 fourcc_tag = AV_RL32(&preamble[0]); | |
299 /* chunk sizes are 16-bit aligned */ | |
300 size = (AV_RB32(&preamble[4]) + 1) & (~1); | |
301 | 285 |
302 switch (fourcc_tag) { | 286 switch (fourcc_tag) { |
303 | 287 |
304 case BRCH_TAG: | 288 case BRCH_TAG: |
305 /* no-op */ | 289 /* no-op */ |
306 break; | 290 break; |
307 | 291 |
308 case SHOT_TAG: | 292 case SHOT_TAG: |
309 /* load up new palette */ | 293 /* load up new palette */ |
310 if ((ret = get_buffer(pb, preamble, 4)) != 4) | 294 palette_number = get_le32(pb); |
311 return AVERROR(EIO); | |
312 palette_number = AV_RL32(&preamble[0]); | |
313 if (palette_number >= wc3->palette_count) | 295 if (palette_number >= wc3->palette_count) |
314 return AVERROR_INVALIDDATA; | 296 return AVERROR_INVALIDDATA; |
315 base_palette_index = palette_number * PALETTE_COUNT * 3; | 297 base_palette_index = palette_number * PALETTE_COUNT * 3; |
316 for (i = 0; i < PALETTE_COUNT; i++) { | 298 for (i = 0; i < PALETTE_COUNT; i++) { |
317 r = wc3->palettes[base_palette_index + i * 3 + 0]; | 299 r = wc3->palettes[base_palette_index + i * 3 + 0]; |
365 packet_read = 1; | 347 packet_read = 1; |
366 break; | 348 break; |
367 | 349 |
368 default: | 350 default: |
369 av_log (s, AV_LOG_ERROR, " unrecognized WC3 chunk: %c%c%c%c (0x%02X%02X%02X%02X)\n", | 351 av_log (s, AV_LOG_ERROR, " unrecognized WC3 chunk: %c%c%c%c (0x%02X%02X%02X%02X)\n", |
370 preamble[0], preamble[1], preamble[2], preamble[3], | 352 (char)fourcc_tag, (char)(fourcc_tag >> 8), (char)(fourcc_tag >> 16), (char)(fourcc_tag >> 24), |
371 preamble[0], preamble[1], preamble[2], preamble[3]); | 353 (char)fourcc_tag, (char)(fourcc_tag >> 8), (char)(fourcc_tag >> 16), (char)(fourcc_tag >> 24)); |
372 ret = AVERROR_INVALIDDATA; | 354 ret = AVERROR_INVALIDDATA; |
373 packet_read = 1; | 355 packet_read = 1; |
374 break; | 356 break; |
375 } | 357 } |
376 } | 358 } |