summaryrefslogtreecommitdiff
path: root/libavcodec/dpx.c
diff options
context:
space:
mode:
authorChristophe Gisquet <christophe.gisquet@gmail.com>2014-08-13 00:37:00 +0200
committerMichael Niedermayer <michaelni@gmx.at>2014-08-14 13:35:24 +0200
commit4ba45c189ccafdedcdb703e40441fbd24fe62989 (patch)
treec1c9bb7b844029e0a87ba80212f62e6f26a9074a /libavcodec/dpx.c
parentb634c12cb9673428672aa0fb216e866709451e61 (diff)
dpx: use aligned line starts
SMPTE 268M-2003 specifies that each line starts at a 4-bytes boundary. Therefore, modify correspondingly the input buffer strides and size. Partially fixes ticket #3692: DLAD_8b_3c_big.dpx still has inverted colors, which might be related to endianness. Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
Diffstat (limited to 'libavcodec/dpx.c')
-rw-r--r--libavcodec/dpx.c42
1 files changed, 30 insertions, 12 deletions
diff --git a/libavcodec/dpx.c b/libavcodec/dpx.c
index d8fb4e077b..5d8c4f3341 100644
--- a/libavcodec/dpx.c
+++ b/libavcodec/dpx.c
@@ -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;
}