1 /*
2 * DPX (.dpx) image decoder
3 * Copyright (c) 2009 Jimmy Christensen
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 #include "libavutil/avstring.h"
23 #include "libavutil/intreadwrite.h"
24 #include "libavutil/intfloat.h"
25 #include "libavutil/imgutils.h"
26 #include "bytestream.h"
27 #include "avcodec.h"
28 #include "internal.h"
29
read16(const uint8_t ** ptr,int is_big)30 static unsigned int read16(const uint8_t **ptr, int is_big)
31 {
32 unsigned int temp;
33 if (is_big) {
34 temp = AV_RB16(*ptr);
35 } else {
36 temp = AV_RL16(*ptr);
37 }
38 *ptr += 2;
39 return temp;
40 }
41
read32(const uint8_t ** ptr,int is_big)42 static unsigned int read32(const uint8_t **ptr, int is_big)
43 {
44 unsigned int temp;
45 if (is_big) {
46 temp = AV_RB32(*ptr);
47 } else {
48 temp = AV_RL32(*ptr);
49 }
50 *ptr += 4;
51 return temp;
52 }
53
read10in32_gray(const uint8_t ** ptr,uint32_t * lbuf,int * n_datum,int is_big,int shift)54 static uint16_t read10in32_gray(const uint8_t **ptr, uint32_t *lbuf,
55 int *n_datum, int is_big, int shift)
56 {
57 uint16_t temp;
58
59 if (*n_datum)
60 (*n_datum)--;
61 else {
62 *lbuf = read32(ptr, is_big);
63 *n_datum = 2;
64 }
65
66 temp = *lbuf >> shift & 0x3FF;
67 *lbuf = *lbuf >> 10;
68
69 return temp;
70 }
71
read10in32(const uint8_t ** ptr,uint32_t * lbuf,int * n_datum,int is_big,int shift)72 static uint16_t read10in32(const uint8_t **ptr, uint32_t *lbuf,
73 int *n_datum, int is_big, int shift)
74 {
75 if (*n_datum)
76 (*n_datum)--;
77 else {
78 *lbuf = read32(ptr, is_big);
79 *n_datum = 2;
80 }
81
82 *lbuf = *lbuf << 10 | *lbuf >> shift & 0x3FFFFF;
83
84 return *lbuf & 0x3FF;
85 }
86
read12in32(const uint8_t ** ptr,uint32_t * lbuf,int * n_datum,int is_big)87 static uint16_t read12in32(const uint8_t **ptr, uint32_t *lbuf,
88 int *n_datum, int is_big)
89 {
90 if (*n_datum)
91 (*n_datum)--;
92 else {
93 *lbuf = read32(ptr, is_big);
94 *n_datum = 7;
95 }
96
97 switch (*n_datum){
98 case 7: return *lbuf & 0xFFF;
99 case 6: return (*lbuf >> 12) & 0xFFF;
100 case 5: {
101 uint32_t c = *lbuf >> 24;
102 *lbuf = read32(ptr, is_big);
103 c |= *lbuf << 8;
104 return c & 0xFFF;
105 }
106 case 4: return (*lbuf >> 4) & 0xFFF;
107 case 3: return (*lbuf >> 16) & 0xFFF;
108 case 2: {
109 uint32_t c = *lbuf >> 28;
110 *lbuf = read32(ptr, is_big);
111 c |= *lbuf << 4;
112 return c & 0xFFF;
113 }
114 case 1: return (*lbuf >> 8) & 0xFFF;
115 default: return *lbuf >> 20;
116 }
117 }
118
decode_frame(AVCodecContext * avctx,void * data,int * got_frame,AVPacket * avpkt)119 static int decode_frame(AVCodecContext *avctx,
120 void *data,
121 int *got_frame,
122 AVPacket *avpkt)
123 {
124 const uint8_t *buf = avpkt->data;
125 int buf_size = avpkt->size;
126 AVFrame *const p = data;
127 uint8_t *ptr[AV_NUM_DATA_POINTERS];
128 uint32_t header_version, version = 0;
129 char creator[101];
130 char input_device[33];
131
132 unsigned int offset;
133 int magic_num, endian;
134 int x, y, stride, i, ret;
135 int w, h, bits_per_color, descriptor, elements, packing;
136 int encoding, need_align = 0;
137
138 unsigned int rgbBuffer = 0;
139 int n_datum = 0;
140
141 if (avpkt->size <= 1634) {
142 av_log(avctx, AV_LOG_ERROR, "Packet too small for DPX header\n");
143 return AVERROR_INVALIDDATA;
144 }
145
146 magic_num = AV_RB32(buf);
147 buf += 4;
148
149 /* Check if the files "magic number" is "SDPX" which means it uses
150 * big-endian or XPDS which is for little-endian files */
151 if (magic_num == AV_RL32("SDPX")) {
152 endian = 0;
153 } else if (magic_num == AV_RB32("SDPX")) {
154 endian = 1;
155 } else {
156 av_log(avctx, AV_LOG_ERROR, "DPX marker not found\n");
157 return AVERROR_INVALIDDATA;
158 }
159
160 offset = read32(&buf, endian);
161 if (avpkt->size <= offset) {
162 av_log(avctx, AV_LOG_ERROR, "Invalid data start offset\n");
163 return AVERROR_INVALIDDATA;
164 }
165
166 header_version = read32(&buf, 0);
167 if (header_version == MKTAG('V','1','.','0'))
168 version = 1;
169 if (header_version == MKTAG('V','2','.','0'))
170 version = 2;
171 if (!version)
172 av_log(avctx, AV_LOG_WARNING, "Unknown header format version %s.\n",
173 av_fourcc2str(header_version));
174
175 // Check encryption
176 buf = avpkt->data + 660;
177 ret = read32(&buf, endian);
178 if (ret != 0xFFFFFFFF) {
179 avpriv_report_missing_feature(avctx, "Encryption");
180 av_log(avctx, AV_LOG_WARNING, "The image is encrypted and may "
181 "not properly decode.\n");
182 }
183
184 // Need to end in 0x304 offset from start of file
185 buf = avpkt->data + 0x304;
186 w = read32(&buf, endian);
187 h = read32(&buf, endian);
188
189 if ((ret = ff_set_dimensions(avctx, w, h)) < 0)
190 return ret;
191
192 // Need to end in 0x320 to read the descriptor
193 buf += 20;
194 descriptor = buf[0];
195
196 // Need to end in 0x323 to read the bits per color
197 buf += 3;
198 avctx->bits_per_raw_sample =
199 bits_per_color = buf[0];
200 buf++;
201 packing = read16(&buf, endian);
202 encoding = read16(&buf, endian);
203
204 if (encoding) {
205 avpriv_report_missing_feature(avctx, "Encoding %d", encoding);
206 return AVERROR_PATCHWELCOME;
207 }
208
209 buf += 820;
210 avctx->sample_aspect_ratio.num = read32(&buf, endian);
211 avctx->sample_aspect_ratio.den = read32(&buf, endian);
212 if (avctx->sample_aspect_ratio.num > 0 && avctx->sample_aspect_ratio.den > 0)
213 av_reduce(&avctx->sample_aspect_ratio.num, &avctx->sample_aspect_ratio.den,
214 avctx->sample_aspect_ratio.num, avctx->sample_aspect_ratio.den,
215 0x10000);
216 else
217 avctx->sample_aspect_ratio = (AVRational){ 0, 1 };
218
219 if (offset >= 1724 + 4) {
220 buf = avpkt->data + 1724;
221 i = read32(&buf, endian);
222 if(i) {
223 AVRational q = av_d2q(av_int2float(i), 4096);
224 if (q.num > 0 && q.den > 0)
225 avctx->framerate = q;
226 }
227 }
228
229 switch (descriptor) {
230 case 6: // Y
231 elements = 1;
232 break;
233 case 52: // ABGR
234 case 51: // RGBA
235 case 103: // UYVA4444
236 elements = 4;
237 break;
238 case 50: // RGB
239 case 102: // UYV444
240 elements = 3;
241 break;
242 case 100: // UYVY422
243 elements = 2;
244 break;
245 default:
246 avpriv_report_missing_feature(avctx, "Descriptor %d", descriptor);
247 return AVERROR_PATCHWELCOME;
248 }
249
250 switch (bits_per_color) {
251 case 8:
252 stride = avctx->width * elements;
253 break;
254 case 10:
255 if (!packing) {
256 av_log(avctx, AV_LOG_ERROR, "Packing to 32bit required\n");
257 return -1;
258 }
259 stride = (avctx->width * elements + 2) / 3 * 4;
260 break;
261 case 12:
262 stride = avctx->width * elements;
263 if (packing) {
264 stride *= 2;
265 } else {
266 stride *= 3;
267 if (stride % 8) {
268 stride /= 8;
269 stride++;
270 stride *= 8;
271 }
272 stride /= 2;
273 }
274 break;
275 case 16:
276 stride = 2 * avctx->width * elements;
277 break;
278 case 1:
279 case 32:
280 case 64:
281 avpriv_report_missing_feature(avctx, "Depth %d", bits_per_color);
282 return AVERROR_PATCHWELCOME;
283 default:
284 return AVERROR_INVALIDDATA;
285 }
286
287 // Table 3c: Runs will always break at scan line boundaries. Packing
288 // will always break to the next 32-bit word at scan-line boundaries.
289 // Unfortunately, the encoder produced invalid files, so attempt
290 // to detect it
291 need_align = FFALIGN(stride, 4);
292 if (need_align*avctx->height + (int64_t)offset > avpkt->size) {
293 // Alignment seems unappliable, try without
294 if (stride*avctx->height + (int64_t)offset > avpkt->size) {
295 av_log(avctx, AV_LOG_ERROR, "Overread buffer. Invalid header?\n");
296 return AVERROR_INVALIDDATA;
297 } else {
298 av_log(avctx, AV_LOG_INFO, "Decoding DPX without scanline "
299 "alignment.\n");
300 need_align = 0;
301 }
302 } else {
303 need_align -= stride;
304 stride = FFALIGN(stride, 4);
305 }
306
307 switch (1000 * descriptor + 10 * bits_per_color + endian) {
308 case 6081:
309 case 6080:
310 avctx->pix_fmt = AV_PIX_FMT_GRAY8;
311 break;
312 case 6121:
313 case 6120:
314 avctx->pix_fmt = AV_PIX_FMT_GRAY12;
315 break;
316 case 50081:
317 case 50080:
318 avctx->pix_fmt = AV_PIX_FMT_RGB24;
319 break;
320 case 52081:
321 case 52080:
322 avctx->pix_fmt = AV_PIX_FMT_ABGR;
323 break;
324 case 51081:
325 case 51080:
326 avctx->pix_fmt = AV_PIX_FMT_RGBA;
327 break;
328 case 50100:
329 case 50101:
330 avctx->pix_fmt = AV_PIX_FMT_GBRP10;
331 break;
332 case 51100:
333 case 51101:
334 avctx->pix_fmt = AV_PIX_FMT_GBRAP10;
335 break;
336 case 50120:
337 case 50121:
338 avctx->pix_fmt = AV_PIX_FMT_GBRP12;
339 break;
340 case 51120:
341 case 51121:
342 avctx->pix_fmt = AV_PIX_FMT_GBRAP12;
343 break;
344 case 6100:
345 case 6101:
346 avctx->pix_fmt = AV_PIX_FMT_GRAY10;
347 break;
348 case 6161:
349 avctx->pix_fmt = AV_PIX_FMT_GRAY16BE;
350 break;
351 case 6160:
352 avctx->pix_fmt = AV_PIX_FMT_GRAY16LE;
353 break;
354 case 50161:
355 avctx->pix_fmt = AV_PIX_FMT_RGB48BE;
356 break;
357 case 50160:
358 avctx->pix_fmt = AV_PIX_FMT_RGB48LE;
359 break;
360 case 51161:
361 avctx->pix_fmt = AV_PIX_FMT_RGBA64BE;
362 break;
363 case 51160:
364 avctx->pix_fmt = AV_PIX_FMT_RGBA64LE;
365 break;
366 case 100081:
367 avctx->pix_fmt = AV_PIX_FMT_UYVY422;
368 break;
369 case 102081:
370 avctx->pix_fmt = AV_PIX_FMT_YUV444P;
371 break;
372 case 103081:
373 avctx->pix_fmt = AV_PIX_FMT_YUVA444P;
374 break;
375 default:
376 av_log(avctx, AV_LOG_ERROR, "Unsupported format\n");
377 return AVERROR_PATCHWELCOME;
378 }
379
380 ff_set_sar(avctx, avctx->sample_aspect_ratio);
381
382 if ((ret = ff_get_buffer(avctx, p, 0)) < 0)
383 return ret;
384
385 av_strlcpy(creator, avpkt->data + 160, 100);
386 creator[100] = '\0';
387 av_dict_set(&p->metadata, "Creator", creator, 0);
388
389 av_strlcpy(input_device, avpkt->data + 1556, 32);
390 input_device[32] = '\0';
391 av_dict_set(&p->metadata, "Input Device", input_device, 0);
392
393 // Move pointer to offset from start of file
394 buf = avpkt->data + offset;
395
396 for (i=0; i<AV_NUM_DATA_POINTERS; i++)
397 ptr[i] = p->data[i];
398
399 switch (bits_per_color) {
400 case 10:
401 for (x = 0; x < avctx->height; x++) {
402 uint16_t *dst[4] = {(uint16_t*)ptr[0],
403 (uint16_t*)ptr[1],
404 (uint16_t*)ptr[2],
405 (uint16_t*)ptr[3]};
406 int shift = elements > 1 ? packing == 1 ? 22 : 20 : packing == 1 ? 2 : 0;
407 for (y = 0; y < avctx->width; y++) {
408 if (elements >= 3)
409 *dst[2]++ = read10in32(&buf, &rgbBuffer,
410 &n_datum, endian, shift);
411 if (elements == 1)
412 *dst[0]++ = read10in32_gray(&buf, &rgbBuffer,
413 &n_datum, endian, shift);
414 else
415 *dst[0]++ = read10in32(&buf, &rgbBuffer,
416 &n_datum, endian, shift);
417 if (elements >= 2)
418 *dst[1]++ = read10in32(&buf, &rgbBuffer,
419 &n_datum, endian, shift);
420 if (elements == 4)
421 *dst[3]++ =
422 read10in32(&buf, &rgbBuffer,
423 &n_datum, endian, shift);
424 }
425 if (memcmp(input_device, "Scanity", 7))
426 n_datum = 0;
427 for (i = 0; i < elements; i++)
428 ptr[i] += p->linesize[i];
429 }
430 break;
431 case 12:
432 for (x = 0; x < avctx->height; x++) {
433 uint16_t *dst[4] = {(uint16_t*)ptr[0],
434 (uint16_t*)ptr[1],
435 (uint16_t*)ptr[2],
436 (uint16_t*)ptr[3]};
437 int shift = packing == 1 ? 4 : 0;
438 for (y = 0; y < avctx->width; y++) {
439 if (packing) {
440 if (elements >= 3)
441 *dst[2]++ = read16(&buf, endian) >> shift & 0xFFF;
442 *dst[0]++ = read16(&buf, endian) >> shift & 0xFFF;
443 if (elements >= 2)
444 *dst[1]++ = read16(&buf, endian) >> shift & 0xFFF;
445 if (elements == 4)
446 *dst[3]++ = read16(&buf, endian) >> shift & 0xFFF;
447 } else {
448 if (elements >= 3)
449 *dst[2]++ = read12in32(&buf, &rgbBuffer,
450 &n_datum, endian);
451 *dst[0]++ = read12in32(&buf, &rgbBuffer,
452 &n_datum, endian);
453 if (elements >= 2)
454 *dst[1]++ = read12in32(&buf, &rgbBuffer,
455 &n_datum, endian);
456 if (elements == 4)
457 *dst[3]++ = read12in32(&buf, &rgbBuffer,
458 &n_datum, endian);
459 }
460 }
461 n_datum = 0;
462 for (i = 0; i < elements; i++)
463 ptr[i] += p->linesize[i];
464 // Jump to next aligned position
465 buf += need_align;
466 }
467 break;
468 case 16:
469 elements *= 2;
470 case 8:
471 if ( avctx->pix_fmt == AV_PIX_FMT_YUVA444P
472 || avctx->pix_fmt == AV_PIX_FMT_YUV444P) {
473 for (x = 0; x < avctx->height; x++) {
474 ptr[0] = p->data[0] + x * p->linesize[0];
475 ptr[1] = p->data[1] + x * p->linesize[1];
476 ptr[2] = p->data[2] + x * p->linesize[2];
477 ptr[3] = p->data[3] + x * p->linesize[3];
478 for (y = 0; y < avctx->width; y++) {
479 *ptr[1]++ = *buf++;
480 *ptr[0]++ = *buf++;
481 *ptr[2]++ = *buf++;
482 if (avctx->pix_fmt == AV_PIX_FMT_YUVA444P)
483 *ptr[3]++ = *buf++;
484 }
485 }
486 } else {
487 av_image_copy_plane(ptr[0], p->linesize[0],
488 buf, stride,
489 elements * avctx->width, avctx->height);
490 }
491 break;
492 }
493
494 *got_frame = 1;
495
496 return buf_size;
497 }
498
499 AVCodec ff_dpx_decoder = {
500 .name = "dpx",
501 .long_name = NULL_IF_CONFIG_SMALL("DPX (Digital Picture Exchange) image"),
502 .type = AVMEDIA_TYPE_VIDEO,
503 .id = AV_CODEC_ID_DPX,
504 .decode = decode_frame,
505 .capabilities = AV_CODEC_CAP_DR1,
506 };
507