]> git.sesse.net Git - ffmpeg/blob - libavcodec/qtrle.c
Remove redundant #inclusion of common.h, avcodec.h already #includes it.
[ffmpeg] / libavcodec / qtrle.c
1 /*
2  * Quicktime Animation (RLE) Video Decoder
3  * Copyright (C) 2004 the ffmpeg project
4  *
5  * This file is part of FFmpeg.
6  *
7  * FFmpeg is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * FFmpeg is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with FFmpeg; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  *
21  */
22
23 /**
24  * @file qtrle.c
25  * QT RLE Video Decoder by Mike Melanson (melanson@pcisys.net)
26  * For more information about the QT RLE format, visit:
27  *   http://www.pcisys.net/~melanson/codecs/
28  *
29  * The QT RLE decoder has seven modes of operation:
30  * 1, 2, 4, 8, 16, 24, and 32 bits per pixel. For modes 1, 2, 4, and 8
31  * the decoder outputs PAL8 colorspace data. 16-bit data yields RGB555
32  * data. 24-bit data is RGB24 and 32-bit data is RGB32.
33  */
34
35 #include <stdio.h>
36 #include <stdlib.h>
37 #include <string.h>
38 #include <unistd.h>
39
40 #include "avcodec.h"
41 #include "dsputil.h"
42
43 typedef struct QtrleContext {
44
45     AVCodecContext *avctx;
46     DSPContext dsp;
47     AVFrame frame;
48
49     unsigned char *buf;
50     int size;
51
52 } QtrleContext;
53
54 #define CHECK_STREAM_PTR(n) \
55   if ((stream_ptr + n) > s->size) { \
56     av_log (s->avctx, AV_LOG_INFO, "Problem: stream_ptr out of bounds (%d >= %d)\n", \
57       stream_ptr + n, s->size); \
58     return; \
59   }
60
61 #define CHECK_PIXEL_PTR(n) \
62   if ((pixel_ptr + n > pixel_limit) || (pixel_ptr + n < 0)) { \
63     av_log (s->avctx, AV_LOG_INFO, "Problem: pixel_ptr = %d, pixel_limit = %d\n", \
64       pixel_ptr + n, pixel_limit); \
65     return; \
66   } \
67
68 static void qtrle_decode_1bpp(QtrleContext *s)
69 {
70 }
71
72 static void qtrle_decode_2bpp(QtrleContext *s)
73 {
74 }
75
76 static void qtrle_decode_4bpp(QtrleContext *s)
77 {
78     int stream_ptr;
79     int header;
80     int start_line;
81     int lines_to_change;
82     int rle_code;
83     int row_ptr, pixel_ptr;
84     int row_inc = s->frame.linesize[0];
85     unsigned char pi1, pi2, pi3, pi4, pi5, pi6, pi7, pi8;  /* 8 palette indices */
86     unsigned char *rgb = s->frame.data[0];
87     int pixel_limit = s->frame.linesize[0] * s->avctx->height;
88
89     /* check if this frame is even supposed to change */
90     if (s->size < 8)
91         return;
92
93     /* start after the chunk size */
94     stream_ptr = 4;
95
96     /* fetch the header */
97     CHECK_STREAM_PTR(2);
98     header = AV_RB16(&s->buf[stream_ptr]);
99     stream_ptr += 2;
100
101     /* if a header is present, fetch additional decoding parameters */
102     if (header & 0x0008) {
103         CHECK_STREAM_PTR(8);
104         start_line = AV_RB16(&s->buf[stream_ptr]);
105         stream_ptr += 4;
106         lines_to_change = AV_RB16(&s->buf[stream_ptr]);
107         stream_ptr += 4;
108     } else {
109         start_line = 0;
110         lines_to_change = s->avctx->height;
111     }
112
113     row_ptr = row_inc * start_line;
114     while (lines_to_change--) {
115         CHECK_STREAM_PTR(2);
116         pixel_ptr = row_ptr + (8 * (s->buf[stream_ptr++] - 1));
117
118         while ((rle_code = (signed char)s->buf[stream_ptr++]) != -1) {
119             if (rle_code == 0) {
120                 /* there's another skip code in the stream */
121                 CHECK_STREAM_PTR(1);
122                 pixel_ptr += (8 * (s->buf[stream_ptr++] - 1));
123                 CHECK_PIXEL_PTR(0);  /* make sure pixel_ptr is positive */
124             } else if (rle_code < 0) {
125                 /* decode the run length code */
126                 rle_code = -rle_code;
127                 /* get the next 4 bytes from the stream, treat them as palette
128                  * indices, and output them rle_code times */
129                 CHECK_STREAM_PTR(4);
130                 pi1 = ((s->buf[stream_ptr]) >> 4) & 0x0f;
131                 pi2 = (s->buf[stream_ptr++]) & 0x0f;
132                 pi3 = ((s->buf[stream_ptr]) >> 4) & 0x0f;
133                 pi4 = (s->buf[stream_ptr++]) & 0x0f;
134                 pi5 = ((s->buf[stream_ptr]) >> 4) & 0x0f;
135                 pi6 = (s->buf[stream_ptr++]) & 0x0f;
136                 pi7 = ((s->buf[stream_ptr]) >> 4) & 0x0f;
137                 pi8 = (s->buf[stream_ptr++]) & 0x0f;
138
139                 CHECK_PIXEL_PTR(rle_code * 8);
140
141                 while (rle_code--) {
142                     rgb[pixel_ptr++] = pi1;
143                     rgb[pixel_ptr++] = pi2;
144                     rgb[pixel_ptr++] = pi3;
145                     rgb[pixel_ptr++] = pi4;
146                     rgb[pixel_ptr++] = pi5;
147                     rgb[pixel_ptr++] = pi6;
148                     rgb[pixel_ptr++] = pi7;
149                     rgb[pixel_ptr++] = pi8;
150                 }
151             } else {
152                 /* copy the same pixel directly to output 4 times */
153                 rle_code *= 4;
154                 CHECK_STREAM_PTR(rle_code);
155                 CHECK_PIXEL_PTR(rle_code*2);
156
157                 while (rle_code--) {
158                     rgb[pixel_ptr++] = ((s->buf[stream_ptr]) >> 4) & 0x0f;
159                     rgb[pixel_ptr++] = (s->buf[stream_ptr++]) & 0x0f;
160                 }
161             }
162         }
163         row_ptr += row_inc;
164     }
165 }
166
167 static void qtrle_decode_8bpp(QtrleContext *s)
168 {
169     int stream_ptr;
170     int header;
171     int start_line;
172     int lines_to_change;
173     int rle_code;
174     int row_ptr, pixel_ptr;
175     int row_inc = s->frame.linesize[0];
176     unsigned char pi1, pi2, pi3, pi4;  /* 4 palette indices */
177     unsigned char *rgb = s->frame.data[0];
178     int pixel_limit = s->frame.linesize[0] * s->avctx->height;
179
180     /* check if this frame is even supposed to change */
181     if (s->size < 8)
182         return;
183
184     /* start after the chunk size */
185     stream_ptr = 4;
186
187     /* fetch the header */
188     CHECK_STREAM_PTR(2);
189     header = AV_RB16(&s->buf[stream_ptr]);
190     stream_ptr += 2;
191
192     /* if a header is present, fetch additional decoding parameters */
193     if (header & 0x0008) {
194         CHECK_STREAM_PTR(8);
195         start_line = AV_RB16(&s->buf[stream_ptr]);
196         stream_ptr += 4;
197         lines_to_change = AV_RB16(&s->buf[stream_ptr]);
198         stream_ptr += 4;
199     } else {
200         start_line = 0;
201         lines_to_change = s->avctx->height;
202     }
203
204     row_ptr = row_inc * start_line;
205     while (lines_to_change--) {
206         CHECK_STREAM_PTR(2);
207         pixel_ptr = row_ptr + (4 * (s->buf[stream_ptr++] - 1));
208
209         while ((rle_code = (signed char)s->buf[stream_ptr++]) != -1) {
210             if (rle_code == 0) {
211                 /* there's another skip code in the stream */
212                 CHECK_STREAM_PTR(1);
213                 pixel_ptr += (4 * (s->buf[stream_ptr++] - 1));
214                 CHECK_PIXEL_PTR(0);  /* make sure pixel_ptr is positive */
215             } else if (rle_code < 0) {
216                 /* decode the run length code */
217                 rle_code = -rle_code;
218                 /* get the next 4 bytes from the stream, treat them as palette
219                  * indices, and output them rle_code times */
220                 CHECK_STREAM_PTR(4);
221                 pi1 = s->buf[stream_ptr++];
222                 pi2 = s->buf[stream_ptr++];
223                 pi3 = s->buf[stream_ptr++];
224                 pi4 = s->buf[stream_ptr++];
225
226                 CHECK_PIXEL_PTR(rle_code * 4);
227
228                 while (rle_code--) {
229                     rgb[pixel_ptr++] = pi1;
230                     rgb[pixel_ptr++] = pi2;
231                     rgb[pixel_ptr++] = pi3;
232                     rgb[pixel_ptr++] = pi4;
233                 }
234             } else {
235                 /* copy the same pixel directly to output 4 times */
236                 rle_code *= 4;
237                 CHECK_STREAM_PTR(rle_code);
238                 CHECK_PIXEL_PTR(rle_code);
239
240                 while (rle_code--) {
241                     rgb[pixel_ptr++] = s->buf[stream_ptr++];
242                 }
243             }
244         }
245         row_ptr += row_inc;
246     }
247 }
248
249 static void qtrle_decode_16bpp(QtrleContext *s)
250 {
251     int stream_ptr;
252     int header;
253     int start_line;
254     int lines_to_change;
255     int rle_code;
256     int row_ptr, pixel_ptr;
257     int row_inc = s->frame.linesize[0];
258     unsigned short rgb16;
259     unsigned char *rgb = s->frame.data[0];
260     int pixel_limit = s->frame.linesize[0] * s->avctx->height;
261
262     /* check if this frame is even supposed to change */
263     if (s->size < 8)
264         return;
265
266     /* start after the chunk size */
267     stream_ptr = 4;
268
269     /* fetch the header */
270     CHECK_STREAM_PTR(2);
271     header = AV_RB16(&s->buf[stream_ptr]);
272     stream_ptr += 2;
273
274     /* if a header is present, fetch additional decoding parameters */
275     if (header & 0x0008) {
276         CHECK_STREAM_PTR(8);
277         start_line = AV_RB16(&s->buf[stream_ptr]);
278         stream_ptr += 4;
279         lines_to_change = AV_RB16(&s->buf[stream_ptr]);
280         stream_ptr += 4;
281     } else {
282         start_line = 0;
283         lines_to_change = s->avctx->height;
284     }
285
286     row_ptr = row_inc * start_line;
287     while (lines_to_change--) {
288         CHECK_STREAM_PTR(2);
289         pixel_ptr = row_ptr + (s->buf[stream_ptr++] - 1) * 2;
290
291         while ((rle_code = (signed char)s->buf[stream_ptr++]) != -1) {
292             if (rle_code == 0) {
293                 /* there's another skip code in the stream */
294                 CHECK_STREAM_PTR(1);
295                 pixel_ptr += (s->buf[stream_ptr++] - 1) * 2;
296                 CHECK_PIXEL_PTR(0);  /* make sure pixel_ptr is positive */
297             } else if (rle_code < 0) {
298                 /* decode the run length code */
299                 rle_code = -rle_code;
300                 CHECK_STREAM_PTR(2);
301                 rgb16 = AV_RB16(&s->buf[stream_ptr]);
302                 stream_ptr += 2;
303
304                 CHECK_PIXEL_PTR(rle_code * 2);
305
306                 while (rle_code--) {
307                     *(unsigned short *)(&rgb[pixel_ptr]) = rgb16;
308                     pixel_ptr += 2;
309                 }
310             } else {
311                 CHECK_STREAM_PTR(rle_code * 2);
312                 CHECK_PIXEL_PTR(rle_code * 2);
313
314                 /* copy pixels directly to output */
315                 while (rle_code--) {
316                     rgb16 = AV_RB16(&s->buf[stream_ptr]);
317                     stream_ptr += 2;
318                     *(unsigned short *)(&rgb[pixel_ptr]) = rgb16;
319                     pixel_ptr += 2;
320                 }
321             }
322         }
323         row_ptr += row_inc;
324     }
325 }
326
327 static void qtrle_decode_24bpp(QtrleContext *s)
328 {
329     int stream_ptr;
330     int header;
331     int start_line;
332     int lines_to_change;
333     int rle_code;
334     int row_ptr, pixel_ptr;
335     int row_inc = s->frame.linesize[0];
336     unsigned char r, g, b;
337     unsigned char *rgb = s->frame.data[0];
338     int pixel_limit = s->frame.linesize[0] * s->avctx->height;
339
340     /* check if this frame is even supposed to change */
341     if (s->size < 8)
342         return;
343
344     /* start after the chunk size */
345     stream_ptr = 4;
346
347     /* fetch the header */
348     CHECK_STREAM_PTR(2);
349     header = AV_RB16(&s->buf[stream_ptr]);
350     stream_ptr += 2;
351
352     /* if a header is present, fetch additional decoding parameters */
353     if (header & 0x0008) {
354         CHECK_STREAM_PTR(8);
355         start_line = AV_RB16(&s->buf[stream_ptr]);
356         stream_ptr += 4;
357         lines_to_change = AV_RB16(&s->buf[stream_ptr]);
358         stream_ptr += 4;
359     } else {
360         start_line = 0;
361         lines_to_change = s->avctx->height;
362     }
363
364     row_ptr = row_inc * start_line;
365     while (lines_to_change--) {
366         CHECK_STREAM_PTR(2);
367         pixel_ptr = row_ptr + (s->buf[stream_ptr++] - 1) * 3;
368
369         while ((rle_code = (signed char)s->buf[stream_ptr++]) != -1) {
370             if (rle_code == 0) {
371                 /* there's another skip code in the stream */
372                 CHECK_STREAM_PTR(1);
373                 pixel_ptr += (s->buf[stream_ptr++] - 1) * 3;
374                 CHECK_PIXEL_PTR(0);  /* make sure pixel_ptr is positive */
375             } else if (rle_code < 0) {
376                 /* decode the run length code */
377                 rle_code = -rle_code;
378                 CHECK_STREAM_PTR(3);
379                 r = s->buf[stream_ptr++];
380                 g = s->buf[stream_ptr++];
381                 b = s->buf[stream_ptr++];
382
383                 CHECK_PIXEL_PTR(rle_code * 3);
384
385                 while (rle_code--) {
386                     rgb[pixel_ptr++] = r;
387                     rgb[pixel_ptr++] = g;
388                     rgb[pixel_ptr++] = b;
389                 }
390             } else {
391                 CHECK_STREAM_PTR(rle_code * 3);
392                 CHECK_PIXEL_PTR(rle_code * 3);
393
394                 /* copy pixels directly to output */
395                 while (rle_code--) {
396                     rgb[pixel_ptr++] = s->buf[stream_ptr++];
397                     rgb[pixel_ptr++] = s->buf[stream_ptr++];
398                     rgb[pixel_ptr++] = s->buf[stream_ptr++];
399                 }
400             }
401         }
402         row_ptr += row_inc;
403     }
404 }
405
406 static void qtrle_decode_32bpp(QtrleContext *s)
407 {
408     int stream_ptr;
409     int header;
410     int start_line;
411     int lines_to_change;
412     int rle_code;
413     int row_ptr, pixel_ptr;
414     int row_inc = s->frame.linesize[0];
415     unsigned char a, r, g, b;
416     unsigned int argb;
417     unsigned char *rgb = s->frame.data[0];
418     int pixel_limit = s->frame.linesize[0] * s->avctx->height;
419
420     /* check if this frame is even supposed to change */
421     if (s->size < 8)
422         return;
423
424     /* start after the chunk size */
425     stream_ptr = 4;
426
427     /* fetch the header */
428     CHECK_STREAM_PTR(2);
429     header = AV_RB16(&s->buf[stream_ptr]);
430     stream_ptr += 2;
431
432     /* if a header is present, fetch additional decoding parameters */
433     if (header & 0x0008) {
434         CHECK_STREAM_PTR(8);
435         start_line = AV_RB16(&s->buf[stream_ptr]);
436         stream_ptr += 4;
437         lines_to_change = AV_RB16(&s->buf[stream_ptr]);
438         stream_ptr += 4;
439     } else {
440         start_line = 0;
441         lines_to_change = s->avctx->height;
442     }
443
444     row_ptr = row_inc * start_line;
445     while (lines_to_change--) {
446         CHECK_STREAM_PTR(2);
447         pixel_ptr = row_ptr + (s->buf[stream_ptr++] - 1) * 4;
448
449         while ((rle_code = (signed char)s->buf[stream_ptr++]) != -1) {
450             if (rle_code == 0) {
451                 /* there's another skip code in the stream */
452                 CHECK_STREAM_PTR(1);
453                 pixel_ptr += (s->buf[stream_ptr++] - 1) * 4;
454                 CHECK_PIXEL_PTR(0);  /* make sure pixel_ptr is positive */
455             } else if (rle_code < 0) {
456                 /* decode the run length code */
457                 rle_code = -rle_code;
458                 CHECK_STREAM_PTR(4);
459                 a = s->buf[stream_ptr++];
460                 r = s->buf[stream_ptr++];
461                 g = s->buf[stream_ptr++];
462                 b = s->buf[stream_ptr++];
463                 argb = (a << 24) | (r << 16) | (g << 8) | (b << 0);
464
465                 CHECK_PIXEL_PTR(rle_code * 4);
466
467                 while (rle_code--) {
468                     *(unsigned int *)(&rgb[pixel_ptr]) = argb;
469                     pixel_ptr += 4;
470                 }
471             } else {
472                 CHECK_STREAM_PTR(rle_code * 4);
473                 CHECK_PIXEL_PTR(rle_code * 4);
474
475                 /* copy pixels directly to output */
476                 while (rle_code--) {
477                     a = s->buf[stream_ptr++];
478                     r = s->buf[stream_ptr++];
479                     g = s->buf[stream_ptr++];
480                     b = s->buf[stream_ptr++];
481                     argb = (a << 24) | (r << 16) | (g << 8) | (b << 0);
482                     *(unsigned int *)(&rgb[pixel_ptr]) = argb;
483                     pixel_ptr += 4;
484                 }
485             }
486         }
487         row_ptr += row_inc;
488     }
489 }
490
491 static int qtrle_decode_init(AVCodecContext *avctx)
492 {
493     QtrleContext *s = avctx->priv_data;
494
495     s->avctx = avctx;
496     switch (avctx->bits_per_sample) {
497     case 1:
498     case 2:
499     case 4:
500     case 8:
501     case 33:
502     case 34:
503     case 36:
504     case 40:
505         avctx->pix_fmt = PIX_FMT_PAL8;
506         break;
507
508     case 16:
509         avctx->pix_fmt = PIX_FMT_RGB555;
510         break;
511
512     case 24:
513         avctx->pix_fmt = PIX_FMT_RGB24;
514         break;
515
516     case 32:
517         avctx->pix_fmt = PIX_FMT_RGB32;
518         break;
519
520     default:
521         av_log (avctx, AV_LOG_ERROR, "Unsupported colorspace: %d bits/sample?\n",
522             avctx->bits_per_sample);
523         break;
524     }
525     dsputil_init(&s->dsp, avctx);
526
527     s->frame.data[0] = NULL;
528
529     return 0;
530 }
531
532 static int qtrle_decode_frame(AVCodecContext *avctx,
533                               void *data, int *data_size,
534                               uint8_t *buf, int buf_size)
535 {
536     QtrleContext *s = avctx->priv_data;
537
538     s->buf = buf;
539     s->size = buf_size;
540
541     s->frame.reference = 1;
542     s->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE |
543                             FF_BUFFER_HINTS_REUSABLE | FF_BUFFER_HINTS_READABLE;
544     if (avctx->reget_buffer(avctx, &s->frame)) {
545         av_log (s->avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
546         return -1;
547     }
548
549     switch (avctx->bits_per_sample) {
550     case 1:
551     case 33:
552         qtrle_decode_1bpp(s);
553         break;
554
555     case 2:
556     case 34:
557         qtrle_decode_2bpp(s);
558         break;
559
560     case 4:
561     case 36:
562         qtrle_decode_4bpp(s);
563         /* make the palette available on the way out */
564         memcpy(s->frame.data[1], s->avctx->palctrl->palette, AVPALETTE_SIZE);
565         if (s->avctx->palctrl->palette_changed) {
566             s->frame.palette_has_changed = 1;
567             s->avctx->palctrl->palette_changed = 0;
568         }
569         break;
570
571     case 8:
572     case 40:
573         qtrle_decode_8bpp(s);
574         /* make the palette available on the way out */
575         memcpy(s->frame.data[1], s->avctx->palctrl->palette, AVPALETTE_SIZE);
576         if (s->avctx->palctrl->palette_changed) {
577             s->frame.palette_has_changed = 1;
578             s->avctx->palctrl->palette_changed = 0;
579         }
580         break;
581
582     case 16:
583         qtrle_decode_16bpp(s);
584         break;
585
586     case 24:
587         qtrle_decode_24bpp(s);
588         break;
589
590     case 32:
591         qtrle_decode_32bpp(s);
592         break;
593
594     default:
595         av_log (s->avctx, AV_LOG_ERROR, "Unsupported colorspace: %d bits/sample?\n",
596             avctx->bits_per_sample);
597         break;
598     }
599
600     *data_size = sizeof(AVFrame);
601     *(AVFrame*)data = s->frame;
602
603     /* always report that the buffer was completely consumed */
604     return buf_size;
605 }
606
607 static int qtrle_decode_end(AVCodecContext *avctx)
608 {
609     QtrleContext *s = avctx->priv_data;
610
611     if (s->frame.data[0])
612         avctx->release_buffer(avctx, &s->frame);
613
614     return 0;
615 }
616
617 AVCodec qtrle_decoder = {
618     "qtrle",
619     CODEC_TYPE_VIDEO,
620     CODEC_ID_QTRLE,
621     sizeof(QtrleContext),
622     qtrle_decode_init,
623     NULL,
624     qtrle_decode_end,
625     qtrle_decode_frame,
626     CODEC_CAP_DR1,
627 };
628