1 // Copyright 2017 Google Inc. All Rights Reserved.
2 //
3 // Use of this source code is governed by a BSD-style license
4 // that can be found in the COPYING file in the root of the source
5 // tree. An additional intellectual property rights grant can be found
6 // in the file PATENTS. All contributing project authors may
7 // be found in the AUTHORS file in the root of the source tree.
8 // -----------------------------------------------------------------------------
9 //
10 // Decodes an animated WebP file and dumps the decoded frames as PNG or TIFF.
11 //
12 // Author: Skal ([email protected])
13
14 #include <stdio.h>
15 #include <string.h> // for 'strcmp'.
16
17 #include "./anim_util.h"
18 #include "webp/decode.h"
19 #include "../imageio/image_enc.h"
20 #include "./unicode.h"
21
22 #if defined(_MSC_VER) && _MSC_VER < 1900
23 #define snprintf _snprintf
24 #endif
25
Help(void)26 static void Help(void) {
27 printf("Usage: anim_dump [options] files...\n");
28 printf("\nOptions:\n");
29 printf(" -folder <string> .... dump folder (default: '.')\n");
30 printf(" -prefix <string> .... prefix for dumped frames "
31 "(default: 'dump_')\n");
32 printf(" -tiff ............... save frames as TIFF\n");
33 printf(" -pam ................ save frames as PAM\n");
34 printf(" -h .................. this help\n");
35 printf(" -version ............ print version number and exit\n");
36 }
37
main(int argc,const char * argv[])38 int main(int argc, const char* argv[]) {
39 int error = 0;
40 const W_CHAR* dump_folder = TO_W_CHAR(".");
41 const W_CHAR* prefix = TO_W_CHAR("dump_");
42 const W_CHAR* suffix = TO_W_CHAR("png");
43 WebPOutputFileFormat format = PNG;
44 int c;
45
46 INIT_WARGV(argc, argv);
47
48 if (argc < 2) {
49 Help();
50 FREE_WARGV_AND_RETURN(-1);
51 }
52
53 for (c = 1; !error && c < argc; ++c) {
54 if (!strcmp(argv[c], "-folder")) {
55 if (c + 1 == argc) {
56 fprintf(stderr, "missing argument after option '%s'\n", argv[c]);
57 error = 1;
58 break;
59 }
60 dump_folder = GET_WARGV(argv, ++c);
61 } else if (!strcmp(argv[c], "-prefix")) {
62 if (c + 1 == argc) {
63 fprintf(stderr, "missing argument after option '%s'\n", argv[c]);
64 error = 1;
65 break;
66 }
67 prefix = GET_WARGV(argv, ++c);
68 } else if (!strcmp(argv[c], "-tiff")) {
69 format = TIFF;
70 suffix = TO_W_CHAR("tiff");
71 } else if (!strcmp(argv[c], "-pam")) {
72 format = PAM;
73 suffix = TO_W_CHAR("pam");
74 } else if (!strcmp(argv[c], "-h") || !strcmp(argv[c], "-help")) {
75 Help();
76 FREE_WARGV_AND_RETURN(0);
77 } else if (!strcmp(argv[c], "-version")) {
78 int dec_version, demux_version;
79 GetAnimatedImageVersions(&dec_version, &demux_version);
80 printf("WebP Decoder version: %d.%d.%d\nWebP Demux version: %d.%d.%d\n",
81 (dec_version >> 16) & 0xff, (dec_version >> 8) & 0xff,
82 (dec_version >> 0) & 0xff,
83 (demux_version >> 16) & 0xff, (demux_version >> 8) & 0xff,
84 (demux_version >> 0) & 0xff);
85 FREE_WARGV_AND_RETURN(0);
86 } else {
87 uint32_t i;
88 AnimatedImage image;
89 const W_CHAR* const file = GET_WARGV(argv, c);
90 memset(&image, 0, sizeof(image));
91 WPRINTF("Decoding file: %s as %s/%sxxxx.%s\n",
92 file, dump_folder, prefix, suffix);
93 if (!ReadAnimatedImage((const char*)file, &image, 0, NULL)) {
94 WFPRINTF(stderr, "Error decoding file: %s\n Aborting.\n", file);
95 error = 1;
96 break;
97 }
98 for (i = 0; !error && i < image.num_frames; ++i) {
99 W_CHAR out_file[1024];
100 WebPDecBuffer buffer;
101 if (!WebPInitDecBuffer(&buffer)) {
102 fprintf(stderr, "Cannot init dec buffer\n");
103 error = 1;
104 continue;
105 }
106 buffer.colorspace = MODE_RGBA;
107 buffer.is_external_memory = 1;
108 buffer.width = image.canvas_width;
109 buffer.height = image.canvas_height;
110 buffer.u.RGBA.rgba = image.frames[i].rgba;
111 buffer.u.RGBA.stride = buffer.width * sizeof(uint32_t);
112 buffer.u.RGBA.size = buffer.u.RGBA.stride * buffer.height;
113 WSNPRINTF(out_file, sizeof(out_file), "%s/%s%.4d.%s",
114 dump_folder, prefix, i, suffix);
115 if (!WebPSaveImage(&buffer, format, (const char*)out_file)) {
116 WFPRINTF(stderr, "Error while saving image '%s'\n", out_file);
117 error = 1;
118 }
119 WebPFreeDecBuffer(&buffer);
120 }
121 ClearAnimatedImage(&image);
122 }
123 }
124 FREE_WARGV_AND_RETURN(error ? 1 : 0);
125 }
126