GCC Code Coverage Report
Directory: ../../../ffmpeg/ Exec Total Coverage
File: src/libavcodec/dpx.c Lines: 175 315 55.6 %
Date: 2019-11-18 18:00:01 Branches: 71 154 46.1 %

Line Branch Exec Source
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
4257974
static unsigned int read16(const uint8_t **ptr, int is_big)
31
{
32
    unsigned int temp;
33
4257974
    if (is_big) {
34
4
        temp = AV_RB16(*ptr);
35
    } else {
36
4257970
        temp = AV_RL16(*ptr);
37
    }
38
4257974
    *ptr += 2;
39
4257974
    return temp;
40
}
41
42
2839167
static unsigned int read32(const uint8_t **ptr, int is_big)
43
{
44
    unsigned int temp;
45
2839167
    if (is_big) {
46
14
        temp = AV_RB32(*ptr);
47
    } else {
48
2839153
        temp = AV_RL32(*ptr);
49
    }
50
2839167
    *ptr += 4;
51
2839167
    return temp;
52
}
53
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
72
8515584
static uint16_t read10in32(const uint8_t **ptr, uint32_t *lbuf,
73
                           int *n_datum, int is_big, int shift)
74
{
75
8515584
    if (*n_datum)
76
5677056
        (*n_datum)--;
77
    else {
78
2838528
        *lbuf = read32(ptr, is_big);
79
2838528
        *n_datum = 2;
80
    }
81
82
8515584
    *lbuf = *lbuf << 10 | *lbuf >> shift & 0x3FFFFF;
83
84
8515584
    return *lbuf & 0x3FF;
85
}
86
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
119
91
static int decode_frame(AVCodecContext *avctx,
120
                        void *data,
121
                        int *got_frame,
122
                        AVPacket *avpkt)
