mirror of
https://git.ffmpeg.org/ffmpeg.git
synced 2024-12-30 11:22:14 +00:00
added 8 bit palette support
Originally committed as revision 1561 to svn://svn.ffmpeg.org/ffmpeg/trunk
This commit is contained in:
parent
7e6d70d0b1
commit
3ce27f13b9
@ -41,6 +41,7 @@
|
||||
#define PNG_IHDR 0x0001
|
||||
#define PNG_IDAT 0x0002
|
||||
#define PNG_ALLIMAGE 0x0004
|
||||
#define PNG_PLTE 0x0008
|
||||
|
||||
#define IOBUF_SIZE 4096
|
||||
|
||||
@ -58,6 +59,7 @@ typedef struct PNGDecodeState {
|
||||
|
||||
uint8_t *image_buf;
|
||||
int image_linesize;
|
||||
uint32_t palette[256];
|
||||
uint8_t *crow_buf;
|
||||
uint8_t *empty_row;
|
||||
int crow_size; /* compressed row size (include filter type) */
|
||||
@ -66,7 +68,7 @@ typedef struct PNGDecodeState {
|
||||
z_stream zstream;
|
||||
} PNGDecodeState;
|
||||
|
||||
const uint8_t pngsig[8] = {137, 80, 78, 71, 13, 10, 26, 10};
|
||||
static const uint8_t pngsig[8] = {137, 80, 78, 71, 13, 10, 26, 10};
|
||||
|
||||
static int png_probe(AVProbeData *pd)
|
||||
{
|
||||
@ -77,12 +79,12 @@ static int png_probe(AVProbeData *pd)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void *png_zalloc(void *opaque, unsigned int items, unsigned int size)
|
||||
static void *png_zalloc(void *opaque, unsigned int items, unsigned int size)
|
||||
{
|
||||
return av_malloc(items * size);
|
||||
}
|
||||
|
||||
void png_zfree(void *opaque, void *ptr)
|
||||
static void png_zfree(void *opaque, void *ptr)
|
||||
{
|
||||
av_free(ptr);
|
||||
}
|
||||
@ -287,6 +289,9 @@ static int png_read(ByteIOContext *f,
|
||||
s->color_type == PNG_COLOR_TYPE_GRAY) {
|
||||
info->pix_fmt = PIX_FMT_MONOBLACK;
|
||||
s->row_size = (s->width + 7) >> 3;
|
||||
} else if (s->color_type == PNG_COLOR_TYPE_PALETTE) {
|
||||
info->pix_fmt = PIX_FMT_PAL8;
|
||||
s->row_size = s->width;;
|
||||
} else {
|
||||
goto fail;
|
||||
}
|
||||
@ -306,6 +311,9 @@ static int png_read(ByteIOContext *f,
|
||||
#endif
|
||||
s->image_buf = info->pict.data[0];
|
||||
s->image_linesize = info->pict.linesize[0];
|
||||
/* copy the palette if needed */
|
||||
if (s->color_type == PNG_COLOR_TYPE_PALETTE)
|
||||
memcpy(info->pict.data[1], s->palette, 256 * sizeof(uint32_t));
|
||||
/* empty row is used if differencing to the first row */
|
||||
s->empty_row = av_mallocz(s->row_size);
|
||||
if (!s->empty_row)
|
||||
@ -323,6 +331,43 @@ static int png_read(ByteIOContext *f,
|
||||
/* skip crc */
|
||||
crc = get_be32(f);
|
||||
break;
|
||||
case MKTAG('P', 'L', 'T', 'E'):
|
||||
{
|
||||
int n, i, r, g, b;
|
||||
|
||||
if ((length % 3) != 0 || length > 256 * 3)
|
||||
goto skip_tag;
|
||||
/* read the palette */
|
||||
n = length / 3;
|
||||
for(i=0;i<n;i++) {
|
||||
r = get_byte(f);
|
||||
g = get_byte(f);
|
||||
b = get_byte(f);
|
||||
s->palette[i] = (0xff << 24) | (r << 16) | (g << 8) | b;
|
||||
}
|
||||
for(;i<256;i++) {
|
||||
s->palette[i] = (0xff << 24);
|
||||
}
|
||||
s->state |= PNG_PLTE;
|
||||
crc = get_be32(f);
|
||||
}
|
||||
break;
|
||||
case MKTAG('t', 'R', 'N', 'S'):
|
||||
{
|
||||
int v, i;
|
||||
|
||||
/* read the transparency. XXX: Only palette mode supported */
|
||||
if (s->color_type != PNG_COLOR_TYPE_PALETTE ||
|
||||
length > 256 ||
|
||||
!(s->state & PNG_PLTE))
|
||||
goto skip_tag;
|
||||
for(i=0;i<length;i++) {
|
||||
v = get_byte(f);
|
||||
s->palette[i] = (s->palette[i] & 0x00ffffff) | (v << 24);
|
||||
}
|
||||
crc = get_be32(f);
|
||||
}
|
||||
break;
|
||||
case MKTAG('I', 'E', 'N', 'D'):
|
||||
if (!(s->state & PNG_ALLIMAGE))
|
||||
goto fail;
|
||||
@ -330,6 +375,7 @@ static int png_read(ByteIOContext *f,
|
||||
goto exit_loop;
|
||||
default:
|
||||
/* skip tag */
|
||||
skip_tag:
|
||||
url_fskip(f, length + 4);
|
||||
break;
|
||||
}
|
||||
@ -399,6 +445,11 @@ static int png_write(ByteIOContext *f, AVImageInfo *info)
|
||||
color_type = PNG_COLOR_TYPE_GRAY;
|
||||
row_size = (info->width + 7) >> 3;
|
||||
break;
|
||||
case PIX_FMT_PAL8:
|
||||
bit_depth = 8;
|
||||
color_type = PNG_COLOR_TYPE_PALETTE;
|
||||
row_size = info->width;
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
@ -426,6 +477,34 @@ static int png_write(ByteIOContext *f, AVImageInfo *info)
|
||||
|
||||
png_write_chunk(f, MKTAG('I', 'H', 'D', 'R'), buf, 13);
|
||||
|
||||
/* put the palette if needed */
|
||||
if (color_type == PNG_COLOR_TYPE_PALETTE) {
|
||||
int has_alpha, alpha, i;
|
||||
unsigned int v;
|
||||
uint32_t *palette;
|
||||
uint8_t *alpha_ptr;
|
||||
|
||||
palette = (uint32_t *)info->pict.data[1];
|
||||
ptr = buf;
|
||||
alpha_ptr = buf + 256 * 3;
|
||||
has_alpha = 0;
|
||||
for(i = 0; i < 256; i++) {
|
||||
v = palette[i];
|
||||
alpha = v >> 24;
|
||||
if (alpha != 0xff)
|
||||
has_alpha = 1;
|
||||
*alpha_ptr++ = alpha;
|
||||
ptr[0] = v >> 16;
|
||||
ptr[1] = v >> 8;
|
||||
ptr[2] = v;
|
||||
ptr += 3;
|
||||
}
|
||||
png_write_chunk(f, MKTAG('P', 'L', 'T', 'E'), buf, 256 * 3);
|
||||
if (has_alpha) {
|
||||
png_write_chunk(f, MKTAG('t', 'R', 'N', 'S'), buf + 256 * 3, 256);
|
||||
}
|
||||
}
|
||||
|
||||
/* now put each row */
|
||||
zstream.avail_out = IOBUF_SIZE;
|
||||
zstream.next_out = buf;
|
||||
@ -481,6 +560,6 @@ AVImageFormat png_image_format = {
|
||||
"png",
|
||||
png_probe,
|
||||
png_read,
|
||||
(1 << PIX_FMT_RGB24) | (1 << PIX_FMT_GRAY8) | (1 << PIX_FMT_MONOBLACK),
|
||||
(1 << PIX_FMT_RGB24) | (1 << PIX_FMT_GRAY8) | (1 << PIX_FMT_MONOBLACK) | (1 << PIX_FMT_PAL8),
|
||||
png_write,
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user