Commit 8b46d75e authored by Fabrice Bellard's avatar Fabrice Bellard

rgba32 support

Originally committed as revision 1795 to svn://svn.ffmpeg.org/ffmpeg/trunk
parent 6d93f194
...@@ -63,6 +63,7 @@ typedef struct PNGDecodeState { ...@@ -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) ...@@ -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,7 +161,33 @@ static void png_filter_row(uint8_t *dst, int filter_type, ...@@ -159,7 +161,33 @@ 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; ptr = s->image_buf + s->image_linesize * s->y;
/* 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) if (s->y == 0)
last_row = s->empty_row; last_row = s->empty_row;
else else
...@@ -167,6 +195,7 @@ static void png_handle_row(PNGDecodeState *s) ...@@ -167,6 +195,7 @@ static void png_handle_row(PNGDecodeState *s)
png_filter_row(ptr, s->crow_buf[0], s->crow_buf + 1, png_filter_row(ptr, s->crow_buf[0], s->crow_buf + 1,
last_row, s->row_size, s->bpp); 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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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) ...@@ -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) ...@@ -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];
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); 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 = { ...@@ -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
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