mirror of
https://git.ffmpeg.org/ffmpeg.git
synced 2025-01-02 13:02:13 +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_IHDR 0x0001
|
||||||
#define PNG_IDAT 0x0002
|
#define PNG_IDAT 0x0002
|
||||||
#define PNG_ALLIMAGE 0x0004
|
#define PNG_ALLIMAGE 0x0004
|
||||||
|
#define PNG_PLTE 0x0008
|
||||||
|
|
||||||
#define IOBUF_SIZE 4096
|
#define IOBUF_SIZE 4096
|
||||||
|
|
||||||
@ -58,6 +59,7 @@ typedef struct PNGDecodeState {
|
|||||||
|
|
||||||
uint8_t *image_buf;
|
uint8_t *image_buf;
|
||||||
int image_linesize;
|
int image_linesize;
|
||||||
|
uint32_t palette[256];
|
||||||
uint8_t *crow_buf;
|
uint8_t *crow_buf;
|
||||||
uint8_t *empty_row;
|
uint8_t *empty_row;
|
||||||
int crow_size; /* compressed row size (include filter type) */
|
int crow_size; /* compressed row size (include filter type) */
|
||||||
@ -66,7 +68,7 @@ typedef struct PNGDecodeState {
|
|||||||
z_stream zstream;
|
z_stream zstream;
|
||||||
} PNGDecodeState;
|
} 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)
|
static int png_probe(AVProbeData *pd)
|
||||||
{
|
{
|
||||||
@ -77,12 +79,12 @@ static int png_probe(AVProbeData *pd)
|
|||||||
return 0;
|
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);
|
return av_malloc(items * size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void png_zfree(void *opaque, void *ptr)
|
static void png_zfree(void *opaque, void *ptr)
|
||||||
{
|
{
|
||||||
av_free(ptr);
|
av_free(ptr);
|
||||||
}
|
}
|
||||||
@ -287,6 +289,9 @@ static int png_read(ByteIOContext *f,
|
|||||||
s->color_type == PNG_COLOR_TYPE_GRAY) {
|
s->color_type == PNG_COLOR_TYPE_GRAY) {
|
||||||
info->pix_fmt = PIX_FMT_MONOBLACK;
|
info->pix_fmt = PIX_FMT_MONOBLACK;
|
||||||
s->row_size = (s->width + 7) >> 3;
|
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 {
|
} else {
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
@ -306,6 +311,9 @@ static int png_read(ByteIOContext *f,
|
|||||||
#endif
|
#endif
|
||||||
s->image_buf = info->pict.data[0];
|
s->image_buf = info->pict.data[0];
|
||||||
s->image_linesize = info->pict.linesize[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 */
|
/* empty row is used if differencing to the first row */
|
||||||
s->empty_row = av_mallocz(s->row_size);
|
s->empty_row = av_mallocz(s->row_size);
|
||||||
if (!s->empty_row)
|
if (!s->empty_row)
|
||||||
@ -323,6 +331,43 @@ static int png_read(ByteIOContext *f,
|
|||||||
/* skip crc */
|
/* skip crc */
|
||||||
crc = get_be32(f);
|
crc = get_be32(f);
|
||||||
break;
|
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'):
|
case MKTAG('I', 'E', 'N', 'D'):
|
||||||
if (!(s->state & PNG_ALLIMAGE))
|
if (!(s->state & PNG_ALLIMAGE))
|
||||||
goto fail;
|
goto fail;
|
||||||
@ -330,6 +375,7 @@ static int png_read(ByteIOContext *f,
|
|||||||
goto exit_loop;
|
goto exit_loop;
|
||||||
default:
|
default:
|
||||||
/* skip tag */
|
/* skip tag */
|
||||||
|
skip_tag:
|
||||||
url_fskip(f, length + 4);
|
url_fskip(f, length + 4);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -399,6 +445,11 @@ static int png_write(ByteIOContext *f, AVImageInfo *info)
|
|||||||
color_type = PNG_COLOR_TYPE_GRAY;
|
color_type = PNG_COLOR_TYPE_GRAY;
|
||||||
row_size = (info->width + 7) >> 3;
|
row_size = (info->width + 7) >> 3;
|
||||||
break;
|
break;
|
||||||
|
case PIX_FMT_PAL8:
|
||||||
|
bit_depth = 8;
|
||||||
|
color_type = PNG_COLOR_TYPE_PALETTE;
|
||||||
|
row_size = info->width;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
return -1;
|
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);
|
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 */
|
/* now put each row */
|
||||||
zstream.avail_out = IOBUF_SIZE;
|
zstream.avail_out = IOBUF_SIZE;
|
||||||
zstream.next_out = buf;
|
zstream.next_out = buf;
|
||||||
@ -481,6 +560,6 @@ 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_RGB24) | (1 << PIX_FMT_GRAY8) | (1 << PIX_FMT_MONOBLACK) | (1 << PIX_FMT_PAL8),
|
||||||
png_write,
|
png_write,
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user