mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2024-12-23 12:43:46 +02:00
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>
This commit is contained in:
parent
b634c12cb9
commit
4ba45c189c
@ -77,9 +77,9 @@ static int decode_frame(AVCodecContext *avctx,
|
|||||||
|
|
||||||
unsigned int offset;
|
unsigned int offset;
|
||||||
int magic_num, endian;
|
int magic_num, endian;
|
||||||
int x, y, i, ret;
|
int x, y, stride, i, ret;
|
||||||
int w, h, bits_per_color, descriptor, elements, packing, total_size;
|
int w, h, bits_per_color, descriptor, elements, packing;
|
||||||
int encoding;
|
int encoding, need_align = 0;
|
||||||
|
|
||||||
unsigned int rgbBuffer = 0;
|
unsigned int rgbBuffer = 0;
|
||||||
int n_datum = 0;
|
int n_datum = 0;
|
||||||
@ -185,24 +185,24 @@ static int decode_frame(AVCodecContext *avctx,
|
|||||||
|
|
||||||
switch (bits_per_color) {
|
switch (bits_per_color) {
|
||||||
case 8:
|
case 8:
|
||||||
total_size = avctx->width * avctx->height * elements;
|
stride = avctx->width * elements;
|
||||||
break;
|
break;
|
||||||
case 10:
|
case 10:
|
||||||
if (!packing) {
|
if (!packing) {
|
||||||
av_log(avctx, AV_LOG_ERROR, "Packing to 32bit required\n");
|
av_log(avctx, AV_LOG_ERROR, "Packing to 32bit required\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
total_size = (avctx->width * elements + 2) / 3 * 4 * avctx->height;
|
stride = (avctx->width * elements + 2) / 3 * 4;
|
||||||
break;
|
break;
|
||||||
case 12:
|
case 12:
|
||||||
if (!packing) {
|
if (!packing) {
|
||||||
av_log(avctx, AV_LOG_ERROR, "Packing to 16bit required\n");
|
av_log(avctx, AV_LOG_ERROR, "Packing to 16bit required\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
total_size = 2 * avctx->width * avctx->height * elements;
|
stride = 2 * avctx->width * elements;
|
||||||
break;
|
break;
|
||||||
case 16:
|
case 16:
|
||||||
total_size = 2 * avctx->width * avctx->height * elements;
|
stride = 2 * avctx->width * elements;
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
case 32:
|
case 32:
|
||||||
@ -213,6 +213,26 @@ static int decode_frame(AVCodecContext *avctx,
|
|||||||
return AVERROR_INVALIDDATA;
|
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) {
|
switch (1000 * descriptor + 10 * bits_per_color + endian) {
|
||||||
case 6081:
|
case 6081:
|
||||||
case 6080:
|
case 6080:
|
||||||
@ -276,10 +296,6 @@ static int decode_frame(AVCodecContext *avctx,
|
|||||||
for (i=0; i<AV_NUM_DATA_POINTERS; i++)
|
for (i=0; i<AV_NUM_DATA_POINTERS; i++)
|
||||||
ptr[i] = p->data[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) {
|
switch (bits_per_color) {
|
||||||
case 10:
|
case 10:
|
||||||
for (x = 0; x < avctx->height; x++) {
|
for (x = 0; x < avctx->height; x++) {
|
||||||
@ -318,6 +334,8 @@ static int decode_frame(AVCodecContext *avctx,
|
|||||||
// For 12 bit, ignore alpha
|
// For 12 bit, ignore alpha
|
||||||
if (elements == 4)
|
if (elements == 4)
|
||||||
buf += 2;
|
buf += 2;
|
||||||
|
// Jump to next aligned position
|
||||||
|
buf += need_align;
|
||||||
}
|
}
|
||||||
for (i = 0; i < 3; i++)
|
for (i = 0; i < 3; i++)
|
||||||
ptr[i] += p->linesize[i];
|
ptr[i] += p->linesize[i];
|
||||||
@ -327,7 +345,7 @@ static int decode_frame(AVCodecContext *avctx,
|
|||||||
elements *= 2;
|
elements *= 2;
|
||||||
case 8:
|
case 8:
|
||||||
av_image_copy_plane(ptr[0], p->linesize[0],
|
av_image_copy_plane(ptr[0], p->linesize[0],
|
||||||
buf, elements * avctx->width,
|
buf, stride,
|
||||||
elements * avctx->width, avctx->height);
|
elements * avctx->width, avctx->height);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user