Mercurial > libavcodec.hg
comparison qtrle.c @ 7761:94f82ed28dc4 libavcodec
reduce code duplication by moving common header parsing
from the bpp-specific parts to the frame decode
author | stefang |
---|---|
date | Sun, 31 Aug 2008 08:09:54 +0000 |
parents | e943e1409077 |
children | d1ebbf1e4d50 |
comparison
equal
deleted
inserted
replaced
7760:c4a4495715dd | 7761:94f82ed28dc4 |
---|---|
60 av_log (s->avctx, AV_LOG_INFO, "Problem: pixel_ptr = %d, pixel_limit = %d\n", \ | 60 av_log (s->avctx, AV_LOG_INFO, "Problem: pixel_ptr = %d, pixel_limit = %d\n", \ |
61 pixel_ptr + n, pixel_limit); \ | 61 pixel_ptr + n, pixel_limit); \ |
62 return; \ | 62 return; \ |
63 } \ | 63 } \ |
64 | 64 |
65 static void qtrle_decode_1bpp(QtrleContext *s) | 65 static void qtrle_decode_1bpp(QtrleContext *s, int stream_ptr, int row_ptr, int lines_to_change) |
66 { | 66 { |
67 } | 67 } |
68 | 68 |
69 static void qtrle_decode_2bpp(QtrleContext *s) | 69 static void qtrle_decode_2bpp(QtrleContext *s, int stream_ptr, int row_ptr, int lines_to_change) |
70 { | 70 { |
71 } | 71 } |
72 | 72 |
73 static void qtrle_decode_4bpp(QtrleContext *s) | 73 static void qtrle_decode_4bpp(QtrleContext *s, int stream_ptr, int row_ptr, int lines_to_change) |
74 { | 74 { |
75 int stream_ptr; | |
76 int header; | |
77 int start_line; | |
78 int lines_to_change; | |
79 int rle_code; | 75 int rle_code; |
80 int row_ptr, pixel_ptr; | 76 int pixel_ptr; |
81 int row_inc = s->frame.linesize[0]; | 77 int row_inc = s->frame.linesize[0]; |
82 unsigned char pi1, pi2, pi3, pi4, pi5, pi6, pi7, pi8; /* 8 palette indexes */ | 78 unsigned char pi1, pi2, pi3, pi4, pi5, pi6, pi7, pi8; /* 8 palette indexes */ |
83 unsigned char *rgb = s->frame.data[0]; | 79 unsigned char *rgb = s->frame.data[0]; |
84 int pixel_limit = s->frame.linesize[0] * s->avctx->height; | 80 int pixel_limit = s->frame.linesize[0] * s->avctx->height; |
85 | 81 |
86 /* check if this frame is even supposed to change */ | |
87 if (s->size < 8) | |
88 return; | |
89 | |
90 /* start after the chunk size */ | |
91 stream_ptr = 4; | |
92 | |
93 /* fetch the header */ | |
94 CHECK_STREAM_PTR(2); | |
95 header = AV_RB16(&s->buf[stream_ptr]); | |
96 stream_ptr += 2; | |
97 | |
98 /* if a header is present, fetch additional decoding parameters */ | |
99 if (header & 0x0008) { | |
100 CHECK_STREAM_PTR(8); | |
101 start_line = AV_RB16(&s->buf[stream_ptr]); | |
102 stream_ptr += 4; | |
103 lines_to_change = AV_RB16(&s->buf[stream_ptr]); | |
104 stream_ptr += 4; | |
105 } else { | |
106 start_line = 0; | |
107 lines_to_change = s->avctx->height; | |
108 } | |
109 | |
110 row_ptr = row_inc * start_line; | |
111 while (lines_to_change--) { | 82 while (lines_to_change--) { |
112 CHECK_STREAM_PTR(2); | 83 CHECK_STREAM_PTR(2); |
113 pixel_ptr = row_ptr + (8 * (s->buf[stream_ptr++] - 1)); | 84 pixel_ptr = row_ptr + (8 * (s->buf[stream_ptr++] - 1)); |
114 | 85 |
115 while ((rle_code = (signed char)s->buf[stream_ptr++]) != -1) { | 86 while ((rle_code = (signed char)s->buf[stream_ptr++]) != -1) { |
159 } | 130 } |
160 row_ptr += row_inc; | 131 row_ptr += row_inc; |
161 } | 132 } |
162 } | 133 } |
163 | 134 |
164 static void qtrle_decode_8bpp(QtrleContext *s) | 135 static void qtrle_decode_8bpp(QtrleContext *s, int stream_ptr, int row_ptr, int lines_to_change) |
165 { | 136 { |
166 int stream_ptr; | |
167 int header; | |
168 int start_line; | |
169 int lines_to_change; | |
170 int rle_code; | 137 int rle_code; |
171 int row_ptr, pixel_ptr; | 138 int pixel_ptr; |
172 int row_inc = s->frame.linesize[0]; | 139 int row_inc = s->frame.linesize[0]; |
173 unsigned char pi1, pi2, pi3, pi4; /* 4 palette indexes */ | 140 unsigned char pi1, pi2, pi3, pi4; /* 4 palette indexes */ |
174 unsigned char *rgb = s->frame.data[0]; | 141 unsigned char *rgb = s->frame.data[0]; |
175 int pixel_limit = s->frame.linesize[0] * s->avctx->height; | 142 int pixel_limit = s->frame.linesize[0] * s->avctx->height; |
176 | 143 |
177 /* check if this frame is even supposed to change */ | |
178 if (s->size < 8) | |
179 return; | |
180 | |
181 /* start after the chunk size */ | |
182 stream_ptr = 4; | |
183 | |
184 /* fetch the header */ | |
185 CHECK_STREAM_PTR(2); | |
186 header = AV_RB16(&s->buf[stream_ptr]); | |
187 stream_ptr += 2; | |
188 | |
189 /* if a header is present, fetch additional decoding parameters */ | |
190 if (header & 0x0008) { | |
191 CHECK_STREAM_PTR(8); | |
192 start_line = AV_RB16(&s->buf[stream_ptr]); | |
193 stream_ptr += 4; | |
194 lines_to_change = AV_RB16(&s->buf[stream_ptr]); | |
195 stream_ptr += 4; | |
196 } else { | |
197 start_line = 0; | |
198 lines_to_change = s->avctx->height; | |
199 } | |
200 | |
201 row_ptr = row_inc * start_line; | |
202 while (lines_to_change--) { | 144 while (lines_to_change--) { |
203 CHECK_STREAM_PTR(2); | 145 CHECK_STREAM_PTR(2); |
204 pixel_ptr = row_ptr + (4 * (s->buf[stream_ptr++] - 1)); | 146 pixel_ptr = row_ptr + (4 * (s->buf[stream_ptr++] - 1)); |
205 | 147 |
206 while ((rle_code = (signed char)s->buf[stream_ptr++]) != -1) { | 148 while ((rle_code = (signed char)s->buf[stream_ptr++]) != -1) { |
241 } | 183 } |
242 row_ptr += row_inc; | 184 row_ptr += row_inc; |
243 } | 185 } |
244 } | 186 } |
245 | 187 |
246 static void qtrle_decode_16bpp(QtrleContext *s) | 188 static void qtrle_decode_16bpp(QtrleContext *s, int stream_ptr, int row_ptr, int lines_to_change) |
247 { | 189 { |
248 int stream_ptr; | |
249 int header; | |
250 int start_line; | |
251 int lines_to_change; | |
252 int rle_code; | 190 int rle_code; |
253 int row_ptr, pixel_ptr; | 191 int pixel_ptr; |
254 int row_inc = s->frame.linesize[0]; | 192 int row_inc = s->frame.linesize[0]; |
255 unsigned short rgb16; | 193 unsigned short rgb16; |
256 unsigned char *rgb = s->frame.data[0]; | 194 unsigned char *rgb = s->frame.data[0]; |
257 int pixel_limit = s->frame.linesize[0] * s->avctx->height; | 195 int pixel_limit = s->frame.linesize[0] * s->avctx->height; |
258 | 196 |
259 /* check if this frame is even supposed to change */ | |
260 if (s->size < 8) | |
261 return; | |
262 | |
263 /* start after the chunk size */ | |
264 stream_ptr = 4; | |
265 | |
266 /* fetch the header */ | |
267 CHECK_STREAM_PTR(2); | |
268 header = AV_RB16(&s->buf[stream_ptr]); | |
269 stream_ptr += 2; | |
270 | |
271 /* if a header is present, fetch additional decoding parameters */ | |
272 if (header & 0x0008) { | |
273 CHECK_STREAM_PTR(8); | |
274 start_line = AV_RB16(&s->buf[stream_ptr]); | |
275 stream_ptr += 4; | |
276 lines_to_change = AV_RB16(&s->buf[stream_ptr]); | |
277 stream_ptr += 4; | |
278 } else { | |
279 start_line = 0; | |
280 lines_to_change = s->avctx->height; | |
281 } | |
282 | |
283 row_ptr = row_inc * start_line; | |
284 while (lines_to_change--) { | 197 while (lines_to_change--) { |
285 CHECK_STREAM_PTR(2); | 198 CHECK_STREAM_PTR(2); |
286 pixel_ptr = row_ptr + (s->buf[stream_ptr++] - 1) * 2; | 199 pixel_ptr = row_ptr + (s->buf[stream_ptr++] - 1) * 2; |
287 | 200 |
288 while ((rle_code = (signed char)s->buf[stream_ptr++]) != -1) { | 201 while ((rle_code = (signed char)s->buf[stream_ptr++]) != -1) { |
319 } | 232 } |
320 row_ptr += row_inc; | 233 row_ptr += row_inc; |
321 } | 234 } |
322 } | 235 } |
323 | 236 |
324 static void qtrle_decode_24bpp(QtrleContext *s) | 237 static void qtrle_decode_24bpp(QtrleContext *s, int stream_ptr, int row_ptr, int lines_to_change) |
325 { | 238 { |
326 int stream_ptr; | |
327 int header; | |
328 int start_line; | |
329 int lines_to_change; | |
330 int rle_code; | 239 int rle_code; |
331 int row_ptr, pixel_ptr; | 240 int pixel_ptr; |
332 int row_inc = s->frame.linesize[0]; | 241 int row_inc = s->frame.linesize[0]; |
333 unsigned char r, g, b; | 242 unsigned char r, g, b; |
334 unsigned char *rgb = s->frame.data[0]; | 243 unsigned char *rgb = s->frame.data[0]; |
335 int pixel_limit = s->frame.linesize[0] * s->avctx->height; | 244 int pixel_limit = s->frame.linesize[0] * s->avctx->height; |
336 | 245 |
337 /* check if this frame is even supposed to change */ | |
338 if (s->size < 8) | |
339 return; | |
340 | |
341 /* start after the chunk size */ | |
342 stream_ptr = 4; | |
343 | |
344 /* fetch the header */ | |
345 CHECK_STREAM_PTR(2); | |
346 header = AV_RB16(&s->buf[stream_ptr]); | |
347 stream_ptr += 2; | |
348 | |
349 /* if a header is present, fetch additional decoding parameters */ | |
350 if (header & 0x0008) { | |
351 CHECK_STREAM_PTR(8); | |
352 start_line = AV_RB16(&s->buf[stream_ptr]); | |
353 stream_ptr += 4; | |
354 lines_to_change = AV_RB16(&s->buf[stream_ptr]); | |
355 stream_ptr += 4; | |
356 } else { | |
357 start_line = 0; | |
358 lines_to_change = s->avctx->height; | |
359 } | |
360 | |
361 row_ptr = row_inc * start_line; | |
362 while (lines_to_change--) { | 246 while (lines_to_change--) { |
363 CHECK_STREAM_PTR(2); | 247 CHECK_STREAM_PTR(2); |
364 pixel_ptr = row_ptr + (s->buf[stream_ptr++] - 1) * 3; | 248 pixel_ptr = row_ptr + (s->buf[stream_ptr++] - 1) * 3; |
365 | 249 |
366 while ((rle_code = (signed char)s->buf[stream_ptr++]) != -1) { | 250 while ((rle_code = (signed char)s->buf[stream_ptr++]) != -1) { |
398 } | 282 } |
399 row_ptr += row_inc; | 283 row_ptr += row_inc; |
400 } | 284 } |
401 } | 285 } |
402 | 286 |
403 static void qtrle_decode_32bpp(QtrleContext *s) | 287 static void qtrle_decode_32bpp(QtrleContext *s, int stream_ptr, int row_ptr, int lines_to_change) |
404 { | 288 { |
405 int stream_ptr; | |
406 int header; | |
407 int start_line; | |
408 int lines_to_change; | |
409 int rle_code; | 289 int rle_code; |
410 int row_ptr, pixel_ptr; | 290 int pixel_ptr; |
411 int row_inc = s->frame.linesize[0]; | 291 int row_inc = s->frame.linesize[0]; |
412 unsigned char a, r, g, b; | 292 unsigned char a, r, g, b; |
413 unsigned int argb; | 293 unsigned int argb; |
414 unsigned char *rgb = s->frame.data[0]; | 294 unsigned char *rgb = s->frame.data[0]; |
415 int pixel_limit = s->frame.linesize[0] * s->avctx->height; | 295 int pixel_limit = s->frame.linesize[0] * s->avctx->height; |
416 | 296 |
417 /* check if this frame is even supposed to change */ | |
418 if (s->size < 8) | |
419 return; | |
420 | |
421 /* start after the chunk size */ | |
422 stream_ptr = 4; | |
423 | |
424 /* fetch the header */ | |
425 CHECK_STREAM_PTR(2); | |
426 header = AV_RB16(&s->buf[stream_ptr]); | |
427 stream_ptr += 2; | |
428 | |
429 /* if a header is present, fetch additional decoding parameters */ | |
430 if (header & 0x0008) { | |
431 CHECK_STREAM_PTR(8); | |
432 start_line = AV_RB16(&s->buf[stream_ptr]); | |
433 stream_ptr += 4; | |
434 lines_to_change = AV_RB16(&s->buf[stream_ptr]); | |
435 stream_ptr += 4; | |
436 } else { | |
437 start_line = 0; | |
438 lines_to_change = s->avctx->height; | |
439 } | |
440 | |
441 row_ptr = row_inc * start_line; | |
442 while (lines_to_change--) { | 297 while (lines_to_change--) { |
443 CHECK_STREAM_PTR(2); | 298 CHECK_STREAM_PTR(2); |
444 pixel_ptr = row_ptr + (s->buf[stream_ptr++] - 1) * 4; | 299 pixel_ptr = row_ptr + (s->buf[stream_ptr++] - 1) * 4; |
445 | 300 |
446 while ((rle_code = (signed char)s->buf[stream_ptr++]) != -1) { | 301 while ((rle_code = (signed char)s->buf[stream_ptr++]) != -1) { |
528 static int qtrle_decode_frame(AVCodecContext *avctx, | 383 static int qtrle_decode_frame(AVCodecContext *avctx, |
529 void *data, int *data_size, | 384 void *data, int *data_size, |
530 const uint8_t *buf, int buf_size) | 385 const uint8_t *buf, int buf_size) |
531 { | 386 { |
532 QtrleContext *s = avctx->priv_data; | 387 QtrleContext *s = avctx->priv_data; |
388 int header, start_line; | |
389 int stream_ptr, height, row_ptr; | |
533 | 390 |
534 s->buf = buf; | 391 s->buf = buf; |
535 s->size = buf_size; | 392 s->size = buf_size; |
536 | 393 |
537 s->frame.reference = 1; | 394 s->frame.reference = 1; |
540 if (avctx->reget_buffer(avctx, &s->frame)) { | 397 if (avctx->reget_buffer(avctx, &s->frame)) { |
541 av_log (s->avctx, AV_LOG_ERROR, "reget_buffer() failed\n"); | 398 av_log (s->avctx, AV_LOG_ERROR, "reget_buffer() failed\n"); |
542 return -1; | 399 return -1; |
543 } | 400 } |
544 | 401 |
402 /* check if this frame is even supposed to change */ | |
403 if (s->size < 8) | |
404 goto done; | |
405 | |
406 /* start after the chunk size */ | |
407 stream_ptr = 4; | |
408 | |
409 /* fetch the header */ | |
410 header = AV_RB16(&s->buf[stream_ptr]); | |
411 stream_ptr += 2; | |
412 | |
413 /* if a header is present, fetch additional decoding parameters */ | |
414 if (header & 0x0008) { | |
415 if(s->size < 14) | |
416 goto done; | |
417 start_line = AV_RB16(&s->buf[stream_ptr]); | |
418 stream_ptr += 4; | |
419 height = AV_RB16(&s->buf[stream_ptr]); | |
420 stream_ptr += 4; | |
421 } else { | |
422 start_line = 0; | |
423 height = s->avctx->height; | |
424 } | |
425 row_ptr = s->frame.linesize[0] * start_line; | |
426 | |
545 switch (avctx->bits_per_sample) { | 427 switch (avctx->bits_per_sample) { |
546 case 1: | 428 case 1: |
547 case 33: | 429 case 33: |
548 qtrle_decode_1bpp(s); | 430 qtrle_decode_1bpp(s, stream_ptr, row_ptr, height); |
549 break; | 431 break; |
550 | 432 |
551 case 2: | 433 case 2: |
552 case 34: | 434 case 34: |
553 qtrle_decode_2bpp(s); | 435 qtrle_decode_2bpp(s, stream_ptr, row_ptr, height); |
554 break; | 436 break; |
555 | 437 |
556 case 4: | 438 case 4: |
557 case 36: | 439 case 36: |
558 qtrle_decode_4bpp(s); | 440 qtrle_decode_4bpp(s, stream_ptr, row_ptr, height); |
559 /* make the palette available on the way out */ | 441 /* make the palette available on the way out */ |
560 memcpy(s->frame.data[1], s->avctx->palctrl->palette, AVPALETTE_SIZE); | 442 memcpy(s->frame.data[1], s->avctx->palctrl->palette, AVPALETTE_SIZE); |
561 if (s->avctx->palctrl->palette_changed) { | 443 if (s->avctx->palctrl->palette_changed) { |
562 s->frame.palette_has_changed = 1; | 444 s->frame.palette_has_changed = 1; |
563 s->avctx->palctrl->palette_changed = 0; | 445 s->avctx->palctrl->palette_changed = 0; |
564 } | 446 } |
565 break; | 447 break; |
566 | 448 |
567 case 8: | 449 case 8: |
568 case 40: | 450 case 40: |
569 qtrle_decode_8bpp(s); | 451 qtrle_decode_8bpp(s, stream_ptr, row_ptr, height); |
570 /* make the palette available on the way out */ | 452 /* make the palette available on the way out */ |
571 memcpy(s->frame.data[1], s->avctx->palctrl->palette, AVPALETTE_SIZE); | 453 memcpy(s->frame.data[1], s->avctx->palctrl->palette, AVPALETTE_SIZE); |
572 if (s->avctx->palctrl->palette_changed) { | 454 if (s->avctx->palctrl->palette_changed) { |
573 s->frame.palette_has_changed = 1; | 455 s->frame.palette_has_changed = 1; |
574 s->avctx->palctrl->palette_changed = 0; | 456 s->avctx->palctrl->palette_changed = 0; |
575 } | 457 } |
576 break; | 458 break; |
577 | 459 |
578 case 16: | 460 case 16: |
579 qtrle_decode_16bpp(s); | 461 qtrle_decode_16bpp(s, stream_ptr, row_ptr, height); |
580 break; | 462 break; |
581 | 463 |
582 case 24: | 464 case 24: |
583 qtrle_decode_24bpp(s); | 465 qtrle_decode_24bpp(s, stream_ptr, row_ptr, height); |
584 break; | 466 break; |
585 | 467 |
586 case 32: | 468 case 32: |
587 qtrle_decode_32bpp(s); | 469 qtrle_decode_32bpp(s, stream_ptr, row_ptr, height); |
588 break; | 470 break; |
589 | 471 |
590 default: | 472 default: |
591 av_log (s->avctx, AV_LOG_ERROR, "Unsupported colorspace: %d bits/sample?\n", | 473 av_log (s->avctx, AV_LOG_ERROR, "Unsupported colorspace: %d bits/sample?\n", |
592 avctx->bits_per_sample); | 474 avctx->bits_per_sample); |
593 break; | 475 break; |
594 } | 476 } |
595 | 477 done: |
596 *data_size = sizeof(AVFrame); | 478 *data_size = sizeof(AVFrame); |
597 *(AVFrame*)data = s->frame; | 479 *(AVFrame*)data = s->frame; |
598 | 480 |
599 /* always report that the buffer was completely consumed */ | 481 /* always report that the buffer was completely consumed */ |
600 return buf_size; | 482 return buf_size; |