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