FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavcodec/dpx.c
Date: 2025-09-01 20:07:09
Exec Total Coverage
Lines: 239 469 51.0%
Functions: 4 6 66.7%
Branches: 108 248 43.5%

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