Commit 69849a2d authored by Christophe Gisquet's avatar Christophe Gisquet Committed by Michael Niedermayer

dpxenc: enforce alignment requirement

S268M-2003 specifies that each line start is aligned on a 4-byte boundary.
Reviewed-by: 's avatarPaul B Mahol <onemda@gmail.com>
Signed-off-by: 's avatarMichael Niedermayer <michaelni@gmx.at>
parent d92550d1
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
typedef struct DPXContext { typedef struct DPXContext {
int big_endian; int big_endian;
int bits_per_component; int bits_per_component;
int num_components;
int descriptor; int descriptor;
int planar; int planar;
} DPXContext; } DPXContext;
...@@ -39,6 +40,7 @@ static av_cold int encode_init(AVCodecContext *avctx) ...@@ -39,6 +40,7 @@ static av_cold int encode_init(AVCodecContext *avctx)
s->big_endian = !!(desc->flags & AV_PIX_FMT_FLAG_BE); s->big_endian = !!(desc->flags & AV_PIX_FMT_FLAG_BE);
s->bits_per_component = desc->comp[0].depth_minus1 + 1; s->bits_per_component = desc->comp[0].depth_minus1 + 1;
s->num_components = desc->nb_components;
s->descriptor = (desc->flags & AV_PIX_FMT_FLAG_ALPHA) ? 51 : 50; s->descriptor = (desc->flags & AV_PIX_FMT_FLAG_ALPHA) ? 51 : 50;
s->planar = !!(desc->flags & AV_PIX_FMT_FLAG_PLANAR); s->planar = !!(desc->flags & AV_PIX_FMT_FLAG_PLANAR);
...@@ -142,7 +144,9 @@ static void encode_gbrp12(AVCodecContext *avctx, const AVPicture *pic, uint16_t ...@@ -142,7 +144,9 @@ static void encode_gbrp12(AVCodecContext *avctx, const AVPicture *pic, uint16_t
const uint16_t *src[3] = {(uint16_t*)pic->data[0], const uint16_t *src[3] = {(uint16_t*)pic->data[0],
(uint16_t*)pic->data[1], (uint16_t*)pic->data[1],
(uint16_t*)pic->data[2]}; (uint16_t*)pic->data[2]};
int x, y, i; int x, y, i, pad;
pad = avctx->width*6;
pad = (FFALIGN(pad, 4) - pad) >> 1;
for (y = 0; y < avctx->height; y++) { for (y = 0; y < avctx->height; y++) {
for (x = 0; x < avctx->width; x++) { for (x = 0; x < avctx->width; x++) {
uint16_t value[3]; uint16_t value[3];
...@@ -155,6 +159,8 @@ static void encode_gbrp12(AVCodecContext *avctx, const AVPicture *pic, uint16_t ...@@ -155,6 +159,8 @@ static void encode_gbrp12(AVCodecContext *avctx, const AVPicture *pic, uint16_t
value[2] = AV_RL16(src[1] + x) << 4; value[2] = AV_RL16(src[1] + x) << 4;
value[0] = AV_RL16(src[2] + x) << 4; value[0] = AV_RL16(src[2] + x) << 4;
} }
for (i = 0; i < pad; i++)
*dst++ = 0;
for (i = 0; i < 3; i++) for (i = 0; i < 3; i++)
write16(dst++, value[i]); write16(dst++, value[i]);
} }
...@@ -167,14 +173,25 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt, ...@@ -167,14 +173,25 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
const AVFrame *frame, int *got_packet) const AVFrame *frame, int *got_packet)
{ {
DPXContext *s = avctx->priv_data; DPXContext *s = avctx->priv_data;
int size, ret; int size, ret, need_align, len;
uint8_t *buf; uint8_t *buf;
#define HEADER_SIZE 1664 /* DPX Generic header */ #define HEADER_SIZE 1664 /* DPX Generic header */
if (s->bits_per_component == 10) if (s->bits_per_component == 10)
size = avctx->height * avctx->width * 4; size = avctx->height * avctx->width * 4;
else else if (s->bits_per_component == 12) {
size = avpicture_get_size(avctx->pix_fmt, avctx->width, avctx->height); // 3 components, 12 bits put on 16 bits
len = avctx->width*6;
size = FFALIGN(len, 4);
need_align = size - len;
size *= avctx->height;
} else {
// N components, M bits
len = avctx->width * s->num_components * s->bits_per_component >> 3;
size = FFALIGN(len, 4);
need_align = size - len;
size *= avctx->height;
}
if ((ret = ff_alloc_packet2(avctx, pkt, size + HEADER_SIZE)) < 0) if ((ret = ff_alloc_packet2(avctx, pkt, size + HEADER_SIZE)) < 0)
return ret; return ret;
buf = pkt->data; buf = pkt->data;
...@@ -211,9 +228,22 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt, ...@@ -211,9 +228,22 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
switch(s->bits_per_component) { switch(s->bits_per_component) {
case 8: case 8:
case 16: case 16:
if (need_align) {
int j;
const uint8_t *src = frame->data[0];
uint8_t *dst = pkt->data + HEADER_SIZE;
size = (len + need_align) * avctx->height;
for (j=0; j<avctx->height; j++) {
memcpy(dst, src, len);
memset(dst + len, 0, need_align);
dst += len + need_align;
src += frame->linesize[0];
}
} else {
size = avpicture_layout((const AVPicture*)frame, avctx->pix_fmt, size = avpicture_layout((const AVPicture*)frame, avctx->pix_fmt,
avctx->width, avctx->height, avctx->width, avctx->height,
buf + HEADER_SIZE, pkt->size - HEADER_SIZE); buf + HEADER_SIZE, pkt->size - HEADER_SIZE);
}
if (size < 0) if (size < 0)
return size; return size;
break; break;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment