#include "png.h"
/* TODO:
- * - add 2, 4 and 16 bit depth support
+ * - add 16 bit depth support
*/
#include <zlib.h>
dsp_mask = png_pass_dsp_mask[pass];
switch(bits_per_pixel) {
case 1:
- /* we must initialize the line to zero before writing to it */
- if (pass == 0)
- memset(dst, 0, (width + 7) >> 3);
src_x = 0;
for(x = 0; x < width; x++) {
j = (x & 7);
if ((dsp_mask << j) & 0x80) {
b = (src[src_x >> 3] >> (7 - (src_x & 7))) & 1;
+ dst[x >> 3] &= 0xFF7F>>j;
dst[x >> 3] |= b << (7 - j);
}
if ((mask << j) & 0x80)
src_x++;
}
break;
+ case 2:
+ src_x = 0;
+ for(x = 0; x < width; x++) {
+ int j2 = 2*(x&3);
+ j = (x & 7);
+ if ((dsp_mask << j) & 0x80) {
+ b = (src[src_x >> 2] >> (6 - 2*(src_x & 3))) & 3;
+ dst[x >> 2] &= 0xFF3F>>j2;
+ dst[x >> 2] |= b << (6 - j2);
+ }
+ if ((mask << j) & 0x80)
+ src_x++;
+ }
+ break;
+ case 4:
+ src_x = 0;
+ for(x = 0; x < width; x++) {
+ int j2 = 4*(x&1);
+ j = (x & 7);
+ if ((dsp_mask << j) & 0x80) {
+ b = (src[src_x >> 1] >> (4 - 4*(src_x & 1))) & 15;
+ dst[x >> 1] &= 0xFF0F>>j2;
+ dst[x >> 1] |= b << (4 - j2);
+ }
+ if ((mask << j) & 0x80)
+ src_x++;
+ }
+ break;
default:
bpp = bits_per_pixel >> 3;
d = dst;
}
s->y++;
if (s->y == s->height) {
+ memset(s->last_row, 0, s->row_size);
for(;;) {
if (s->pass == NB_PASSES - 1) {
s->state |= PNG_ALLIMAGE;
if(p->data[0])
avctx->release_buffer(avctx, p);
- p->reference= 0;
+ p->reference= 1;
if(avctx->get_buffer(avctx, p) < 0){
av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
goto fail;
}
}
exit_loop:
+
+ if(s->bits_per_pixel == 2){
+ int i, j;
+ uint8_t *pd = s->current_picture->data[0];
+ for(j=0; j < s->height; j++) {
+ for(i=s->width/4-1; i>=0; i--) {
+ pd[4*i+3]= pd[i] &3;
+ pd[4*i+2]= (pd[i]>>2)&3;
+ pd[4*i+1]= (pd[i]>>4)&3;
+ pd[4*i+0]= pd[i]>>6;
+ }
+ pd += s->image_linesize;
+ }
+ }
+ if(s->bits_per_pixel == 4){
+ int i, j;
+ uint8_t *pd = s->current_picture->data[0];
+ for(j=0; j < s->height; j++) {
+ for(i=s->width/2-1; i>=0; i--) {
+ pd[2*i+1]= pd[i]&15;
+ pd[2*i+0]= pd[i]>>4;
+ }
+ pd += s->image_linesize;
+ }
+ }
+
/* handle p-frames only if a predecessor frame is available */
if(s->last_picture->data[0] != NULL) {
if(!(avpkt->flags & AV_PKT_FLAG_KEY)) {
}
AVCodec ff_png_decoder = {
- "png",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_PNG,
- sizeof(PNGDecContext),
- png_dec_init,
- NULL,
- png_dec_end,
- decode_frame,
- CODEC_CAP_DR1 /*| CODEC_CAP_DRAW_HORIZ_BAND*/,
- NULL,
+ .name = "png",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_PNG,
+ .priv_data_size = sizeof(PNGDecContext),
+ .init = png_dec_init,
+ .close = png_dec_end,
+ .decode = decode_frame,
+ .capabilities = CODEC_CAP_DR1 /*| CODEC_CAP_DRAW_HORIZ_BAND*/,
.long_name = NULL_IF_CONFIG_SMALL("PNG image"),
};