1 /*
2 * QuickDraw (qdrw) codec
3 * Copyright (c) 2004 Konstantin Shishkov
4 * Copyright (c) 2015 Vittorio Giovara
5 *
6 * This file is part of FFmpeg.
7 *
8 * FFmpeg is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
12 *
13 * FFmpeg is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with FFmpeg; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 */
22
23 /**
24 * @file
25 * Apple QuickDraw codec.
26 * https://developer.apple.com/legacy/library/documentation/mac/QuickDraw/QuickDraw-461.html
27 */
28
34
43
45 };
46
48 uint32_t *pal, int colors)
49 {
50 int i;
51
52 for (i = 0; i <= colors; i++) {
54 unsigned int idx = bytestream2_get_be16(gbc); /* color index */
55 if (idx > 255) {
57 "Palette index out of range: %u\n", idx);
59 continue;
60 }
63 r = bytestream2_get_byte(gbc);
65 g = bytestream2_get_byte(gbc);
67 b = bytestream2_get_byte(gbc);
69 pal[idx] = (0xFF
U << 24) | (r << 16) | (g << 8) | b;
70 }
71 return 0;
72 }
73
75 {
78 int i, j;
79
80 for (i = 0; i < avctx->
height; i++) {
81 int size, left, code, pix;
83 int pos = 0;
84
85 /* size of packed line */
86 if (offset / 4 > 200)
87 size = left = bytestream2_get_be16(gbc);
88 else
89 size = left = bytestream2_get_byte(gbc);
92
93 /* decode line */
94 while (left > 0) {
95 code = bytestream2_get_byte(gbc);
96 if (code & 0x80 ) { /* run */
97 pix = bytestream2_get_byte(gbc);
98 for (j = 0; j < 257 - code; j++) {
99 if (pos < offset)
100 out[pos++] = (pix & 0xC0) >> 6;
101 if (pos < offset)
102 out[pos++] = (pix & 0x30) >> 4;
103 if (pos < offset)
104 out[pos++] = (pix & 0x0C) >> 2;
105 if (pos < offset)
106 out[pos++] = (pix & 0x03);
107 }
108 left -= 2;
109 } else { /* copy */
110 for (j = 0; j < code + 1; j++) {
111 pix = bytestream2_get_byte(gbc);
112 if (pos < offset)
113 out[pos++] = (pix & 0xC0) >> 6;
114 if (pos < offset)
115 out[pos++] = (pix & 0x30) >> 4;
116 if (pos < offset)
117 out[pos++] = (pix & 0x0C) >> 2;
118 if (pos < offset)
119 out[pos++] = (pix & 0x03);
120 }
121 left -= 1 + (code + 1);
122 }
123 }
125 }
126 return 0;
127 }
128
130 {
133 int i, j;
134
135 for (i = 0; i < avctx->
height; i++) {
136 int size, left, code, pix;
138 int pos = 0;
139
140 /* size of packed line */
141 size = left = bytestream2_get_be16(gbc);
144
145 /* decode line */
146 while (left > 0) {
147 code = bytestream2_get_byte(gbc);
148 if (code & 0x80 ) { /* run */
149 pix = bytestream2_get_byte(gbc);
150 for (j = 0; j < 257 - code; j++) {
151 if (pos < offset)
152 out[pos++] = (pix & 0xF0) >> 4;
153 if (pos < offset)
154 out[pos++] = pix & 0xF;
155 }
156 left -= 2;
157 } else { /* copy */
158 for (j = 0; j < code + 1; j++) {
159 pix = bytestream2_get_byte(gbc);
160 if (pos < offset)
161 out[pos++] = (pix & 0xF0) >> 4;
162 if (pos < offset)
163 out[pos++] = pix & 0xF;
164 }
165 left -= 1 + (code + 1);
166 }
167 }
169 }
170 return 0;
171 }
172
174 {
177 int i, j;
178
179 for (i = 0; i < avctx->
height; i++) {
180 int size, left, code, pix;
181 uint16_t *
out = (uint16_t *)outdata;
182 int pos = 0;
183
184 /* size of packed line */
185 size = left = bytestream2_get_be16(gbc);
188
189 /* decode line */
190 while (left > 0) {
191 code = bytestream2_get_byte(gbc);
192 if (code & 0x80 ) { /* run */
193 pix = bytestream2_get_be16(gbc);
194 for (j = 0; j < 257 - code; j++) {
195 if (pos < offset) {
196 out[pos++] = pix;
197 }
198 }
199 left -= 3;
200 } else { /* copy */
201 for (j = 0; j < code + 1; j++) {
202 if (pos < offset) {
203 out[pos++] = bytestream2_get_be16(gbc);
204 } else {
206 }
207 }
208 left -= 1 + (code + 1) * 2;
209 }
210 }
212 }
213 return 0;
214 }
215
217 int step)
218 {
219 int i, j;
222
223 for (i = 0; i < avctx->
height; i++) {
224 int size, left, code, pix;
226 int pos = 0;
227
228 /* size of packed line */
229 size = left = bytestream2_get_be16(gbc);
232
233 /* decode line */
234 while (left > 0) {
235 code = bytestream2_get_byte(gbc);
236 if (code & 0x80 ) { /* run */
237 pix = bytestream2_get_byte(gbc);
238 for (j = 0; j < 257 - code; j++) {
239 if (pos < offset)
240 out[pos] = pix;
241 pos += step;
242 if (pos >= offset && step > 1) {
244 pos++;
245 }
246 }
247 left -= 2;
248 } else { /* copy */
249 for (j = 0; j < code + 1; j++) {
250 pix = bytestream2_get_byte(gbc);
251 if (pos < offset)
252 out[pos] = pix;
253 pos += step;
254 if (pos >= offset && step > 1) {
256 pos++;
257 }
258 }
259 left -= 2 + code;
260 }
261 }
263 }
264 return 0;
265 }
266
268 {
269 unsigned w,
h,
v0, v1;
270
271 if (buf_size < 40)
272 return 0;
273
278
279 if (!w || !h)
280 return 0;
281
282 if (v0 == 0x1101)
283 return 1;
284 if (v0 == 0x0011 && v1 == 0x02FF)
285 return 2;
286 return 0;
287 }
288
289
291 void *
data,
int *got_frame,
293 {
296 int colors;
298 int ver;
299
303 )
305
307
308 /* smallest PICT header */
313 }
314
316 h = bytestream2_get_be16(&gbc);
317 w = bytestream2_get_be16(&gbc);
318
320 if (ret < 0)
321 return ret;
322
323 /* version 1 is identified by 0x1101
324 * it uses byte-aligned opcodes rather than word-aligned */
325 if (ver == 1) {
328 } else if (ver != 2) {
331 }
332
334
336 int bppcnt, bpp;
337 int rowbytes, pack_type;
338 int opcode = bytestream2_get_be16(&gbc);
339
340 switch(opcode) {
343 break;
347
349 bppcnt = bytestream2_get_be16(&gbc); /* cmpCount */
350 bpp = bytestream2_get_be16(&gbc); /* cmpSize */
351
353 if (bppcnt == 1 && bpp == 8) {
355 } else if (bppcnt == 1 && (bpp == 4 || bpp == 2)) {
357 } else if (bppcnt == 3 && bpp == 5) {
359 } else {
361 "Invalid pixel format (bppcnt %d bpp %d) in Packbit\n",
362 bppcnt, bpp);
364 }
365
366 /* jump to palette */
368 colors = bytestream2_get_be16(&gbc);
369
370 if (colors < 0 || colors > 256) {
372 "Error color count - %i(0x%X)\n", colors, colors);
374 }
379 }
381 return ret;
382
384 if (ret < 0)
385 return ret;
387
388 /* jump to image data */
390
394 }
395
398 else if (bpp == 2)
400 else if (bpp == 4)
402 else
404 if (ret < 0)
405 return ret;
406 *got_frame = 1;
407 break;
411
413 rowbytes = bytestream2_get_be16(&gbc) & 0x3FFF;
414 if (rowbytes <= 250) {
417 }
418
420 h = bytestream2_get_be16(&gbc);
421 w = bytestream2_get_be16(&gbc);
423
425 if (ret < 0)
426 return ret;
427
428 pack_type = bytestream2_get_be16(&gbc);
429
431 bppcnt = bytestream2_get_be16(&gbc); /* cmpCount */
432 bpp = bytestream2_get_be16(&gbc); /* cmpSize */
433
435 if (bppcnt == 3 && bpp == 8) {
437 } else if (bppcnt == 3 && bpp == 5) {
439 } else if (bppcnt == 4 && bpp == 8) {
441 } else {
443 "Invalid pixel format (bppcnt %d bpp %d) in Directbit\n",
444 bppcnt, bpp);
446 }
447
448 /* set packing when default is selected */
449 if (pack_type == 0)
450 pack_type = bppcnt;
451
452 if (pack_type != 3 && pack_type != 4) {
455 }
457 return ret;
458
459 /* jump to data */
461
465 }
466
469 else
471 if (ret < 0)
472 return ret;
473 *got_frame = 1;
474 break;
476 bytestream2_get_be16(&gbc);
478 break;
479 default:
481 break;
482 }
483 /* exit the loop when a known pixel block has been found */
484 if (*got_frame) {
485 int eop, trail;
486
487 /* re-align to a word */
489
490 eop = bytestream2_get_be16(&gbc);
494 "Missing end of picture opcode (found 0x%04X)\n", eop);
495 if (trail)
497 break;
498 }
499 }
500
501 if (*got_frame) {
504
506 } else {
508
510 }
511 }
512
520 };
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
This structure describes decoded (raw) audio or video data.
ptrdiff_t const GLvoid * data
#define AV_LOG_WARNING
Something somehow does not look correct.
packed RGB 8:8:8, 24bpp, RGBRGB...
int ff_set_dimensions(AVCodecContext *s, int width, int height)
Check that the provided frame dimensions are valid and set them on the codec context.
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
static av_always_inline void bytestream2_init(GetByteContext *g, const uint8_t *buf, int buf_size)
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_WL16 uint64_t_TMPL AV_WB64 unsigned int_TMPL AV_WB32 unsigned int_TMPL AV_WB24 unsigned int_TMPL AV_RB16
void void avpriv_request_sample(void *avc, const char *msg,...) av_printf_format(2
Log a generic warning message about a missing feature.
static int parse_palette(AVCodecContext *avctx, GetByteContext *gbc, uint32_t *pal, int colors)
8 bits with AV_PIX_FMT_RGB32 palette
#define AV_LOG_TRACE
Extremely verbose debugging, useful for libav* development.
static int decode_rle_bpp4(AVCodecContext *avctx, AVFrame *p, GetByteContext *gbc)
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
static av_always_inline void bytestream2_skip(GetByteContext *g, unsigned int size)
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
static av_always_inline unsigned int bytestream2_get_bytes_left(GetByteContext *g)
static int decode_rle(AVCodecContext *avctx, AVFrame *p, GetByteContext *gbc, int step)
const char * name
Name of the codec implementation.
static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt)
static const uint8_t offset[127][2]
packed ARGB 8:8:8:8, 32bpp, ARGBARGB...
static int decode_rle16(AVCodecContext *avctx, AVFrame *p, GetByteContext *gbc)
enum AVPictureType pict_type
Picture type of the frame.
int width
picture width / height.
#define AVERROR_PATCHWELCOME
Not yet implemented in FFmpeg, patches welcome.
Libavcodec external API header.
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
main external API structure.
int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame, int flags)
Get a buffer for a frame.
int palette_has_changed
Tell user application that palette has changed from previous frame.
void avpriv_report_missing_feature(void *avc, const char *msg,...) av_printf_format(2
Log a generic warning message about a missing feature.
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
common internal api header.
common internal and external API header
static int decode_rle_bpp2(AVCodecContext *avctx, AVFrame *p, GetByteContext *gbc)
#define AV_PIX_FMT_RGB555
int key_frame
1 -> keyframe, 0-> not
static int check_header(const char *buf, int buf_size)
This structure stores compressed data.
#define AV_CODEC_CAP_DR1
Codec uses get_buffer() for allocating buffers and supports custom allocators.