Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
Benoit Fouet authored on 2014/11/21 20:05:47... | ... |
@@ -2068,6 +2068,7 @@ amrwb_decoder_select="lsp" |
2068 | 2068 |
amv_decoder_select="sp5x_decoder exif" |
2069 | 2069 |
amv_encoder_select="aandcttables mpegvideoenc" |
2070 | 2070 |
ape_decoder_select="bswapdsp llauddsp" |
2071 |
+apng_decoder_select="zlib" |
|
2071 | 2072 |
asv1_decoder_select="blockdsp bswapdsp idctdsp" |
2072 | 2073 |
asv1_encoder_select="bswapdsp fdctdsp pixblockdsp" |
2073 | 2074 |
asv2_decoder_select="blockdsp bswapdsp idctdsp" |
... | ... |
@@ -136,6 +136,7 @@ OBJS-$(CONFIG_AMV_ENCODER) += mjpegenc.o mjpeg.o mjpegenc_common.o \ |
136 | 136 |
OBJS-$(CONFIG_ANM_DECODER) += anm.o |
137 | 137 |
OBJS-$(CONFIG_ANSI_DECODER) += ansi.o cga_data.o |
138 | 138 |
OBJS-$(CONFIG_APE_DECODER) += apedec.o |
139 |
+OBJS-$(CONFIG_APNG_DECODER) += png.o pngdec.o pngdsp.o |
|
139 | 140 |
OBJS-$(CONFIG_SSA_DECODER) += assdec.o ass.o ass_split.o |
140 | 141 |
OBJS-$(CONFIG_SSA_ENCODER) += assenc.o ass.o |
141 | 142 |
OBJS-$(CONFIG_ASS_DECODER) += assdec.o ass.o ass_split.o |
... | ... |
@@ -105,6 +105,7 @@ void avcodec_register_all(void) |
105 | 105 |
REGISTER_ENCDEC (AMV, amv); |
106 | 106 |
REGISTER_DECODER(ANM, anm); |
107 | 107 |
REGISTER_DECODER(ANSI, ansi); |
108 |
+ REGISTER_DECODER(APNG, apng); |
|
108 | 109 |
REGISTER_ENCDEC (ASV1, asv1); |
109 | 110 |
REGISTER_ENCDEC (ASV2, asv2); |
110 | 111 |
REGISTER_DECODER(AURA, aura); |
... | ... |
@@ -319,6 +319,7 @@ enum AVCodecID { |
319 | 319 |
AV_CODEC_ID_HEVC = MKBETAG('H','2','6','5'), |
320 | 320 |
#define AV_CODEC_ID_H265 AV_CODEC_ID_HEVC |
321 | 321 |
AV_CODEC_ID_VP7 = MKBETAG('V','P','7','0'), |
322 |
+ AV_CODEC_ID_APNG = MKBETAG('A','P','N','G'), |
|
322 | 323 |
|
323 | 324 |
/* various PCM "codecs" */ |
324 | 325 |
AV_CODEC_ID_FIRST_AUDIO = 0x10000, ///< A dummy id pointing at the start of audio codecs |
... | ... |
@@ -1440,6 +1440,14 @@ static const AVCodecDescriptor codec_descriptors[] = { |
1440 | 1440 |
.props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS, |
1441 | 1441 |
.mime_types= MT("image/x-xwindowdump"), |
1442 | 1442 |
}, |
1443 |
+ { |
|
1444 |
+ .id = AV_CODEC_ID_APNG, |
|
1445 |
+ .type = AVMEDIA_TYPE_VIDEO, |
|
1446 |
+ .name = "apng", |
|
1447 |
+ .long_name = NULL_IF_CONFIG_SMALL("APNG (Animated Portable Network Graphics) image"), |
|
1448 |
+ .props = AV_CODEC_PROP_LOSSLESS, |
|
1449 |
+ .mime_types= MT("image/png"), |
|
1450 |
+ }, |
|
1443 | 1451 |
|
1444 | 1452 |
/* various PCM "codecs" */ |
1445 | 1453 |
{ |
... | ... |
@@ -786,15 +786,55 @@ static void handle_small_bpp(PNGDecContext *s, AVFrame *p) |
786 | 786 |
} |
787 | 787 |
} |
788 | 788 |
|
789 |
+static int decode_fctl_chunk(AVCodecContext *avctx, PNGDecContext *s, |
|
790 |
+ uint32_t length) |
|
791 |
+{ |
|
792 |
+ uint32_t sequence_number, width, height, x_offset, y_offset; |
|
793 |
+ |
|
794 |
+ if (length != 26) |
|
795 |
+ return AVERROR_INVALIDDATA; |
|
796 |
+ |
|
797 |
+ sequence_number = bytestream2_get_be32(&s->gb); |
|
798 |
+ width = bytestream2_get_be32(&s->gb); |
|
799 |
+ height = bytestream2_get_be32(&s->gb); |
|
800 |
+ x_offset = bytestream2_get_be32(&s->gb); |
|
801 |
+ y_offset = bytestream2_get_be32(&s->gb); |
|
802 |
+ bytestream2_skip(&s->gb, 10); /* delay_num (2) |
|
803 |
+ * delay_den (2) |
|
804 |
+ * dispose_op (1) |
|
805 |
+ * blend_op (1) |
|
806 |
+ * crc (4) |
|
807 |
+ */ |
|
808 |
+ |
|
809 |
+ if (width != s->width || height != s->height || |
|
810 |
+ x_offset != 0 || y_offset != 0) { |
|
811 |
+ if (sequence_number == 0) |
|
812 |
+ return AVERROR_INVALIDDATA; |
|
813 |
+ avpriv_request_sample(avctx, "non key frames"); |
|
814 |
+ return AVERROR_PATCHWELCOME; |
|
815 |
+ } |
|
816 |
+ |
|
817 |
+ return 0; |
|
818 |
+} |
|
819 |
+ |
|
789 | 820 |
static int decode_frame_common(AVCodecContext *avctx, PNGDecContext *s, |
790 | 821 |
AVFrame *p, AVPacket *avpkt) |
791 | 822 |
{ |
792 | 823 |
AVDictionary *metadata = NULL; |
793 | 824 |
uint32_t tag, length; |
825 |
+ int decode_next_dat = 0; |
|
826 |
+ int ret = AVERROR_INVALIDDATA; |
|
794 | 827 |
|
795 | 828 |
for (;;) { |
796 |
- if (bytestream2_get_bytes_left(&s->gb) <= 0) { |
|
797 |
- av_log(avctx, AV_LOG_ERROR, "%d bytes left\n", bytestream2_get_bytes_left(&s->gb)); |
|
829 |
+ length = bytestream2_get_bytes_left(&s->gb); |
|
830 |
+ if (length <= 0) { |
|
831 |
+ if (avctx->codec_id == AV_CODEC_ID_APNG && length == 0) { |
|
832 |
+ if (!(s->state & PNG_IDAT)) |
|
833 |
+ return 0; |
|
834 |
+ else |
|
835 |
+ goto exit_loop; |
|
836 |
+ } |
|
837 |
+ av_log(avctx, AV_LOG_ERROR, "%d bytes left\n", length); |
|
798 | 838 |
if ( s->state & PNG_ALLIMAGE |
799 | 839 |
&& avctx->strict_std_compliance <= FF_COMPLIANCE_NORMAL) |
800 | 840 |
goto exit_loop; |
... | ... |
@@ -822,7 +862,24 @@ static int decode_frame_common(AVCodecContext *avctx, PNGDecContext *s, |
822 | 822 |
if (decode_phys_chunk(avctx, s) < 0) |
823 | 823 |
goto fail; |
824 | 824 |
break; |
825 |
+ case MKTAG('f', 'c', 'T', 'L'): |
|
826 |
+ if (avctx->codec_id != AV_CODEC_ID_APNG) |
|
827 |
+ goto skip_tag; |
|
828 |
+ if ((ret = decode_fctl_chunk(avctx, s, length)) < 0) |
|
829 |
+ goto fail; |
|
830 |
+ decode_next_dat = 1; |
|
831 |
+ break; |
|
832 |
+ case MKTAG('f', 'd', 'A', 'T'): |
|
833 |
+ if (avctx->codec_id != AV_CODEC_ID_APNG) |
|
834 |
+ goto skip_tag; |
|
835 |
+ if (!decode_next_dat) |
|
836 |
+ goto fail; |
|
837 |
+ bytestream2_get_be32(&s->gb); |
|
838 |
+ length -= 4; |
|
839 |
+ /* fallthrough */ |
|
825 | 840 |
case MKTAG('I', 'D', 'A', 'T'): |
841 |
+ if (avctx->codec_id == AV_CODEC_ID_APNG && !decode_next_dat) |
|
842 |
+ goto skip_tag; |
|
826 | 843 |
if (decode_idat_chunk(avctx, s, length, p) < 0) |
827 | 844 |
goto fail; |
828 | 845 |
break; |
... | ... |
@@ -894,9 +951,10 @@ exit_loop: |
894 | 894 |
fail: |
895 | 895 |
av_dict_free(&metadata); |
896 | 896 |
ff_thread_report_progress(&s->picture, INT_MAX, 0); |
897 |
- return AVERROR_INVALIDDATA; |
|
897 |
+ return ret; |
|
898 | 898 |
} |
899 | 899 |
|
900 |
+#if CONFIG_PNG_DECODER |
|
900 | 901 |
static int decode_frame_png(AVCodecContext *avctx, |
901 | 902 |
void *data, int *got_frame, |
902 | 903 |
AVPacket *avpkt) |
... | ... |
@@ -948,6 +1006,63 @@ the_end: |
948 | 948 |
s->crow_buf = NULL; |
949 | 949 |
return ret; |
950 | 950 |
} |
951 |
+#endif |
|
952 |
+ |
|
953 |
+#if CONFIG_APNG_DECODER |
|
954 |
+static int decode_frame_apng(AVCodecContext *avctx, |
|
955 |
+ void *data, int *got_frame, |
|
956 |
+ AVPacket *avpkt) |
|
957 |
+{ |
|
958 |
+ PNGDecContext *const s = avctx->priv_data; |
|
959 |
+ int ret; |
|
960 |
+ AVFrame *p; |
|
961 |
+ |
|
962 |
+ ff_thread_release_buffer(avctx, &s->last_picture); |
|
963 |
+ FFSWAP(ThreadFrame, s->picture, s->last_picture); |
|
964 |
+ p = s->picture.f; |
|
965 |
+ |
|
966 |
+ if (!(s->state & PNG_IHDR)) { |
|
967 |
+ if (!avctx->extradata_size) |
|
968 |
+ return AVERROR_INVALIDDATA; |
|
969 |
+ |
|
970 |
+ /* only init fields, there is no zlib use in extradata */ |
|
971 |
+ s->zstream.zalloc = ff_png_zalloc; |
|
972 |
+ s->zstream.zfree = ff_png_zfree; |
|
973 |
+ |
|
974 |
+ bytestream2_init(&s->gb, avctx->extradata, avctx->extradata_size); |
|
975 |
+ if ((ret = decode_frame_common(avctx, s, p, avpkt)) < 0) |
|
976 |
+ goto end; |
|
977 |
+ } |
|
978 |
+ |
|
979 |
+ /* reset state for a new frame */ |
|
980 |
+ if ((ret = inflateInit(&s->zstream)) != Z_OK) { |
|
981 |
+ av_log(avctx, AV_LOG_ERROR, "inflateInit returned error %d\n", ret); |
|
982 |
+ ret = AVERROR_EXTERNAL; |
|
983 |
+ goto end; |
|
984 |
+ } |
|
985 |
+ s->y = 0; |
|
986 |
+ s->state &= ~(PNG_IDAT | PNG_ALLIMAGE); |
|
987 |
+ bytestream2_init(&s->gb, avpkt->data, avpkt->size); |
|
988 |
+ if ((ret = decode_frame_common(avctx, s, p, avpkt)) < 0) |
|
989 |
+ goto end; |
|
990 |
+ |
|
991 |
+ if (!(s->state & PNG_ALLIMAGE)) |
|
992 |
+ av_log(avctx, AV_LOG_WARNING, "Frame did not contain a complete image\n"); |
|
993 |
+ if (!(s->state & (PNG_ALLIMAGE|PNG_IDAT))) { |
|
994 |
+ ret = AVERROR_INVALIDDATA; |
|
995 |
+ goto end; |
|
996 |
+ } |
|
997 |
+ if ((ret = av_frame_ref(data, s->picture.f)) < 0) |
|
998 |
+ goto end; |
|
999 |
+ |
|
1000 |
+ *got_frame = 1; |
|
1001 |
+ ret = bytestream2_tell(&s->gb); |
|
1002 |
+ |
|
1003 |
+end: |
|
1004 |
+ inflateEnd(&s->zstream); |
|
1005 |
+ return ret; |
|
1006 |
+} |
|
1007 |
+#endif |
|
951 | 1008 |
|
952 | 1009 |
static int update_thread_context(AVCodecContext *dst, const AVCodecContext *src) |
953 | 1010 |
{ |
... | ... |
@@ -1000,6 +1115,23 @@ static av_cold int png_dec_end(AVCodecContext *avctx) |
1000 | 1000 |
return 0; |
1001 | 1001 |
} |
1002 | 1002 |
|
1003 |
+#if CONFIG_APNG_DECODER |
|
1004 |
+AVCodec ff_apng_decoder = { |
|
1005 |
+ .name = "apng", |
|
1006 |
+ .long_name = NULL_IF_CONFIG_SMALL("APNG (Animated Portable Network Graphics) image"), |
|
1007 |
+ .type = AVMEDIA_TYPE_VIDEO, |
|
1008 |
+ .id = AV_CODEC_ID_APNG, |
|
1009 |
+ .priv_data_size = sizeof(PNGDecContext), |
|
1010 |
+ .init = png_dec_init, |
|
1011 |
+ .close = png_dec_end, |
|
1012 |
+ .decode = decode_frame_apng, |
|
1013 |
+ .init_thread_copy = ONLY_IF_THREADS_ENABLED(png_dec_init), |
|
1014 |
+ .update_thread_context = ONLY_IF_THREADS_ENABLED(update_thread_context), |
|
1015 |
+ .capabilities = CODEC_CAP_DR1 | CODEC_CAP_FRAME_THREADS /*| CODEC_CAP_DRAW_HORIZ_BAND*/, |
|
1016 |
+}; |
|
1017 |
+#endif |
|
1018 |
+ |
|
1019 |
+#if CONFIG_PNG_DECODER |
|
1003 | 1020 |
AVCodec ff_png_decoder = { |
1004 | 1021 |
.name = "png", |
1005 | 1022 |
.long_name = NULL_IF_CONFIG_SMALL("PNG (Portable Network Graphics) image"), |
... | ... |
@@ -1013,3 +1145,4 @@ AVCodec ff_png_decoder = { |
1013 | 1013 |
.update_thread_context = ONLY_IF_THREADS_ENABLED(update_thread_context), |
1014 | 1014 |
.capabilities = CODEC_CAP_DR1 | CODEC_CAP_FRAME_THREADS /*| CODEC_CAP_DRAW_HORIZ_BAND*/, |
1015 | 1015 |
}; |
1016 |
+#endif |
... | ... |
@@ -29,8 +29,8 @@ |
29 | 29 |
#include "libavutil/version.h" |
30 | 30 |
|
31 | 31 |
#define LIBAVCODEC_VERSION_MAJOR 56 |
32 |
-#define LIBAVCODEC_VERSION_MINOR 12 |
|
33 |
-#define LIBAVCODEC_VERSION_MICRO 101 |
|
32 |
+#define LIBAVCODEC_VERSION_MINOR 13 |
|
33 |
+#define LIBAVCODEC_VERSION_MICRO 100 |
|
34 | 34 |
|
35 | 35 |
#define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ |
36 | 36 |
LIBAVCODEC_VERSION_MINOR, \ |