Mercurial > libavcodec.hg
annotate pngdec.c @ 6323:e6da66f378c7 libavcodec
mpegvideo.h has two function declarations with the 'inline' specifier
but no definition for those functions. The C standard requires a
definition to appear in the same translation unit for any function
declared with 'inline'. Most of the files including mpegvideo.h do not
define those functions. Fix this by removing the 'inline' specifiers
from the header.
patch by Uoti Urpala
author | diego |
---|---|
date | Sun, 03 Feb 2008 17:54:30 +0000 |
parents | 817e302aae08 |
children | 0a403ade8c81 |
rev | line source |
---|---|
2342 | 1 /* |
2 * PNG image format | |
3 * Copyright (c) 2003 Fabrice Bellard. | |
4 * | |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3777
diff
changeset
|
5 * This file is part of FFmpeg. |
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3777
diff
changeset
|
6 * |
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3777
diff
changeset
|
7 * FFmpeg is free software; you can redistribute it and/or |
2342 | 8 * modify it under the terms of the GNU Lesser General Public |
9 * License as published by the Free Software Foundation; either | |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3777
diff
changeset
|
10 * version 2.1 of the License, or (at your option) any later version. |
2342 | 11 * |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3777
diff
changeset
|
12 * FFmpeg is distributed in the hope that it will be useful, |
2342 | 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
15 * Lesser General Public License for more details. | |
16 * | |
17 * You should have received a copy of the GNU Lesser General Public | |
3947
c8c591fe26f8
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
3777
diff
changeset
|
18 * License along with FFmpeg; if not, write to the Free Software |
3036
0b546eab515d
Update licensing information: The FSF changed postal address.
diego
parents:
2967
diff
changeset
|
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
2342 | 20 */ |
21 #include "avcodec.h" | |
5067 | 22 #include "bytestream.h" |
5337 | 23 #include "png.h" |
2342 | 24 |
25 /* TODO: | |
26 * - add 2, 4 and 16 bit depth support | |
27 */ | |
28 | |
29 #include <zlib.h> | |
30 | |
31 //#define DEBUG | |
32 | |
5339 | 33 typedef struct PNGDecContext { |
6245 | 34 const uint8_t *bytestream; |
35 const uint8_t *bytestream_start; | |
36 const uint8_t *bytestream_end; | |
5339 | 37 AVFrame picture; |
38 | |
39 int state; | |
40 int width, height; | |
41 int bit_depth; | |
42 int color_type; | |
43 int compression_type; | |
44 int interlace_type; | |
45 int filter_type; | |
46 int channels; | |
47 int bits_per_pixel; | |
48 int bpp; | |
49 | |
50 uint8_t *image_buf; | |
51 int image_linesize; | |
52 uint32_t palette[256]; | |
53 uint8_t *crow_buf; | |
54 uint8_t *last_row; | |
55 uint8_t *tmp_row; | |
56 int pass; | |
57 int crow_size; /* compressed row size (include filter type) */ | |
58 int row_size; /* decompressed row size */ | |
59 int pass_row_size; /* decompress row size of the current pass */ | |
60 int y; | |
61 z_stream zstream; | |
62 } PNGDecContext; | |
63 | |
2342 | 64 /* Mask to determine which y pixels can be written in a pass */ |
65 static const uint8_t png_pass_dsp_ymask[NB_PASSES] = { | |
66 0xff, 0xff, 0x0f, 0xcc, 0x33, 0xff, 0x55, | |
67 }; | |
68 | |
69 /* Mask to determine which pixels to overwrite while displaying */ | |
2967 | 70 static const uint8_t png_pass_dsp_mask[NB_PASSES] = { |
2342 | 71 0xff, 0x0f, 0xff, 0x33, 0xff, 0x55, 0xff |
72 }; | |
73 | |
74 /* NOTE: we try to construct a good looking image at each pass. width | |
5355 | 75 is the original image width. We also do pixel format conversion at |
2342 | 76 this stage */ |
2967 | 77 static void png_put_interlaced_row(uint8_t *dst, int width, |
78 int bits_per_pixel, int pass, | |
2342 | 79 int color_type, const uint8_t *src) |
80 { | |
81 int x, mask, dsp_mask, j, src_x, b, bpp; | |
82 uint8_t *d; | |
83 const uint8_t *s; | |
2967 | 84 |
5337 | 85 mask = ff_png_pass_mask[pass]; |
2342 | 86 dsp_mask = png_pass_dsp_mask[pass]; |
87 switch(bits_per_pixel) { | |
88 case 1: | |
5097 | 89 /* we must initialize the line to zero before writing to it */ |
2342 | 90 if (pass == 0) |
91 memset(dst, 0, (width + 7) >> 3); | |
92 src_x = 0; | |
93 for(x = 0; x < width; x++) { | |
94 j = (x & 7); | |
95 if ((dsp_mask << j) & 0x80) { | |
96 b = (src[src_x >> 3] >> (7 - (src_x & 7))) & 1; | |
97 dst[x >> 3] |= b << (7 - j); | |
98 } | |
99 if ((mask << j) & 0x80) | |
100 src_x++; | |
101 } | |
102 break; | |
103 default: | |
104 bpp = bits_per_pixel >> 3; | |
105 d = dst; | |
106 s = src; | |
107 if (color_type == PNG_COLOR_TYPE_RGB_ALPHA) { | |
108 for(x = 0; x < width; x++) { | |
109 j = x & 7; | |
110 if ((dsp_mask << j) & 0x80) { | |
111 *(uint32_t *)d = (s[3] << 24) | (s[0] << 16) | (s[1] << 8) | s[2]; | |
112 } | |
113 d += bpp; | |
114 if ((mask << j) & 0x80) | |
115 s += bpp; | |
116 } | |
117 } else { | |
118 for(x = 0; x < width; x++) { | |
119 j = x & 7; | |
120 if ((dsp_mask << j) & 0x80) { | |
121 memcpy(d, s, bpp); | |
122 } | |
123 d += bpp; | |
124 if ((mask << j) & 0x80) | |
125 s += bpp; | |
126 } | |
127 } | |
128 break; | |
129 } | |
130 } | |
131 | |
132 /* XXX: optimize */ | |
133 /* NOTE: 'dst' can be equal to 'last' */ | |
2967 | 134 static void png_filter_row(uint8_t *dst, int filter_type, |
2342 | 135 uint8_t *src, uint8_t *last, int size, int bpp) |
136 { | |
137 int i, p; | |
138 | |
139 switch(filter_type) { | |
140 case PNG_FILTER_VALUE_NONE: | |
141 memcpy(dst, src, size); | |
142 break; | |
143 case PNG_FILTER_VALUE_SUB: | |
144 for(i = 0; i < bpp; i++) { | |
145 dst[i] = src[i]; | |
146 } | |
147 for(i = bpp; i < size; i++) { | |
148 p = dst[i - bpp]; | |
149 dst[i] = p + src[i]; | |
150 } | |
151 break; | |
152 case PNG_FILTER_VALUE_UP: | |
153 for(i = 0; i < size; i++) { | |
154 p = last[i]; | |
155 dst[i] = p + src[i]; | |
156 } | |
157 break; | |
158 case PNG_FILTER_VALUE_AVG: | |
159 for(i = 0; i < bpp; i++) { | |
160 p = (last[i] >> 1); | |
161 dst[i] = p + src[i]; | |
162 } | |
163 for(i = bpp; i < size; i++) { | |
164 p = ((dst[i - bpp] + last[i]) >> 1); | |
165 dst[i] = p + src[i]; | |
166 } | |
167 break; | |
168 case PNG_FILTER_VALUE_PAETH: | |
169 for(i = 0; i < bpp; i++) { | |
170 p = last[i]; | |
171 dst[i] = p + src[i]; | |
172 } | |
173 for(i = bpp; i < size; i++) { | |
174 int a, b, c, pa, pb, pc; | |
175 | |
176 a = dst[i - bpp]; | |
177 b = last[i]; | |
178 c = last[i - bpp]; | |
179 | |
180 p = b - c; | |
181 pc = a - c; | |
182 | |
183 pa = abs(p); | |
184 pb = abs(pc); | |
185 pc = abs(p + pc); | |
186 | |
187 if (pa <= pb && pa <= pc) | |
188 p = a; | |
189 else if (pb <= pc) | |
190 p = b; | |
191 else | |
192 p = c; | |
193 dst[i] = p + src[i]; | |
194 } | |
195 break; | |
196 } | |
197 } | |
198 | |
4515 | 199 static void convert_to_rgb32(uint8_t *dst, const uint8_t *src, int width) |
2342 | 200 { |
201 int j; | |
202 unsigned int r, g, b, a; | |
203 | |
204 for(j = 0;j < width; j++) { | |
205 r = src[0]; | |
206 g = src[1]; | |
207 b = src[2]; | |
208 a = src[3]; | |
209 *(uint32_t *)dst = (a << 24) | (r << 16) | (g << 8) | b; | |
210 dst += 4; | |
211 src += 4; | |
212 } | |
213 } | |
214 | |
215 /* process exactly one decompressed row */ | |
5339 | 216 static void png_handle_row(PNGDecContext *s) |
2342 | 217 { |
218 uint8_t *ptr, *last_row; | |
219 int got_line; | |
2967 | 220 |
2342 | 221 if (!s->interlace_type) { |
222 ptr = s->image_buf + s->image_linesize * s->y; | |
223 /* need to swap bytes correctly for RGB_ALPHA */ | |
224 if (s->color_type == PNG_COLOR_TYPE_RGB_ALPHA) { | |
2967 | 225 png_filter_row(s->tmp_row, s->crow_buf[0], s->crow_buf + 1, |
2342 | 226 s->last_row, s->row_size, s->bpp); |
227 memcpy(s->last_row, s->tmp_row, s->row_size); | |
4515 | 228 convert_to_rgb32(ptr, s->tmp_row, s->width); |
2342 | 229 } else { |
230 /* in normal case, we avoid one copy */ | |
231 if (s->y == 0) | |
232 last_row = s->last_row; | |
233 else | |
234 last_row = ptr - s->image_linesize; | |
2967 | 235 |
236 png_filter_row(ptr, s->crow_buf[0], s->crow_buf + 1, | |
2342 | 237 last_row, s->row_size, s->bpp); |
238 } | |
239 s->y++; | |
240 if (s->y == s->height) { | |
241 s->state |= PNG_ALLIMAGE; | |
242 } | |
243 } else { | |
244 got_line = 0; | |
245 for(;;) { | |
246 ptr = s->image_buf + s->image_linesize * s->y; | |
5337 | 247 if ((ff_png_pass_ymask[s->pass] << (s->y & 7)) & 0x80) { |
2342 | 248 /* if we already read one row, it is time to stop to |
249 wait for the next one */ | |
250 if (got_line) | |
251 break; | |
2967 | 252 png_filter_row(s->tmp_row, s->crow_buf[0], s->crow_buf + 1, |
2342 | 253 s->last_row, s->pass_row_size, s->bpp); |
254 memcpy(s->last_row, s->tmp_row, s->pass_row_size); | |
255 got_line = 1; | |
256 } | |
257 if ((png_pass_dsp_ymask[s->pass] << (s->y & 7)) & 0x80) { | |
4515 | 258 /* NOTE: RGB32 is handled directly in png_put_interlaced_row */ |
2967 | 259 png_put_interlaced_row(ptr, s->width, s->bits_per_pixel, s->pass, |
2342 | 260 s->color_type, s->last_row); |
261 } | |
262 s->y++; | |
263 if (s->y == s->height) { | |
264 for(;;) { | |
265 if (s->pass == NB_PASSES - 1) { | |
266 s->state |= PNG_ALLIMAGE; | |
267 goto the_end; | |
268 } else { | |
269 s->pass++; | |
270 s->y = 0; | |
5337 | 271 s->pass_row_size = ff_png_pass_row_size(s->pass, |
2967 | 272 s->bits_per_pixel, |
2342 | 273 s->width); |
274 s->crow_size = s->pass_row_size + 1; | |
275 if (s->pass_row_size != 0) | |
276 break; | |
277 /* skip pass if empty row */ | |
278 } | |
279 } | |
280 } | |
281 } | |
282 the_end: ; | |
283 } | |
284 } | |
285 | |
5339 | 286 static int png_decode_idat(PNGDecContext *s, int length) |
2342 | 287 { |
288 int ret; | |
289 s->zstream.avail_in = length; | |
290 s->zstream.next_in = s->bytestream; | |
291 s->bytestream += length; | |
2967 | 292 |
2342 | 293 if(s->bytestream > s->bytestream_end) |
294 return -1; | |
295 | |
296 /* decode one line if possible */ | |
297 while (s->zstream.avail_in > 0) { | |
298 ret = inflate(&s->zstream, Z_PARTIAL_FLUSH); | |
299 if (ret != Z_OK && ret != Z_STREAM_END) { | |
300 return -1; | |
301 } | |
302 if (s->zstream.avail_out == 0) { | |
303 if (!(s->state & PNG_ALLIMAGE)) { | |
304 png_handle_row(s); | |
305 } | |
306 s->zstream.avail_out = s->crow_size; | |
307 s->zstream.next_out = s->crow_buf; | |
308 } | |
309 } | |
310 return 0; | |
311 } | |
312 | |
2967 | 313 static int decode_frame(AVCodecContext *avctx, |
2342 | 314 void *data, int *data_size, |
6245 | 315 const uint8_t *buf, int buf_size) |
2342 | 316 { |
5339 | 317 PNGDecContext * const s = avctx->priv_data; |
2342 | 318 AVFrame *picture = data; |
319 AVFrame * const p= (AVFrame*)&s->picture; | |
320 uint32_t tag, length; | |
321 int ret, crc; | |
322 | |
323 s->bytestream_start= | |
324 s->bytestream= buf; | |
325 s->bytestream_end= buf + buf_size; | |
326 | |
327 /* check signature */ | |
5337 | 328 if (memcmp(s->bytestream, ff_pngsig, 8) != 0) |
2342 | 329 return -1; |
330 s->bytestream+= 8; | |
331 s->y= | |
332 s->state=0; | |
5339 | 333 // memset(s, 0, sizeof(PNGDecContext)); |
2342 | 334 /* init the zlib */ |
5337 | 335 s->zstream.zalloc = ff_png_zalloc; |
336 s->zstream.zfree = ff_png_zfree; | |
2342 | 337 s->zstream.opaque = NULL; |
338 ret = inflateInit(&s->zstream); | |
339 if (ret != Z_OK) | |
340 return -1; | |
341 for(;;) { | |
2347
c6280d48be02
When bswap_32 is a macro, png images fail to decode properly, patch by (Milan Cutka <cutka>at<szm>dot<sk>)
michael
parents:
2342
diff
changeset
|
342 int tag32; |
2342 | 343 if (s->bytestream >= s->bytestream_end) |
344 goto fail; | |
5067 | 345 length = bytestream_get_be32(&s->bytestream); |
2342 | 346 if (length > 0x7fffffff) |
347 goto fail; | |
5067 | 348 tag32 = bytestream_get_be32(&s->bytestream); |
2347
c6280d48be02
When bswap_32 is a macro, png images fail to decode properly, patch by (Milan Cutka <cutka>at<szm>dot<sk>)
michael
parents:
2342
diff
changeset
|
349 tag = bswap_32(tag32); |
2342 | 350 #ifdef DEBUG |
3177 | 351 av_log(avctx, AV_LOG_DEBUG, "png: tag=%c%c%c%c length=%u\n", |
2342 | 352 (tag & 0xff), |
353 ((tag >> 8) & 0xff), | |
354 ((tag >> 16) & 0xff), | |
355 ((tag >> 24) & 0xff), length); | |
356 #endif | |
357 switch(tag) { | |
358 case MKTAG('I', 'H', 'D', 'R'): | |
359 if (length != 13) | |
360 goto fail; | |
5067 | 361 s->width = bytestream_get_be32(&s->bytestream); |
362 s->height = bytestream_get_be32(&s->bytestream); | |
2422 | 363 if(avcodec_check_dimensions(avctx, s->width, s->height)){ |
364 s->width= s->height= 0; | |
365 goto fail; | |
366 } | |
2342 | 367 s->bit_depth = *s->bytestream++; |
368 s->color_type = *s->bytestream++; | |
369 s->compression_type = *s->bytestream++; | |
370 s->filter_type = *s->bytestream++; | |
371 s->interlace_type = *s->bytestream++; | |
5067 | 372 crc = bytestream_get_be32(&s->bytestream); |
2342 | 373 s->state |= PNG_IHDR; |
374 #ifdef DEBUG | |
3177 | 375 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", |
2967 | 376 s->width, s->height, s->bit_depth, s->color_type, |
2342 | 377 s->compression_type, s->filter_type, s->interlace_type); |
378 #endif | |
379 break; | |
380 case MKTAG('I', 'D', 'A', 'T'): | |
381 if (!(s->state & PNG_IHDR)) | |
382 goto fail; | |
383 if (!(s->state & PNG_IDAT)) { | |
384 /* init image info */ | |
385 avctx->width = s->width; | |
386 avctx->height = s->height; | |
387 | |
5337 | 388 s->channels = ff_png_get_nb_channels(s->color_type); |
2342 | 389 s->bits_per_pixel = s->bit_depth * s->channels; |
390 s->bpp = (s->bits_per_pixel + 7) >> 3; | |
391 s->row_size = (avctx->width * s->bits_per_pixel + 7) >> 3; | |
392 | |
2967 | 393 if (s->bit_depth == 8 && |
2342 | 394 s->color_type == PNG_COLOR_TYPE_RGB) { |
395 avctx->pix_fmt = PIX_FMT_RGB24; | |
2967 | 396 } else if (s->bit_depth == 8 && |
2342 | 397 s->color_type == PNG_COLOR_TYPE_RGB_ALPHA) { |
4494
ce643a22f049
Replace deprecated PIX_FMT names by the newer variants.
diego
parents:
4379
diff
changeset
|
398 avctx->pix_fmt = PIX_FMT_RGB32; |
2967 | 399 } else if (s->bit_depth == 8 && |
2342 | 400 s->color_type == PNG_COLOR_TYPE_GRAY) { |
401 avctx->pix_fmt = PIX_FMT_GRAY8; | |
4067 | 402 } else if (s->bit_depth == 16 && |
403 s->color_type == PNG_COLOR_TYPE_GRAY) { | |
404 avctx->pix_fmt = PIX_FMT_GRAY16BE; | |
2967 | 405 } else if (s->bit_depth == 1 && |
2342 | 406 s->color_type == PNG_COLOR_TYPE_GRAY) { |
407 avctx->pix_fmt = PIX_FMT_MONOBLACK; | |
408 } else if (s->color_type == PNG_COLOR_TYPE_PALETTE) { | |
409 avctx->pix_fmt = PIX_FMT_PAL8; | |
410 } else { | |
411 goto fail; | |
412 } | |
413 if(p->data[0]) | |
414 avctx->release_buffer(avctx, p); | |
2967 | 415 |
2342 | 416 p->reference= 0; |
417 if(avctx->get_buffer(avctx, p) < 0){ | |
418 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); | |
419 goto fail; | |
420 } | |
421 p->pict_type= FF_I_TYPE; | |
422 p->key_frame= 1; | |
423 p->interlaced_frame = !!s->interlace_type; | |
424 | |
425 /* compute the compressed row size */ | |
426 if (!s->interlace_type) { | |
427 s->crow_size = s->row_size + 1; | |
428 } else { | |
429 s->pass = 0; | |
5337 | 430 s->pass_row_size = ff_png_pass_row_size(s->pass, |
2967 | 431 s->bits_per_pixel, |
2342 | 432 s->width); |
433 s->crow_size = s->pass_row_size + 1; | |
434 } | |
435 #ifdef DEBUG | |
3177 | 436 av_log(avctx, AV_LOG_DEBUG, "row_size=%d crow_size =%d\n", |
2342 | 437 s->row_size, s->crow_size); |
438 #endif | |
439 s->image_buf = p->data[0]; | |
440 s->image_linesize = p->linesize[0]; | |
441 /* copy the palette if needed */ | |
442 if (s->color_type == PNG_COLOR_TYPE_PALETTE) | |
443 memcpy(p->data[1], s->palette, 256 * sizeof(uint32_t)); | |
444 /* empty row is used if differencing to the first row */ | |
445 s->last_row = av_mallocz(s->row_size); | |
446 if (!s->last_row) | |
447 goto fail; | |
448 if (s->interlace_type || | |
449 s->color_type == PNG_COLOR_TYPE_RGB_ALPHA) { | |
450 s->tmp_row = av_malloc(s->row_size); | |
451 if (!s->tmp_row) | |
452 goto fail; | |
453 } | |
454 /* compressed row */ | |
455 s->crow_buf = av_malloc(s->row_size + 1); | |
456 if (!s->crow_buf) | |
457 goto fail; | |
458 s->zstream.avail_out = s->crow_size; | |
459 s->zstream.next_out = s->crow_buf; | |
460 } | |
461 s->state |= PNG_IDAT; | |
462 if (png_decode_idat(s, length) < 0) | |
463 goto fail; | |
464 /* skip crc */ | |
5067 | 465 crc = bytestream_get_be32(&s->bytestream); |
2342 | 466 break; |
467 case MKTAG('P', 'L', 'T', 'E'): | |
468 { | |
469 int n, i, r, g, b; | |
2967 | 470 |
2342 | 471 if ((length % 3) != 0 || length > 256 * 3) |
472 goto skip_tag; | |
473 /* read the palette */ | |
474 n = length / 3; | |
475 for(i=0;i<n;i++) { | |
476 r = *s->bytestream++; | |
477 g = *s->bytestream++; | |
478 b = *s->bytestream++; | |
479 s->palette[i] = (0xff << 24) | (r << 16) | (g << 8) | b; | |
480 } | |
481 for(;i<256;i++) { | |
482 s->palette[i] = (0xff << 24); | |
483 } | |
484 s->state |= PNG_PLTE; | |
5067 | 485 crc = bytestream_get_be32(&s->bytestream); |
2342 | 486 } |
487 break; | |
488 case MKTAG('t', 'R', 'N', 'S'): | |
489 { | |
490 int v, i; | |
491 | |
492 /* read the transparency. XXX: Only palette mode supported */ | |
493 if (s->color_type != PNG_COLOR_TYPE_PALETTE || | |
494 length > 256 || | |
495 !(s->state & PNG_PLTE)) | |
496 goto skip_tag; | |
497 for(i=0;i<length;i++) { | |
498 v = *s->bytestream++; | |
499 s->palette[i] = (s->palette[i] & 0x00ffffff) | (v << 24); | |
500 } | |
5067 | 501 crc = bytestream_get_be32(&s->bytestream); |
2342 | 502 } |
503 break; | |
504 case MKTAG('I', 'E', 'N', 'D'): | |
505 if (!(s->state & PNG_ALLIMAGE)) | |
506 goto fail; | |
5067 | 507 crc = bytestream_get_be32(&s->bytestream); |
2342 | 508 goto exit_loop; |
509 default: | |
510 /* skip tag */ | |
511 skip_tag: | |
512 s->bytestream += length + 4; | |
513 break; | |
514 } | |
515 } | |
516 exit_loop: | |
517 *picture= *(AVFrame*)&s->picture; | |
518 *data_size = sizeof(AVPicture); | |
519 | |
520 ret = s->bytestream - s->bytestream_start; | |
521 the_end: | |
522 inflateEnd(&s->zstream); | |
523 av_freep(&s->crow_buf); | |
524 av_freep(&s->last_row); | |
525 av_freep(&s->tmp_row); | |
526 return ret; | |
527 fail: | |
528 ret = -1; | |
529 goto the_end; | |
530 } | |
531 | |
5339 | 532 static int png_dec_init(AVCodecContext *avctx){ |
533 PNGDecContext *s = avctx->priv_data; | |
534 | |
535 avcodec_get_frame_defaults((AVFrame*)&s->picture); | |
536 avctx->coded_frame= (AVFrame*)&s->picture; | |
537 | |
538 return 0; | |
539 } | |
540 | |
2342 | 541 AVCodec png_decoder = { |
542 "png", | |
543 CODEC_TYPE_VIDEO, | |
544 CODEC_ID_PNG, | |
5339 | 545 sizeof(PNGDecContext), |
546 png_dec_init, | |
2342 | 547 NULL, |
548 NULL, //decode_end, | |
549 decode_frame, | |
550 0 /*CODEC_CAP_DR1*/ /*| CODEC_CAP_DRAW_HORIZ_BAND*/, | |
551 NULL | |
552 }; |