*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "avcodec.h"
int channels;
int bits_per_pixel;
int bpp;
-
+
uint8_t *image_buf;
int image_linesize;
uint32_t palette[256];
return ((*b)[-4]<<24) + ((*b)[-3]<<16) + ((*b)[-2]<<8) + (*b)[-1];
}
+#ifdef CONFIG_ENCODERS
static void put32(uint8_t **b, unsigned int v){
*(*b)++= v>>24;
*(*b)++= v>>16;
*(*b)++= v>>8;
*(*b)++= v;
}
+#endif
static const uint8_t pngsig[8] = {137, 80, 78, 71, 13, 10, 26, 10};
};
/* Mask to determine which pixels to overwrite while displaying */
-static const uint8_t png_pass_dsp_mask[NB_PASSES] = {
+static const uint8_t png_pass_dsp_mask[NB_PASSES] = {
0xff, 0x0f, 0xff, 0x33, 0xff, 0x55, 0xff
};
#if 0
/* NOTE: we try to construct a good looking image at each pass. width
is the original image width. We also do pixel format convertion at
this stage */
-static void png_put_interlaced_row(uint8_t *dst, int width,
- int bits_per_pixel, int pass,
+static void png_put_interlaced_row(uint8_t *dst, int width,
+ int bits_per_pixel, int pass,
int color_type, const uint8_t *src)
{
int x, mask, dsp_mask, j, src_x, b, bpp;
uint8_t *d;
const uint8_t *s;
-
+
mask = png_pass_mask[pass];
dsp_mask = png_pass_dsp_mask[pass];
switch(bits_per_pixel) {
}
}
-static void png_get_interlaced_row(uint8_t *dst, int row_size,
- int bits_per_pixel, int pass,
+#ifdef CONFIG_ENCODERS
+static void png_get_interlaced_row(uint8_t *dst, int row_size,
+ int bits_per_pixel, int pass,
const uint8_t *src, int width)
{
int x, mask, dst_x, j, b, bpp;
break;
}
}
+#endif
/* 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)
{
int i, p;
}
}
+#ifdef CONFIG_ENCODERS
static void convert_from_rgba32(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 = ((uint32_t *)src)[j];
+ v = ((const uint32_t *)src)[j];
d[0] = v >> 16;
d[1] = v >> 8;
d[2] = v;
d += 4;
}
}
+#endif
+#ifdef CONFIG_DECODERS
static void convert_to_rgba32(uint8_t *dst, const uint8_t *src, int width)
{
int j;
{
uint8_t *ptr, *last_row;
int got_line;
-
+
if (!s->interlace_type) {
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) {
- png_filter_row(s->tmp_row, s->crow_buf[0], s->crow_buf + 1,
+ png_filter_row(s->tmp_row, s->crow_buf[0], s->crow_buf + 1,
s->last_row, s->row_size, s->bpp);
memcpy(s->last_row, s->tmp_row, s->row_size);
convert_to_rgba32(ptr, s->tmp_row, s->width);
last_row = s->last_row;
else
last_row = ptr - s->image_linesize;
-
- 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);
}
s->y++;
wait for the next one */
if (got_line)
break;
- png_filter_row(s->tmp_row, s->crow_buf[0], s->crow_buf + 1,
+ png_filter_row(s->tmp_row, s->crow_buf[0], s->crow_buf + 1,
s->last_row, s->pass_row_size, s->bpp);
memcpy(s->last_row, s->tmp_row, s->pass_row_size);
got_line = 1;
}
if ((png_pass_dsp_ymask[s->pass] << (s->y & 7)) & 0x80) {
/* NOTE: rgba32 is handled directly in png_put_interlaced_row */
- png_put_interlaced_row(ptr, s->width, s->bits_per_pixel, s->pass,
+ png_put_interlaced_row(ptr, s->width, s->bits_per_pixel, s->pass,
s->color_type, s->last_row);
}
s->y++;
} else {
s->pass++;
s->y = 0;
- s->pass_row_size = png_pass_row_size(s->pass,
- s->bits_per_pixel,
+ s->pass_row_size = png_pass_row_size(s->pass,
+ s->bits_per_pixel,
s->width);
s->crow_size = s->pass_row_size + 1;
if (s->pass_row_size != 0)
s->zstream.avail_in = length;
s->zstream.next_in = s->bytestream;
s->bytestream += length;
-
+
if(s->bytestream > s->bytestream_end)
return -1;
return 0;
}
-static int decode_frame(AVCodecContext *avctx,
+static int decode_frame(AVCodecContext *avctx,
void *data, int *data_size,
uint8_t *buf, int buf_size)
{
tag32 = get32(&s->bytestream);
tag = bswap_32(tag32);
#ifdef DEBUG
- printf("png: tag=%c%c%c%c length=%u\n",
+ av_log(avctx, AV_LOG_DEBUG, "png: tag=%c%c%c%c length=%u\n",
(tag & 0xff),
((tag >> 8) & 0xff),
((tag >> 16) & 0xff),
crc = get32(&s->bytestream);
s->state |= PNG_IHDR;
#ifdef DEBUG
- printf("width=%d height=%d depth=%d color_type=%d compression_type=%d filter_type=%d interlace_type=%d\n",
- s->width, s->height, s->bit_depth, s->color_type,
+ av_log(avctx, AV_LOG_DEBUG, "width=%d height=%d depth=%d color_type=%d compression_type=%d filter_type=%d interlace_type=%d\n",
+ s->width, s->height, s->bit_depth, s->color_type,
s->compression_type, s->filter_type, s->interlace_type);
#endif
break;
s->bpp = (s->bits_per_pixel + 7) >> 3;
s->row_size = (avctx->width * s->bits_per_pixel + 7) >> 3;
- if (s->bit_depth == 8 &&
+ if (s->bit_depth == 8 &&
s->color_type == PNG_COLOR_TYPE_RGB) {
avctx->pix_fmt = PIX_FMT_RGB24;
- } else if (s->bit_depth == 8 &&
+ } else if (s->bit_depth == 8 &&
s->color_type == PNG_COLOR_TYPE_RGB_ALPHA) {
avctx->pix_fmt = PIX_FMT_RGBA32;
- } else if (s->bit_depth == 8 &&
+ } else if (s->bit_depth == 8 &&
s->color_type == PNG_COLOR_TYPE_GRAY) {
avctx->pix_fmt = PIX_FMT_GRAY8;
- } else if (s->bit_depth == 1 &&
+ } else if (s->bit_depth == 1 &&
s->color_type == PNG_COLOR_TYPE_GRAY) {
avctx->pix_fmt = PIX_FMT_MONOBLACK;
} else if (s->color_type == PNG_COLOR_TYPE_PALETTE) {
}
if(p->data[0])
avctx->release_buffer(avctx, p);
-
+
p->reference= 0;
if(avctx->get_buffer(avctx, p) < 0){
av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
s->crow_size = s->row_size + 1;
} else {
s->pass = 0;
- s->pass_row_size = png_pass_row_size(s->pass,
- s->bits_per_pixel,
+ s->pass_row_size = png_pass_row_size(s->pass,
+ s->bits_per_pixel,
s->width);
s->crow_size = s->pass_row_size + 1;
}
#ifdef DEBUG
- printf("row_size=%d crow_size =%d\n",
+ av_log(avctx, AV_LOG_DEBUG, "row_size=%d crow_size =%d\n",
s->row_size, s->crow_size);
#endif
s->image_buf = p->data[0];
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 */
ret = -1;
goto the_end;
}
+#endif
+#ifdef CONFIG_ENCODERS
static void png_write_chunk(uint8_t **f, uint32_t tag,
const uint8_t *buf, int length)
{
}
return 0;
}
+#endif /* CONFIG_ENCODERS */
static int common_init(AVCodecContext *avctx){
PNGContext *s = avctx->priv_data;
return 0;
}
+#ifdef CONFIG_ENCODERS
static int encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size, void *data){
PNGContext *s = avctx->priv_data;
AVFrame *pict = data;
*p = *pict;
p->pict_type= FF_I_TYPE;
p->key_frame= 1;
-
+
s->bytestream_start=
s->bytestream= buf;
s->bytestream_end= buf+buf_size;
/* write png header */
memcpy(s->bytestream, pngsig, 8);
s->bytestream += 8;
-
+
to_be32(s->buf, avctx->width);
to_be32(s->buf + 4, avctx->height);
s->buf[8] = bit_depth;
s->buf[10] = 0; /* compression type */
s->buf[11] = 0; /* filter type */
s->buf[12] = is_progressive; /* interlace type */
-
+
png_write_chunk(&s->bytestream, MKTAG('I', 'H', 'D', 'R'), s->buf, 13);
/* put the palette if needed */
unsigned int v;
uint32_t *palette;
uint8_t *alpha_ptr;
-
+
palette = (uint32_t *)p->data[1];
ptr = s->buf;
alpha_ptr = s->buf + 256 * 3;
} else {
ptr1 = ptr;
}
- png_get_interlaced_row(crow_buf + 1, pass_row_size,
- bits_per_pixel, pass,
+ png_get_interlaced_row(crow_buf + 1, pass_row_size,
+ bits_per_pixel, pass,
ptr1, avctx->width);
crow_buf[0] = PNG_FILTER_VALUE_NONE;
png_write_row(s, crow_buf, pass_row_size + 1);
ret = -1;
goto the_end;
}
+#endif
+#ifdef CONFIG_PNG_DECODER
AVCodec png_decoder = {
"png",
CODEC_TYPE_VIDEO,
0 /*CODEC_CAP_DR1*/ /*| CODEC_CAP_DRAW_HORIZ_BAND*/,
NULL
};
+#endif
+#ifdef CONFIG_PNG_ENCODER
AVCodec png_encoder = {
"png",
CODEC_TYPE_VIDEO,
NULL, //encode_end,
.pix_fmts= (enum PixelFormat[]){PIX_FMT_RGB24, PIX_FMT_RGBA32, PIX_FMT_PAL8, PIX_FMT_GRAY8, PIX_FMT_MONOBLACK, -1},
};
+#endif // CONFIG_PNG_ENCODER
#endif