mirror of
https://git.ffmpeg.org/ffmpeg.git
synced 2025-01-22 07:13:20 +00:00
rgba32 support
Originally committed as revision 1795 to svn://svn.ffmpeg.org/ffmpeg/trunk
This commit is contained in:
parent
6d93f19449
commit
8b46d75e4a
@ -63,6 +63,7 @@ typedef struct PNGDecodeState {
|
|||||||
uint32_t palette[256];
|
uint32_t palette[256];
|
||||||
uint8_t *crow_buf;
|
uint8_t *crow_buf;
|
||||||
uint8_t *empty_row;
|
uint8_t *empty_row;
|
||||||
|
uint8_t *tmp_row;
|
||||||
int crow_size; /* compressed row size (include filter type) */
|
int crow_size; /* compressed row size (include filter type) */
|
||||||
int row_size; /* decompressed row size */
|
int row_size; /* decompressed row size */
|
||||||
int y;
|
int y;
|
||||||
@ -91,6 +92,7 @@ static void png_zfree(void *opaque, void *ptr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* XXX: optimize */
|
/* XXX: optimize */
|
||||||
|
/* NOTE: 'dst' can be equal to 'last' */
|
||||||
static void png_filter_row(uint8_t *dst, int filter_type,
|
static void png_filter_row(uint8_t *dst, int filter_type,
|
||||||
uint8_t *src, uint8_t *last, int size, int bpp)
|
uint8_t *src, uint8_t *last, int size, int bpp)
|
||||||
{
|
{
|
||||||
@ -159,14 +161,41 @@ static void png_filter_row(uint8_t *dst, int filter_type,
|
|||||||
static void png_handle_row(PNGDecodeState *s)
|
static void png_handle_row(PNGDecodeState *s)
|
||||||
{
|
{
|
||||||
uint8_t *ptr, *last_row;
|
uint8_t *ptr, *last_row;
|
||||||
ptr = s->image_buf + s->image_linesize * s->y;
|
|
||||||
if (s->y == 0)
|
|
||||||
last_row = s->empty_row;
|
|
||||||
else
|
|
||||||
last_row = ptr - s->image_linesize;
|
|
||||||
|
|
||||||
png_filter_row(ptr, s->crow_buf[0], s->crow_buf + 1,
|
ptr = s->image_buf + s->image_linesize * s->y;
|
||||||
last_row, s->row_size, s->bpp);
|
|
||||||
|
/* need to swap bytes correctly for RGB_ALPHA */
|
||||||
|
if (s->color_type == PNG_COLOR_TYPE_RGB_ALPHA) {
|
||||||
|
int j, w;
|
||||||
|
unsigned int r, g, b, a;
|
||||||
|
const uint8_t *src;
|
||||||
|
|
||||||
|
png_filter_row(s->tmp_row, s->crow_buf[0], s->crow_buf + 1,
|
||||||
|
s->empty_row, s->row_size, s->bpp);
|
||||||
|
memcpy(s->empty_row, s->tmp_row, s->row_size);
|
||||||
|
|
||||||
|
src = s->tmp_row;
|
||||||
|
w = s->width;
|
||||||
|
for(j = 0;j < w; j++) {
|
||||||
|
r = src[0];
|
||||||
|
g = src[1];
|
||||||
|
b = src[2];
|
||||||
|
a = src[3];
|
||||||
|
*(uint32_t *)ptr = (a << 24) | (r << 16) | (g << 8) | b;
|
||||||
|
ptr += 4;
|
||||||
|
src += 4;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* in normal case, we avoid one copy */
|
||||||
|
|
||||||
|
if (s->y == 0)
|
||||||
|
last_row = s->empty_row;
|
||||||
|
else
|
||||||
|
last_row = ptr - s->image_linesize;
|
||||||
|
|
||||||
|
png_filter_row(ptr, s->crow_buf[0], s->crow_buf + 1,
|
||||||
|
last_row, s->row_size, s->bpp);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int png_decode_idat(PNGDecodeState *s, ByteIOContext *f, int length)
|
static int png_decode_idat(PNGDecodeState *s, ByteIOContext *f, int length)
|
||||||
@ -282,6 +311,10 @@ static int png_read(ByteIOContext *f,
|
|||||||
s->color_type == PNG_COLOR_TYPE_RGB) {
|
s->color_type == PNG_COLOR_TYPE_RGB) {
|
||||||
info->pix_fmt = PIX_FMT_RGB24;
|
info->pix_fmt = PIX_FMT_RGB24;
|
||||||
s->row_size = s->width * 3;
|
s->row_size = s->width * 3;
|
||||||
|
} else if (s->bit_depth == 8 &&
|
||||||
|
s->color_type == PNG_COLOR_TYPE_RGB_ALPHA) {
|
||||||
|
info->pix_fmt = PIX_FMT_RGBA32;
|
||||||
|
s->row_size = s->width * 4;
|
||||||
} else if (s->bit_depth == 8 &&
|
} else if (s->bit_depth == 8 &&
|
||||||
s->color_type == PNG_COLOR_TYPE_GRAY) {
|
s->color_type == PNG_COLOR_TYPE_GRAY) {
|
||||||
info->pix_fmt = PIX_FMT_GRAY8;
|
info->pix_fmt = PIX_FMT_GRAY8;
|
||||||
@ -292,7 +325,7 @@ static int png_read(ByteIOContext *f,
|
|||||||
s->row_size = (s->width + 7) >> 3;
|
s->row_size = (s->width + 7) >> 3;
|
||||||
} else if (s->color_type == PNG_COLOR_TYPE_PALETTE) {
|
} else if (s->color_type == PNG_COLOR_TYPE_PALETTE) {
|
||||||
info->pix_fmt = PIX_FMT_PAL8;
|
info->pix_fmt = PIX_FMT_PAL8;
|
||||||
s->row_size = s->width;;
|
s->row_size = s->width;
|
||||||
} else {
|
} else {
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
@ -319,6 +352,11 @@ static int png_read(ByteIOContext *f,
|
|||||||
s->empty_row = av_mallocz(s->row_size);
|
s->empty_row = av_mallocz(s->row_size);
|
||||||
if (!s->empty_row)
|
if (!s->empty_row)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
if (s->color_type == PNG_COLOR_TYPE_RGB_ALPHA) {
|
||||||
|
s->tmp_row = av_malloc(s->row_size);
|
||||||
|
if (!s->tmp_row)
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
/* compressed row */
|
/* compressed row */
|
||||||
s->crow_buf = av_malloc(s->crow_size);
|
s->crow_buf = av_malloc(s->crow_size);
|
||||||
if (!s->crow_buf)
|
if (!s->crow_buf)
|
||||||
@ -386,6 +424,8 @@ static int png_read(ByteIOContext *f,
|
|||||||
the_end:
|
the_end:
|
||||||
inflateEnd(&s->zstream);
|
inflateEnd(&s->zstream);
|
||||||
av_free(s->crow_buf);
|
av_free(s->crow_buf);
|
||||||
|
av_free(s->empty_row);
|
||||||
|
av_free(s->tmp_row);
|
||||||
return ret;
|
return ret;
|
||||||
fail:
|
fail:
|
||||||
ret = -1;
|
ret = -1;
|
||||||
@ -431,6 +471,11 @@ static int png_write(ByteIOContext *f, AVImageInfo *info)
|
|||||||
z_stream zstream;
|
z_stream zstream;
|
||||||
|
|
||||||
switch(info->pix_fmt) {
|
switch(info->pix_fmt) {
|
||||||
|
case PIX_FMT_RGBA32:
|
||||||
|
bit_depth = 8;
|
||||||
|
color_type = PNG_COLOR_TYPE_RGB_ALPHA;
|
||||||
|
row_size = info->width * 4;
|
||||||
|
break;
|
||||||
case PIX_FMT_RGB24:
|
case PIX_FMT_RGB24:
|
||||||
bit_depth = 8;
|
bit_depth = 8;
|
||||||
color_type = PNG_COLOR_TYPE_RGB;
|
color_type = PNG_COLOR_TYPE_RGB;
|
||||||
@ -512,7 +557,24 @@ static int png_write(ByteIOContext *f, AVImageInfo *info)
|
|||||||
for(y = 0;y < info->height; y++) {
|
for(y = 0;y < info->height; y++) {
|
||||||
/* XXX: do filtering */
|
/* XXX: do filtering */
|
||||||
ptr = info->pict.data[0] + y * info->pict.linesize[0];
|
ptr = info->pict.data[0] + y * info->pict.linesize[0];
|
||||||
memcpy(crow_buf + 1, ptr, row_size);
|
if (color_type == PNG_COLOR_TYPE_RGB_ALPHA) {
|
||||||
|
uint8_t *d;
|
||||||
|
int j, w;
|
||||||
|
unsigned int v;
|
||||||
|
|
||||||
|
w = info->width;
|
||||||
|
d = crow_buf + 1;
|
||||||
|
for(j = 0; j < w; j++) {
|
||||||
|
v = ((uint32_t *)ptr)[j];
|
||||||
|
d[0] = v >> 16;
|
||||||
|
d[1] = v >> 8;
|
||||||
|
d[2] = v;
|
||||||
|
d[3] = v >> 24;
|
||||||
|
d += 4;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
memcpy(crow_buf + 1, ptr, row_size);
|
||||||
|
}
|
||||||
crow_buf[0] = PNG_FILTER_VALUE_NONE;
|
crow_buf[0] = PNG_FILTER_VALUE_NONE;
|
||||||
zstream.avail_in = row_size + 1;
|
zstream.avail_in = row_size + 1;
|
||||||
zstream.next_in = crow_buf;
|
zstream.next_in = crow_buf;
|
||||||
@ -561,7 +623,8 @@ AVImageFormat png_image_format = {
|
|||||||
"png",
|
"png",
|
||||||
png_probe,
|
png_probe,
|
||||||
png_read,
|
png_read,
|
||||||
(1 << PIX_FMT_RGB24) | (1 << PIX_FMT_GRAY8) | (1 << PIX_FMT_MONOBLACK) | (1 << PIX_FMT_PAL8),
|
(1 << PIX_FMT_RGBA32) | (1 << PIX_FMT_RGB24) | (1 << PIX_FMT_GRAY8) |
|
||||||
|
(1 << PIX_FMT_MONOBLACK) | (1 << PIX_FMT_PAL8),
|
||||||
png_write,
|
png_write,
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user