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