00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "libavutil/imgutils.h"
00025 #include "avcodec.h"
00026 #include "bytestream.h"
00027 #include "png.h"
00028 #include "pngdsp.h"
00029
00030
00031
00032
00033
00034 #include <zlib.h>
00035
00036
00037
00038 typedef struct PNGDecContext {
00039 PNGDSPContext dsp;
00040
00041 GetByteContext gb;
00042 AVFrame picture1, picture2;
00043 AVFrame *current_picture, *last_picture;
00044
00045 int state;
00046 int width, height;
00047 int bit_depth;
00048 int color_type;
00049 int compression_type;
00050 int interlace_type;
00051 int filter_type;
00052 int channels;
00053 int bits_per_pixel;
00054 int bpp;
00055
00056 uint8_t *image_buf;
00057 int image_linesize;
00058 uint32_t palette[256];
00059 uint8_t *crow_buf;
00060 uint8_t *last_row;
00061 uint8_t *tmp_row;
00062 int pass;
00063 int crow_size;
00064 int row_size;
00065 int pass_row_size;
00066 int y;
00067 z_stream zstream;
00068 } PNGDecContext;
00069
00070
00071 static const uint8_t png_pass_mask[NB_PASSES] = {
00072 0x01, 0x01, 0x11, 0x11, 0x55, 0x55, 0xff,
00073 };
00074
00075
00076 static const uint8_t png_pass_dsp_ymask[NB_PASSES] = {
00077 0xff, 0xff, 0x0f, 0xff, 0x33, 0xff, 0x55,
00078 };
00079
00080
00081 static const uint8_t png_pass_dsp_mask[NB_PASSES] = {
00082 0xff, 0x0f, 0xff, 0x33, 0xff, 0x55, 0xff
00083 };
00084
00085
00086
00087
00088 static void png_put_interlaced_row(uint8_t *dst, int width,
00089 int bits_per_pixel, int pass,
00090 int color_type, const uint8_t *src)
00091 {
00092 int x, mask, dsp_mask, j, src_x, b, bpp;
00093 uint8_t *d;
00094 const uint8_t *s;
00095
00096 mask = png_pass_mask[pass];
00097 dsp_mask = png_pass_dsp_mask[pass];
00098 switch(bits_per_pixel) {
00099 case 1:
00100 src_x = 0;
00101 for(x = 0; x < width; x++) {
00102 j = (x & 7);
00103 if ((dsp_mask << j) & 0x80) {
00104 b = (src[src_x >> 3] >> (7 - (src_x & 7))) & 1;
00105 dst[x >> 3] &= 0xFF7F>>j;
00106 dst[x >> 3] |= b << (7 - j);
00107 }
00108 if ((mask << j) & 0x80)
00109 src_x++;
00110 }
00111 break;
00112 case 2:
00113 src_x = 0;
00114 for(x = 0; x < width; x++) {
00115 int j2 = 2*(x&3);
00116 j = (x & 7);
00117 if ((dsp_mask << j) & 0x80) {
00118 b = (src[src_x >> 2] >> (6 - 2*(src_x & 3))) & 3;
00119 dst[x >> 2] &= 0xFF3F>>j2;
00120 dst[x >> 2] |= b << (6 - j2);
00121 }
00122 if ((mask << j) & 0x80)
00123 src_x++;
00124 }
00125 break;
00126 case 4:
00127 src_x = 0;
00128 for(x = 0; x < width; x++) {
00129 int j2 = 4*(x&1);
00130 j = (x & 7);
00131 if ((dsp_mask << j) & 0x80) {
00132 b = (src[src_x >> 1] >> (4 - 4*(src_x & 1))) & 15;
00133 dst[x >> 1] &= 0xFF0F>>j2;
00134 dst[x >> 1] |= b << (4 - j2);
00135 }
00136 if ((mask << j) & 0x80)
00137 src_x++;
00138 }
00139 break;
00140 default:
00141 bpp = bits_per_pixel >> 3;
00142 d = dst;
00143 s = src;
00144 for(x = 0; x < width; x++) {
00145 j = x & 7;
00146 if ((dsp_mask << j) & 0x80) {
00147 memcpy(d, s, bpp);
00148 }
00149 d += bpp;
00150 if ((mask << j) & 0x80)
00151 s += bpp;
00152 }
00153 break;
00154 }
00155 }
00156
00157 void ff_add_png_paeth_prediction(uint8_t *dst, uint8_t *src, uint8_t *top, int w, int bpp)
00158 {
00159 int i;
00160 for(i = 0; i < w; i++) {
00161 int a, b, c, p, pa, pb, pc;
00162
00163 a = dst[i - bpp];
00164 b = top[i];
00165 c = top[i - bpp];
00166
00167 p = b - c;
00168 pc = a - c;
00169
00170 pa = abs(p);
00171 pb = abs(pc);
00172 pc = abs(p + pc);
00173
00174 if (pa <= pb && pa <= pc)
00175 p = a;
00176 else if (pb <= pc)
00177 p = b;
00178 else
00179 p = c;
00180 dst[i] = p + src[i];
00181 }
00182 }
00183
00184 #define UNROLL1(bpp, op) {\
00185 r = dst[0];\
00186 if(bpp >= 2) g = dst[1];\
00187 if(bpp >= 3) b = dst[2];\
00188 if(bpp >= 4) a = dst[3];\
00189 for(; i < size; i+=bpp) {\
00190 dst[i+0] = r = op(r, src[i+0], last[i+0]);\
00191 if(bpp == 1) continue;\
00192 dst[i+1] = g = op(g, src[i+1], last[i+1]);\
00193 if(bpp == 2) continue;\
00194 dst[i+2] = b = op(b, src[i+2], last[i+2]);\
00195 if(bpp == 3) continue;\
00196 dst[i+3] = a = op(a, src[i+3], last[i+3]);\
00197 }\
00198 }
00199
00200 #define UNROLL_FILTER(op)\
00201 if(bpp == 1) UNROLL1(1, op)\
00202 else if(bpp == 2) UNROLL1(2, op)\
00203 else if(bpp == 3) UNROLL1(3, op)\
00204 else if(bpp == 4) UNROLL1(4, op)\
00205 else {\
00206 for (; i < size; i += bpp) {\
00207 int j;\
00208 for (j = 0; j < bpp; j++)\
00209 dst[i+j] = op(dst[i+j-bpp], src[i+j], last[i+j]);\
00210 }\
00211 }
00212
00213
00214 static void png_filter_row(PNGDSPContext *dsp, uint8_t *dst, int filter_type,
00215 uint8_t *src, uint8_t *last, int size, int bpp)
00216 {
00217 int i, p, r, g, b, a;
00218
00219 switch(filter_type) {
00220 case PNG_FILTER_VALUE_NONE:
00221 memcpy(dst, src, size);
00222 break;
00223 case PNG_FILTER_VALUE_SUB:
00224 for(i = 0; i < bpp; i++) {
00225 dst[i] = src[i];
00226 }
00227 if(bpp == 4) {
00228 p = *(int*)dst;
00229 for(; i < size; i+=bpp) {
00230 int s = *(int*)(src+i);
00231 p = ((s&0x7f7f7f7f) + (p&0x7f7f7f7f)) ^ ((s^p)&0x80808080);
00232 *(int*)(dst+i) = p;
00233 }
00234 } else {
00235 #define OP_SUB(x,s,l) x+s
00236 UNROLL_FILTER(OP_SUB);
00237 }
00238 break;
00239 case PNG_FILTER_VALUE_UP:
00240 dsp->add_bytes_l2(dst, src, last, size);
00241 break;
00242 case PNG_FILTER_VALUE_AVG:
00243 for(i = 0; i < bpp; i++) {
00244 p = (last[i] >> 1);
00245 dst[i] = p + src[i];
00246 }
00247 #define OP_AVG(x,s,l) (((x + l) >> 1) + s) & 0xff
00248 UNROLL_FILTER(OP_AVG);
00249 break;
00250 case PNG_FILTER_VALUE_PAETH:
00251 for(i = 0; i < bpp; i++) {
00252 p = last[i];
00253 dst[i] = p + src[i];
00254 }
00255 if(bpp > 2 && size > 4) {
00256
00257 int w = bpp==4 ? size : size-3;
00258 dsp->add_paeth_prediction(dst+i, src+i, last+i, w-i, bpp);
00259 i = w;
00260 }
00261 ff_add_png_paeth_prediction(dst+i, src+i, last+i, size-i, bpp);
00262 break;
00263 }
00264 }
00265
00266
00267
00268 #define YUV2RGB(NAME, TYPE) \
00269 static void deloco_ ## NAME(TYPE *dst, int size, int alpha) \
00270 { \
00271 int i; \
00272 for (i = 0; i < size; i += 3 + alpha) { \
00273 int g = dst [i+1]; \
00274 dst[i+0] += g; \
00275 dst[i+2] += g; \
00276 } \
00277 }
00278
00279 YUV2RGB(rgb8, uint8_t)
00280 YUV2RGB(rgb16, uint16_t)
00281
00282
00283 static void png_handle_row(PNGDecContext *s)
00284 {
00285 uint8_t *ptr, *last_row;
00286 int got_line;
00287
00288 if (!s->interlace_type) {
00289 ptr = s->image_buf + s->image_linesize * s->y;
00290 if (s->y == 0)
00291 last_row = s->last_row;
00292 else
00293 last_row = ptr - s->image_linesize;
00294
00295 png_filter_row(&s->dsp, ptr, s->crow_buf[0], s->crow_buf + 1,
00296 last_row, s->row_size, s->bpp);
00297
00298 if (s->filter_type == PNG_FILTER_TYPE_LOCO && s->y > 0) {
00299 if (s->bit_depth == 16) {
00300 deloco_rgb16((uint16_t *)(ptr - s->image_linesize), s->row_size / 2,
00301 s->color_type == PNG_COLOR_TYPE_RGB_ALPHA);
00302 } else {
00303 deloco_rgb8(ptr - s->image_linesize, s->row_size,
00304 s->color_type == PNG_COLOR_TYPE_RGB_ALPHA);
00305 }
00306 }
00307 s->y++;
00308 if (s->y == s->height) {
00309 s->state |= PNG_ALLIMAGE;
00310 if (s->filter_type == PNG_FILTER_TYPE_LOCO) {
00311 if (s->bit_depth == 16) {
00312 deloco_rgb16((uint16_t *)ptr, s->row_size / 2,
00313 s->color_type == PNG_COLOR_TYPE_RGB_ALPHA);
00314 } else {
00315 deloco_rgb8(ptr, s->row_size,
00316 s->color_type == PNG_COLOR_TYPE_RGB_ALPHA);
00317 }
00318 }
00319 }
00320 } else {
00321 got_line = 0;
00322 for(;;) {
00323 ptr = s->image_buf + s->image_linesize * s->y;
00324 if ((ff_png_pass_ymask[s->pass] << (s->y & 7)) & 0x80) {
00325
00326
00327 if (got_line)
00328 break;
00329 png_filter_row(&s->dsp, s->tmp_row, s->crow_buf[0], s->crow_buf + 1,
00330 s->last_row, s->pass_row_size, s->bpp);
00331 FFSWAP(uint8_t*, s->last_row, s->tmp_row);
00332 got_line = 1;
00333 }
00334 if ((png_pass_dsp_ymask[s->pass] << (s->y & 7)) & 0x80) {
00335 png_put_interlaced_row(ptr, s->width, s->bits_per_pixel, s->pass,
00336 s->color_type, s->last_row);
00337 }
00338 s->y++;
00339 if (s->y == s->height) {
00340 memset(s->last_row, 0, s->row_size);
00341 for(;;) {
00342 if (s->pass == NB_PASSES - 1) {
00343 s->state |= PNG_ALLIMAGE;
00344 goto the_end;
00345 } else {
00346 s->pass++;
00347 s->y = 0;
00348 s->pass_row_size = ff_png_pass_row_size(s->pass,
00349 s->bits_per_pixel,
00350 s->width);
00351 s->crow_size = s->pass_row_size + 1;
00352 if (s->pass_row_size != 0)
00353 break;
00354
00355 }
00356 }
00357 }
00358 }
00359 the_end: ;
00360 }
00361 }
00362
00363 static int png_decode_idat(PNGDecContext *s, int length)
00364 {
00365 int ret;
00366 s->zstream.avail_in = FFMIN(length, bytestream2_get_bytes_left(&s->gb));
00367 s->zstream.next_in = (unsigned char *)s->gb.buffer;
00368 bytestream2_skip(&s->gb, length);
00369
00370
00371 while (s->zstream.avail_in > 0) {
00372 ret = inflate(&s->zstream, Z_PARTIAL_FLUSH);
00373 if (ret != Z_OK && ret != Z_STREAM_END) {
00374 return -1;
00375 }
00376 if (s->zstream.avail_out == 0) {
00377 if (!(s->state & PNG_ALLIMAGE)) {
00378 png_handle_row(s);
00379 }
00380 s->zstream.avail_out = s->crow_size;
00381 s->zstream.next_out = s->crow_buf;
00382 }
00383 }
00384 return 0;
00385 }
00386
00387 static int decode_frame(AVCodecContext *avctx,
00388 void *data, int *data_size,
00389 AVPacket *avpkt)
00390 {
00391 const uint8_t *buf = avpkt->data;
00392 int buf_size = avpkt->size;
00393 PNGDecContext * const s = avctx->priv_data;
00394 AVFrame *picture = data;
00395 AVFrame *p;
00396 uint8_t *crow_buf_base = NULL;
00397 uint32_t tag, length;
00398 int ret;
00399
00400 FFSWAP(AVFrame *, s->current_picture, s->last_picture);
00401 avctx->coded_frame= s->current_picture;
00402 p = s->current_picture;
00403
00404
00405 if (buf_size < 8 ||
00406 memcmp(buf, ff_pngsig, 8) != 0 &&
00407 memcmp(buf, ff_mngsig, 8) != 0) {
00408 av_log(avctx, AV_LOG_ERROR, "Missing png signature\n");
00409 return -1;
00410 }
00411
00412 bytestream2_init(&s->gb, buf + 8, buf_size - 8);
00413 s->y=
00414 s->state=0;
00415
00416
00417 s->zstream.zalloc = ff_png_zalloc;
00418 s->zstream.zfree = ff_png_zfree;
00419 s->zstream.opaque = NULL;
00420 ret = inflateInit(&s->zstream);
00421 if (ret != Z_OK)
00422 return -1;
00423 for(;;) {
00424 if (bytestream2_get_bytes_left(&s->gb) <= 0) {
00425 av_log(avctx, AV_LOG_ERROR, "No bytes left\n");
00426 goto fail;
00427 }
00428
00429 length = bytestream2_get_be32(&s->gb);
00430 if (length > 0x7fffffff || length > bytestream2_get_bytes_left(&s->gb)) {
00431 av_log(avctx, AV_LOG_ERROR, "chunk too big\n");
00432 goto fail;
00433 }
00434 tag = bytestream2_get_le32(&s->gb);
00435 if (avctx->debug & FF_DEBUG_STARTCODE)
00436 av_log(avctx, AV_LOG_DEBUG, "png: tag=%c%c%c%c length=%u\n",
00437 (tag & 0xff),
00438 ((tag >> 8) & 0xff),
00439 ((tag >> 16) & 0xff),
00440 ((tag >> 24) & 0xff), length);
00441 switch(tag) {
00442 case MKTAG('I', 'H', 'D', 'R'):
00443 if (length != 13)
00444 goto fail;
00445 s->width = bytestream2_get_be32(&s->gb);
00446 s->height = bytestream2_get_be32(&s->gb);
00447 if(av_image_check_size(s->width, s->height, 0, avctx)){
00448 s->width= s->height= 0;
00449 av_log(avctx, AV_LOG_ERROR, "Invalid image size\n");
00450 goto fail;
00451 }
00452 s->bit_depth = bytestream2_get_byte(&s->gb);
00453 s->color_type = bytestream2_get_byte(&s->gb);
00454 s->compression_type = bytestream2_get_byte(&s->gb);
00455 s->filter_type = bytestream2_get_byte(&s->gb);
00456 s->interlace_type = bytestream2_get_byte(&s->gb);
00457 bytestream2_skip(&s->gb, 4);
00458 s->state |= PNG_IHDR;
00459 if (avctx->debug & FF_DEBUG_PICT_INFO)
00460 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",
00461 s->width, s->height, s->bit_depth, s->color_type,
00462 s->compression_type, s->filter_type, s->interlace_type);
00463 break;
00464 case MKTAG('I', 'D', 'A', 'T'):
00465 if (!(s->state & PNG_IHDR)) {
00466 av_log(avctx, AV_LOG_ERROR, "IDAT without IHDR\n");
00467 goto fail;
00468 }
00469 if (!(s->state & PNG_IDAT)) {
00470
00471 avctx->width = s->width;
00472 avctx->height = s->height;
00473
00474 s->channels = ff_png_get_nb_channels(s->color_type);
00475 s->bits_per_pixel = s->bit_depth * s->channels;
00476 s->bpp = (s->bits_per_pixel + 7) >> 3;
00477 s->row_size = (avctx->width * s->bits_per_pixel + 7) >> 3;
00478
00479 if ((s->bit_depth == 2 || s->bit_depth == 4 || s->bit_depth == 8) &&
00480 s->color_type == PNG_COLOR_TYPE_RGB) {
00481 avctx->pix_fmt = PIX_FMT_RGB24;
00482 } else if ((s->bit_depth == 2 || s->bit_depth == 4 || s->bit_depth == 8) &&
00483 s->color_type == PNG_COLOR_TYPE_RGB_ALPHA) {
00484 avctx->pix_fmt = PIX_FMT_RGBA;
00485 } else if ((s->bit_depth == 2 || s->bit_depth == 4 || s->bit_depth == 8) &&
00486 s->color_type == PNG_COLOR_TYPE_GRAY) {
00487 avctx->pix_fmt = PIX_FMT_GRAY8;
00488 } else if (s->bit_depth == 16 &&
00489 s->color_type == PNG_COLOR_TYPE_GRAY) {
00490 avctx->pix_fmt = PIX_FMT_GRAY16BE;
00491 } else if (s->bit_depth == 16 &&
00492 s->color_type == PNG_COLOR_TYPE_RGB) {
00493 avctx->pix_fmt = PIX_FMT_RGB48BE;
00494 } else if (s->bit_depth == 16 &&
00495 s->color_type == PNG_COLOR_TYPE_RGB_ALPHA) {
00496 avctx->pix_fmt = PIX_FMT_RGBA64BE;
00497 } else if ((s->bits_per_pixel == 1 || s->bits_per_pixel == 2 || s->bits_per_pixel == 4 || s->bits_per_pixel == 8) &&
00498 s->color_type == PNG_COLOR_TYPE_PALETTE) {
00499 avctx->pix_fmt = PIX_FMT_PAL8;
00500 } else if (s->bit_depth == 1) {
00501 avctx->pix_fmt = PIX_FMT_MONOBLACK;
00502 } else if (s->bit_depth == 8 &&
00503 s->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) {
00504 avctx->pix_fmt = PIX_FMT_Y400A;
00505 } else {
00506 av_log(avctx, AV_LOG_ERROR, "unsupported bit depth %d "
00507 "and color type %d\n",
00508 s->bit_depth, s->color_type);
00509 goto fail;
00510 }
00511 if(p->data[0])
00512 avctx->release_buffer(avctx, p);
00513
00514 p->reference= 3;
00515 if(avctx->get_buffer(avctx, p) < 0){
00516 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
00517 goto fail;
00518 }
00519 p->pict_type= AV_PICTURE_TYPE_I;
00520 p->key_frame= 1;
00521 p->interlaced_frame = !!s->interlace_type;
00522
00523
00524 if (!s->interlace_type) {
00525 s->crow_size = s->row_size + 1;
00526 } else {
00527 s->pass = 0;
00528 s->pass_row_size = ff_png_pass_row_size(s->pass,
00529 s->bits_per_pixel,
00530 s->width);
00531 s->crow_size = s->pass_row_size + 1;
00532 }
00533 av_dlog(avctx, "row_size=%d crow_size =%d\n",
00534 s->row_size, s->crow_size);
00535 s->image_buf = p->data[0];
00536 s->image_linesize = p->linesize[0];
00537
00538 if (avctx->pix_fmt == PIX_FMT_PAL8)
00539 memcpy(p->data[1], s->palette, 256 * sizeof(uint32_t));
00540
00541 s->last_row = av_mallocz(s->row_size);
00542 if (!s->last_row)
00543 goto fail;
00544 if (s->interlace_type ||
00545 s->color_type == PNG_COLOR_TYPE_RGB_ALPHA) {
00546 s->tmp_row = av_malloc(s->row_size);
00547 if (!s->tmp_row)
00548 goto fail;
00549 }
00550
00551 crow_buf_base = av_malloc(s->row_size + 16);
00552 if (!crow_buf_base)
00553 goto fail;
00554
00555
00556 s->crow_buf = crow_buf_base + 15;
00557 s->zstream.avail_out = s->crow_size;
00558 s->zstream.next_out = s->crow_buf;
00559 }
00560 s->state |= PNG_IDAT;
00561 if (png_decode_idat(s, length) < 0)
00562 goto fail;
00563 bytestream2_skip(&s->gb, 4);
00564 break;
00565 case MKTAG('P', 'L', 'T', 'E'):
00566 {
00567 int n, i, r, g, b;
00568
00569 if ((length % 3) != 0 || length > 256 * 3)
00570 goto skip_tag;
00571
00572 n = length / 3;
00573 for(i=0;i<n;i++) {
00574 r = bytestream2_get_byte(&s->gb);
00575 g = bytestream2_get_byte(&s->gb);
00576 b = bytestream2_get_byte(&s->gb);
00577 s->palette[i] = (0xff << 24) | (r << 16) | (g << 8) | b;
00578 }
00579 for(;i<256;i++) {
00580 s->palette[i] = (0xff << 24);
00581 }
00582 s->state |= PNG_PLTE;
00583 bytestream2_skip(&s->gb, 4);
00584 }
00585 break;
00586 case MKTAG('t', 'R', 'N', 'S'):
00587 {
00588 int v, i;
00589
00590
00591 if (s->color_type != PNG_COLOR_TYPE_PALETTE ||
00592 length > 256 ||
00593 !(s->state & PNG_PLTE))
00594 goto skip_tag;
00595 for(i=0;i<length;i++) {
00596 v = bytestream2_get_byte(&s->gb);
00597 s->palette[i] = (s->palette[i] & 0x00ffffff) | (v << 24);
00598 }
00599 bytestream2_skip(&s->gb, 4);
00600 }
00601 break;
00602 case MKTAG('I', 'E', 'N', 'D'):
00603 if (!(s->state & PNG_ALLIMAGE))
00604 av_log(avctx, AV_LOG_ERROR, "IEND without all image\n");
00605 if (!(s->state & (PNG_ALLIMAGE|PNG_IDAT))) {
00606 goto fail;
00607 }
00608 bytestream2_skip(&s->gb, 4);
00609 goto exit_loop;
00610 default:
00611
00612 skip_tag:
00613 bytestream2_skip(&s->gb, length + 4);
00614 break;
00615 }
00616 }
00617 exit_loop:
00618
00619 if(s->bits_per_pixel == 1 && s->color_type == PNG_COLOR_TYPE_PALETTE){
00620 int i, j;
00621 uint8_t *pd = s->current_picture->data[0];
00622 for(j=0; j < s->height; j++) {
00623 for(i=s->width/8-1; i>=0; i--) {
00624 pd[8*i+7]= pd[i] &1;
00625 pd[8*i+6]= (pd[i]>>1)&1;
00626 pd[8*i+5]= (pd[i]>>2)&1;
00627 pd[8*i+4]= (pd[i]>>3)&1;
00628 pd[8*i+3]= (pd[i]>>4)&1;
00629 pd[8*i+2]= (pd[i]>>5)&1;
00630 pd[8*i+1]= (pd[i]>>6)&1;
00631 pd[8*i+0]= pd[i]>>7;
00632 }
00633 pd += s->image_linesize;
00634 }
00635 }
00636 if(s->bits_per_pixel == 2){
00637 int i, j;
00638 uint8_t *pd = s->current_picture->data[0];
00639 for(j=0; j < s->height; j++) {
00640 if (s->color_type == PNG_COLOR_TYPE_PALETTE){
00641 for(i=s->width/4-1; i>=0; i--) {
00642 pd[4*i+3]= pd[i] &3;
00643 pd[4*i+2]= (pd[i]>>2)&3;
00644 pd[4*i+1]= (pd[i]>>4)&3;
00645 pd[4*i+0]= pd[i]>>6;
00646 }
00647 } else {
00648 for(i=s->width/4-1; i>=0; i--) {
00649 pd[4*i+3]= ( pd[i] &3)*0x55;
00650 pd[4*i+2]= ((pd[i]>>2)&3)*0x55;
00651 pd[4*i+1]= ((pd[i]>>4)&3)*0x55;
00652 pd[4*i+0]= ( pd[i]>>6 )*0x55;
00653 }
00654 }
00655 pd += s->image_linesize;
00656 }
00657 }
00658 if(s->bits_per_pixel == 4){
00659 int i, j;
00660 uint8_t *pd = s->current_picture->data[0];
00661 for(j=0; j < s->height; j++) {
00662 if (s->color_type == PNG_COLOR_TYPE_PALETTE){
00663 for(i=s->width/2-1; i>=0; i--) {
00664 pd[2*i+1]= pd[i]&15;
00665 pd[2*i+0]= pd[i]>>4;
00666 }
00667 } else {
00668 for(i=s->width/2-1; i>=0; i--) {
00669 pd[2*i+1]= (pd[i]&15)*0x11;
00670 pd[2*i+0]= (pd[i]>>4)*0x11;
00671 }
00672 }
00673 pd += s->image_linesize;
00674 }
00675 }
00676
00677
00678 if(s->last_picture->data[0] != NULL) {
00679 if( !(avpkt->flags & AV_PKT_FLAG_KEY)
00680 && s->last_picture->width == s->current_picture->width
00681 && s->last_picture->height== s->current_picture->height
00682 ) {
00683 int i, j;
00684 uint8_t *pd = s->current_picture->data[0];
00685 uint8_t *pd_last = s->last_picture->data[0];
00686
00687 for(j=0; j < s->height; j++) {
00688 for(i=0; i < s->width * s->bpp; i++) {
00689 pd[i] += pd_last[i];
00690 }
00691 pd += s->image_linesize;
00692 pd_last += s->image_linesize;
00693 }
00694 }
00695 }
00696
00697 *picture= *s->current_picture;
00698 *data_size = sizeof(AVFrame);
00699
00700 ret = bytestream2_tell(&s->gb);
00701 the_end:
00702 inflateEnd(&s->zstream);
00703 av_free(crow_buf_base);
00704 s->crow_buf = NULL;
00705 av_freep(&s->last_row);
00706 av_freep(&s->tmp_row);
00707 return ret;
00708 fail:
00709 ret = -1;
00710 goto the_end;
00711 }
00712
00713 static av_cold int png_dec_init(AVCodecContext *avctx)
00714 {
00715 PNGDecContext *s = avctx->priv_data;
00716
00717 s->current_picture = &s->picture1;
00718 s->last_picture = &s->picture2;
00719 avcodec_get_frame_defaults(&s->picture1);
00720 avcodec_get_frame_defaults(&s->picture2);
00721
00722 ff_pngdsp_init(&s->dsp);
00723
00724 return 0;
00725 }
00726
00727 static av_cold int png_dec_end(AVCodecContext *avctx)
00728 {
00729 PNGDecContext *s = avctx->priv_data;
00730
00731 if (s->picture1.data[0])
00732 avctx->release_buffer(avctx, &s->picture1);
00733 if (s->picture2.data[0])
00734 avctx->release_buffer(avctx, &s->picture2);
00735
00736 return 0;
00737 }
00738
00739 AVCodec ff_png_decoder = {
00740 .name = "png",
00741 .type = AVMEDIA_TYPE_VIDEO,
00742 .id = CODEC_ID_PNG,
00743 .priv_data_size = sizeof(PNGDecContext),
00744 .init = png_dec_init,
00745 .close = png_dec_end,
00746 .decode = decode_frame,
00747 .capabilities = CODEC_CAP_DR1 ,
00748 .long_name = NULL_IF_CONFIG_SMALL("PNG (Portable Network Graphics) image"),
00749 };