|
|
@ -172,23 +172,6 @@ static uint8_t *png_choose_filter(PNGEncContext *s, uint8_t *dst, |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static void convert_from_rgb32(uint8_t *dst, const uint8_t *src, int width) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
uint8_t *d; |
|
|
|
|
|
|
|
int j; |
|
|
|
|
|
|
|
unsigned int v; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
d = dst; |
|
|
|
|
|
|
|
for(j = 0; j < width; j++) { |
|
|
|
|
|
|
|
v = ((const uint32_t *)src)[j]; |
|
|
|
|
|
|
|
d[0] = v >> 16; |
|
|
|
|
|
|
|
d[1] = v >> 8; |
|
|
|
|
|
|
|
d[2] = v; |
|
|
|
|
|
|
|
d[3] = v >> 24; |
|
|
|
|
|
|
|
d += 4; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void png_write_chunk(uint8_t **f, uint32_t tag, |
|
|
|
static void png_write_chunk(uint8_t **f, uint32_t tag, |
|
|
|
const uint8_t *buf, int length) |
|
|
|
const uint8_t *buf, int length) |
|
|
|
{ |
|
|
|
{ |
|
|
@ -239,7 +222,6 @@ static int encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size, |
|
|
|
uint8_t *ptr, *top; |
|
|
|
uint8_t *ptr, *top; |
|
|
|
uint8_t *crow_base = NULL, *crow_buf, *crow; |
|
|
|
uint8_t *crow_base = NULL, *crow_buf, *crow; |
|
|
|
uint8_t *progressive_buf = NULL; |
|
|
|
uint8_t *progressive_buf = NULL; |
|
|
|
uint8_t *rgba_buf = NULL; |
|
|
|
|
|
|
|
uint8_t *top_buf = NULL; |
|
|
|
uint8_t *top_buf = NULL; |
|
|
|
|
|
|
|
|
|
|
|
*p = *pict; |
|
|
|
*p = *pict; |
|
|
@ -252,7 +234,7 @@ static int encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size, |
|
|
|
|
|
|
|
|
|
|
|
is_progressive = !!(avctx->flags & CODEC_FLAG_INTERLACED_DCT); |
|
|
|
is_progressive = !!(avctx->flags & CODEC_FLAG_INTERLACED_DCT); |
|
|
|
switch(avctx->pix_fmt) { |
|
|
|
switch(avctx->pix_fmt) { |
|
|
|
case PIX_FMT_RGB32: |
|
|
|
case PIX_FMT_RGBA: |
|
|
|
bit_depth = 8; |
|
|
|
bit_depth = 8; |
|
|
|
color_type = PNG_COLOR_TYPE_RGB_ALPHA; |
|
|
|
color_type = PNG_COLOR_TYPE_RGB_ALPHA; |
|
|
|
break; |
|
|
|
break; |
|
|
@ -305,12 +287,7 @@ static int encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size, |
|
|
|
if (!progressive_buf) |
|
|
|
if (!progressive_buf) |
|
|
|
goto fail; |
|
|
|
goto fail; |
|
|
|
} |
|
|
|
} |
|
|
|
if (color_type == PNG_COLOR_TYPE_RGB_ALPHA) { |
|
|
|
if (is_progressive) { |
|
|
|
rgba_buf = av_malloc(row_size + 1); |
|
|
|
|
|
|
|
if (!rgba_buf) |
|
|
|
|
|
|
|
goto fail; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if (is_progressive || color_type == PNG_COLOR_TYPE_RGB_ALPHA) { |
|
|
|
|
|
|
|
top_buf = av_malloc(row_size + 1); |
|
|
|
top_buf = av_malloc(row_size + 1); |
|
|
|
if (!top_buf) |
|
|
|
if (!top_buf) |
|
|
|
goto fail; |
|
|
|
goto fail; |
|
|
@ -371,10 +348,6 @@ static int encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size, |
|
|
|
if ((ff_png_pass_ymask[pass] << (y & 7)) & 0x80) { |
|
|
|
if ((ff_png_pass_ymask[pass] << (y & 7)) & 0x80) { |
|
|
|
ptr = p->data[0] + y * p->linesize[0]; |
|
|
|
ptr = p->data[0] + y * p->linesize[0]; |
|
|
|
FFSWAP(uint8_t*, progressive_buf, top_buf); |
|
|
|
FFSWAP(uint8_t*, progressive_buf, top_buf); |
|
|
|
if (color_type == PNG_COLOR_TYPE_RGB_ALPHA) { |
|
|
|
|
|
|
|
convert_from_rgb32(rgba_buf, ptr, avctx->width); |
|
|
|
|
|
|
|
ptr = rgba_buf; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
png_get_interlaced_row(progressive_buf, pass_row_size, |
|
|
|
png_get_interlaced_row(progressive_buf, pass_row_size, |
|
|
|
bits_per_pixel, pass, |
|
|
|
bits_per_pixel, pass, |
|
|
|
ptr, avctx->width); |
|
|
|
ptr, avctx->width); |
|
|
@ -389,11 +362,6 @@ static int encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size, |
|
|
|
top = NULL; |
|
|
|
top = NULL; |
|
|
|
for(y = 0; y < avctx->height; y++) { |
|
|
|
for(y = 0; y < avctx->height; y++) { |
|
|
|
ptr = p->data[0] + y * p->linesize[0]; |
|
|
|
ptr = p->data[0] + y * p->linesize[0]; |
|
|
|
if (color_type == PNG_COLOR_TYPE_RGB_ALPHA) { |
|
|
|
|
|
|
|
FFSWAP(uint8_t*, rgba_buf, top_buf); |
|
|
|
|
|
|
|
convert_from_rgb32(rgba_buf, ptr, avctx->width); |
|
|
|
|
|
|
|
ptr = rgba_buf; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
crow = png_choose_filter(s, crow_buf, ptr, top, row_size, bits_per_pixel>>3); |
|
|
|
crow = png_choose_filter(s, crow_buf, ptr, top, row_size, bits_per_pixel>>3); |
|
|
|
png_write_row(s, crow, row_size + 1); |
|
|
|
png_write_row(s, crow, row_size + 1); |
|
|
|
top = ptr; |
|
|
|
top = ptr; |
|
|
@ -421,7 +389,6 @@ static int encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size, |
|
|
|
the_end: |
|
|
|
the_end: |
|
|
|
av_free(crow_base); |
|
|
|
av_free(crow_base); |
|
|
|
av_free(progressive_buf); |
|
|
|
av_free(progressive_buf); |
|
|
|
av_free(rgba_buf); |
|
|
|
|
|
|
|
av_free(top_buf); |
|
|
|
av_free(top_buf); |
|
|
|
deflateEnd(&s->zstream); |
|
|
|
deflateEnd(&s->zstream); |
|
|
|
return ret; |
|
|
|
return ret; |
|
|
@ -451,6 +418,6 @@ AVCodec ff_png_encoder = { |
|
|
|
.priv_data_size = sizeof(PNGEncContext), |
|
|
|
.priv_data_size = sizeof(PNGEncContext), |
|
|
|
.init = png_enc_init, |
|
|
|
.init = png_enc_init, |
|
|
|
.encode = encode_frame, |
|
|
|
.encode = encode_frame, |
|
|
|
.pix_fmts= (const enum PixelFormat[]){PIX_FMT_RGB24, PIX_FMT_RGB32, PIX_FMT_PAL8, PIX_FMT_GRAY8, PIX_FMT_GRAY8A, PIX_FMT_GRAY16BE, PIX_FMT_MONOBLACK, PIX_FMT_NONE}, |
|
|
|
.pix_fmts= (const enum PixelFormat[]){PIX_FMT_RGB24, PIX_FMT_RGBA, PIX_FMT_PAL8, PIX_FMT_GRAY8, PIX_FMT_GRAY8A, PIX_FMT_GRAY16BE, PIX_FMT_MONOBLACK, PIX_FMT_NONE}, |
|
|
|
.long_name= NULL_IF_CONFIG_SMALL("PNG image"), |
|
|
|
.long_name= NULL_IF_CONFIG_SMALL("PNG image"), |
|
|
|
}; |
|
|
|
}; |
|
|
|