decode mng color decorrelation
Originally committed as revision 12228 to svn://svn.ffmpeg.org/ffmpeg/trunk
This commit is contained in:
parent
d248905ba5
commit
042e0adda9
@ -23,6 +23,7 @@
|
||||
#include "png.h"
|
||||
|
||||
const uint8_t ff_pngsig[8] = {137, 80, 78, 71, 13, 10, 26, 10};
|
||||
const uint8_t ff_mngsig[8] = {138, 77, 78, 71, 13, 10, 26, 10};
|
||||
|
||||
/* Mask to determine which y pixels are valid in a pass */
|
||||
const uint8_t ff_png_pass_ymask[NB_PASSES] = {
|
||||
|
@ -34,6 +34,7 @@
|
||||
#define PNG_COLOR_TYPE_RGB_ALPHA (PNG_COLOR_MASK_COLOR | PNG_COLOR_MASK_ALPHA)
|
||||
#define PNG_COLOR_TYPE_GRAY_ALPHA (PNG_COLOR_MASK_ALPHA)
|
||||
|
||||
#define PNG_FILTER_TYPE_LOCO 64
|
||||
#define PNG_FILTER_VALUE_NONE 0
|
||||
#define PNG_FILTER_VALUE_SUB 1
|
||||
#define PNG_FILTER_VALUE_UP 2
|
||||
@ -49,6 +50,7 @@
|
||||
#define NB_PASSES 7
|
||||
|
||||
extern const uint8_t ff_pngsig[8];
|
||||
extern const uint8_t ff_mngsig[8];
|
||||
|
||||
/* Mask to determine which y pixels are valid in a pass */
|
||||
extern const uint8_t ff_png_pass_ymask[NB_PASSES];
|
||||
|
@ -234,7 +234,7 @@ static void png_filter_row(DSPContext *dsp, uint8_t *dst, int filter_type,
|
||||
}
|
||||
}
|
||||
|
||||
static void convert_to_rgb32(uint8_t *dst, const uint8_t *src, int width)
|
||||
static av_always_inline void convert_to_rgb32_loco(uint8_t *dst, const uint8_t *src, int width, int loco)
|
||||
{
|
||||
int j;
|
||||
unsigned int r, g, b, a;
|
||||
@ -244,12 +244,34 @@ static void convert_to_rgb32(uint8_t *dst, const uint8_t *src, int width)
|
||||
g = src[1];
|
||||
b = src[2];
|
||||
a = src[3];
|
||||
if(loco) {
|
||||
r = (r+g)&0xff;
|
||||
b = (b+g)&0xff;
|
||||
}
|
||||
*(uint32_t *)dst = (a << 24) | (r << 16) | (g << 8) | b;
|
||||
dst += 4;
|
||||
src += 4;
|
||||
}
|
||||
}
|
||||
|
||||
static void convert_to_rgb32(uint8_t *dst, const uint8_t *src, int width, int loco)
|
||||
{
|
||||
if(loco)
|
||||
convert_to_rgb32_loco(dst, src, width, 1);
|
||||
else
|
||||
convert_to_rgb32_loco(dst, src, width, 0);
|
||||
}
|
||||
|
||||
static void deloco_rgb24(uint8_t *dst, int size)
|
||||
{
|
||||
int i;
|
||||
for(i=0; i<size; i+=3) {
|
||||
int g = dst[i+1];
|
||||
dst[i+0] += g;
|
||||
dst[i+2] += g;
|
||||
}
|
||||
}
|
||||
|
||||
/* process exactly one decompressed row */
|
||||
static void png_handle_row(PNGDecContext *s)
|
||||
{
|
||||
@ -262,7 +284,7 @@ static void png_handle_row(PNGDecContext *s)
|
||||
if (s->color_type == PNG_COLOR_TYPE_RGB_ALPHA) {
|
||||
png_filter_row(&s->dsp, s->tmp_row, s->crow_buf[0], s->crow_buf + 1,
|
||||
s->last_row, s->row_size, s->bpp);
|
||||
convert_to_rgb32(ptr, s->tmp_row, s->width);
|
||||
convert_to_rgb32(ptr, s->tmp_row, s->width, s->filter_type == PNG_FILTER_TYPE_LOCO);
|
||||
FFSWAP(uint8_t*, s->last_row, s->tmp_row);
|
||||
} else {
|
||||
/* in normal case, we avoid one copy */
|
||||
@ -274,9 +296,16 @@ static void png_handle_row(PNGDecContext *s)
|
||||
png_filter_row(&s->dsp, ptr, s->crow_buf[0], s->crow_buf + 1,
|
||||
last_row, s->row_size, s->bpp);
|
||||
}
|
||||
/* loco lags by 1 row so that it doesn't interfere with top prediction */
|
||||
if (s->filter_type == PNG_FILTER_TYPE_LOCO &&
|
||||
s->color_type == PNG_COLOR_TYPE_RGB && s->y > 0)
|
||||
deloco_rgb24(ptr - s->image_linesize, s->row_size);
|
||||
s->y++;
|
||||
if (s->y == s->height) {
|
||||
s->state |= PNG_ALLIMAGE;
|
||||
if (s->filter_type == PNG_FILTER_TYPE_LOCO &&
|
||||
s->color_type == PNG_COLOR_TYPE_RGB)
|
||||
deloco_rgb24(ptr, s->row_size);
|
||||
}
|
||||
} else {
|
||||
got_line = 0;
|
||||
@ -363,7 +392,8 @@ static int decode_frame(AVCodecContext *avctx,
|
||||
s->bytestream_end= buf + buf_size;
|
||||
|
||||
/* check signature */
|
||||
if (memcmp(s->bytestream, ff_pngsig, 8) != 0)
|
||||
if (memcmp(s->bytestream, ff_pngsig, 8) != 0 &&
|
||||
memcmp(s->bytestream, ff_mngsig, 8) != 0)
|
||||
return -1;
|
||||
s->bytestream+= 8;
|
||||
s->y=
|
||||
|
@ -41,6 +41,7 @@ static const IdStrMap img_tags[] = {
|
||||
{ CODEC_ID_MJPEG , "jpg"},
|
||||
{ CODEC_ID_LJPEG , "ljpg"},
|
||||
{ CODEC_ID_PNG , "png"},
|
||||
{ CODEC_ID_PNG , "mng"},
|
||||
{ CODEC_ID_PPM , "ppm"},
|
||||
{ CODEC_ID_PGM , "pgm"},
|
||||
{ CODEC_ID_PGMYUV , "pgmyuv"},
|
||||
|
Loading…
Reference in New Issue
Block a user