|
|
|
@@ -77,9 +77,9 @@ static int decode_frame(AVCodecContext *avctx, |
|
|
|
|
|
|
|
unsigned int offset; |
|
|
|
int magic_num, endian; |
|
|
|
int x, y, i, ret; |
|
|
|
int w, h, bits_per_color, descriptor, elements, packing, total_size; |
|
|
|
int encoding; |
|
|
|
int x, y, stride, i, ret; |
|
|
|
int w, h, bits_per_color, descriptor, elements, packing; |
|
|
|
int encoding, need_align = 0; |
|
|
|
|
|
|
|
unsigned int rgbBuffer = 0; |
|
|
|
int n_datum = 0; |
|
|
|
@@ -185,24 +185,24 @@ static int decode_frame(AVCodecContext *avctx, |
|
|
|
|
|
|
|
switch (bits_per_color) { |
|
|
|
case 8: |
|
|
|
total_size = avctx->width * avctx->height * elements; |
|
|
|
stride = avctx->width * elements; |
|
|
|
break; |
|
|
|
case 10: |
|
|
|
if (!packing) { |
|
|
|
av_log(avctx, AV_LOG_ERROR, "Packing to 32bit required\n"); |
|
|
|
return -1; |
|
|
|
} |
|
|
|
total_size = (avctx->width * elements + 2) / 3 * 4 * avctx->height; |
|
|
|
stride = (avctx->width * elements + 2) / 3 * 4; |
|
|
|
break; |
|
|
|
case 12: |
|
|
|
if (!packing) { |
|
|
|
av_log(avctx, AV_LOG_ERROR, "Packing to 16bit required\n"); |
|
|
|
return -1; |
|
|
|
} |
|
|
|
total_size = 2 * avctx->width * avctx->height * elements; |
|
|
|
stride = 2 * avctx->width * elements; |
|
|
|
break; |
|
|
|
case 16: |
|
|
|
total_size = 2 * avctx->width * avctx->height * elements; |
|
|
|
stride = 2 * avctx->width * elements; |
|
|
|
break; |
|
|
|
case 1: |
|
|
|
case 32: |
|
|
|
@@ -213,6 +213,26 @@ static int decode_frame(AVCodecContext *avctx, |
|
|
|
return AVERROR_INVALIDDATA; |
|
|
|
} |
|
|
|
|
|
|
|
// Table 3c: Runs will always break at scan line boundaries. Packing |
|
|
|
// will always break to the next 32-bit word at scan-line boundaries. |
|
|
|
// Unfortunately, the encoder produced invalid files, so attempt |
|
|
|
// to detect it |
|
|
|
need_align = FFALIGN(stride, 4); |
|
|
|
if (need_align*avctx->height + (int64_t)offset > avpkt->size) { |
|
|
|
// Alignment seems unappliable, try without |
|
|
|
if (stride*avctx->height + (int64_t)offset > avpkt->size) { |
|
|
|
av_log(avctx, AV_LOG_ERROR, "Overread buffer. Invalid header?\n"); |
|
|
|
return AVERROR_INVALIDDATA; |
|
|
|
} else { |
|
|
|
av_log(avctx, AV_LOG_INFO, "Decoding DPX without scanline " |
|
|
|
"alignment.\n"); |
|
|
|
need_align = 0; |
|
|
|
} |
|
|
|
} else { |
|
|
|
need_align -= stride; |
|
|
|
stride = FFALIGN(stride, 4); |
|
|
|
} |
|
|
|
|
|
|
|
switch (1000 * descriptor + 10 * bits_per_color + endian) { |
|
|
|
case 6081: |
|
|
|
case 6080: |
|
|
|
@@ -276,10 +296,6 @@ static int decode_frame(AVCodecContext *avctx, |
|
|
|
for (i=0; i<AV_NUM_DATA_POINTERS; i++) |
|
|
|
ptr[i] = p->data[i]; |
|
|
|
|
|
|
|
if (total_size + (int64_t)offset > avpkt->size) { |
|
|
|
av_log(avctx, AV_LOG_ERROR, "Overread buffer. Invalid header?\n"); |
|
|
|
return AVERROR_INVALIDDATA; |
|
|
|
} |
|
|
|
switch (bits_per_color) { |
|
|
|
case 10: |
|
|
|
for (x = 0; x < avctx->height; x++) { |
|
|
|
@@ -318,6 +334,8 @@ static int decode_frame(AVCodecContext *avctx, |
|
|
|
// For 12 bit, ignore alpha |
|
|
|
if (elements == 4) |
|
|
|
buf += 2; |
|
|
|
// Jump to next aligned position |
|
|
|
buf += need_align; |
|
|
|
} |
|
|
|
for (i = 0; i < 3; i++) |
|
|
|
ptr[i] += p->linesize[i]; |
|
|
|
@@ -327,7 +345,7 @@ static int decode_frame(AVCodecContext *avctx, |
|
|
|
elements *= 2; |
|
|
|
case 8: |
|
|
|
av_image_copy_plane(ptr[0], p->linesize[0], |
|
|
|
buf, elements * avctx->width, |
|
|
|
buf, stride, |
|
|
|
elements * avctx->width, avctx->height); |
|
|
|
break; |
|
|
|
} |
|
|
|
|