]> git.sesse.net Git - ffmpeg/blob - libavcodec/qtrle.c
Merge commit '1fd2deedcc6400e08b31566a547a5fac3b38cefb'
[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  * @file
24  * QT RLE Video Decoder by Mike Melanson (melanson@pcisys.net)
25  * For more information about the QT RLE format, visit:
26  *   http://www.pcisys.net/~melanson/codecs/
27  *
28  * The QT RLE decoder has seven modes of operation:
29  * 1, 2, 4, 8, 16, 24, and 32 bits per pixel. For modes 1, 2, 4, and 8
30  * the decoder outputs PAL8 colorspace data. 16-bit data yields RGB555
31  * data. 24-bit data is RGB24 and 32-bit data is RGB32.
32  */
33
34 #include <stdio.h>
35 #include <stdlib.h>
36 #include <string.h>
37
38 #include "avcodec.h"
39 #include "bytestream.h"
40
41 typedef struct QtrleContext {
42     AVCodecContext *avctx;
43     AVFrame frame;
44
45     GetByteContext g;
46     uint32_t pal[256];
47 } QtrleContext;
48
49 #define CHECK_PIXEL_PTR(n) \
50   if ((pixel_ptr + n > pixel_limit) || (pixel_ptr + n < 0)) { \
51     av_log (s->avctx, AV_LOG_INFO, "Problem: pixel_ptr = %d, pixel_limit = %d\n", \
52       pixel_ptr + n, pixel_limit); \
53     return; \
54   } \
55
56 static void qtrle_decode_1bpp(QtrleContext *s, int row_ptr, int lines_to_change)
57 {
58     int rle_code;
59     int pixel_ptr = 0;
60     int row_inc = s->frame.linesize[0];
61     unsigned char pi0, pi1;  /* 2 8-pixel values */
62     unsigned char *rgb = s->frame.data[0];
63     int pixel_limit = s->frame.linesize[0] * s->avctx->height;
64     int skip;
65     /* skip & 0x80 appears to mean 'start a new line', which can be interpreted
66      * as 'go to next line' during the decoding of a frame but is 'go to first
67      * line' at the beginning. Since we always interpret it as 'go to next line'
68      * in the decoding loop (which makes code simpler/faster), the first line
69      * would not be counted, so we count one more.
70      * See: https://ffmpeg.org/trac/ffmpeg/ticket/226
71      * In the following decoding loop, row_ptr will be the position of the
72      * _next_ row. */
73     lines_to_change++;
74
75     while (lines_to_change) {
76         skip     =              bytestream2_get_byte(&s->g);
77         rle_code = (signed char)bytestream2_get_byte(&s->g);
78         if (rle_code == 0)
79             break;
80         if(skip & 0x80) {
81             lines_to_change--;
82             pixel_ptr = row_ptr + 2 * (skip & 0x7f);
83             row_ptr += row_inc;
84         } else
85             pixel_ptr += 2 * skip;
86         CHECK_PIXEL_PTR(0);  /* make sure pixel_ptr is positive */
87
88         if(rle_code == -1)
89             continue;
90
91         if (rle_code < 0) {
92             /* decode the run length code */
93             rle_code = -rle_code;
94             /* get the next 2 bytes from the stream, treat them as groups
95              * of 8 pixels, and output them rle_code times */
96
97             pi0 = bytestream2_get_byte(&s->g);
98             pi1 = bytestream2_get_byte(&s->g);
99             CHECK_PIXEL_PTR(rle_code * 2);
100
101             while (rle_code--) {
102                 rgb[pixel_ptr++] = pi0;
103                 rgb[pixel_ptr++] = pi1;
104             }
105         } else {
106             /* copy the same pixel directly to output 2 times */
107             rle_code *= 2;
108             CHECK_PIXEL_PTR(rle_code);
109
110             while (rle_code--)
111                 rgb[pixel_ptr++] = bytestream2_get_byte(&s->g);
112         }
113     }
114 }
115
116 static inline void qtrle_decode_2n4bpp(QtrleContext *s, int row_ptr,
117                                        int lines_to_change, int bpp)
118 {
119     int rle_code, i;
120     int pixel_ptr;
121     int row_inc = s->frame.linesize[0];
122     unsigned char pi[16];  /* 16 palette indices */
123     unsigned char *rgb = s->frame.data[0];
124     int pixel_limit = s->frame.linesize[0] * s->avctx->height;
125     int num_pixels = (bpp == 4) ? 8 : 16;
126
127     while (lines_to_change--) {
128         pixel_ptr = row_ptr + (num_pixels * (bytestream2_get_byte(&s->g) - 1));
129         CHECK_PIXEL_PTR(0);  /* make sure pixel_ptr is positive */
130
131         while ((rle_code = (signed char)bytestream2_get_byte(&s->g)) != -1) {
132             if (rle_code == 0) {
133                 /* there's another skip code in the stream */
134                 pixel_ptr += (num_pixels * (bytestream2_get_byte(&s->g) - 1));
135                 CHECK_PIXEL_PTR(0);  /* make sure pixel_ptr is positive */
136             } else if (rle_code < 0) {
137                 /* decode the run length code */
138                 rle_code = -rle_code;
139                 /* get the next 4 bytes from the stream, treat them as palette
140                  * indexes, and output them rle_code times */
141                 for (i = num_pixels-1; i >= 0; i--) {
142                     pi[num_pixels-1-i] = (bytestream2_peek_byte(&s->g) >> ((i*bpp) & 0x07)) & ((1<<bpp)-1);
143                     bytestream2_skip(&s->g, ((i & ((num_pixels>>2)-1)) == 0));
144                 }
145                 CHECK_PIXEL_PTR(rle_code * num_pixels);
146                 while (rle_code--) {
147                     for (i = 0; i < num_pixels; i++)
148                         rgb[pixel_ptr++] = pi[i];
149                 }
150             } else {
151                 /* copy the same pixel directly to output 4 times */
152                 rle_code *= 4;
153                 CHECK_PIXEL_PTR(rle_code*(num_pixels>>2));
154                 while (rle_code--) {
155                     if(bpp == 4) {
156                         int x = bytestream2_get_byte(&s->g);
157                         rgb[pixel_ptr++] = (x >> 4) & 0x0f;
158                         rgb[pixel_ptr++] =  x       & 0x0f;
159                     } else {
160                         int x = bytestream2_get_byte(&s->g);
161                         rgb[pixel_ptr++] = (x >> 6) & 0x03;
162                         rgb[pixel_ptr++] = (x >> 4) & 0x03;
163                         rgb[pixel_ptr++] = (x >> 2) & 0x03;
164                         rgb[pixel_ptr++] =  x       & 0x03;
165                     }
166                 }
167             }
168         }
169         row_ptr += row_inc;
170     }
171 }
172
173 static void qtrle_decode_8bpp(QtrleContext *s, int row_ptr, int lines_to_change)
174 {
175     int rle_code;
176     int pixel_ptr;
177     int row_inc = s->frame.linesize[0];
178     unsigned char pi1, pi2, pi3, pi4;  /* 4 palette indexes */
179     unsigned char *rgb = s->frame.data[0];
180     int pixel_limit = s->frame.linesize[0] * s->avctx->height;
181
182     while (lines_to_change--) {
183         pixel_ptr = row_ptr + (4 * (bytestream2_get_byte(&s->g) - 1));
184         CHECK_PIXEL_PTR(0);  /* make sure pixel_ptr is positive */
185
186         while ((rle_code = (signed char)bytestream2_get_byte(&s->g)) != -1) {
187             if (rle_code == 0) {
188                 /* there's another skip code in the stream */
189                 pixel_ptr += (4 * (bytestream2_get_byte(&s->g) - 1));
190                 CHECK_PIXEL_PTR(0);  /* make sure pixel_ptr is positive */
191             } else if (rle_code < 0) {
192                 /* decode the run length code */
193                 rle_code = -rle_code;
194                 /* get the next 4 bytes from the stream, treat them as palette
195                  * indexes, and output them rle_code times */
196                 pi1 = bytestream2_get_byte(&s->g);
197                 pi2 = bytestream2_get_byte(&s->g);
198                 pi3 = bytestream2_get_byte(&s->g);
199                 pi4 = bytestream2_get_byte(&s->g);
200
201                 CHECK_PIXEL_PTR(rle_code * 4);
202
203                 while (rle_code--) {
204                     rgb[pixel_ptr++] = pi1;
205                     rgb[pixel_ptr++] = pi2;
206                     rgb[pixel_ptr++] = pi3;
207                     rgb[pixel_ptr++] = pi4;
208                 }
209             } else {
210                 /* copy the same pixel directly to output 4 times */
211                 rle_code *= 4;
212                 CHECK_PIXEL_PTR(rle_code);
213
214                 while (rle_code--) {
215                     rgb[pixel_ptr++] = bytestream2_get_byte(&s->g);
216                 }
217             }
218         }
219         row_ptr += row_inc;
220     }
221 }
222
223 static void qtrle_decode_16bpp(QtrleContext *s, int row_ptr, int lines_to_change)
224 {
225     int rle_code;
226     int pixel_ptr;
227     int row_inc = s->frame.linesize[0];
228     unsigned short rgb16;
229     unsigned char *rgb = s->frame.data[0];
230     int pixel_limit = s->frame.linesize[0] * s->avctx->height;
231
232     while (lines_to_change--) {
233         pixel_ptr = row_ptr + (bytestream2_get_byte(&s->g) - 1) * 2;
234         CHECK_PIXEL_PTR(0);  /* make sure pixel_ptr is positive */
235
236         while ((rle_code = (signed char)bytestream2_get_byte(&s->g)) != -1) {
237             if (rle_code == 0) {
238                 /* there's another skip code in the stream */
239                 pixel_ptr += (bytestream2_get_byte(&s->g) - 1) * 2;
240                 CHECK_PIXEL_PTR(0);  /* make sure pixel_ptr is positive */
241             } else if (rle_code < 0) {
242                 /* decode the run length code */
243                 rle_code = -rle_code;
244                 rgb16 = bytestream2_get_be16(&s->g);
245
246                 CHECK_PIXEL_PTR(rle_code * 2);
247
248                 while (rle_code--) {
249                     *(unsigned short *)(&rgb[pixel_ptr]) = rgb16;
250                     pixel_ptr += 2;
251                 }
252             } else {
253                 CHECK_PIXEL_PTR(rle_code * 2);
254
255                 /* copy pixels directly to output */
256                 while (rle_code--) {
257                     rgb16 = bytestream2_get_be16(&s->g);
258                     *(unsigned short *)(&rgb[pixel_ptr]) = rgb16;
259                     pixel_ptr += 2;
260                 }
261             }
262         }
263         row_ptr += row_inc;
264     }
265 }
266
267 static void qtrle_decode_24bpp(QtrleContext *s, int row_ptr, int lines_to_change)
268 {
269     int rle_code;
270     int pixel_ptr;
271     int row_inc = s->frame.linesize[0];
272     unsigned char r, g, b;
273     unsigned char *rgb = s->frame.data[0];
274     int pixel_limit = s->frame.linesize[0] * s->avctx->height;
275
276     while (lines_to_change--) {
277         pixel_ptr = row_ptr + (bytestream2_get_byte(&s->g) - 1) * 3;
278         CHECK_PIXEL_PTR(0);  /* make sure pixel_ptr is positive */
279
280         while ((rle_code = (signed char)bytestream2_get_byte(&s->g)) != -1) {
281             if (rle_code == 0) {
282                 /* there's another skip code in the stream */
283                 pixel_ptr += (bytestream2_get_byte(&s->g) - 1) * 3;
284                 CHECK_PIXEL_PTR(0);  /* make sure pixel_ptr is positive */
285             } else if (rle_code < 0) {
286                 /* decode the run length code */
287                 rle_code = -rle_code;
288                 r = bytestream2_get_byte(&s->g);
289                 g = bytestream2_get_byte(&s->g);
290                 b = bytestream2_get_byte(&s->g);
291
292                 CHECK_PIXEL_PTR(rle_code * 3);
293
294                 while (rle_code--) {
295                     rgb[pixel_ptr++] = r;
296                     rgb[pixel_ptr++] = g;
297                     rgb[pixel_ptr++] = b;
298                 }
299             } else {
300                 CHECK_PIXEL_PTR(rle_code * 3);
301
302                 /* copy pixels directly to output */
303                 while (rle_code--) {
304                     rgb[pixel_ptr++] = bytestream2_get_byte(&s->g);
305                     rgb[pixel_ptr++] = bytestream2_get_byte(&s->g);
306                     rgb[pixel_ptr++] = bytestream2_get_byte(&s->g);
307                 }
308             }
309         }
310         row_ptr += row_inc;
311     }
312 }
313
314 static void qtrle_decode_32bpp(QtrleContext *s, int row_ptr, int lines_to_change)
315 {
316     int rle_code;
317     int pixel_ptr;
318     int row_inc = s->frame.linesize[0];
319     unsigned int argb;
320     unsigned char *rgb = s->frame.data[0];
321     int pixel_limit = s->frame.linesize[0] * s->avctx->height;
322
323     while (lines_to_change--) {
324         pixel_ptr = row_ptr + (bytestream2_get_byte(&s->g) - 1) * 4;
325         CHECK_PIXEL_PTR(0);  /* make sure pixel_ptr is positive */
326
327         while ((rle_code = (signed char)bytestream2_get_byte(&s->g)) != -1) {
328             if (rle_code == 0) {
329                 /* there's another skip code in the stream */
330                 pixel_ptr += (bytestream2_get_byte(&s->g) - 1) * 4;
331                 CHECK_PIXEL_PTR(0);  /* make sure pixel_ptr is positive */
332             } else if (rle_code < 0) {
333                 /* decode the run length code */
334                 rle_code = -rle_code;
335                 argb = bytestream2_get_be32(&s->g);
336
337                 CHECK_PIXEL_PTR(rle_code * 4);
338
339                 while (rle_code--) {
340                     AV_WN32A(rgb + pixel_ptr, argb);
341                     pixel_ptr += 4;
342                 }
343             } else {
344                 CHECK_PIXEL_PTR(rle_code * 4);
345
346                 /* copy pixels directly to output */
347                 while (rle_code--) {
348                     argb = bytestream2_get_be32(&s->g);
349                     AV_WN32A(rgb + pixel_ptr, argb);
350                     pixel_ptr  += 4;
351                 }
352             }
353         }
354         row_ptr += row_inc;
355     }
356 }
357
358 static av_cold int qtrle_decode_init(AVCodecContext *avctx)
359 {
360     QtrleContext *s = avctx->priv_data;
361
362     s->avctx = avctx;
363     switch (avctx->bits_per_coded_sample) {
364     case 1:
365     case 33:
366         avctx->pix_fmt = AV_PIX_FMT_MONOWHITE;
367         break;
368
369     case 2:
370     case 4:
371     case 8:
372     case 34:
373     case 36:
374     case 40:
375         avctx->pix_fmt = AV_PIX_FMT_PAL8;
376         break;
377
378     case 16:
379         avctx->pix_fmt = AV_PIX_FMT_RGB555;
380         break;
381
382     case 24:
383         avctx->pix_fmt = AV_PIX_FMT_RGB24;
384         break;
385
386     case 32:
387         avctx->pix_fmt = AV_PIX_FMT_RGB32;
388         break;
389
390     default:
391         av_log (avctx, AV_LOG_ERROR, "Unsupported colorspace: %d bits/sample?\n",
392             avctx->bits_per_coded_sample);
393         return AVERROR_INVALIDDATA;
394     }
395
396     avcodec_get_frame_defaults(&s->frame);
397     s->frame.data[0] = NULL;
398
399     return 0;
400 }
401
402 static int qtrle_decode_frame(AVCodecContext *avctx,
403                               void *data, int *got_frame,
404                               AVPacket *avpkt)
405 {
406     QtrleContext *s = avctx->priv_data;
407     int header, start_line;
408     int height, row_ptr;
409     int has_palette = 0;
410     int ret;
411
412     bytestream2_init(&s->g, avpkt->data, avpkt->size);
413     s->frame.reference = 3;
414     s->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE |
415                             FF_BUFFER_HINTS_REUSABLE | FF_BUFFER_HINTS_READABLE;
416     if ((ret = avctx->reget_buffer(avctx, &s->frame)) < 0) {
417         av_log (s->avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
418         return ret;
419     }
420
421     /* check if this frame is even supposed to change */
422     if (avpkt->size < 8)
423         goto done;
424
425     /* start after the chunk size */
426     bytestream2_seek(&s->g, 4, SEEK_SET);
427
428     /* fetch the header */
429     header = bytestream2_get_be16(&s->g);
430
431     /* if a header is present, fetch additional decoding parameters */
432     if (header & 0x0008) {
433         if (avpkt->size < 14)
434             goto done;
435         start_line = bytestream2_get_be16(&s->g);
436         bytestream2_skip(&s->g, 2);
437         height     = bytestream2_get_be16(&s->g);
438         bytestream2_skip(&s->g, 2);
439         if (height > s->avctx->height - start_line)
440             goto done;
441     } else {
442         start_line = 0;
443         height     = s->avctx->height;
444     }
445     row_ptr = s->frame.linesize[0] * start_line;
446
447     switch (avctx->bits_per_coded_sample) {
448     case 1:
449     case 33:
450         qtrle_decode_1bpp(s, row_ptr, height);
451         break;
452
453     case 2:
454     case 34:
455         qtrle_decode_2n4bpp(s, row_ptr, height, 2);
456         has_palette = 1;
457         break;
458
459     case 4:
460     case 36:
461         qtrle_decode_2n4bpp(s, row_ptr, height, 4);
462         has_palette = 1;
463         break;
464
465     case 8:
466     case 40:
467         qtrle_decode_8bpp(s, row_ptr, height);
468         has_palette = 1;
469         break;
470
471     case 16:
472         qtrle_decode_16bpp(s, row_ptr, height);
473         break;
474
475     case 24:
476         qtrle_decode_24bpp(s, row_ptr, height);
477         break;
478
479     case 32:
480         qtrle_decode_32bpp(s, row_ptr, height);
481         break;
482
483     default:
484         av_log (s->avctx, AV_LOG_ERROR, "Unsupported colorspace: %d bits/sample?\n",
485             avctx->bits_per_coded_sample);
486         break;
487     }
488
489     if(has_palette) {
490         const uint8_t *pal = av_packet_get_side_data(avpkt, AV_PKT_DATA_PALETTE, NULL);
491
492         if (pal) {
493             s->frame.palette_has_changed = 1;
494             memcpy(s->pal, pal, AVPALETTE_SIZE);
495         }
496
497         /* make the palette available on the way out */
498         memcpy(s->frame.data[1], s->pal, AVPALETTE_SIZE);
499     }
500
501 done:
502     *got_frame      = 1;
503     *(AVFrame*)data = s->frame;
504
505     /* always report that the buffer was completely consumed */
506     return avpkt->size;
507 }
508
509 static av_cold int qtrle_decode_end(AVCodecContext *avctx)
510 {
511     QtrleContext *s = avctx->priv_data;
512
513     if (s->frame.data[0])
514         avctx->release_buffer(avctx, &s->frame);
515
516     return 0;
517 }
518
519 AVCodec ff_qtrle_decoder = {
520     .name           = "qtrle",
521     .type           = AVMEDIA_TYPE_VIDEO,
522     .id             = AV_CODEC_ID_QTRLE,
523     .priv_data_size = sizeof(QtrleContext),
524     .init           = qtrle_decode_init,
525     .close          = qtrle_decode_end,
526     .decode         = qtrle_decode_frame,
527     .capabilities   = CODEC_CAP_DR1,
528     .long_name      = NULL_IF_CONFIG_SMALL("QuickTime Animation (RLE) video"),
529 };