diff --git a/Makefile.vc b/Makefile.vc index 87300e59..c71a6adb 100644 --- a/Makefile.vc +++ b/Makefile.vc @@ -155,6 +155,7 @@ CFGSET = TRUE !MESSAGE - all - build (de)mux-based targets for CFG !MESSAGE - gif2webp - requires libgif & >= VS2013 !MESSAGE - anim_diff - requires libgif & >= VS2013 +!MESSAGE - anim_dump !MESSAGE !MESSAGE RTLIBCFG controls the runtime library linkage - 'static' or 'dynamic'. !MESSAGE 'legacy' will produce a Windows 2000 compatible library. @@ -355,10 +356,15 @@ all: ex $(EXTRA_EXAMPLES) # C99 support which is only available from VS2013 onward. gif2webp: $(DIRBIN)\gif2webp.exe anim_diff: $(DIRBIN)\anim_diff.exe +anim_dump: $(DIRBIN)\anim_dump.exe $(DIRBIN)\anim_diff.exe: $(DIROBJ)\examples\anim_diff.obj $(EX_ANIM_UTIL_OBJS) $(DIRBIN)\anim_diff.exe: $(EX_UTIL_OBJS) $(IMAGEIO_UTIL_OBJS) $(DIRBIN)\anim_diff.exe: $(EX_GIF_DEC_OBJS) $(LIBWEBPDEMUX) $(LIBWEBP) +$(DIRBIN)\anim_dump.exe: $(DIROBJ)\examples\anim_dump.obj $(EX_ANIM_UTIL_OBJS) +$(DIRBIN)\anim_dump.exe: $(EX_UTIL_OBJS) $(IMAGEIO_UTIL_OBJS) +$(DIRBIN)\anim_dump.exe: $(EX_GIF_DEC_OBJS) $(LIBWEBPDEMUX) $(LIBWEBP) +$(DIRBIN)\anim_dump.exe: $(IMAGEIO_ENC_OBJS) $(DIRBIN)\cwebp.exe: $(DIROBJ)\examples\cwebp.obj $(IMAGEIO_DEC_OBJS) $(DIRBIN)\cwebp.exe: $(IMAGEIO_UTIL_OBJS) $(DIRBIN)\dwebp.exe: $(DIROBJ)\examples\dwebp.obj $(IMAGEIO_DEC_OBJS) @@ -453,6 +459,9 @@ $(DIROBJ)\dsp\enc_avx2.obj: src\dsp\enc_avx2.c $(DIROBJ)\examples\anim_diff.obj: examples\anim_diff.c $(CC) $(CFLAGS) /DWEBP_HAVE_GIF /Fd$(LIBWEBP_PDBNAME) \ /Fo$(DIROBJ)\examples\ examples\$(@B).c +$(DIROBJ)\examples\anim_dump.obj: examples\anim_dump.c + $(CC) $(CFLAGS) /DWEBP_HAVE_GIF /Fd$(LIBWEBP_PDBNAME) \ + /Fo$(DIROBJ)\examples\ examples\$(@B).c $(DIROBJ)\examples\anim_util.obj: examples\anim_util.c $(CC) $(CFLAGS) /DWEBP_HAVE_GIF /Fd$(LIBWEBP_PDBNAME) \ /Fo$(DIROBJ)\examples\ examples\$(@B).c diff --git a/examples/Makefile.am b/examples/Makefile.am index 86e33f9e..05827634 100644 --- a/examples/Makefile.am +++ b/examples/Makefile.am @@ -2,7 +2,7 @@ AM_CPPFLAGS += -I$(top_builddir)/src -I$(top_srcdir)/src bin_PROGRAMS = dwebp cwebp if BUILD_ANIMDIFF - noinst_PROGRAMS = anim_diff + noinst_PROGRAMS = anim_diff anim_dump endif if BUILD_GIF2WEBP bin_PROGRAMS += gif2webp @@ -33,6 +33,16 @@ anim_diff_LDADD += libexample_util.la anim_diff_LDADD += ../imageio/libimageio_util.la anim_diff_LDADD += $(GIF_LIBS) -lm +anim_dump_SOURCES = anim_dump.c anim_util.c anim_util.h +anim_dump_CPPFLAGS = $(AM_CPPFLAGS) $(USE_EXPERIMENTAL_CODE) $(PNG_INCLUDES) +anim_dump_CPPFLAGS += $(GIF_INCLUDES) +anim_dump_LDADD = +anim_dump_LDADD += ../src/demux/libwebpdemux.la +anim_dump_LDADD += libexample_util.la +anim_dump_LDADD += ../imageio/libimageio_util.la +anim_dump_LDADD += ../imageio/libimageenc.la +anim_dump_LDADD += $(PNG_LIBS) $(GIF_LIBS) $(TIFF_LIBS) -lm + cwebp_SOURCES = cwebp.c stopwatch.h cwebp_CPPFLAGS = $(AM_CPPFLAGS) $(USE_EXPERIMENTAL_CODE) cwebp_LDADD = @@ -97,8 +107,10 @@ webpinfo_LDADD += ../src/libwebp.la if BUILD_LIBWEBPDECODER anim_diff_LDADD += ../src/libwebpdecoder.la + anim_dump_LDADD += ../src/libwebpdecoder.la vwebp_LDADD += ../src/libwebpdecoder.la else anim_diff_LDADD += ../src/libwebp.la + anim_dump_LDADD += ../src/libwebp.la vwebp_LDADD += ../src/libwebp.la endif diff --git a/examples/anim_dump.c b/examples/anim_dump.c new file mode 100644 index 00000000..b955b54a --- /dev/null +++ b/examples/anim_dump.c @@ -0,0 +1,104 @@ +// Copyright 2017 Google Inc. All Rights Reserved. +// +// Use of this source code is governed by a BSD-style license +// that can be found in the COPYING file in the root of the source +// tree. An additional intellectual property rights grant can be found +// in the file PATENTS. All contributing project authors may +// be found in the AUTHORS file in the root of the source tree. +// ----------------------------------------------------------------------------- +// +// Decodes an animated WebP file and dumps the decoded frames as PNG or TIFF. +// +// Author: Skal (pascal.massimino@gmail.com) + +#include +#include // for 'strcmp'. + +#include "./anim_util.h" +#include "webp/decode.h" +#include "../imageio/image_enc.h" + +#if defined(_MSC_VER) && _MSC_VER < 1900 +#define snprintf _snprintf +#endif + +static void Help(void) { + printf("Usage: anim_dump [options] files...\n"); + printf("\nOptions:\n"); + printf(" -folder .... dump folder (default: '.')\n"); + printf(" -prefix .... prefix for dumped frames " + "(default: 'dump_')\n"); + printf(" -tiff ............... save frames as TIFF\n"); + printf(" -pam ................ save frames as PAM\n"); +} + +int main(int argc, const char* argv[]) { + int error = 0; + const char* dump_folder = "."; + const char* prefix = "dump_"; + const char* suffix = "png"; + WebPOutputFileFormat format = PNG; + int c; + + if (argc < 2) { + Help(); + return -1; + } + + for (c = 1; !error && c < argc; ++c) { + if (!strcmp(argv[c], "-folder")) { + if (c + 1 == argc) { + fprintf(stderr, "missing argument after option '%s'\n", argv[c]); + error = 1; + break; + } + dump_folder = argv[++c]; + } else if (!strcmp(argv[c], "-prefix")) { + if (c + 1 == argc) { + fprintf(stderr, "missing argument after option '%s'\n", argv[c]); + error = 1; + break; + } + prefix = argv[++c]; + } else if (!strcmp(argv[c], "-tiff")) { + format = TIFF; + suffix = "tiff"; + } else if (!strcmp(argv[c], "-pam")) { + format = PAM; + suffix = "pam"; + } else { + uint32_t i; + AnimatedImage image; + const char* const file = argv[c]; + memset(&image, 0, sizeof(image)); + printf("Decoding file: %s as %s/%sxxxx.%s\n", + file, dump_folder, prefix, suffix); + if (!ReadAnimatedImage(file, &image, 0, NULL)) { + fprintf(stderr, "Error decoding file: %s\n Aborting.\n", file); + error = 1; + break; + } + for (i = 0; !error && i < image.num_frames; ++i) { + char out_file[1024]; + WebPDecBuffer buffer; + WebPInitDecBuffer(&buffer); + buffer.colorspace = MODE_RGBA; + buffer.is_external_memory = 1; + buffer.width = image.canvas_width; + buffer.height = image.canvas_height; + buffer.u.RGBA.rgba = image.frames[i].rgba; + buffer.u.RGBA.stride = buffer.width * sizeof(uint32_t); + buffer.u.RGBA.size = buffer.u.RGBA.stride * buffer.height; + snprintf(out_file, sizeof(out_file), "%s/%s%.4d.%s", + dump_folder, prefix, i, suffix); + if (!WebPSaveImage(&buffer, format, out_file)) { + fprintf(stderr, "Error while saving image '%s'\n", out_file); + error = 1; + } + WebPFreeDecBuffer(&buffer); + } + ClearAnimatedImage(&image); + } + } + return error ? 1 : 0; +} diff --git a/makefile.unix b/makefile.unix index 223584c6..5e605ca5 100644 --- a/makefile.unix +++ b/makefile.unix @@ -332,7 +332,8 @@ OUT_LIBS += src/libwebp.a EXTRA_LIB = extras/libwebpextras.a OUT_EXAMPLES = examples/cwebp examples/dwebp EXTRA_EXAMPLES = examples/gif2webp examples/vwebp examples/webpmux \ - examples/anim_diff examples/img2webp examples/webpinfo + examples/anim_diff examples/anim_dump \ + examples/img2webp examples/webpinfo OTHER_EXAMPLES = extras/get_disto extras/webp_quality extras/vwebp_sdl OUTPUT = $(OUT_LIBS) $(OUT_EXAMPLES) @@ -378,6 +379,7 @@ src/demux/libwebpdemux.a: $(LIBWEBPDEMUX_OBJS) $(AR) $(ARFLAGS) $@ $^ examples/anim_diff: examples/anim_diff.o $(ANIM_UTIL_OBJS) $(GIFDEC_OBJS) +examples/anim_dump: examples/anim_dump.o $(ANIM_UTIL_OBJS) examples/cwebp: examples/cwebp.o examples/dwebp: examples/dwebp.o examples/gif2webp: examples/gif2webp.o $(GIFDEC_OBJS) @@ -391,6 +393,13 @@ examples/anim_diff: src/demux/libwebpdemux.a examples/libexample_util.a examples/anim_diff: imageio/libimageio_util.a src/libwebp.a examples/anim_diff: EXTRA_LIBS += $(GIF_LIBS) examples/anim_diff: EXTRA_FLAGS += -DWEBP_HAVE_GIF +examples/anim_dump: examples/libanim_util.a +examples/anim_dump: src/demux/libwebpdemux.a +examples/anim_dump: examples/libexample_util.a +examples/anim_dump: imageio/libimageio_util.a +examples/anim_dump: imageio/libimageenc.a +examples/anim_dump: src/libwebp.a +examples/anim_dump: EXTRA_LIBS += $(GIF_LIBS) $(DWEBP_LIBS) examples/cwebp: examples/libexample_util.a examples/cwebp: imageio/libimagedec.a examples/cwebp: imageio/libimageio_util.a