From: Josef Zlomek
Fixes: 4907
Adds support for decoding of animated WebP.
The WebP parser now splits the input stream into packets containing one frame.
The WebP decoder adds the animation related features according to the specs:
https://developers.google.com/speed/webp/docs/riff_container#animation
The frames of the animation may be smaller than the image canvas.
Therefore, the frame is decoded to a temporary frame,
then it is blended into the canvas, the canvas is copied to the output frame,
and finally the frame is disposed from the canvas.
The output to AV_PIX_FMT_YUVA420P/AV_PIX_FMT_YUV420P is still supported.
The background color is specified only as BGRA in the WebP file
so it is converted to YUVA if YUV formats are output.
Signed-off-by: Josef Zlomek
---
Changelog| 1 +
libavcodec/codec_desc.c | 3 +-
libavcodec/version.h | 2 +-
libavcodec/webp.c| 713 +++
libavcodec/webp.h| 44 +++
libavcodec/webp_parser.c | 132 +---
6 files changed, 787 insertions(+), 108 deletions(-)
create mode 100644 libavcodec/webp.h
diff --git a/Changelog b/Changelog
index 8268e42cbc..4ec27782ac 100644
--- a/Changelog
+++ b/Changelog
@@ -5,6 +5,7 @@ version :
- libaribcaption decoder
- Playdate video decoder and demuxer
- Extend VAAPI support for libva-win32 on Windows
+- animated WebP parser/decoder
version 6.0:
- Radiance HDR image support
diff --git a/libavcodec/codec_desc.c b/libavcodec/codec_desc.c
index d40977d6b3..e1980be5f8 100644
--- a/libavcodec/codec_desc.c
+++ b/libavcodec/codec_desc.c
@@ -1251,8 +1251,7 @@ static const AVCodecDescriptor codec_descriptors[] = {
.type = AVMEDIA_TYPE_VIDEO,
.name = "webp",
.long_name = NULL_IF_CONFIG_SMALL("WebP"),
-.props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY |
- AV_CODEC_PROP_LOSSLESS,
+.props = AV_CODEC_PROP_LOSSY | AV_CODEC_PROP_LOSSLESS,
.mime_types= MT("image/webp"),
},
{
diff --git a/libavcodec/version.h b/libavcodec/version.h
index 80e2ae630d..c576ee1520 100644
--- a/libavcodec/version.h
+++ b/libavcodec/version.h
@@ -30,7 +30,7 @@
#include "version_major.h"
#define LIBAVCODEC_VERSION_MINOR 10
-#define LIBAVCODEC_VERSION_MICRO 100
+#define LIBAVCODEC_VERSION_MICRO 101
#define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
LIBAVCODEC_VERSION_MINOR, \
diff --git a/libavcodec/webp.c b/libavcodec/webp.c
index b4357f95d5..aee6f197a8 100644
--- a/libavcodec/webp.c
+++ b/libavcodec/webp.c
@@ -35,12 +35,15 @@
* Exif metadata
* ICC profile
*
+ * @author Josef Zlomek, Pexeso Inc.
+ * Animation
+ *
* Unimplemented:
- * - Animation
* - XMP metadata
*/
#include "libavutil/imgutils.h"
+#include "libavutil/colorspace.h"
#define BITSTREAM_READER_LE
#include "avcodec.h"
@@ -52,12 +55,7 @@
#include "thread.h"
#include "tiff_common.h"
#include "vp8.h"
-
-#define VP8X_FLAG_ANIMATION 0x02
-#define VP8X_FLAG_XMP_METADATA 0x04
-#define VP8X_FLAG_EXIF_METADATA 0x08
-#define VP8X_FLAG_ALPHA 0x10
-#define VP8X_FLAG_ICC 0x20
+#include "webp.h"
#define MAX_PALETTE_SIZE256
#define MAX_CACHE_BITS 11
@@ -193,6 +191,8 @@ typedef struct ImageContext {
typedef struct WebPContext {
VP8Context v; /* VP8 Context used for lossy decoding
*/
GetBitContext gb; /* bitstream reader for main image
chunk */
+ThreadFrame canvas_frame; /* ThreadFrame for canvas */
+AVFrame *frame; /* AVFrame for decoded frame */
AVFrame *alpha_frame; /* AVFrame for alpha data decompressed
from VP8L */
AVPacket *pkt; /* AVPacket to be passed to the
underlying VP8 decoder */
AVCodecContext *avctx; /* parent AVCodecContext */
@@ -204,9 +204,24 @@ typedef struct WebPContext {
int alpha_data_size;/* alpha chunk data size */
int has_exif; /* set after an EXIF chunk has been
processed */
int has_iccp; /* set after an ICCP chunk has been
processed */
-int width; /* image width */
-int height; /* image height */
-int lossless; /* indicates lossless or lossy */
+int vp8x_flags; /* global flags from VP8X chunk */
+int canvas_width; /* canvas width */
+int canvas_height; /* canvas height */
+int anmf_flags; /* frame flags from ANMF chunk */
+int width; /* frame width */
+int height; /* frame height */
+int pos_x; /* frame position X */
+int pos_y;