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