1 /*
2 * Targa (.tga) image decoder
3 * Copyright (c) 2006 Konstantin Shishkov
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
28
32
35 {
37
38 if (*y < h) {
39 return line + interleave *
stride;
40 } else {
41 *y = (*y + 1) & (interleave - 1);
42 if (*y && *y < h) {
43 return start + *y *
stride;
44 } else {
45 return NULL;
46 }
47 }
48 }
49
53 {
55 int depth = (bpp + 1) >> 3;
59
60 x = y = count = 0;
61 while (dst) {
64 "Ran ouf of data before end-of-image\n");
66 }
67 type = bytestream2_get_byteu(&s->
gb);
68 count = (type & 0x7F) + 1;
69 type &= 0x80;
70 if (!type) {
71 do {
72 int n =
FFMIN(count, w - x);
77 if (x == w) {
78 x = 0;
79 dst = line =
advance_line(start, line, stride, &y, h, interleave);
80 }
81 } while (dst && count > 0);
82 } else {
85 do {
86 int n =
FFMIN(count, w - x);
89 do {
90 memcpy(dst, tmp, depth);
92 } while (--n);
93 if (x == w) {
94 x = 0;
95 dst = line =
advance_line(start, line, stride, &y, h, interleave);
96 }
97 } while (dst && count > 0);
98 }
99 }
100
101 if (count) {
104 }
105
106 return 0;
107 }
108
110 void *
data,
int *got_frame,
112 {
117 int idlen, pal, compr,
y, w, h, bpp,
flags,
ret;
118 int first_clr, colors, csize;
120
122
123 /* parse image header */
124 idlen = bytestream2_get_byte(&s->
gb);
125 pal = bytestream2_get_byte(&s->
gb);
126 compr = bytestream2_get_byte(&s->
gb);
127 first_clr = bytestream2_get_le16(&s->
gb);
128 colors = bytestream2_get_le16(&s->
gb);
129 csize = bytestream2_get_byte(&s->
gb);
131 w = bytestream2_get_le16(&s->
gb);
132 h = bytestream2_get_le16(&s->
gb);
133 bpp = bytestream2_get_byte(&s->
gb);
134
137 "Not enough data to read header\n");
139 }
140
141 flags = bytestream2_get_byte(&s->
gb);
142
143 if (!pal && (first_clr || colors || csize)) {
145 // specification says we should ignore those value in this case
146 first_clr = colors = csize = 0;
147 }
148
149 // skip identifier if any
151
152 switch (bpp) {
153 case 8:
155 break;
156 case 15:
157 case 16:
159 break;
160 case 24:
162 break;
163 case 32:
165 break;
166 default:
169 }
170
171 if (colors && (colors + first_clr) > 256) {
172 av_log(avctx,
AV_LOG_ERROR,
"Incorrect palette: %i colors with offset %i\n", colors, first_clr);
174 }
175
183
187 } else { //image is upside-down
190 }
191
194
195 if (colors) {
196 int pal_size, pal_sample_size;
197
198 switch (csize) {
199 case 32: pal_sample_size = 4; break;
200 case 24: pal_sample_size = 3; break;
201 case 16:
202 case 15: pal_sample_size = 2; break;
203 default:
206 }
207 pal_size = colors * pal_sample_size;
210 else {
212 uint32_t *pal = ((uint32_t *)p->
data[1]) + first_clr;
213
216 "Not enough data to read palette\n");
218 }
219 switch (pal_sample_size) {
220 case 4:
221 for (t = 0; t < colors; t++)
222 *pal++ = bytestream2_get_le32u(&s->
gb);
223 break;
224 case 3:
225 /* RGB24 */
226 for (t = 0; t < colors; t++)
227 *pal++ = (0xffU<<24) | bytestream2_get_le24u(&s->
gb);
228 break;
229 case 2:
230 /* RGB555 */
231 for (t = 0; t < colors; t++) {
232 uint32_t
v = bytestream2_get_le16u(&s->
gb);
233 v = ((v & 0x7C00) << 9) |
234 ((v & 0x03E0) << 6) |
235 ((v & 0x001F) << 3);
236 /* left bit replication */
237 v |= (v & 0xE0E0E0
U) >> 5;
238 *pal++ = (0xff
U<<24) | v;
239 }
240 break;
241 }
243 }
244 }
245
248 } else {
251 if (res < 0)
253 } else {
254 size_t img_size = w * ((bpp + 1) >> 3);
258 "Not enough data available for image\n");
260 }
261
262 line = dst;
263 y = 0;
264 do {
266 line =
advance_line(dst, line, stride, &y, h, interleave);
267 } while (line);
268 }
269 }
270
272 int x;
273 for (y = 0; y < h; y++) {
275 for (x = 0; x < w >> 1; x++) {
276 switch (bpp) {
277 case 32:
278 FFSWAP(uint32_t, ((uint32_t *)line)[x], ((uint32_t *)line)[w - x - 1]);
279 break;
280 case 24:
284 break;
285 case 16:
286 FFSWAP(uint16_t, ((uint16_t *)line)[x], ((uint16_t *)line)[w - x - 1]);
287 break;
288 case 8:
290 }
291 }
292 }
293 }
294
295 *got_frame = 1;
296
298 }
299
308 };