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/bprint.h"
00025 #include "libavutil/imgutils.h"
00026 #include "avcodec.h"
00027 #include "bytestream.h"
00028 #include "internal.h"
00029 #include "png.h"
00030 #include "pngdsp.h"
00031
00032
00033
00034
00035
00036 #include <zlib.h>
00037
00038
00039
00040 typedef struct PNGDecContext {
00041 PNGDSPContext dsp;
00042 AVCodecContext *avctx;
00043
00044 GetByteContext gb;
00045 AVFrame picture1, picture2;
00046 AVFrame *current_picture, *last_picture;
00047
00048 int state;
00049 int width, height;
00050 int bit_depth;
00051 int color_type;
00052 int compression_type;
00053 int interlace_type;
00054 int filter_type;
00055 int channels;
00056 int bits_per_pixel;
00057 int bpp;
00058
00059 uint8_t *image_buf;
00060 int image_linesize;
00061 uint32_t palette[256];
00062 uint8_t *crow_buf;
00063 uint8_t *last_row;
00064 uint8_t *tmp_row;
00065 int pass;
00066 int crow_size;
00067 int row_size;
00068 int pass_row_size;
00069 int y;
00070 z_stream zstream;
00071 } PNGDecContext;
00072
00073
00074 static const uint8_t png_pass_mask[NB_PASSES] = {
00075 0x01, 0x01, 0x11, 0x11, 0x55, 0x55, 0xff,
00076 };
00077
00078
00079 static const uint8_t png_pass_dsp_ymask[NB_PASSES] = {
00080 0xff, 0xff, 0x0f, 0xff, 0x33, 0xff, 0x55,
00081 };
00082
00083
00084 static const uint8_t png_pass_dsp_mask[NB_PASSES] = {
00085 0xff, 0x0f, 0xff, 0x33, 0xff, 0x55, 0xff
00086 };
00087
00088
00089
00090
00091 static void png_put_interlaced_row(uint8_t *dst, int width,
00092 int bits_per_pixel, int pass,
00093 int color_type, const uint8_t *src)
00094 {
00095 int x, mask, dsp_mask, j, src_x, b, bpp;
00096 uint8_t *d;
00097 const uint8_t *s;
00098
00099 mask = png_pass_mask[pass];
00100 dsp_mask = png_pass_dsp_mask[pass];
00101 switch(bits_per_pixel) {
00102 case 1:
00103 src_x = 0;
00104 for(x = 0; x < width; x++) {
00105 j = (x & 7);
00106 if ((dsp_mask << j) & 0x80) {
00107 b = (src[src_x >> 3] >> (7 - (src_x & 7))) & 1;
00108 dst[x >> 3] &= 0xFF7F>>j;
00109 dst[x >> 3] |= b << (7 - j);
00110 }
00111 if ((mask << j) & 0x80)
00112 src_x++;
00113 }
00114 break;
00115 case 2:
00116 src_x = 0;
00117 for(x = 0; x < width; x++) {
00118 int j2 = 2*(x&3);
00119 j = (x & 7);
00120 if ((dsp_mask << j) & 0x80) {
00121 b = (src[src_x >> 2] >> (6 - 2*(src_x & 3))) & 3;
00122 dst[x >> 2] &= 0xFF3F>>j2;
00123 dst[x >> 2] |= b << (6 - j2);
00124 }
00125 if ((mask << j) & 0x80)
00126 src_x++;
00127 }
00128 break;
00129 case 4:
00130 src_x = 0;
00131 for(x = 0; x < width; x++) {
00132 int j2 = 4*(x&1);
00133 j = (x & 7);
00134 if ((dsp_mask << j) & 0x80) {
00135 b = (src[src_x >> 1] >> (4 - 4*(src_x & 1))) & 15;
00136 dst[x >> 1] &= 0xFF0F>>j2;
00137 dst[x >> 1] |= b << (4 - j2);
00138 }
00139 if ((mask << j) & 0x80)
00140 src_x++;
00141 }
00142 break;
00143 default:
00144 bpp = bits_per_pixel >> 3;
00145 d = dst;
00146 s = src;
00147 for(x = 0; x < width; x++) {
00148 j = x & 7;
00149 if ((dsp_mask << j) & 0x80) {
00150 memcpy(d, s, bpp);
00151 }
00152 d += bpp;
00153 if ((mask << j) & 0x80)
00154 s += bpp;
00155 }
00156 break;
00157 }
00158 }
00159
00160 void ff_add_png_paeth_prediction(uint8_t *dst, uint8_t *src, uint8_t *top, int w, int bpp)
00161 {
00162 int i;
00163 for(i = 0; i < w; i++) {
00164 int a, b, c, p, pa, pb, pc;
00165
00166 a = dst[i - bpp];
00167 b = top[i];
00168 c = top[i - bpp];
00169
00170 p = b - c;
00171 pc = a - c;
00172
00173 pa = abs(p);
00174 pb = abs(pc);
00175 pc = abs(p + pc);
00176
00177 if (pa <= pb && pa <= pc)
00178 p = a;
00179 else if (pb <= pc)
00180 p = b;
00181 else
00182 p = c;
00183 dst[i] = p + src[i];
00184 }
00185 }
00186
00187 #define UNROLL1(bpp, op) {\
00188 r = dst[0];\
00189 if(bpp >= 2) g = dst[1];\
00190 if(bpp >= 3) b = dst[2];\
00191 if(bpp >= 4) a = dst[3];\
00192 for(; i < size; i+=bpp) {\
00193 dst[i+0] = r = op(r, src[i+0], last[i+0]);\
00194 if(bpp == 1) continue;\
00195 dst[i+1] = g = op(g, src[i+1], last[i+1]);\
00196 if(bpp == 2) continue;\
00197 dst[i+2] = b = op(b, src[i+2], last[i+2]);\
00198 if(bpp == 3) continue;\
00199 dst[i+3] = a = op(a, src[i+3], last[i+3]);\
00200 }\
00201 }
00202
00203 #define UNROLL_FILTER(op)\
00204 if(bpp == 1) UNROLL1(1, op)\
00205 else if(bpp == 2) UNROLL1(2, op)\
00206 else if(bpp == 3) UNROLL1(3, op)\
00207 else if(bpp == 4) UNROLL1(4, op)\
00208 else {\
00209 for (; i < size; i += bpp) {\
00210 int j;\
00211 for (j = 0; j < bpp; j++)\
00212 dst[i+j] = op(dst[i+j-bpp], src[i+j], last[i+j]);\
00213 }\
00214 }
00215
00216
00217 static void png_filter_row(PNGDSPContext *dsp, uint8_t *dst, int filter_type,
00218 uint8_t *src, uint8_t *last, int size, int bpp)
00219 {
00220 int i, p, r, g, b, a;
00221
00222 switch(filter_type) {
00223 case PNG_FILTER_VALUE_NONE:
00224 memcpy(dst, src, size);
00225 break;
00226 case PNG_FILTER_VALUE_SUB:
00227 for(i = 0; i < bpp; i++) {
00228 dst[i] = src[i];
00229 }
00230 if(bpp == 4) {
00231 p = *(int*)dst;
00232 for(; i < size; i+=bpp) {
00233 int s = *(int*)(src+i);
00234 p = ((s&0x7f7f7f7f) + (p&0x7f7f7f7f)) ^ ((s^p)&0x80808080);
00235 *(int*)(dst+i) = p;
00236 }
00237 } else {
00238 #define OP_SUB(x,s,l) x+s
00239 UNROLL_FILTER(OP_SUB);
00240 }
00241 break;
00242 case PNG_FILTER_VALUE_UP:
00243 dsp->add_bytes_l2(dst, src, last, size);
00244 break;
00245 case PNG_FILTER_VALUE_AVG:
00246 for(i = 0; i < bpp; i++) {
00247 p = (last[i] >> 1);
00248 dst[i] = p + src[i];
00249 }
00250 #define OP_AVG(x,s,l) (((x + l) >> 1) + s) & 0xff
00251 UNROLL_FILTER(OP_AVG);
00252 break;
00253 case PNG_FILTER_VALUE_PAETH:
00254 for(i = 0; i < bpp; i++) {
00255 p = last[i];
00256 dst[i] = p + src[i];
00257 }
00258 if(bpp > 2 && size > 4) {
00259
00260 int w = bpp==4 ? size : size-3;
00261 dsp->add_paeth_prediction(dst+i, src+i, last+i, w-i, bpp);
00262 i = w;
00263 }
00264 ff_add_png_paeth_prediction(dst+i, src+i, last+i, size-i, bpp);
00265 break;
00266 }
00267 }
00268
00269
00270
00271 #define YUV2RGB(NAME, TYPE) \
00272 static void deloco_ ## NAME(TYPE *dst, int size, int alpha) \
00273 { \
00274 int i; \
00275 for (i = 0; i < size; i += 3 + alpha) { \
00276 int g = dst [i+1]; \
00277 dst[i+0] += g; \
00278 dst[i+2] += g; \
00279 } \
00280 }
00281
00282 YUV2RGB(rgb8, uint8_t)
00283 YUV2RGB(rgb16, uint16_t)
00284
00285
00286 static void png_handle_row(PNGDecContext *s)
00287 {
00288 uint8_t *ptr, *last_row;
00289 int got_line;
00290
00291 if (!s->interlace_type) {
00292 ptr = s->image_buf + s->image_linesize * s->y;
00293 if (s->y == 0)
00294 last_row = s->last_row;
00295 else
00296 last_row = ptr - s->image_linesize;
00297
00298 png_filter_row(&s->dsp, ptr, s->crow_buf[0], s->crow_buf + 1,
00299 last_row, s->row_size, s->bpp);
00300
00301 if (s->filter_type == PNG_FILTER_TYPE_LOCO && s->y > 0) {
00302 if (s->bit_depth == 16) {
00303 deloco_rgb16((uint16_t *)(ptr - s->image_linesize), s->row_size / 2,
00304 s->color_type == PNG_COLOR_TYPE_RGB_ALPHA);
00305 } else {
00306 deloco_rgb8(ptr - s->image_linesize, s->row_size,
00307 s->color_type == PNG_COLOR_TYPE_RGB_ALPHA);
00308 }
00309 }
00310 s->y++;
00311 if (s->y == s->height) {
00312 s->state |= PNG_ALLIMAGE;
00313 if (s->filter_type == PNG_FILTER_TYPE_LOCO) {
00314 if (s->bit_depth == 16) {
00315 deloco_rgb16((uint16_t *)ptr, s->row_size / 2,
00316 s->color_type == PNG_COLOR_TYPE_RGB_ALPHA);
00317 } else {
00318 deloco_rgb8(ptr, s->row_size,
00319 s->color_type == PNG_COLOR_TYPE_RGB_ALPHA);
00320 }
00321 }
00322 }
00323 } else {
00324 got_line = 0;
00325 for(;;) {
00326 ptr = s->image_buf + s->image_linesize * s->y;
00327 if ((ff_png_pass_ymask[s->pass] << (s->y & 7)) & 0x80) {
00328
00329
00330 if (got_line)
00331 break;
00332 png_filter_row(&s->dsp, s->tmp_row, s->crow_buf[0], s->crow_buf + 1,
00333 s->last_row, s->pass_row_size, s->bpp);
00334 FFSWAP(uint8_t*, s->last_row, s->tmp_row);
00335 got_line = 1;
00336 }
00337 if ((png_pass_dsp_ymask[s->pass] << (s->y & 7)) & 0x80) {
00338 png_put_interlaced_row(ptr, s->width, s->bits_per_pixel, s->pass,
00339 s->color_type, s->last_row);
00340 }
00341 s->y++;
00342 if (s->y == s->height) {
00343 memset(s->last_row, 0, s->row_size);
00344 for(;;) {
00345 if (s->pass == NB_PASSES - 1) {
00346 s->state |= PNG_ALLIMAGE;
00347 goto the_end;
00348 } else {
00349 s->pass++;
00350 s->y = 0;
00351 s->pass_row_size = ff_png_pass_row_size(s->pass,
00352 s->bits_per_pixel,
00353 s->width);
00354 s->crow_size = s->pass_row_size + 1;
00355 if (s->pass_row_size != 0)
00356 break;
00357
00358 }
00359 }
00360 }
00361 }
00362 the_end: ;
00363 }
00364 }
00365
00366 static int png_decode_idat(PNGDecContext *s, int length)
00367 {
00368 int ret;
00369 s->zstream.avail_in = FFMIN(length, bytestream2_get_bytes_left(&s->gb));
00370 s->zstream.next_in = (unsigned char *)s->gb.buffer;
00371 bytestream2_skip(&s->gb, length);
00372
00373
00374 while (s->zstream.avail_in > 0) {
00375 ret = inflate(&s->zstream, Z_PARTIAL_FLUSH);
00376 if (ret != Z_OK && ret != Z_STREAM_END) {
00377 av_log(s->avctx, AV_LOG_ERROR, "inflate returned %d\n", ret);
00378 return -1;
00379 }
00380 if (s->zstream.avail_out == 0) {
00381 if (!(s->state & PNG_ALLIMAGE)) {
00382 png_handle_row(s);
00383 }
00384 s->zstream.avail_out = s->crow_size;
00385 s->zstream.next_out = s->crow_buf;
00386 }
00387 }
00388 return 0;
00389 }
00390
00391 static int decode_zbuf(AVBPrint *bp, const uint8_t *data,
00392 const uint8_t *data_end)
00393 {
00394 z_stream zstream;
00395 unsigned char *buf;
00396 unsigned buf_size;
00397 int ret;
00398
00399 zstream.zalloc = ff_png_zalloc;
00400 zstream.zfree = ff_png_zfree;
00401 zstream.opaque = NULL;
00402 if (inflateInit(&zstream) != Z_OK)
00403 return AVERROR_EXTERNAL;
00404 zstream.next_in = (unsigned char *)data;
00405 zstream.avail_in = data_end - data;
00406 av_bprint_init(bp, 0, -1);
00407
00408 while (zstream.avail_in > 0) {
00409 av_bprint_get_buffer(bp, 1, &buf, &buf_size);
00410 if (!buf_size) {
00411 ret = AVERROR(ENOMEM);
00412 goto fail;
00413 }
00414 zstream.next_out = buf;
00415 zstream.avail_out = buf_size;
00416 ret = inflate(&zstream, Z_PARTIAL_FLUSH);
00417 if (ret != Z_OK && ret != Z_STREAM_END) {
00418 ret = AVERROR_EXTERNAL;
00419 goto fail;
00420 }
00421 bp->len += zstream.next_out - buf;
00422 if (ret == Z_STREAM_END)
00423 break;
00424 }
00425 inflateEnd(&zstream);
00426 bp->str[bp->len] = 0;
00427 return 0;
00428
00429 fail:
00430 inflateEnd(&zstream);
00431 av_bprint_finalize(bp, NULL);
00432 return ret;
00433 }
00434
00435 static uint8_t *iso88591_to_utf8(const uint8_t *in, size_t size_in)
00436 {
00437 size_t extra = 0, i;
00438 uint8_t *out, *q;
00439
00440 for (i = 0; i < size_in; i++)
00441 extra += in[i] >= 0x80;
00442 if (size_in == SIZE_MAX || extra > SIZE_MAX - size_in - 1)
00443 return NULL;
00444 q = out = av_malloc(size_in + extra + 1);
00445 if (!out)
00446 return NULL;
00447 for (i = 0; i < size_in; i++) {
00448 if (in[i] >= 0x80) {
00449 *(q++) = 0xC0 | (in[i] >> 6);
00450 *(q++) = 0x80 | (in[i] & 0x3F);
00451 } else {
00452 *(q++) = in[i];
00453 }
00454 }
00455 *(q++) = 0;
00456 return out;
00457 }
00458
00459 static int decode_text_chunk(PNGDecContext *s, uint32_t length, int compressed,
00460 AVDictionary **dict)
00461 {
00462 int ret, method;
00463 const uint8_t *data = s->gb.buffer;
00464 const uint8_t *data_end = data + length;
00465 const uint8_t *keyword = data;
00466 const uint8_t *keyword_end = memchr(keyword, 0, data_end - keyword);
00467 uint8_t *kw_utf8 = NULL, *text, *txt_utf8 = NULL;
00468 unsigned text_len;
00469 AVBPrint bp;
00470
00471 if (!keyword_end)
00472 return AVERROR_INVALIDDATA;
00473 data = keyword_end + 1;
00474
00475 if (compressed) {
00476 if (data == data_end)
00477 return AVERROR_INVALIDDATA;
00478 method = *(data++);
00479 if (method)
00480 return AVERROR_INVALIDDATA;
00481 if ((ret = decode_zbuf(&bp, data, data_end)) < 0)
00482 return ret;
00483 text_len = bp.len;
00484 av_bprint_finalize(&bp, (char **)&text);
00485 if (!text)
00486 return AVERROR(ENOMEM);
00487 } else {
00488 text = (uint8_t *)data;
00489 text_len = data_end - text;
00490 }
00491
00492 kw_utf8 = iso88591_to_utf8(keyword, keyword_end - keyword);
00493 txt_utf8 = iso88591_to_utf8(text, text_len);
00494 if (text != data)
00495 av_free(text);
00496 if (!(kw_utf8 && txt_utf8)) {
00497 av_free(kw_utf8);
00498 av_free(txt_utf8);
00499 return AVERROR(ENOMEM);
00500 }
00501
00502 av_dict_set(dict, kw_utf8, txt_utf8,
00503 AV_DICT_DONT_STRDUP_KEY | AV_DICT_DONT_STRDUP_VAL);
00504 return 0;
00505 }
00506
00507 static int decode_frame(AVCodecContext *avctx,
00508 void *data, int *got_frame,
00509 AVPacket *avpkt)
00510 {
00511 const uint8_t *buf = avpkt->data;
00512 int buf_size = avpkt->size;
00513 PNGDecContext * const s = avctx->priv_data;
00514 AVFrame *picture = data;
00515 AVFrame *p;
00516 AVDictionary *metadata = NULL;
00517 uint8_t *crow_buf_base = NULL;
00518 uint32_t tag, length;
00519 int64_t sig;
00520 int ret;
00521
00522 FFSWAP(AVFrame *, s->current_picture, s->last_picture);
00523 avctx->coded_frame= s->current_picture;
00524 p = s->current_picture;
00525
00526 bytestream2_init(&s->gb, buf, buf_size);
00527
00528
00529 sig = bytestream2_get_be64(&s->gb);
00530 if (sig != PNGSIG &&
00531 sig != MNGSIG) {
00532 av_log(avctx, AV_LOG_ERROR, "Missing png signature\n");
00533 return -1;
00534 }
00535
00536 s->y=
00537 s->state=0;
00538
00539
00540 s->zstream.zalloc = ff_png_zalloc;
00541 s->zstream.zfree = ff_png_zfree;
00542 s->zstream.opaque = NULL;
00543 ret = inflateInit(&s->zstream);
00544 if (ret != Z_OK) {
00545 av_log(avctx, AV_LOG_ERROR, "inflateInit returned %d\n", ret);
00546 return -1;
00547 }
00548 for(;;) {
00549 if (bytestream2_get_bytes_left(&s->gb) <= 0) {
00550 av_log(avctx, AV_LOG_ERROR, "No bytes left\n");
00551 goto fail;
00552 }
00553
00554 length = bytestream2_get_be32(&s->gb);
00555 if (length > 0x7fffffff || length > bytestream2_get_bytes_left(&s->gb)) {
00556 av_log(avctx, AV_LOG_ERROR, "chunk too big\n");
00557 goto fail;
00558 }
00559 tag = bytestream2_get_le32(&s->gb);
00560 if (avctx->debug & FF_DEBUG_STARTCODE)
00561 av_log(avctx, AV_LOG_DEBUG, "png: tag=%c%c%c%c length=%u\n",
00562 (tag & 0xff),
00563 ((tag >> 8) & 0xff),
00564 ((tag >> 16) & 0xff),
00565 ((tag >> 24) & 0xff), length);
00566 switch(tag) {
00567 case MKTAG('I', 'H', 'D', 'R'):
00568 if (length != 13)
00569 goto fail;
00570 s->width = bytestream2_get_be32(&s->gb);
00571 s->height = bytestream2_get_be32(&s->gb);
00572 if(av_image_check_size(s->width, s->height, 0, avctx)){
00573 s->width= s->height= 0;
00574 av_log(avctx, AV_LOG_ERROR, "Invalid image size\n");
00575 goto fail;
00576 }
00577 s->bit_depth = bytestream2_get_byte(&s->gb);
00578 s->color_type = bytestream2_get_byte(&s->gb);
00579 s->compression_type = bytestream2_get_byte(&s->gb);
00580 s->filter_type = bytestream2_get_byte(&s->gb);
00581 s->interlace_type = bytestream2_get_byte(&s->gb);
00582 bytestream2_skip(&s->gb, 4);
00583 s->state |= PNG_IHDR;
00584 if (avctx->debug & FF_DEBUG_PICT_INFO)
00585 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",
00586 s->width, s->height, s->bit_depth, s->color_type,
00587 s->compression_type, s->filter_type, s->interlace_type);
00588 break;
00589 case MKTAG('p', 'H', 'Y', 's'):
00590 if (s->state & PNG_IDAT) {
00591 av_log(avctx, AV_LOG_ERROR, "pHYs after IDAT\n");
00592 goto fail;
00593 }
00594 avctx->sample_aspect_ratio.num = bytestream2_get_be32(&s->gb);
00595 avctx->sample_aspect_ratio.den = bytestream2_get_be32(&s->gb);
00596 if (avctx->sample_aspect_ratio.num < 0 || avctx->sample_aspect_ratio.den < 0)
00597 avctx->sample_aspect_ratio = (AVRational){ 0, 1 };
00598 bytestream2_skip(&s->gb, 1);
00599 bytestream2_skip(&s->gb, 4);
00600 break;
00601 case MKTAG('I', 'D', 'A', 'T'):
00602 if (!(s->state & PNG_IHDR)) {
00603 av_log(avctx, AV_LOG_ERROR, "IDAT without IHDR\n");
00604 goto fail;
00605 }
00606 if (!(s->state & PNG_IDAT)) {
00607
00608 avctx->width = s->width;
00609 avctx->height = s->height;
00610
00611 s->channels = ff_png_get_nb_channels(s->color_type);
00612 s->bits_per_pixel = s->bit_depth * s->channels;
00613 s->bpp = (s->bits_per_pixel + 7) >> 3;
00614 s->row_size = (avctx->width * s->bits_per_pixel + 7) >> 3;
00615
00616 if ((s->bit_depth == 2 || s->bit_depth == 4 || s->bit_depth == 8) &&
00617 s->color_type == PNG_COLOR_TYPE_RGB) {
00618 avctx->pix_fmt = AV_PIX_FMT_RGB24;
00619 } else if ((s->bit_depth == 2 || s->bit_depth == 4 || s->bit_depth == 8) &&
00620 s->color_type == PNG_COLOR_TYPE_RGB_ALPHA) {
00621 avctx->pix_fmt = AV_PIX_FMT_RGBA;
00622 } else if ((s->bit_depth == 2 || s->bit_depth == 4 || s->bit_depth == 8) &&
00623 s->color_type == PNG_COLOR_TYPE_GRAY) {
00624 avctx->pix_fmt = AV_PIX_FMT_GRAY8;
00625 } else if (s->bit_depth == 16 &&
00626 s->color_type == PNG_COLOR_TYPE_GRAY) {
00627 avctx->pix_fmt = AV_PIX_FMT_GRAY16BE;
00628 } else if (s->bit_depth == 16 &&
00629 s->color_type == PNG_COLOR_TYPE_RGB) {
00630 avctx->pix_fmt = AV_PIX_FMT_RGB48BE;
00631 } else if (s->bit_depth == 16 &&
00632 s->color_type == PNG_COLOR_TYPE_RGB_ALPHA) {
00633 avctx->pix_fmt = AV_PIX_FMT_RGBA64BE;
00634 } else if ((s->bits_per_pixel == 1 || s->bits_per_pixel == 2 || s->bits_per_pixel == 4 || s->bits_per_pixel == 8) &&
00635 s->color_type == PNG_COLOR_TYPE_PALETTE) {
00636 avctx->pix_fmt = AV_PIX_FMT_PAL8;
00637 } else if (s->bit_depth == 1) {
00638 avctx->pix_fmt = AV_PIX_FMT_MONOBLACK;
00639 } else if (s->bit_depth == 8 &&
00640 s->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) {
00641 avctx->pix_fmt = AV_PIX_FMT_Y400A;
00642 } else {
00643 av_log(avctx, AV_LOG_ERROR, "unsupported bit depth %d "
00644 "and color type %d\n",
00645 s->bit_depth, s->color_type);
00646 goto fail;
00647 }
00648 if(p->data[0])
00649 avctx->release_buffer(avctx, p);
00650
00651 p->reference= 3;
00652 if(ff_get_buffer(avctx, p) < 0){
00653 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
00654 goto fail;
00655 }
00656 p->pict_type= AV_PICTURE_TYPE_I;
00657 p->key_frame= 1;
00658 p->interlaced_frame = !!s->interlace_type;
00659
00660
00661 if (!s->interlace_type) {
00662 s->crow_size = s->row_size + 1;
00663 } else {
00664 s->pass = 0;
00665 s->pass_row_size = ff_png_pass_row_size(s->pass,
00666 s->bits_per_pixel,
00667 s->width);
00668 s->crow_size = s->pass_row_size + 1;
00669 }
00670 av_dlog(avctx, "row_size=%d crow_size =%d\n",
00671 s->row_size, s->crow_size);
00672 s->image_buf = p->data[0];
00673 s->image_linesize = p->linesize[0];
00674
00675 if (avctx->pix_fmt == AV_PIX_FMT_PAL8)
00676 memcpy(p->data[1], s->palette, 256 * sizeof(uint32_t));
00677
00678 s->last_row = av_mallocz(s->row_size);
00679 if (!s->last_row)
00680 goto fail;
00681 if (s->interlace_type ||
00682 s->color_type == PNG_COLOR_TYPE_RGB_ALPHA) {
00683 s->tmp_row = av_malloc(s->row_size);
00684 if (!s->tmp_row)
00685 goto fail;
00686 }
00687
00688 crow_buf_base = av_malloc(s->row_size + 16);
00689 if (!crow_buf_base)
00690 goto fail;
00691
00692
00693 s->crow_buf = crow_buf_base + 15;
00694 s->zstream.avail_out = s->crow_size;
00695 s->zstream.next_out = s->crow_buf;
00696 }
00697 s->state |= PNG_IDAT;
00698 if (png_decode_idat(s, length) < 0)
00699 goto fail;
00700 bytestream2_skip(&s->gb, 4);
00701 break;
00702 case MKTAG('P', 'L', 'T', 'E'):
00703 {
00704 int n, i, r, g, b;
00705
00706 if ((length % 3) != 0 || length > 256 * 3)
00707 goto skip_tag;
00708
00709 n = length / 3;
00710 for(i=0;i<n;i++) {
00711 r = bytestream2_get_byte(&s->gb);
00712 g = bytestream2_get_byte(&s->gb);
00713 b = bytestream2_get_byte(&s->gb);
00714 s->palette[i] = (0xFFU << 24) | (r << 16) | (g << 8) | b;
00715 }
00716 for(;i<256;i++) {
00717 s->palette[i] = (0xFFU << 24);
00718 }
00719 s->state |= PNG_PLTE;
00720 bytestream2_skip(&s->gb, 4);
00721 }
00722 break;
00723 case MKTAG('t', 'R', 'N', 'S'):
00724 {
00725 int v, i;
00726
00727
00728 if (s->color_type != PNG_COLOR_TYPE_PALETTE ||
00729 length > 256 ||
00730 !(s->state & PNG_PLTE))
00731 goto skip_tag;
00732 for(i=0;i<length;i++) {
00733 v = bytestream2_get_byte(&s->gb);
00734 s->palette[i] = (s->palette[i] & 0x00ffffff) | (v << 24);
00735 }
00736 bytestream2_skip(&s->gb, 4);
00737 }
00738 break;
00739 case MKTAG('t', 'E', 'X', 't'):
00740 if (decode_text_chunk(s, length, 0, &metadata) < 0)
00741 av_log(avctx, AV_LOG_WARNING, "Broken tEXt chunk\n");
00742 bytestream2_skip(&s->gb, length + 4);
00743 break;
00744 case MKTAG('z', 'T', 'X', 't'):
00745 if (decode_text_chunk(s, length, 1, &metadata) < 0)
00746 av_log(avctx, AV_LOG_WARNING, "Broken zTXt chunk\n");
00747 bytestream2_skip(&s->gb, length + 4);
00748 break;
00749 case MKTAG('I', 'E', 'N', 'D'):
00750 if (!(s->state & PNG_ALLIMAGE))
00751 av_log(avctx, AV_LOG_ERROR, "IEND without all image\n");
00752 if (!(s->state & (PNG_ALLIMAGE|PNG_IDAT))) {
00753 goto fail;
00754 }
00755 bytestream2_skip(&s->gb, 4);
00756 goto exit_loop;
00757 default:
00758
00759 skip_tag:
00760 bytestream2_skip(&s->gb, length + 4);
00761 break;
00762 }
00763 }
00764 exit_loop:
00765
00766 if(s->bits_per_pixel == 1 && s->color_type == PNG_COLOR_TYPE_PALETTE){
00767 int i, j;
00768 uint8_t *pd = s->current_picture->data[0];
00769 for(j=0; j < s->height; j++) {
00770 for(i=s->width/8-1; i>=0; i--) {
00771 pd[8*i+7]= pd[i] &1;
00772 pd[8*i+6]= (pd[i]>>1)&1;
00773 pd[8*i+5]= (pd[i]>>2)&1;
00774 pd[8*i+4]= (pd[i]>>3)&1;
00775 pd[8*i+3]= (pd[i]>>4)&1;
00776 pd[8*i+2]= (pd[i]>>5)&1;
00777 pd[8*i+1]= (pd[i]>>6)&1;
00778 pd[8*i+0]= pd[i]>>7;
00779 }
00780 pd += s->image_linesize;
00781 }
00782 }
00783 if(s->bits_per_pixel == 2){
00784 int i, j;
00785 uint8_t *pd = s->current_picture->data[0];
00786 for(j=0; j < s->height; j++) {
00787 if (s->color_type == PNG_COLOR_TYPE_PALETTE){
00788 for(i=s->width/4-1; i>=0; i--) {
00789 pd[4*i+3]= pd[i] &3;
00790 pd[4*i+2]= (pd[i]>>2)&3;
00791 pd[4*i+1]= (pd[i]>>4)&3;
00792 pd[4*i+0]= pd[i]>>6;
00793 }
00794 } else {
00795 for(i=s->width/4-1; i>=0; i--) {
00796 pd[4*i+3]= ( pd[i] &3)*0x55;
00797 pd[4*i+2]= ((pd[i]>>2)&3)*0x55;
00798 pd[4*i+1]= ((pd[i]>>4)&3)*0x55;
00799 pd[4*i+0]= ( pd[i]>>6 )*0x55;
00800 }
00801 }
00802 pd += s->image_linesize;
00803 }
00804 }
00805 if(s->bits_per_pixel == 4){
00806 int i, j;
00807 uint8_t *pd = s->current_picture->data[0];
00808 for(j=0; j < s->height; j++) {
00809 if (s->color_type == PNG_COLOR_TYPE_PALETTE){
00810 for(i=s->width/2-1; i>=0; i--) {
00811 pd[2*i+1]= pd[i]&15;
00812 pd[2*i+0]= pd[i]>>4;
00813 }
00814 } else {
00815 for(i=s->width/2-1; i>=0; i--) {
00816 pd[2*i+1]= (pd[i]&15)*0x11;
00817 pd[2*i+0]= (pd[i]>>4)*0x11;
00818 }
00819 }
00820 pd += s->image_linesize;
00821 }
00822 }
00823
00824
00825 if(s->last_picture->data[0] != NULL) {
00826 if( !(avpkt->flags & AV_PKT_FLAG_KEY)
00827 && s->last_picture->width == s->current_picture->width
00828 && s->last_picture->height== s->current_picture->height
00829 && s->last_picture->format== s->current_picture->format
00830 ) {
00831 int i, j;
00832 uint8_t *pd = s->current_picture->data[0];
00833 uint8_t *pd_last = s->last_picture->data[0];
00834
00835 for(j=0; j < s->height; j++) {
00836 for(i=0; i < s->width * s->bpp; i++) {
00837 pd[i] += pd_last[i];
00838 }
00839 pd += s->image_linesize;
00840 pd_last += s->image_linesize;
00841 }
00842 }
00843 }
00844
00845 s->current_picture->metadata = metadata;
00846 metadata = NULL;
00847 *picture= *s->current_picture;
00848 *got_frame = 1;
00849
00850 ret = bytestream2_tell(&s->gb);
00851 the_end:
00852 inflateEnd(&s->zstream);
00853 av_free(crow_buf_base);
00854 s->crow_buf = NULL;
00855 av_freep(&s->last_row);
00856 av_freep(&s->tmp_row);
00857 return ret;
00858 fail:
00859 av_dict_free(&metadata);
00860 ret = -1;
00861 goto the_end;
00862 }
00863
00864 static av_cold int png_dec_init(AVCodecContext *avctx)
00865 {
00866 PNGDecContext *s = avctx->priv_data;
00867
00868 s->current_picture = &s->picture1;
00869 s->last_picture = &s->picture2;
00870 avcodec_get_frame_defaults(&s->picture1);
00871 avcodec_get_frame_defaults(&s->picture2);
00872
00873 ff_pngdsp_init(&s->dsp);
00874
00875 s->avctx = avctx;
00876
00877 return 0;
00878 }
00879
00880 static av_cold int png_dec_end(AVCodecContext *avctx)
00881 {
00882 PNGDecContext *s = avctx->priv_data;
00883
00884 if (s->picture1.data[0])
00885 avctx->release_buffer(avctx, &s->picture1);
00886 if (s->picture2.data[0])
00887 avctx->release_buffer(avctx, &s->picture2);
00888
00889 return 0;
00890 }
00891
00892 AVCodec ff_png_decoder = {
00893 .name = "png",
00894 .type = AVMEDIA_TYPE_VIDEO,
00895 .id = AV_CODEC_ID_PNG,
00896 .priv_data_size = sizeof(PNGDecContext),
00897 .init = png_dec_init,
00898 .close = png_dec_end,
00899 .decode = decode_frame,
00900 .capabilities = CODEC_CAP_DR1 ,
00901 .long_name = NULL_IF_CONFIG_SMALL("PNG (Portable Network Graphics) image"),
00902 };