Commit 9dbedf33 authored by Michael Niedermayer's avatar Michael Niedermayer

Merge commit 'c6303f8d'

* commit 'c6303f8d':
  yop: simplify/sanitize the decoding loop
  c93: set palette_has_changed.
  bmp: cosmetics, reformat
  hlsenc: Don't duplicate a string constant

Conflicts:
	libavcodec/bmp.c
	tests/ref/fate/yop
Merged-by: 's avatarMichael Niedermayer <michaelni@gmx.at>
parents ba8e909c c6303f8d
...@@ -25,7 +25,8 @@ ...@@ -25,7 +25,8 @@
#include "internal.h" #include "internal.h"
#include "msrledec.h" #include "msrledec.h"
static av_cold int bmp_decode_init(AVCodecContext *avctx){ static av_cold int bmp_decode_init(AVCodecContext *avctx)
{
BMPContext *s = avctx->priv_data; BMPContext *s = avctx->priv_data;
avcodec_get_frame_defaults(&s->picture); avcodec_get_frame_defaults(&s->picture);
...@@ -56,19 +57,19 @@ static int bmp_decode_frame(AVCodecContext *avctx, ...@@ -56,19 +57,19 @@ static int bmp_decode_frame(AVCodecContext *avctx,
const uint8_t *buf0 = buf; const uint8_t *buf0 = buf;
GetByteContext gb; GetByteContext gb;
if(buf_size < 14){ if (buf_size < 14) {
av_log(avctx, AV_LOG_ERROR, "buf size too small (%d)\n", buf_size); av_log(avctx, AV_LOG_ERROR, "buf size too small (%d)\n", buf_size);
return -1; return -1;
} }
if(bytestream_get_byte(&buf) != 'B' || if (bytestream_get_byte(&buf) != 'B' ||
bytestream_get_byte(&buf) != 'M') { bytestream_get_byte(&buf) != 'M') {
av_log(avctx, AV_LOG_ERROR, "bad magic number\n"); av_log(avctx, AV_LOG_ERROR, "bad magic number\n");
return -1; return -1;
} }
fsize = bytestream_get_le32(&buf); fsize = bytestream_get_le32(&buf);
if(buf_size < fsize){ if (buf_size < fsize) {
av_log(avctx, AV_LOG_ERROR, "not enough data (%d < %d), trying to decode anyway\n", av_log(avctx, AV_LOG_ERROR, "not enough data (%d < %d), trying to decode anyway\n",
buf_size, fsize); buf_size, fsize);
fsize = buf_size; fsize = buf_size;
...@@ -79,22 +80,22 @@ static int bmp_decode_frame(AVCodecContext *avctx, ...@@ -79,22 +80,22 @@ static int bmp_decode_frame(AVCodecContext *avctx,
hsize = bytestream_get_le32(&buf); /* header size */ hsize = bytestream_get_le32(&buf); /* header size */
ihsize = bytestream_get_le32(&buf); /* more header size */ ihsize = bytestream_get_le32(&buf); /* more header size */
if(ihsize + 14 > hsize){ if (ihsize + 14 > hsize) {
av_log(avctx, AV_LOG_ERROR, "invalid header size %d\n", hsize); av_log(avctx, AV_LOG_ERROR, "invalid header size %d\n", hsize);
return -1; return -1;
} }
/* sometimes file size is set to some headers size, set a real size in that case */ /* sometimes file size is set to some headers size, set a real size in that case */
if(fsize == 14 || fsize == ihsize + 14) if (fsize == 14 || fsize == ihsize + 14)
fsize = buf_size - 2; fsize = buf_size - 2;
if(fsize <= hsize){ if (fsize <= hsize) {
av_log(avctx, AV_LOG_ERROR, "declared file size is less than header size (%d < %d)\n", av_log(avctx, AV_LOG_ERROR, "declared file size is less than header size (%d < %d)\n",
fsize, hsize); fsize, hsize);
return -1; return -1;
} }
switch(ihsize){ switch (ihsize) {
case 40: // windib case 40: // windib
case 56: // windib v3 case 56: // windib v3
case 64: // OS/2 v2 case 64: // OS/2 v2
...@@ -112,7 +113,8 @@ static int bmp_decode_frame(AVCodecContext *avctx, ...@@ -112,7 +113,8 @@ static int bmp_decode_frame(AVCodecContext *avctx,
return -1; return -1;
} }
if(bytestream_get_le16(&buf) != 1){ /* planes */ /* planes */
if (bytestream_get_le16(&buf) != 1) {
av_log(avctx, AV_LOG_ERROR, "invalid BMP header\n"); av_log(avctx, AV_LOG_ERROR, "invalid BMP header\n");
return -1; return -1;
} }
...@@ -124,12 +126,13 @@ static int bmp_decode_frame(AVCodecContext *avctx, ...@@ -124,12 +126,13 @@ static int bmp_decode_frame(AVCodecContext *avctx,
else else
comp = BMP_RGB; comp = BMP_RGB;
if(comp != BMP_RGB && comp != BMP_BITFIELDS && comp != BMP_RLE4 && comp != BMP_RLE8){ if (comp != BMP_RGB && comp != BMP_BITFIELDS && comp != BMP_RLE4 &&
comp != BMP_RLE8) {
av_log(avctx, AV_LOG_ERROR, "BMP coding %d not supported\n", comp); av_log(avctx, AV_LOG_ERROR, "BMP coding %d not supported\n", comp);
return -1; return -1;
} }
if(comp == BMP_BITFIELDS){ if (comp == BMP_BITFIELDS) {
buf += 20; buf += 20;
rgb[0] = bytestream_get_le32(&buf); rgb[0] = bytestream_get_le32(&buf);
rgb[1] = bytestream_get_le32(&buf); rgb[1] = bytestream_get_le32(&buf);
...@@ -138,13 +141,13 @@ static int bmp_decode_frame(AVCodecContext *avctx, ...@@ -138,13 +141,13 @@ static int bmp_decode_frame(AVCodecContext *avctx,
} }
avctx->width = width; avctx->width = width;
avctx->height = height > 0? height: -height; avctx->height = height > 0 ? height : -height;
avctx->pix_fmt = AV_PIX_FMT_NONE; avctx->pix_fmt = AV_PIX_FMT_NONE;
switch(depth){ switch (depth) {
case 32: case 32:
if(comp == BMP_BITFIELDS){ if (comp == BMP_BITFIELDS) {
if (rgb[0] == 0xFF000000 && rgb[1] == 0x00FF0000 && rgb[2] == 0x0000FF00) if (rgb[0] == 0xFF000000 && rgb[1] == 0x00FF0000 && rgb[2] == 0x0000FF00)
avctx->pix_fmt = alpha ? AV_PIX_FMT_ABGR : AV_PIX_FMT_0BGR; avctx->pix_fmt = alpha ? AV_PIX_FMT_ABGR : AV_PIX_FMT_0BGR;
else if (rgb[0] == 0x00FF0000 && rgb[1] == 0x0000FF00 && rgb[2] == 0x000000FF) else if (rgb[0] == 0x00FF0000 && rgb[1] == 0x0000FF00 && rgb[2] == 0x000000FF)
...@@ -165,7 +168,7 @@ static int bmp_decode_frame(AVCodecContext *avctx, ...@@ -165,7 +168,7 @@ static int bmp_decode_frame(AVCodecContext *avctx,
avctx->pix_fmt = AV_PIX_FMT_BGR24; avctx->pix_fmt = AV_PIX_FMT_BGR24;
break; break;
case 16: case 16:
if(comp == BMP_RGB) if (comp == BMP_RGB)
avctx->pix_fmt = AV_PIX_FMT_RGB555; avctx->pix_fmt = AV_PIX_FMT_RGB555;
else if (comp == BMP_BITFIELDS) { else if (comp == BMP_BITFIELDS) {
if (rgb[0] == 0xF800 && rgb[1] == 0x07E0 && rgb[2] == 0x001F) if (rgb[0] == 0xF800 && rgb[1] == 0x07E0 && rgb[2] == 0x001F)
...@@ -181,16 +184,16 @@ static int bmp_decode_frame(AVCodecContext *avctx, ...@@ -181,16 +184,16 @@ static int bmp_decode_frame(AVCodecContext *avctx,
} }
break; break;
case 8: case 8:
if(hsize - ihsize - 14 > 0) if (hsize - ihsize - 14 > 0)
avctx->pix_fmt = AV_PIX_FMT_PAL8; avctx->pix_fmt = AV_PIX_FMT_PAL8;
else else
avctx->pix_fmt = AV_PIX_FMT_GRAY8; avctx->pix_fmt = AV_PIX_FMT_GRAY8;
break; break;
case 1: case 1:
case 4: case 4:
if(hsize - ihsize - 14 > 0){ if (hsize - ihsize - 14 > 0) {
avctx->pix_fmt = AV_PIX_FMT_PAL8; avctx->pix_fmt = AV_PIX_FMT_PAL8;
}else{ } else {
av_log(avctx, AV_LOG_ERROR, "Unknown palette for %d-colour BMP\n", 1<<depth); av_log(avctx, AV_LOG_ERROR, "Unknown palette for %d-colour BMP\n", 1<<depth);
return -1; return -1;
} }
...@@ -200,16 +203,16 @@ static int bmp_decode_frame(AVCodecContext *avctx, ...@@ -200,16 +203,16 @@ static int bmp_decode_frame(AVCodecContext *avctx,
return -1; return -1;
} }
if(avctx->pix_fmt == AV_PIX_FMT_NONE){ if (avctx->pix_fmt == AV_PIX_FMT_NONE) {
av_log(avctx, AV_LOG_ERROR, "unsupported pixel format\n"); av_log(avctx, AV_LOG_ERROR, "unsupported pixel format\n");
return -1; return -1;
} }
if(p->data[0]) if (p->data[0])
avctx->release_buffer(avctx, p); avctx->release_buffer(avctx, p);
p->reference = 0; p->reference = 0;
if(ff_get_buffer(avctx, p) < 0){ if (ff_get_buffer(avctx, p) < 0) {
av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
return -1; return -1;
} }
...@@ -222,17 +225,17 @@ static int bmp_decode_frame(AVCodecContext *avctx, ...@@ -222,17 +225,17 @@ static int bmp_decode_frame(AVCodecContext *avctx,
/* Line size in file multiple of 4 */ /* Line size in file multiple of 4 */
n = ((avctx->width * depth + 31) / 8) & ~3; n = ((avctx->width * depth + 31) / 8) & ~3;
if(n * avctx->height > dsize && comp != BMP_RLE4 && comp != BMP_RLE8){ if (n * avctx->height > dsize && comp != BMP_RLE4 && comp != BMP_RLE8) {
av_log(avctx, AV_LOG_ERROR, "not enough data (%d < %d)\n", av_log(avctx, AV_LOG_ERROR, "not enough data (%d < %d)\n",
dsize, n * avctx->height); dsize, n * avctx->height);
return -1; return -1;
} }
// RLE may skip decoding some picture areas, so blank picture before decoding // RLE may skip decoding some picture areas, so blank picture before decoding
if(comp == BMP_RLE4 || comp == BMP_RLE8) if (comp == BMP_RLE4 || comp == BMP_RLE8)
memset(p->data[0], 0, avctx->height * p->linesize[0]); memset(p->data[0], 0, avctx->height * p->linesize[0]);
if(height > 0){ if (height > 0) {
ptr = p->data[0] + (avctx->height - 1) * p->linesize[0]; ptr = p->data[0] + (avctx->height - 1) * p->linesize[0];
linesize = -p->linesize[0]; linesize = -p->linesize[0];
} else { } else {
...@@ -240,44 +243,45 @@ static int bmp_decode_frame(AVCodecContext *avctx, ...@@ -240,44 +243,45 @@ static int bmp_decode_frame(AVCodecContext *avctx,
linesize = p->linesize[0]; linesize = p->linesize[0];
} }
if(avctx->pix_fmt == AV_PIX_FMT_PAL8){ if (avctx->pix_fmt == AV_PIX_FMT_PAL8) {
int colors = 1 << depth; int colors = 1 << depth;
memset(p->data[1], 0, 1024); memset(p->data[1], 0, 1024);
if(ihsize >= 36){ if (ihsize >= 36) {
int t; int t;
buf = buf0 + 46; buf = buf0 + 46;
t = bytestream_get_le32(&buf); t = bytestream_get_le32(&buf);
if(t < 0 || t > (1 << depth)){ if (t < 0 || t > (1 << depth)) {
av_log(avctx, AV_LOG_ERROR, "Incorrect number of colors - %X for bitdepth %d\n", t, depth); av_log(avctx, AV_LOG_ERROR, "Incorrect number of colors - %X for bitdepth %d\n", t, depth);
}else if(t){ } else if (t) {
colors = t; colors = t;
} }
} }
buf = buf0 + 14 + ihsize; //palette location buf = buf0 + 14 + ihsize; //palette location
if((hsize-ihsize-14) < (colors << 2)){ // OS/2 bitmap, 3 bytes per palette entry // OS/2 bitmap, 3 bytes per palette entry
for(i = 0; i < colors; i++) if ((hsize-ihsize-14) < (colors << 2)) {
for (i = 0; i < colors; i++)
((uint32_t*)p->data[1])[i] = (0xFFU<<24) | bytestream_get_le24(&buf); ((uint32_t*)p->data[1])[i] = (0xFFU<<24) | bytestream_get_le24(&buf);
}else{ } else {
for(i = 0; i < colors; i++) for (i = 0; i < colors; i++)
((uint32_t*)p->data[1])[i] = 0xFFU << 24 | bytestream_get_le32(&buf); ((uint32_t*)p->data[1])[i] = 0xFFU << 24 | bytestream_get_le32(&buf);
} }
buf = buf0 + hsize; buf = buf0 + hsize;
} }
if(comp == BMP_RLE4 || comp == BMP_RLE8){ if (comp == BMP_RLE4 || comp == BMP_RLE8) {
if(height < 0){ if (height < 0) {
p->data[0] += p->linesize[0] * (avctx->height - 1); p->data[0] += p->linesize[0] * (avctx->height - 1);
p->linesize[0] = -p->linesize[0]; p->linesize[0] = -p->linesize[0];
} }
bytestream2_init(&gb, buf, dsize); bytestream2_init(&gb, buf, dsize);
ff_msrle_decode(avctx, (AVPicture*)p, depth, &gb); ff_msrle_decode(avctx, (AVPicture*)p, depth, &gb);
if(height < 0){ if (height < 0) {
p->data[0] += p->linesize[0] * (avctx->height - 1); p->data[0] += p->linesize[0] * (avctx->height - 1);
p->linesize[0] = -p->linesize[0]; p->linesize[0] = -p->linesize[0];
} }
}else{ } else {
switch(depth){ switch (depth) {
case 1: case 1:
for (i = 0; i < avctx->height; i++) { for (i = 0; i < avctx->height; i++) {
int j; int j;
...@@ -298,16 +302,16 @@ static int bmp_decode_frame(AVCodecContext *avctx, ...@@ -298,16 +302,16 @@ static int bmp_decode_frame(AVCodecContext *avctx,
case 8: case 8:
case 24: case 24:
case 32: case 32:
for(i = 0; i < avctx->height; i++){ for (i = 0; i < avctx->height; i++) {
memcpy(ptr, buf, n); memcpy(ptr, buf, n);
buf += n; buf += n;
ptr += linesize; ptr += linesize;
} }
break; break;
case 4: case 4:
for(i = 0; i < avctx->height; i++){ for (i = 0; i < avctx->height; i++) {
int j; int j;
for(j = 0; j < n; j++){ for (j = 0; j < n; j++) {
ptr[j*2+0] = (buf[j] >> 4) & 0xF; ptr[j*2+0] = (buf[j] >> 4) & 0xF;
ptr[j*2+1] = buf[j] & 0xF; ptr[j*2+1] = buf[j] & 0xF;
} }
...@@ -316,11 +320,11 @@ static int bmp_decode_frame(AVCodecContext *avctx, ...@@ -316,11 +320,11 @@ static int bmp_decode_frame(AVCodecContext *avctx,
} }
break; break;
case 16: case 16:
for(i = 0; i < avctx->height; i++){ for (i = 0; i < avctx->height; i++) {
const uint16_t *src = (const uint16_t *) buf; const uint16_t *src = (const uint16_t *) buf;
uint16_t *dst = (uint16_t *) ptr; uint16_t *dst = (uint16_t *) ptr;
for(j = 0; j < avctx->width; j++) for (j = 0; j < avctx->width; j++)
*dst++ = av_le2ne16(*src++); *dst++ = av_le2ne16(*src++);
buf += n; buf += n;
......
...@@ -237,6 +237,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, ...@@ -237,6 +237,7 @@ static int decode_frame(AVCodecContext *avctx, void *data,
for (i = 0; i < 256; i++) { for (i = 0; i < 256; i++) {
palette[i] = 0xFFU << 24 | bytestream2_get_be24(&gb); palette[i] = 0xFFU << 24 | bytestream2_get_be24(&gb);
} }
newpic->palette_has_changed = 1;
} else { } else {
if (oldpic->data[1]) if (oldpic->data[1])
memcpy(newpic->data[1], oldpic->data[1], 256 * 4); memcpy(newpic->data[1], oldpic->data[1], 256 * 4);
......
...@@ -36,7 +36,6 @@ typedef struct YopDecContext { ...@@ -36,7 +36,6 @@ typedef struct YopDecContext {
int num_pal_colors; int num_pal_colors;
int first_color[2]; int first_color[2];
int frame_data_length; int frame_data_length;
int row_pos;
uint8_t *low_nibble; uint8_t *low_nibble;
uint8_t *srcptr; uint8_t *srcptr;
...@@ -177,27 +176,12 @@ static uint8_t yop_get_next_nibble(YopDecContext *s) ...@@ -177,27 +176,12 @@ static uint8_t yop_get_next_nibble(YopDecContext *s)
return ret; return ret;
} }
/**
* Take s->dstptr to the next macroblock in sequence.
*/
static void yop_next_macroblock(YopDecContext *s)
{
// If we are advancing to the next row of macroblocks
if (s->row_pos == s->frame.linesize[0] - 2) {
s->dstptr += s->frame.linesize[0];
s->row_pos = 0;
}else {
s->row_pos += 2;
}
s->dstptr += 2;
}
static int yop_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, static int yop_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
AVPacket *avpkt) AVPacket *avpkt)
{ {
YopDecContext *s = avctx->priv_data; YopDecContext *s = avctx->priv_data;
int tag, firstcolor, is_odd_frame; int tag, firstcolor, is_odd_frame;
int ret, i; int ret, i, x, y;
uint32_t *palette; uint32_t *palette;
if (s->frame.data[0]) if (s->frame.data[0])
...@@ -214,12 +198,9 @@ static int yop_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, ...@@ -214,12 +198,9 @@ static int yop_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
return ret; return ret;
} }
s->frame.linesize[0] = avctx->width;
s->dstbuf = s->frame.data[0]; s->dstbuf = s->frame.data[0];
s->dstptr = s->frame.data[0]; s->dstptr = s->frame.data[0];
s->srcptr = avpkt->data + 4; s->srcptr = avpkt->data + 4;
s->row_pos = 0;
s->low_nibble = NULL; s->low_nibble = NULL;
is_odd_frame = avpkt->data[0]; is_odd_frame = avpkt->data[0];
...@@ -240,15 +221,18 @@ static int yop_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, ...@@ -240,15 +221,18 @@ static int yop_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
s->frame.palette_has_changed = 1; s->frame.palette_has_changed = 1;
while (s->dstptr - s->dstbuf < for (y = 0; y < avctx->height; y += 2) {
avctx->width * avctx->height && for (x = 0; x < avctx->width; x += 2) {
s->srcptr - avpkt->data < avpkt->size) { if (s->srcptr - avpkt->data >= avpkt->size) {
av_log(avctx, AV_LOG_ERROR, "Packet too small.\n");
return AVERROR_INVALIDDATA;
}
tag = yop_get_next_nibble(s); tag = yop_get_next_nibble(s);
if (tag != 0xf) { if (tag != 0xf) {
yop_paint_block(s, tag); yop_paint_block(s, tag);
}else { } else {
tag = yop_get_next_nibble(s); tag = yop_get_next_nibble(s);
ret = yop_copy_previous_block(s, tag); ret = yop_copy_previous_block(s, tag);
if (ret < 0) { if (ret < 0) {
...@@ -256,7 +240,9 @@ static int yop_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, ...@@ -256,7 +240,9 @@ static int yop_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
return ret; return ret;
} }
} }
yop_next_macroblock(s); s->dstptr += 2;
}
s->dstptr += 2*s->frame.linesize[0] - x;
} }
*got_frame = 1; *got_frame = 1;
......
...@@ -5,4 +5,3 @@ ...@@ -5,4 +5,3 @@
0, 3, 3, 1, 302760, 0xe0fc92da 0, 3, 3, 1, 302760, 0xe0fc92da
0, 4, 4, 1, 302760, 0xd7699bb4 0, 4, 4, 1, 302760, 0xd7699bb4
0, 5, 5, 1, 302760, 0x26e93266 0, 5, 5, 1, 302760, 0x26e93266
0, 6, 6, 1, 302760, 0x4cddb216
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