123
{
124
91
    const uint8_t *buf = avpkt->data;
125
91
    int buf_size       = avpkt->size;
126
91
    AVFrame *const p = data;
127
    uint8_t *ptr[AV_NUM_DATA_POINTERS];
128
91
    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
91
    int encoding, need_align = 0;
137
138
91
    unsigned int rgbBuffer = 0;
139
91
    int n_datum = 0;
140
141
91
    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
91
    magic_num = AV_RB32(buf);
147
91
    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
91
    if (magic_num == AV_RL32("SDPX")) {
152
89
        endian = 0;
153
2
    } else if (magic_num == AV_RB32("SDPX")) {
154
2
        endian = 1;
155
    } else {
156
        av_log(avctx, AV_LOG_ERROR, "DPX marker not found\n");
157
        return AVERROR_INVALIDDATA;
158
    }
159
160
91
    offset = read32(&buf, endian);
161
91
    if (avpkt->size <= offset) {
162
        av_log(avctx, AV_LOG_ERROR, "Invalid data start offset\n");
163
        return AVERROR_INVALIDDATA;
164
    }
165
166
91
    header_version = read32(&buf, 0);
167
91
    if (header_version == MKTAG('V','1','.','0'))
168
89
        version = 1;
169
91
    if (header_version == MKTAG('V','2','.','0'))
170
2
        version = 2;
171
91
    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
91
    buf = avpkt->data + 660;
177
91
    ret = read32(&buf, endian);
178
91
    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
91
    buf = avpkt->data + 0x304;
186
91
    w = read32(&buf, endian);
187
91
    h = read32(&buf, endian);
188
189
91
    if ((ret = ff_set_dimensions(avctx, w, h)) < 0)
190
        return ret;
191
192
    // Need to end in 0x320 to read the descriptor
193
91
    buf += 20;
194
91
    descriptor = buf[0];
195
196
    // Need to end in 0x323 to read the bits per color
197
91
    buf += 3;
198
91
    avctx->bits_per_raw_sample =
199
91
    bits_per_color = buf[0];
200
91
    buf++;
201
91
    packing = read16(&buf, endian);
202
91
    encoding = read16(&buf, endian);
203
204
91
    if (encoding) {
205
        avpriv_report_missing_feature(avctx, "Encoding %d", encoding);
206
        return AVERROR_PATCHWELCOME;
207
    }
208
209
91
    buf += 820;
210
91
    avctx->sample_aspect_ratio.num = read32(&buf, endian);
211
91
    avctx->sample_aspect_ratio.den = read32(&buf, endian);
212

91
    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
91
        avctx->sample_aspect_ratio = (AVRational){ 0, 1 };
218
219
91
    if (offset >= 1724 + 4) {
220
2
        buf = avpkt->data + 1724;
221
2
        i = read32(&buf, endian);
222
2
        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

91
    switch (descriptor) {
230
    case 6:  // Y
231
        elements = 1;
232
        break;
233
14
    case 52: // ABGR
234
    case 51: // RGBA
235
    case 103: // UYVA4444
236
14
        elements = 4;
237
14
        break;
238
77
    case 50: // RGB
239
    case 102: // UYV444
240
77
        elements = 3;
241
77
        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

91
    switch (bits_per_color) {
251
19
    case 8:
252
19
        stride = avctx->width * elements;
253
19
        break;
254
28
    case 10:
255
28
        if (!packing) {
256
            av_log(avctx, AV_LOG_ERROR, "Packing to 32bit required\n");
257
            return -1;
258
        }
259
28
        stride = (avctx->width * elements + 2) / 3 * 4;
260
28
        break;
261
14
    case 12:
262
14
        stride = avctx->width * elements;
263
14
        if (packing) {
264
14
            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
14
        break;
275
30
    case 16:
276
30
        stride = 2 * avctx->width * elements;
277
30
        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
91
    need_align = FFALIGN(stride, 4);
292
91
    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
91
        need_align -= stride;
304
91
        stride = FFALIGN(stride, 4);
305
    }
306
307





91
    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
19
    case 50081:
317
    case 50080:
318
19
        avctx->pix_fmt = AV_PIX_FMT_RGB24;
319
19
        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
28
    case 50100:
329
    case 50101:
330
28
        avctx->pix_fmt = AV_PIX_FMT_GBRP10;
331
28
        break;
332
    case 51100:
333
    case 51101:
334
        avctx->pix_fmt = AV_PIX_FMT_GBRAP10;
335
        break;
336
14
    case 50120:
337
    case 50121:
338
14
        avctx->pix_fmt = AV_PIX_FMT_GBRP12;
339
14
        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
2
    case 50161:
355
2
        avctx->pix_fmt = AV_PIX_FMT_RGB48BE;
356
2
        break;
357
14
    case 50160:
358
14
        avctx->pix_fmt = AV_PIX_FMT_RGB48LE;
359
14
        break;
360
    case 51161:
361
        avctx->pix_fmt = AV_PIX_FMT_RGBA64BE;
362
        break;
363
14
    case 51160:
364
14
        avctx->pix_fmt = AV_PIX_FMT_RGBA64LE;
365
14
        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
91
    ff_set_sar(avctx, avctx->sample_aspect_ratio);
381
382
91
    if ((ret = ff_get_buffer(avctx, p, 0)) < 0)
383
        return ret;
384
385
91
    av_strlcpy(creator, avpkt->data + 160, 100);
386
91
    creator[100] = '\0';
387
91
    av_dict_set(&p->metadata, "Creator", creator, 0);
388
389
91
    av_strlcpy(input_device, avpkt->data + 1556, 32);
390
91
    input_device[32] = '\0';
391
91
    av_dict_set(&p->metadata, "Input Device", input_device, 0);
392
393
    // Move pointer to offset from start of file
394
91
    buf =  avpkt->data + offset;
395
396
819
    for (i=0; i<AV_NUM_DATA_POINTERS; i++)
397
728
        ptr[i] = p->data[i];
398
399

91
    switch (bits_per_color) {
400
28
    case 10:
401
8092
        for (x = 0; x < avctx->height; x++) {
402
8064
            uint16_t *dst[4] = {(uint16_t*)ptr[0],
403
8064
                                (uint16_t*)ptr[1],
404
8064
                                (uint16_t*)ptr[2],
405
8064
                                (uint16_t*)ptr[3]};
406

8064
            int shift = elements > 1 ? packing == 1 ? 22 : 20 : packing == 1 ? 2 : 0;
407
2846592
            for (y = 0; y < avctx->width; y++) {
408
2838528
                if (elements >= 3)
409
2838528
                    *dst[2]++ = read10in32(&buf, &rgbBuffer,
410
                                           &n_datum, endian, shift);
411
2838528
                if (elements == 1)
412
                    *dst[0]++ = read10in32_gray(&buf, &rgbBuffer,
413
                                                &n_datum, endian, shift);
414
                else
415
2838528
                    *dst[0]++ = read10in32(&buf, &rgbBuffer,
416
                                           &n_datum, endian, shift);
417
2838528
                if (elements >= 2)
418
2838528
                    *dst[1]++ = read10in32(&buf, &rgbBuffer,
419
                                           &n_datum, endian, shift);
420
2838528
                if (elements == 4)
421
                    *dst[3]++ =
422
                    read10in32(&buf, &rgbBuffer,
423
                               &n_datum, endian, shift);
424
            }
425
8064
            if (memcmp(input_device, "Scanity", 7))
426
8064
                n_datum = 0;
427
32256
            for (i = 0; i < elements; i++)
428
24192
                ptr[i] += p->linesize[i];
429
        }
430
28
        break;
431
14
    case 12:
432
4046
        for (x = 0; x < avctx->height; x++) {
433
4032
            uint16_t *dst[4] = {(uint16_t*)ptr[0],
434
4032
                                (uint16_t*)ptr[1],
435
4032
                                (uint16_t*)ptr[2],
436
4032
                                (uint16_t*)ptr[3]};
437
4032
            int shift = packing == 1 ? 4 : 0;
438
1423296
            for (y = 0; y < avctx->width; y++) {
439
1419264
                if (packing) {
440
1419264
                    if (elements >= 3)
441
1419264
                        *dst[2]++ = read16(&buf, endian) >> shift & 0xFFF;
442
1419264
                    *dst[0]++ = read16(&buf, endian) >> shift & 0xFFF;
443
1419264
                    if (elements >= 2)
444
1419264
                        *dst[1]++ = read16(&buf, endian) >> shift & 0xFFF;
445
1419264
                    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
4032
            n_datum = 0;
462
16128
            for (i = 0; i < elements; i++)
463
12096
                ptr[i] += p->linesize[i];
464
            // Jump to next aligned position
465
4032
            buf += need_align;
466
        }
467
14
        break;
468
30
    case 16:
469
30
        elements *= 2;
470
49
    case 8:
471
49
        if (   avctx->pix_fmt == AV_PIX_FMT_YUVA444P
472
49
            || 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
49
        av_image_copy_plane(ptr[0], p->linesize[0],
488
                            buf, stride,
489
49
                            elements * avctx->width, avctx->height);
490
        }
491
49
        break;
492
    }
493
494
91
    *got_frame = 1;
495
496
91
    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
};