1 /*
2 * Quicktime Planar RGB (8BPS) Video Decoder
3 * Copyright (C) 2003 Roberto Togni
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 8BPS Video Decoder by Roberto Togni
25 * For more information about the 8BPS format, visit:
26 * http://www.pcisys.net/~melanson/codecs/
27 *
28 * Supports: PAL8 (RGB 8bpp, paletted)
29 * : GBRP (RGB 24bpp)
30 * : GBRAP (RGB 32bpp, 4th plane is alpha)
31 */
32
33 #include <string.h>
34
40
43
46
49
52 {
53 const uint8_t *buf = avpkt->
data;
54 int buf_size = avpkt->
size;
56 const uint8_t *encoded = buf;
57 uint8_t *pixptr, *pixptr_end;
58 unsigned int height = avctx->
height;
// Real image height
59 unsigned int dlen, p, row;
60 const uint8_t *lp, *dp, *ep;
61 uint8_t count;
62 const uint8_t *planemap =
c->planemap;
63 unsigned int planes =
c->planes;
65
68
71
72 ep = encoded + buf_size;
73
74 /* Set data pointer after line lengths */
76
77 for (p = 0; p <
planes; p++) {
78 const int pi = planemap[p];
79 /* Lines length pointer for this plane */
80 lp = encoded + p * (
height << 1);
81
82 /* Decode a plane */
83 for (row = 0; row <
height; row++) {
84 pixptr =
frame->data[pi] + row *
frame->linesize[pi];
85 pixptr_end = pixptr +
frame->linesize[pi];
86 if (ep - lp < row * 2 + 2)
89 /* Decode a row of this plane */
90 while (dlen > 0) {
91 if (ep - dp <= 1)
93 if ((count = *dp++) <= 127) {
94 count++;
95 dlen -= count + 1;
96 if (pixptr_end - pixptr < count)
97 break;
98 if (ep - dp < count)
100 memcpy(pixptr, dp, count);
101 pixptr += count;
102 dp += count;
103 } else {
104 count = 257 - count;
105 if (pixptr_end - pixptr < count)
106 break;
107 memset(pixptr, dp[0], count);
108 pixptr += count;
109 dp++;
110 dlen -= 2;
111 }
112 }
113 }
114 }
115
117 #if FF_API_PALETTE_HAS_CHANGED
119 frame->palette_has_changed =
120 #endif
122 #if FF_API_PALETTE_HAS_CHANGED
124 #endif
125
127 }
128
129 *got_frame = 1;
130
131 /* always report that the buffer was completely consumed */
132 return buf_size;
133 }
134
136 {
138
140
142 case 8:
145 c->planemap[0] = 0;
// 1st plane is palette indexes
146 break;
147 case 24:
150 c->planemap[0] = 2;
// 1st plane is red
151 c->planemap[1] = 0;
// 2nd plane is green
152 c->planemap[2] = 1;
// 3rd plane is blue
153 break;
154 case 32:
157 break;
158 default:
162 }
163
165 c->planemap[0] = 2;
// 1st plane is red
166 c->planemap[1] = 0;
// 2nd plane is green
167 c->planemap[2] = 1;
// 3rd plane is blue
168 c->planemap[3] = 3;
// 4th plane is alpha
169 }
170 return 0;
171 }
172
182 };