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