2 * Quicktime Animation (RLE) Video Decoder
3 * Copyright (c) 2004 The FFmpeg Project
5 * This file is part of FFmpeg.
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.
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.
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
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/
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.
39 #include "bytestream.h"
42 typedef struct QtrleContext
{
43 AVCodecContext
*avctx
;
50 #define CHECK_PIXEL_PTR(n) \
51 if ((pixel_ptr + n > pixel_limit) || (pixel_ptr + n < 0)) { \
52 av_log (s->avctx, AV_LOG_ERROR, "Problem: pixel_ptr = %d, pixel_limit = %d\n",\
53 pixel_ptr + n, pixel_limit); \
57 static void qtrle_decode_1bpp(QtrleContext *s, int row_ptr, int lines_to_change)
61 int row_inc
= s
->frame
->linesize
[0];
62 uint8_t pi0
, pi1
; /* 2 8-pixel values */
63 uint8_t *rgb
= s
->frame
->data
[0];
64 int pixel_limit
= s
->frame
->linesize
[0] * s
->avctx
->height
;
66 /* skip & 0x80 appears to mean 'start a new line', which can be interpreted
67 * as 'go to next line' during the decoding of a frame but is 'go to first
68 * line' at the beginning. Since we always interpret it as 'go to next line'
69 * in the decoding loop (which makes code simpler/faster), the first line
70 * would not be counted, so we count one more.
71 * See: https://trac.ffmpeg.org/ticket/226
72 * In the following decoding loop, row_ptr will be the position of the
78 while (lines_to_change
) {
79 skip
= bytestream2_get_byte(&s
->g
);
80 rle_code
= (int8_t)bytestream2_get_byte(&s
->g
);
86 pixel_ptr
= row_ptr
+ 2 * (skip
& 0x7f);
88 pixel_ptr
+= 2 * skip
;
89 CHECK_PIXEL_PTR(0); /* make sure pixel_ptr is positive */
95 /* decode the run length code */
97 /* get the next 2 bytes from the stream, treat them as groups
98 * of 8 pixels, and output them rle_code times */
100 pi0
= bytestream2_get_byte(&s
->g
);
101 pi1
= bytestream2_get_byte(&s
->g
);
102 CHECK_PIXEL_PTR(rle_code
* 2);
105 rgb
[pixel_ptr
++] = pi0
;
106 rgb
[pixel_ptr
++] = pi1
;
109 /* copy the same pixel directly to output 2 times */
111 CHECK_PIXEL_PTR(rle_code
);
113 bytestream2_get_buffer(&s
->g
, &rgb
[pixel_ptr
], rle_code
);
114 pixel_ptr
+= rle_code
;
119 static inline void qtrle_decode_2n4bpp(QtrleContext
*s
, int row_ptr
,
120 int lines_to_change
, int bpp
)
124 int row_inc
= s
->frame
->linesize
[0];
125 uint8_t pi
[16]; /* 16 palette indices */
126 uint8_t *rgb
= s
->frame
->data
[0];
127 int pixel_limit
= s
->frame
->linesize
[0] * s
->avctx
->height
;
128 int num_pixels
= (bpp
== 4) ? 8 : 16;
130 while (lines_to_change
--) {
131 pixel_ptr
= row_ptr
+ (num_pixels
* (bytestream2_get_byte(&s
->g
) - 1));
134 while ((rle_code
= (int8_t)bytestream2_get_byte(&s
->g
)) != -1) {
136 /* there's another skip code in the stream */
137 pixel_ptr
+= (num_pixels
* (bytestream2_get_byte(&s
->g
) - 1));
138 CHECK_PIXEL_PTR(0); /* make sure pixel_ptr is positive */
139 } else if (rle_code
< 0) {
140 /* decode the run length code */
141 rle_code
= -rle_code
;
142 /* get the next 4 bytes from the stream, treat them as palette
143 * indexes, and output them rle_code times */
144 for (i
= num_pixels
-1; i
>= 0; i
--) {
145 pi
[num_pixels
-1-i
] = (bytestream2_peek_byte(&s
->g
) >> ((i
*bpp
) & 0x07)) & ((1<<bpp
)-1);
146 bytestream2_skip(&s
->g
, ((i
& ((num_pixels
>>2)-1)) == 0));
148 CHECK_PIXEL_PTR(rle_code
* num_pixels
);
150 memcpy(&rgb
[pixel_ptr
], &pi
, num_pixels
);
151 pixel_ptr
+= num_pixels
;
154 /* copy the same pixel directly to output 4 times */
156 CHECK_PIXEL_PTR(rle_code
*(num_pixels
>>2));
159 int x
= bytestream2_get_byte(&s
->g
);
160 rgb
[pixel_ptr
++] = (x
>> 4) & 0x0f;
161 rgb
[pixel_ptr
++] = x
& 0x0f;
163 int x
= bytestream2_get_byte(&s
->g
);
164 rgb
[pixel_ptr
++] = (x
>> 6) & 0x03;
165 rgb
[pixel_ptr
++] = (x
>> 4) & 0x03;
166 rgb
[pixel_ptr
++] = (x
>> 2) & 0x03;
167 rgb
[pixel_ptr
++] = x
& 0x03;
176 static void qtrle_decode_8bpp(QtrleContext
*s
, int row_ptr
, int lines_to_change
)
180 int row_inc
= s
->frame
->linesize
[0];
181 uint8_t pi1
, pi2
, pi3
, pi4
; /* 4 palette indexes */
182 uint8_t *rgb
= s
->frame
->data
[0];
183 int pixel_limit
= s
->frame
->linesize
[0] * s
->avctx
->height
;
185 while (lines_to_change
--) {
186 pixel_ptr
= row_ptr
+ (4 * (bytestream2_get_byte(&s
->g
) - 1));
189 while ((rle_code
= (int8_t)bytestream2_get_byte(&s
->g
)) != -1) {
191 /* there's another skip code in the stream */
192 pixel_ptr
+= (4 * (bytestream2_get_byte(&s
->g
) - 1));
193 CHECK_PIXEL_PTR(0); /* make sure pixel_ptr is positive */
194 } else if (rle_code
< 0) {
195 /* decode the run length code */
196 rle_code
= -rle_code
;
197 /* get the next 4 bytes from the stream, treat them as palette
198 * indexes, and output them rle_code times */
199 pi1
= bytestream2_get_byte(&s
->g
);
200 pi2
= bytestream2_get_byte(&s
->g
);
201 pi3
= bytestream2_get_byte(&s
->g
);
202 pi4
= bytestream2_get_byte(&s
->g
);
204 CHECK_PIXEL_PTR(rle_code
* 4);
207 rgb
[pixel_ptr
++] = pi1
;
208 rgb
[pixel_ptr
++] = pi2
;
209 rgb
[pixel_ptr
++] = pi3
;
210 rgb
[pixel_ptr
++] = pi4
;
213 /* copy the same pixel directly to output 4 times */
215 CHECK_PIXEL_PTR(rle_code
);
217 bytestream2_get_buffer(&s
->g
, &rgb
[pixel_ptr
], rle_code
);
218 pixel_ptr
+= rle_code
;
225 static void qtrle_decode_16bpp(QtrleContext
*s
, int row_ptr
, int lines_to_change
)
229 int row_inc
= s
->frame
->linesize
[0];
231 uint8_t *rgb
= s
->frame
->data
[0];
232 int pixel_limit
= s
->frame
->linesize
[0] * s
->avctx
->height
;
234 while (lines_to_change
--) {
235 pixel_ptr
= row_ptr
+ (bytestream2_get_byte(&s
->g
) - 1) * 2;
238 while ((rle_code
= (int8_t)bytestream2_get_byte(&s
->g
)) != -1) {
240 /* there's another skip code in the stream */
241 pixel_ptr
+= (bytestream2_get_byte(&s
->g
) - 1) * 2;
242 CHECK_PIXEL_PTR(0); /* make sure pixel_ptr is positive */
243 } else if (rle_code
< 0) {
244 /* decode the run length code */
245 rle_code
= -rle_code
;
246 rgb16
= bytestream2_get_be16(&s
->g
);
248 CHECK_PIXEL_PTR(rle_code
* 2);
251 *(uint16_t *)(&rgb
[pixel_ptr
]) = rgb16
;
255 CHECK_PIXEL_PTR(rle_code
* 2);
257 /* copy pixels directly to output */
259 rgb16
= bytestream2_get_be16(&s
->g
);
260 *(uint16_t *)(&rgb
[pixel_ptr
]) = rgb16
;
269 static void qtrle_decode_24bpp(QtrleContext
*s
, int row_ptr
, int lines_to_change
)
273 int row_inc
= s
->frame
->linesize
[0];
275 uint8_t *rgb
= s
->frame
->data
[0];
276 int pixel_limit
= s
->frame
->linesize
[0] * s
->avctx
->height
;
278 while (lines_to_change
--) {
279 pixel_ptr
= row_ptr
+ (bytestream2_get_byte(&s
->g
) - 1) * 3;
282 while ((rle_code
= (int8_t)bytestream2_get_byte(&s
->g
)) != -1) {
284 /* there's another skip code in the stream */
285 pixel_ptr
+= (bytestream2_get_byte(&s
->g
) - 1) * 3;
286 CHECK_PIXEL_PTR(0); /* make sure pixel_ptr is positive */
287 } else if (rle_code
< 0) {
288 /* decode the run length code */
289 rle_code
= -rle_code
;
290 r
= bytestream2_get_byte(&s
->g
);
291 g
= bytestream2_get_byte(&s
->g
);
292 b
= bytestream2_get_byte(&s
->g
);
294 CHECK_PIXEL_PTR(rle_code
* 3);
297 rgb
[pixel_ptr
++] = r
;
298 rgb
[pixel_ptr
++] = g
;
299 rgb
[pixel_ptr
++] = b
;
302 CHECK_PIXEL_PTR(rle_code
* 3);
304 /* copy pixels directly to output */
306 rgb
[pixel_ptr
++] = bytestream2_get_byte(&s
->g
);
307 rgb
[pixel_ptr
++] = bytestream2_get_byte(&s
->g
);
308 rgb
[pixel_ptr
++] = bytestream2_get_byte(&s
->g
);
316 static void qtrle_decode_32bpp(QtrleContext
*s
, int row_ptr
, int lines_to_change
)
320 int row_inc
= s
->frame
->linesize
[0];
322 uint8_t *rgb
= s
->frame
->data
[0];
323 int pixel_limit
= s
->frame
->linesize
[0] * s
->avctx
->height
;
325 while (lines_to_change
--) {
326 pixel_ptr
= row_ptr
+ (bytestream2_get_byte(&s
->g
) - 1) * 4;
329 while ((rle_code
= (int8_t)bytestream2_get_byte(&s
->g
)) != -1) {
331 /* there's another skip code in the stream */
332 pixel_ptr
+= (bytestream2_get_byte(&s
->g
) - 1) * 4;
333 CHECK_PIXEL_PTR(0); /* make sure pixel_ptr is positive */
334 } else if (rle_code
< 0) {
335 /* decode the run length code */
336 rle_code
= -rle_code
;
337 argb
= bytestream2_get_be32(&s
->g
);
339 CHECK_PIXEL_PTR(rle_code
* 4);
342 AV_WN32A(rgb
+ pixel_ptr
, argb
);
346 CHECK_PIXEL_PTR(rle_code
* 4);
348 /* copy pixels directly to output */
350 argb
= bytestream2_get_be32(&s
->g
);
351 AV_WN32A(rgb
+ pixel_ptr
, argb
);
360 static av_cold
int qtrle_decode_init(AVCodecContext
*avctx
)
362 QtrleContext
*s
= avctx
->priv_data
;
365 switch (avctx
->bits_per_coded_sample
) {
368 avctx
->pix_fmt
= AV_PIX_FMT_MONOWHITE
;
377 avctx
->pix_fmt
= AV_PIX_FMT_PAL8
;
381 avctx
->pix_fmt
= AV_PIX_FMT_RGB555
;
385 avctx
->pix_fmt
= AV_PIX_FMT_RGB24
;
389 avctx
->pix_fmt
= AV_PIX_FMT_RGB32
;
393 av_log (avctx
, AV_LOG_ERROR
, "Unsupported colorspace: %d bits/sample?\n",
394 avctx
->bits_per_coded_sample
);
395 return AVERROR_INVALIDDATA
;
398 s
->frame
= av_frame_alloc();
400 return AVERROR(ENOMEM
);
405 static int qtrle_decode_frame(AVCodecContext
*avctx
,
406 void *data
, int *got_frame
,
409 QtrleContext
*s
= avctx
->priv_data
;
410 int header
, start_line
;
415 bytestream2_init(&s
->g
, avpkt
->data
, avpkt
->size
);
416 if ((ret
= ff_reget_buffer(avctx
, s
->frame
)) < 0)
419 /* check if this frame is even supposed to change */
423 /* start after the chunk size */
424 bytestream2_seek(&s
->g
, 4, SEEK_SET
);
426 /* fetch the header */
427 header
= bytestream2_get_be16(&s
->g
);
429 /* if a header is present, fetch additional decoding parameters */
430 if (header
& 0x0008) {
431 if (avpkt
->size
< 14)
433 start_line
= bytestream2_get_be16(&s
->g
);
434 bytestream2_skip(&s
->g
, 2);
435 height
= bytestream2_get_be16(&s
->g
);
436 bytestream2_skip(&s
->g
, 2);
437 if (height
> s
->avctx
->height
- start_line
)
441 height
= s
->avctx
->height
;
443 row_ptr
= s
->frame
->linesize
[0] * start_line
;
445 switch (avctx
->bits_per_coded_sample
) {
448 qtrle_decode_1bpp(s
, row_ptr
, height
);
453 qtrle_decode_2n4bpp(s
, row_ptr
, height
, 2);
459 qtrle_decode_2n4bpp(s
, row_ptr
, height
, 4);
465 qtrle_decode_8bpp(s
, row_ptr
, height
);
470 qtrle_decode_16bpp(s
, row_ptr
, height
);
474 qtrle_decode_24bpp(s
, row_ptr
, height
);
478 qtrle_decode_32bpp(s
, row_ptr
, height
);
482 av_log (s
->avctx
, AV_LOG_ERROR
, "Unsupported colorspace: %d bits/sample?\n",
483 avctx
->bits_per_coded_sample
);
488 const uint8_t *pal
= av_packet_get_side_data(avpkt
, AV_PKT_DATA_PALETTE
, NULL
);
491 s
->frame
->palette_has_changed
= 1;
492 memcpy(s
->pal
, pal
, AVPALETTE_SIZE
);
495 /* make the palette available on the way out */
496 memcpy(s
->frame
->data
[1], s
->pal
, AVPALETTE_SIZE
);
500 if ((ret
= av_frame_ref(data
, s
->frame
)) < 0)
504 /* always report that the buffer was completely consumed */
508 static av_cold
int qtrle_decode_end(AVCodecContext
*avctx
)
510 QtrleContext
*s
= avctx
->priv_data
;
512 av_frame_free(&s
->frame
);
517 AVCodec ff_qtrle_decoder
= {
519 .long_name
= NULL_IF_CONFIG_SMALL("QuickTime Animation (RLE) video"),
520 .type
= AVMEDIA_TYPE_VIDEO
,
521 .id
= AV_CODEC_ID_QTRLE
,
522 .priv_data_size
= sizeof(QtrleContext
),
523 .init
= qtrle_decode_init
,
524 .close
= qtrle_decode_end
,
525 .decode
= qtrle_decode_frame
,
526 .capabilities
= CODEC_CAP_DR1
,