anim_dump.c (4601B)
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 (pascal.massimino@gmail.com) 13 14 #include <stdio.h> 15 #include <stdlib.h> 16 #include <string.h> // for 'strcmp'. 17 18 #include "../imageio/image_enc.h" 19 #include "./anim_util.h" 20 #include "./unicode.h" 21 #include "webp/decode.h" 22 #include "webp/types.h" 23 24 #if defined(_MSC_VER) && _MSC_VER < 1900 25 #define snprintf _snprintf 26 #endif 27 28 static void Help(void) { 29 printf("Usage: anim_dump [options] files...\n"); 30 printf("\nOptions:\n"); 31 printf(" -folder <string> .... dump folder (default: '.')\n"); 32 printf(" -prefix <string> .... prefix for dumped frames " 33 "(default: 'dump_')\n"); 34 printf(" -tiff ............... save frames as TIFF\n"); 35 printf(" -pam ................ save frames as PAM\n"); 36 printf(" -h .................. this help\n"); 37 printf(" -version ............ print version number and exit\n"); 38 } 39 40 // Returns EXIT_SUCCESS on success, EXIT_FAILURE on failure. 41 int main(int argc, const char* argv[]) { 42 int error = 0; 43 const W_CHAR* dump_folder = TO_W_CHAR("."); 44 const W_CHAR* prefix = TO_W_CHAR("dump_"); 45 const W_CHAR* suffix = TO_W_CHAR("png"); 46 WebPOutputFileFormat format = PNG; 47 int c; 48 49 INIT_WARGV(argc, argv); 50 51 if (argc < 2) { 52 Help(); 53 FREE_WARGV_AND_RETURN(EXIT_FAILURE); 54 } 55 56 for (c = 1; !error && c < argc; ++c) { 57 if (!strcmp(argv[c], "-folder")) { 58 if (c + 1 == argc) { 59 fprintf(stderr, "missing argument after option '%s'\n", argv[c]); 60 error = 1; 61 break; 62 } 63 dump_folder = GET_WARGV(argv, ++c); 64 } else if (!strcmp(argv[c], "-prefix")) { 65 if (c + 1 == argc) { 66 fprintf(stderr, "missing argument after option '%s'\n", argv[c]); 67 error = 1; 68 break; 69 } 70 prefix = GET_WARGV(argv, ++c); 71 } else if (!strcmp(argv[c], "-tiff")) { 72 format = TIFF; 73 suffix = TO_W_CHAR("tiff"); 74 } else if (!strcmp(argv[c], "-pam")) { 75 format = PAM; 76 suffix = TO_W_CHAR("pam"); 77 } else if (!strcmp(argv[c], "-h") || !strcmp(argv[c], "-help")) { 78 Help(); 79 FREE_WARGV_AND_RETURN(EXIT_SUCCESS); 80 } else if (!strcmp(argv[c], "-version")) { 81 int dec_version, demux_version; 82 GetAnimatedImageVersions(&dec_version, &demux_version); 83 printf("WebP Decoder version: %d.%d.%d\nWebP Demux version: %d.%d.%d\n", 84 (dec_version >> 16) & 0xff, (dec_version >> 8) & 0xff, 85 (dec_version >> 0) & 0xff, 86 (demux_version >> 16) & 0xff, (demux_version >> 8) & 0xff, 87 (demux_version >> 0) & 0xff); 88 FREE_WARGV_AND_RETURN(EXIT_SUCCESS); 89 } else { 90 uint32_t i; 91 AnimatedImage image; 92 const W_CHAR* const file = GET_WARGV(argv, c); 93 memset(&image, 0, sizeof(image)); 94 WPRINTF("Decoding file: %s as %s/%sxxxx.%s\n", 95 file, dump_folder, prefix, suffix); 96 if (!ReadAnimatedImage((const char*)file, &image, 0, NULL)) { 97 WFPRINTF(stderr, "Error decoding file: %s\n Aborting.\n", file); 98 error = 1; 99 break; 100 } 101 for (i = 0; !error && i < image.num_frames; ++i) { 102 W_CHAR out_file[1024]; 103 WebPDecBuffer buffer; 104 if (!WebPInitDecBuffer(&buffer)) { 105 fprintf(stderr, "Cannot init dec buffer\n"); 106 error = 1; 107 continue; 108 } 109 buffer.colorspace = MODE_RGBA; 110 buffer.is_external_memory = 1; 111 buffer.width = image.canvas_width; 112 buffer.height = image.canvas_height; 113 buffer.u.RGBA.rgba = image.frames[i].rgba; 114 buffer.u.RGBA.stride = buffer.width * sizeof(uint32_t); 115 buffer.u.RGBA.size = buffer.u.RGBA.stride * buffer.height; 116 WSNPRINTF(out_file, sizeof(out_file), "%s/%s%.4d.%s", 117 dump_folder, prefix, i, suffix); 118 if (!WebPSaveImage(&buffer, format, (const char*)out_file)) { 119 WFPRINTF(stderr, "Error while saving image '%s'\n", out_file); 120 error = 1; 121 } 122 WebPFreeDecBuffer(&buffer); 123 } 124 ClearAnimatedImage(&image); 125 } 126 } 127 FREE_WARGV_AND_RETURN(error ? EXIT_FAILURE : EXIT_SUCCESS); 128 }