xref: /aosp_15_r20/external/webp/examples/anim_dump.c (revision b2055c353e87c8814eb2b6b1b11112a1562253bd)
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