xref: /third_party/ffmpeg/libavcodec/dpx.c (revision cabdff1a)
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 "libavutil/timecode.h"
27#include "bytestream.h"
28#include "avcodec.h"
29#include "codec_internal.h"
30#include "internal.h"
31
32enum DPX_TRC {
33    DPX_TRC_USER_DEFINED       = 0,
34    DPX_TRC_PRINTING_DENSITY   = 1,
35    DPX_TRC_LINEAR             = 2,
36    DPX_TRC_LOGARITHMIC        = 3,
37    DPX_TRC_UNSPECIFIED_VIDEO  = 4,
38    DPX_TRC_SMPTE_274          = 5,
39    DPX_TRC_ITU_R_709_4        = 6,
40    DPX_TRC_ITU_R_601_625      = 7,
41    DPX_TRC_ITU_R_601_525      = 8,
42    DPX_TRC_SMPTE_170          = 9,
43    DPX_TRC_ITU_R_624_4_PAL    = 10,
44    DPX_TRC_Z_LINEAR           = 11,
45    DPX_TRC_Z_HOMOGENEOUS      = 12,
46};
47
48enum DPX_COL_SPEC {
49    DPX_COL_SPEC_USER_DEFINED       = 0,
50    DPX_COL_SPEC_PRINTING_DENSITY   = 1,
51    /* 2 = N/A */
52    /* 3 = N/A */
53    DPX_COL_SPEC_UNSPECIFIED_VIDEO  = 4,
54    DPX_COL_SPEC_SMPTE_274          = 5,
55    DPX_COL_SPEC_ITU_R_709_4        = 6,
56    DPX_COL_SPEC_ITU_R_601_625      = 7,
57    DPX_COL_SPEC_ITU_R_601_525      = 8,
58    DPX_COL_SPEC_SMPTE_170          = 9,
59    DPX_COL_SPEC_ITU_R_624_4_PAL    = 10,
60    /* 11 = N/A */
61    /* 12 = N/A */
62};
63
64static unsigned int read16(const uint8_t **ptr, int is_big)
65{
66    unsigned int temp;
67    if (is_big) {
68        temp = AV_RB16(*ptr);
69    } else {
70        temp = AV_RL16(*ptr);
71    }
72    *ptr += 2;
73    return temp;
74}
75
76static unsigned int read32(const uint8_t **ptr, int is_big)
77{
78    unsigned int temp;
79    if (is_big) {
80        temp = AV_RB32(*ptr);
81    } else {
82        temp = AV_RL32(*ptr);
83    }
84    *ptr += 4;
85    return temp;
86}
87
88static uint16_t read10in32_gray(const uint8_t **ptr, uint32_t *lbuf,
89                                int *n_datum, int is_big, int shift)
90{
91    uint16_t temp;
92
93    if (*n_datum)
94        (*n_datum)--;
95    else {
96        *lbuf = read32(ptr, is_big);
97        *n_datum = 2;
98    }
99
100    temp = *lbuf >> shift & 0x3FF;
101    *lbuf = *lbuf >> 10;
102
103    return temp;
104}
105
106static uint16_t read10in32(const uint8_t **ptr, uint32_t *lbuf,
107                           int *n_datum, int is_big, int shift)
108{
109    if (*n_datum)
110        (*n_datum)--;
111    else {
112        *lbuf = read32(ptr, is_big);
113        *n_datum = 2;
114    }
115
116    *lbuf = *lbuf << 10 | *lbuf >> shift & 0x3FFFFF;
117
118    return *lbuf & 0x3FF;
119}
120
121static uint16_t read12in32(const uint8_t **ptr, uint32_t *lbuf,
122                           int *n_datum, int is_big)
123{
124    if (*n_datum)
125        (*n_datum)--;
126    else {
127        *lbuf = read32(ptr, is_big);
128        *n_datum = 7;
129    }
130
131    switch (*n_datum){
132    case 7: return *lbuf & 0xFFF;
133    case 6: return (*lbuf >> 12) & 0xFFF;
134    case 5: {
135            uint32_t c = *lbuf >> 24;
136            *lbuf = read32(ptr, is_big);
137            c |= *lbuf << 8;
138            return c & 0xFFF;
139            }
140    case 4: return (*lbuf >> 4) & 0xFFF;
141    case 3: return (*lbuf >> 16) & 0xFFF;
142    case 2: {
143            uint32_t c = *lbuf >> 28;
144            *lbuf = read32(ptr, is_big);
145            c |= *lbuf << 4;
146            return c & 0xFFF;
147            }
148    case 1: return (*lbuf >> 8) & 0xFFF;
149    default: return *lbuf >> 20;
150    }
151}
152
153static int decode_frame(AVCodecContext *avctx, AVFrame *p,
154                        int *got_frame, AVPacket *avpkt)
155{
156    const uint8_t *buf = avpkt->data;
157    int buf_size       = avpkt->size;
158    uint8_t *ptr[AV_NUM_DATA_POINTERS];
159    uint32_t header_version, version = 0;
160    char creator[101] = { 0 };
161    char input_device[33] = { 0 };
162
163    unsigned int offset;
164    int magic_num, endian;
165    int x, y, stride, i, j, ret;
166    int w, h, bits_per_color, descriptor, elements, packing;
167    int yuv, color_trc, color_spec;
168    int encoding, need_align = 0, unpadded_10bit = 0;
169
170    unsigned int rgbBuffer = 0;
171    int n_datum = 0;
172
173    if (avpkt->size <= 1634) {
174        av_log(avctx, AV_LOG_ERROR, "Packet too small for DPX header\n");
175        return AVERROR_INVALIDDATA;
176    }
177
178    magic_num = AV_RB32(buf);
179    buf += 4;
180
181    /* Check if the files "magic number" is "SDPX" which means it uses
182     * big-endian or XPDS which is for little-endian files */
183    if (magic_num == AV_RL32("SDPX")) {
184        endian = 0;
185    } else if (magic_num == AV_RB32("SDPX")) {
186        endian = 1;
187    } else {
188        av_log(avctx, AV_LOG_ERROR, "DPX marker not found\n");
189        return AVERROR_INVALIDDATA;
190    }
191
192    offset = read32(&buf, endian);
193    if (avpkt->size <= offset) {
194        av_log(avctx, AV_LOG_ERROR, "Invalid data start offset\n");
195        return AVERROR_INVALIDDATA;
196    }
197
198    header_version = read32(&buf, 0);
199    if (header_version == MKTAG('V','1','.','0'))
200        version = 1;
201    if (header_version == MKTAG('V','2','.','0'))
202        version = 2;
203    if (!version)
204        av_log(avctx, AV_LOG_WARNING, "Unknown header format version %s.\n",
205               av_fourcc2str(header_version));
206
207    // Check encryption
208    buf = avpkt->data + 660;
209    ret = read32(&buf, endian);
210    if (ret != 0xFFFFFFFF) {
211        avpriv_report_missing_feature(avctx, "Encryption");
212        av_log(avctx, AV_LOG_WARNING, "The image is encrypted and may "
213               "not properly decode.\n");
214    }
215
216    // Need to end in 0x304 offset from start of file
217    buf = avpkt->data + 0x304;
218    w = read32(&buf, endian);
219    h = read32(&buf, endian);
220
221    if ((ret = ff_set_dimensions(avctx, w, h)) < 0)
222        return ret;
223
224    // Need to end in 0x320 to read the descriptor
225    buf += 20;
226    descriptor = buf[0];
227    color_trc = buf[1];
228    color_spec = buf[2];
229
230    // Need to end in 0x323 to read the bits per color
231    buf += 3;
232    avctx->bits_per_raw_sample =
233    bits_per_color = buf[0];
234    buf++;
235    packing = read16(&buf, endian);
236    encoding = read16(&buf, endian);
237
238    if (encoding) {
239        avpriv_report_missing_feature(avctx, "Encoding %d", encoding);
240        return AVERROR_PATCHWELCOME;
241    }
242
243    if (bits_per_color > 31)
244        return AVERROR_INVALIDDATA;
245
246    buf += 820;
247    avctx->sample_aspect_ratio.num = read32(&buf, endian);
248    avctx->sample_aspect_ratio.den = read32(&buf, endian);
249    if (avctx->sample_aspect_ratio.num > 0 && avctx->sample_aspect_ratio.den > 0)
250        av_reduce(&avctx->sample_aspect_ratio.num, &avctx->sample_aspect_ratio.den,
251                   avctx->sample_aspect_ratio.num,  avctx->sample_aspect_ratio.den,
252                  0x10000);
253    else
254        avctx->sample_aspect_ratio = (AVRational){ 0, 1 };
255
256    /* preferred frame rate from Motion-picture film header */
257    if (offset >= 1724 + 4) {
258        buf = avpkt->data + 1724;
259        i = read32(&buf, endian);
260        if(i && i != 0xFFFFFFFF) {
261            AVRational q = av_d2q(av_int2float(i), 4096);
262            if (q.num > 0 && q.den > 0)
263                avctx->framerate = q;
264        }
265    }
266
267    /* alternative frame rate from television header */
268    if (offset >= 1940 + 4 &&
269        !(avctx->framerate.num && avctx->framerate.den)) {
270        buf = avpkt->data + 1940;
271        i = read32(&buf, endian);
272        if(i && i != 0xFFFFFFFF) {
273            AVRational q = av_d2q(av_int2float(i), 4096);
274            if (q.num > 0 && q.den > 0)
275                avctx->framerate = q;
276        }
277    }
278
279    /* SMPTE TC from television header */
280    if (offset >= 1920 + 4) {
281        uint32_t tc;
282        uint32_t *tc_sd;
283        char tcbuf[AV_TIMECODE_STR_SIZE];
284
285        buf = avpkt->data + 1920;
286        // read32 to native endian, av_bswap32 to opposite of native for
287        // compatibility with av_timecode_make_smpte_tc_string2 etc
288        tc = av_bswap32(read32(&buf, endian));
289
290        if (i != 0xFFFFFFFF) {
291            AVFrameSideData *tcside =
292                av_frame_new_side_data(p, AV_FRAME_DATA_S12M_TIMECODE,
293                                       sizeof(uint32_t) * 4);
294            if (!tcside)
295                return AVERROR(ENOMEM);
296
297            tc_sd = (uint32_t*)tcside->data;
298            tc_sd[0] = 1;
299            tc_sd[1] = tc;
300
301            av_timecode_make_smpte_tc_string2(tcbuf, avctx->framerate,
302                                              tc_sd[1], 0, 0);
303            av_dict_set(&p->metadata, "timecode", tcbuf, 0);
304        }
305    }
306
307    /* color range from television header */
308    if (offset >= 1964 + 4) {
309        buf = avpkt->data + 1952;
310        i = read32(&buf, endian);
311
312        buf = avpkt->data + 1964;
313        j = read32(&buf, endian);
314
315        if (i != 0xFFFFFFFF && j != 0xFFFFFFFF) {
316            float minCV, maxCV;
317            minCV = av_int2float(i);
318            maxCV = av_int2float(j);
319            if (bits_per_color >= 1 &&
320                minCV == 0.0f && maxCV == ((1U<<bits_per_color) - 1)) {
321                avctx->color_range = AVCOL_RANGE_JPEG;
322            } else if (bits_per_color >= 8 &&
323                       minCV == (1  <<(bits_per_color - 4)) &&
324                       maxCV == (235<<(bits_per_color - 8))) {
325                avctx->color_range = AVCOL_RANGE_MPEG;
326            }
327        }
328    }
329
330    switch (descriptor) {
331    case 1:  // R
332    case 2:  // G
333    case 3:  // B
334    case 4:  // A
335    case 6:  // Y
336        elements = 1;
337        yuv = 1;
338        break;
339    case 50: // RGB
340        elements = 3;
341        yuv = 0;
342        break;
343    case 52: // ABGR
344    case 51: // RGBA
345        elements = 4;
346        yuv = 0;
347        break;
348    case 100: // UYVY422
349        elements = 2;
350        yuv = 1;
351        break;
352    case 102: // UYV444
353        elements = 3;
354        yuv = 1;
355        break;
356    case 103: // UYVA4444
357        elements = 4;
358        yuv = 1;
359        break;
360    default:
361        avpriv_report_missing_feature(avctx, "Descriptor %d", descriptor);
362        return AVERROR_PATCHWELCOME;
363    }
364
365    switch (bits_per_color) {
366    case 8:
367        stride = avctx->width * elements;
368        break;
369    case 10:
370        if (!packing) {
371            av_log(avctx, AV_LOG_ERROR, "Packing to 32bit required\n");
372            return -1;
373        }
374        stride = (avctx->width * elements + 2) / 3 * 4;
375        break;
376    case 12:
377        stride = avctx->width * elements;
378        if (packing) {
379            stride *= 2;
380        } else {
381            stride *= 3;
382            if (stride % 8) {
383                stride /= 8;
384                stride++;
385                stride *= 8;
386            }
387            stride /= 2;
388        }
389        break;
390    case 16:
391        stride = 2 * avctx->width * elements;
392        break;
393    case 32:
394        stride = 4 * avctx->width * elements;
395        break;
396    case 1:
397    case 64:
398        avpriv_report_missing_feature(avctx, "Depth %d", bits_per_color);
399        return AVERROR_PATCHWELCOME;
400    default:
401        return AVERROR_INVALIDDATA;
402    }
403
404    switch (color_trc) {
405    case DPX_TRC_LINEAR:
406        avctx->color_trc = AVCOL_TRC_LINEAR;
407        break;
408    case DPX_TRC_SMPTE_274:
409    case DPX_TRC_ITU_R_709_4:
410        avctx->color_trc = AVCOL_TRC_BT709;
411        break;
412    case DPX_TRC_ITU_R_601_625:
413    case DPX_TRC_ITU_R_601_525:
414    case DPX_TRC_SMPTE_170:
415        avctx->color_trc = AVCOL_TRC_SMPTE170M;
416        break;
417    case DPX_TRC_ITU_R_624_4_PAL:
418        avctx->color_trc = AVCOL_TRC_GAMMA28;
419        break;
420    case DPX_TRC_USER_DEFINED:
421    case DPX_TRC_UNSPECIFIED_VIDEO:
422        /* Nothing to do */
423        break;
424    default:
425        av_log(avctx, AV_LOG_VERBOSE, "Cannot map DPX transfer characteristic "
426            "%d to color_trc.\n", color_trc);
427        break;
428    }
429
430    switch (color_spec) {
431    case DPX_COL_SPEC_SMPTE_274:
432    case DPX_COL_SPEC_ITU_R_709_4:
433        avctx->color_primaries = AVCOL_PRI_BT709;
434        break;
435    case DPX_COL_SPEC_ITU_R_601_625:
436    case DPX_COL_SPEC_ITU_R_624_4_PAL:
437        avctx->color_primaries = AVCOL_PRI_BT470BG;
438        break;
439    case DPX_COL_SPEC_ITU_R_601_525:
440    case DPX_COL_SPEC_SMPTE_170:
441        avctx->color_primaries = AVCOL_PRI_SMPTE170M;
442        break;
443    case DPX_COL_SPEC_USER_DEFINED:
444    case DPX_COL_SPEC_UNSPECIFIED_VIDEO:
445        /* Nothing to do */
446        break;
447    default:
448        av_log(avctx, AV_LOG_VERBOSE, "Cannot map DPX color specification "
449            "%d to color_primaries.\n", color_spec);
450        break;
451    }
452
453    if (yuv) {
454        switch (color_spec) {
455        case DPX_COL_SPEC_SMPTE_274:
456        case DPX_COL_SPEC_ITU_R_709_4:
457            avctx->colorspace = AVCOL_SPC_BT709;
458            break;
459        case DPX_COL_SPEC_ITU_R_601_625:
460        case DPX_COL_SPEC_ITU_R_624_4_PAL:
461            avctx->colorspace = AVCOL_SPC_BT470BG;
462            break;
463        case DPX_COL_SPEC_ITU_R_601_525:
464        case DPX_COL_SPEC_SMPTE_170:
465            avctx->colorspace = AVCOL_SPC_SMPTE170M;
466            break;
467        case DPX_COL_SPEC_USER_DEFINED:
468        case DPX_COL_SPEC_UNSPECIFIED_VIDEO:
469            /* Nothing to do */
470            break;
471        default:
472            av_log(avctx, AV_LOG_INFO, "Cannot map DPX color specification "
473                "%d to colorspace.\n", color_spec);
474            break;
475        }
476    } else {
477        avctx->colorspace = AVCOL_SPC_RGB;
478    }
479
480    // Table 3c: Runs will always break at scan line boundaries. Packing
481    // will always break to the next 32-bit word at scan-line boundaries.
482    // Unfortunately, the encoder produced invalid files, so attempt
483    // to detect it
484    need_align = FFALIGN(stride, 4);
485    if (need_align*avctx->height + (int64_t)offset > avpkt->size) {
486        // Alignment seems unappliable, try without
487        if (stride*avctx->height + (int64_t)offset > avpkt->size) {
488            av_log(avctx, AV_LOG_ERROR, "Overread buffer. Invalid header?\n");
489            return AVERROR_INVALIDDATA;
490        } else {
491            av_log(avctx, AV_LOG_INFO, "Decoding DPX without scanline "
492                   "alignment.\n");
493            need_align = 0;
494        }
495    } else {
496        need_align -= stride;
497        stride = FFALIGN(stride, 4);
498    }
499
500    switch (1000 * descriptor + 10 * bits_per_color + endian) {
501    case 1081:
502    case 1080:
503    case 2081:
504    case 2080:
505    case 3081:
506    case 3080:
507    case 4081:
508    case 4080:
509    case 6081:
510    case 6080:
511        avctx->pix_fmt = AV_PIX_FMT_GRAY8;
512        break;
513    case 6121:
514    case 6120:
515        avctx->pix_fmt = AV_PIX_FMT_GRAY12;
516        break;
517    case 1320:
518    case 2320:
519    case 3320:
520    case 4320:
521    case 6320:
522        avctx->pix_fmt = AV_PIX_FMT_GRAYF32LE;
523        break;
524    case 1321:
525    case 2321:
526    case 3321:
527    case 4321:
528    case 6321:
529        avctx->pix_fmt = AV_PIX_FMT_GRAYF32BE;
530        break;
531    case 50081:
532    case 50080:
533        avctx->pix_fmt = AV_PIX_FMT_RGB24;
534        break;
535    case 52081:
536    case 52080:
537        avctx->pix_fmt = AV_PIX_FMT_ABGR;
538        break;
539    case 51081:
540    case 51080:
541        avctx->pix_fmt = AV_PIX_FMT_RGBA;
542        break;
543    case 50100:
544    case 50101:
545        avctx->pix_fmt = AV_PIX_FMT_GBRP10;
546        break;
547    case 51100:
548    case 51101:
549        avctx->pix_fmt = AV_PIX_FMT_GBRAP10;
550        break;
551    case 50120:
552    case 50121:
553        avctx->pix_fmt = AV_PIX_FMT_GBRP12;
554        break;
555    case 51120:
556    case 51121:
557        avctx->pix_fmt = AV_PIX_FMT_GBRAP12;
558        break;
559    case 6100:
560    case 6101:
561        avctx->pix_fmt = AV_PIX_FMT_GRAY10;
562        break;
563    case 6161:
564        avctx->pix_fmt = AV_PIX_FMT_GRAY16BE;
565        break;
566    case 6160:
567        avctx->pix_fmt = AV_PIX_FMT_GRAY16LE;
568        break;
569    case 50161:
570        avctx->pix_fmt = AV_PIX_FMT_RGB48BE;
571        break;
572    case 50160:
573        avctx->pix_fmt = AV_PIX_FMT_RGB48LE;
574        break;
575    case 51161:
576        avctx->pix_fmt = AV_PIX_FMT_RGBA64BE;
577        break;
578    case 51160:
579        avctx->pix_fmt = AV_PIX_FMT_RGBA64LE;
580        break;
581    case 50320:
582        avctx->pix_fmt = AV_PIX_FMT_GBRPF32LE;
583        break;
584    case 50321:
585        avctx->pix_fmt = AV_PIX_FMT_GBRPF32BE;
586        break;
587    case 51320:
588        avctx->pix_fmt = AV_PIX_FMT_GBRAPF32LE;
589        break;
590    case 51321:
591        avctx->pix_fmt = AV_PIX_FMT_GBRAPF32BE;
592        break;
593    case 100081:
594        avctx->pix_fmt = AV_PIX_FMT_UYVY422;
595        break;
596    case 102081:
597        avctx->pix_fmt = AV_PIX_FMT_YUV444P;
598        break;
599    case 103081:
600        avctx->pix_fmt = AV_PIX_FMT_YUVA444P;
601        break;
602    default:
603        av_log(avctx, AV_LOG_ERROR, "Unsupported format %d\n",
604               1000 * descriptor + 10 * bits_per_color + endian);
605        return AVERROR_PATCHWELCOME;
606    }
607
608    ff_set_sar(avctx, avctx->sample_aspect_ratio);
609
610    if ((ret = ff_get_buffer(avctx, p, 0)) < 0)
611        return ret;
612
613    av_strlcpy(creator, avpkt->data + 160, 100);
614    creator[100] = '\0';
615    av_dict_set(&p->metadata, "Creator", creator, 0);
616
617    av_strlcpy(input_device, avpkt->data + 1556, 32);
618    input_device[32] = '\0';
619    av_dict_set(&p->metadata, "Input Device", input_device, 0);
620
621    // Some devices do not pad 10bit samples to whole 32bit words per row
622    if (!memcmp(input_device, "Scanity", 7) ||
623        !memcmp(creator, "Lasergraphics Inc.", 18)) {
624        unpadded_10bit = 1;
625    }
626
627    // Move pointer to offset from start of file
628    buf =  avpkt->data + offset;
629
630    for (i=0; i<AV_NUM_DATA_POINTERS; i++)
631        ptr[i] = p->data[i];
632
633    switch (bits_per_color) {
634    case 10:
635        for (x = 0; x < avctx->height; x++) {
636            uint16_t *dst[4] = {(uint16_t*)ptr[0],
637                                (uint16_t*)ptr[1],
638                                (uint16_t*)ptr[2],
639                                (uint16_t*)ptr[3]};
640            int shift = elements > 1 ? packing == 1 ? 22 : 20 : packing == 1 ? 2 : 0;
641            for (y = 0; y < avctx->width; y++) {
642                if (elements >= 3)
643                    *dst[2]++ = read10in32(&buf, &rgbBuffer,
644                                           &n_datum, endian, shift);
645                if (elements == 1)
646                    *dst[0]++ = read10in32_gray(&buf, &rgbBuffer,
647                                                &n_datum, endian, shift);
648                else
649                    *dst[0]++ = read10in32(&buf, &rgbBuffer,
650                                           &n_datum, endian, shift);
651                if (elements >= 2)
652                    *dst[1]++ = read10in32(&buf, &rgbBuffer,
653                                           &n_datum, endian, shift);
654                if (elements == 4)
655                    *dst[3]++ =
656                    read10in32(&buf, &rgbBuffer,
657                               &n_datum, endian, shift);
658            }
659            if (!unpadded_10bit)
660                n_datum = 0;
661            for (i = 0; i < elements; i++)
662                ptr[i] += p->linesize[i];
663        }
664        break;
665    case 12:
666        for (x = 0; x < avctx->height; x++) {
667            uint16_t *dst[4] = {(uint16_t*)ptr[0],
668                                (uint16_t*)ptr[1],
669                                (uint16_t*)ptr[2],
670                                (uint16_t*)ptr[3]};
671            int shift = packing == 1 ? 4 : 0;
672            for (y = 0; y < avctx->width; y++) {
673                if (packing) {
674                    if (elements >= 3)
675                        *dst[2]++ = read16(&buf, endian) >> shift & 0xFFF;
676                    *dst[0]++ = read16(&buf, endian) >> shift & 0xFFF;
677                    if (elements >= 2)
678                        *dst[1]++ = read16(&buf, endian) >> shift & 0xFFF;
679                    if (elements == 4)
680                        *dst[3]++ = read16(&buf, endian) >> shift & 0xFFF;
681                } else {
682                    if (elements >= 3)
683                        *dst[2]++ = read12in32(&buf, &rgbBuffer,
684                                               &n_datum, endian);
685                    *dst[0]++ = read12in32(&buf, &rgbBuffer,
686                                           &n_datum, endian);
687                    if (elements >= 2)
688                        *dst[1]++ = read12in32(&buf, &rgbBuffer,
689                                               &n_datum, endian);
690                    if (elements == 4)
691                        *dst[3]++ = read12in32(&buf, &rgbBuffer,
692                                               &n_datum, endian);
693                }
694            }
695            n_datum = 0;
696            for (i = 0; i < elements; i++)
697                ptr[i] += p->linesize[i];
698            // Jump to next aligned position
699            buf += need_align;
700        }
701        break;
702    case 32:
703        if (elements == 1) {
704            av_image_copy_plane(ptr[0], p->linesize[0],
705                                buf, stride,
706                                elements * avctx->width * 4, avctx->height);
707        } else {
708            for (y = 0; y < avctx->height; y++) {
709                ptr[0] = p->data[0] + y * p->linesize[0];
710                ptr[1] = p->data[1] + y * p->linesize[1];
711                ptr[2] = p->data[2] + y * p->linesize[2];
712                ptr[3] = p->data[3] + y * p->linesize[3];
713                for (x = 0; x < avctx->width; x++) {
714                    AV_WN32(ptr[2], AV_RN32(buf));
715                    AV_WN32(ptr[0], AV_RN32(buf + 4));
716                    AV_WN32(ptr[1], AV_RN32(buf + 8));
717                    if (avctx->pix_fmt == AV_PIX_FMT_GBRAPF32BE ||
718                        avctx->pix_fmt == AV_PIX_FMT_GBRAPF32LE) {
719                        AV_WN32(ptr[3], AV_RN32(buf + 12));
720                        buf += 4;
721                        ptr[3] += 4;
722                    }
723
724                    buf += 12;
725                    ptr[2] += 4;
726                    ptr[0] += 4;
727                    ptr[1] += 4;
728                }
729            }
730        }
731        break;
732    case 16:
733        elements *= 2;
734    case 8:
735        if (   avctx->pix_fmt == AV_PIX_FMT_YUVA444P
736            || avctx->pix_fmt == AV_PIX_FMT_YUV444P) {
737            for (x = 0; x < avctx->height; x++) {
738                ptr[0] = p->data[0] + x * p->linesize[0];
739                ptr[1] = p->data[1] + x * p->linesize[1];
740                ptr[2] = p->data[2] + x * p->linesize[2];
741                ptr[3] = p->data[3] + x * p->linesize[3];
742                for (y = 0; y < avctx->width; y++) {
743                    *ptr[1]++ = *buf++;
744                    *ptr[0]++ = *buf++;
745                    *ptr[2]++ = *buf++;
746                    if (avctx->pix_fmt == AV_PIX_FMT_YUVA444P)
747                        *ptr[3]++ = *buf++;
748                }
749            }
750        } else {
751        av_image_copy_plane(ptr[0], p->linesize[0],
752                            buf, stride,
753                            elements * avctx->width, avctx->height);
754        }
755        break;
756    }
757
758    *got_frame = 1;
759
760    return buf_size;
761}
762
763const FFCodec ff_dpx_decoder = {
764    .p.name         = "dpx",
765    .p.long_name    = NULL_IF_CONFIG_SMALL("DPX (Digital Picture Exchange) image"),
766    .p.type         = AVMEDIA_TYPE_VIDEO,
767    .p.id           = AV_CODEC_ID_DPX,
768    FF_CODEC_DECODE_CB(decode_frame),
769    .p.capabilities = AV_CODEC_CAP_DR1,
770};
771