Blame examples/anim_dump.c

Packit 9c6abc
// Copyright 2017 Google Inc. All Rights Reserved.
Packit 9c6abc
//
Packit 9c6abc
// Use of this source code is governed by a BSD-style license
Packit 9c6abc
// that can be found in the COPYING file in the root of the source
Packit 9c6abc
// tree. An additional intellectual property rights grant can be found
Packit 9c6abc
// in the file PATENTS. All contributing project authors may
Packit 9c6abc
// be found in the AUTHORS file in the root of the source tree.
Packit 9c6abc
// -----------------------------------------------------------------------------
Packit 9c6abc
//
Packit 9c6abc
// Decodes an animated WebP file and dumps the decoded frames as PNG or TIFF.
Packit 9c6abc
//
Packit 9c6abc
// Author: Skal (pascal.massimino@gmail.com)
Packit 9c6abc
Packit 9c6abc
#include <stdio.h>
Packit 9c6abc
#include <string.h>  // for 'strcmp'.
Packit 9c6abc
Packit 9c6abc
#include "./anim_util.h"
Packit 9c6abc
#include "webp/decode.h"
Packit 9c6abc
#include "../imageio/image_enc.h"
Packit 9c6abc
Packit 9c6abc
#if defined(_MSC_VER) && _MSC_VER < 1900
Packit 9c6abc
#define snprintf _snprintf
Packit 9c6abc
#endif
Packit 9c6abc
Packit 9c6abc
static void Help(void) {
Packit 9c6abc
  printf("Usage: anim_dump [options] files...\n");
Packit 9c6abc
  printf("\nOptions:\n");
Packit 9c6abc
  printf("  -folder <string> .... dump folder (default: '.')\n");
Packit 9c6abc
  printf("  -prefix <string> .... prefix for dumped frames "
Packit 9c6abc
                                  "(default: 'dump_')\n");
Packit 9c6abc
  printf("  -tiff ............... save frames as TIFF\n");
Packit 9c6abc
  printf("  -pam ................ save frames as PAM\n");
Packit 9c6abc
  printf("  -h .................. this help\n");
Packit 9c6abc
  printf("  -version ............ print version number and exit\n");
Packit 9c6abc
}
Packit 9c6abc
Packit 9c6abc
int main(int argc, const char* argv[]) {
Packit 9c6abc
  int error = 0;
Packit 9c6abc
  const char* dump_folder = ".";
Packit 9c6abc
  const char* prefix = "dump_";
Packit 9c6abc
  const char* suffix = "png";
Packit 9c6abc
  WebPOutputFileFormat format = PNG;
Packit 9c6abc
  int c;
Packit 9c6abc
Packit 9c6abc
  if (argc < 2) {
Packit 9c6abc
    Help();
Packit 9c6abc
    return -1;
Packit 9c6abc
  }
Packit 9c6abc
Packit 9c6abc
  for (c = 1; !error && c < argc; ++c) {
Packit 9c6abc
    if (!strcmp(argv[c], "-folder")) {
Packit 9c6abc
      if (c + 1 == argc) {
Packit 9c6abc
        fprintf(stderr, "missing argument after option '%s'\n", argv[c]);
Packit 9c6abc
        error = 1;
Packit 9c6abc
        break;
Packit 9c6abc
      }
Packit 9c6abc
      dump_folder = argv[++c];
Packit 9c6abc
    } else if (!strcmp(argv[c], "-prefix")) {
Packit 9c6abc
      if (c + 1 == argc) {
Packit 9c6abc
        fprintf(stderr, "missing argument after option '%s'\n", argv[c]);
Packit 9c6abc
        error = 1;
Packit 9c6abc
        break;
Packit 9c6abc
      }
Packit 9c6abc
      prefix = argv[++c];
Packit 9c6abc
    } else if (!strcmp(argv[c], "-tiff")) {
Packit 9c6abc
      format = TIFF;
Packit 9c6abc
      suffix = "tiff";
Packit 9c6abc
    } else if (!strcmp(argv[c], "-pam")) {
Packit 9c6abc
      format = PAM;
Packit 9c6abc
      suffix = "pam";
Packit 9c6abc
    } else if (!strcmp(argv[c], "-h") || !strcmp(argv[c], "-help")) {
Packit 9c6abc
      Help();
Packit 9c6abc
      return 0;
Packit 9c6abc
    } else if (!strcmp(argv[c], "-version")) {
Packit 9c6abc
      int dec_version, demux_version;
Packit 9c6abc
      GetAnimatedImageVersions(&dec_version, &demux_version);
Packit 9c6abc
      printf("WebP Decoder version: %d.%d.%d\nWebP Demux version: %d.%d.%d\n",
Packit 9c6abc
             (dec_version >> 16) & 0xff, (dec_version >> 8) & 0xff,
Packit 9c6abc
             (dec_version >> 0) & 0xff,
Packit 9c6abc
             (demux_version >> 16) & 0xff, (demux_version >> 8) & 0xff,
Packit 9c6abc
             (demux_version >> 0) & 0xff);
Packit 9c6abc
      return 0;
Packit 9c6abc
    } else {
Packit 9c6abc
      uint32_t i;
Packit 9c6abc
      AnimatedImage image;
Packit 9c6abc
      const char* const file = argv[c];
Packit 9c6abc
      memset(&image, 0, sizeof(image));
Packit 9c6abc
      printf("Decoding file: %s as %s/%sxxxx.%s\n",
Packit 9c6abc
             file, dump_folder, prefix, suffix);
Packit 9c6abc
      if (!ReadAnimatedImage(file, &image, 0, NULL)) {
Packit 9c6abc
        fprintf(stderr, "Error decoding file: %s\n Aborting.\n", file);
Packit 9c6abc
        error = 1;
Packit 9c6abc
        break;
Packit 9c6abc
      }
Packit 9c6abc
      for (i = 0; !error && i < image.num_frames; ++i) {
Packit 9c6abc
        char out_file[1024];
Packit 9c6abc
        WebPDecBuffer buffer;
Packit 9c6abc
        WebPInitDecBuffer(&buffer);
Packit 9c6abc
        buffer.colorspace = MODE_RGBA;
Packit 9c6abc
        buffer.is_external_memory = 1;
Packit 9c6abc
        buffer.width = image.canvas_width;
Packit 9c6abc
        buffer.height = image.canvas_height;
Packit 9c6abc
        buffer.u.RGBA.rgba = image.frames[i].rgba;
Packit 9c6abc
        buffer.u.RGBA.stride = buffer.width * sizeof(uint32_t);
Packit 9c6abc
        buffer.u.RGBA.size = buffer.u.RGBA.stride * buffer.height;
Packit 9c6abc
        snprintf(out_file, sizeof(out_file), "%s/%s%.4d.%s",
Packit 9c6abc
                 dump_folder, prefix, i, suffix);
Packit 9c6abc
        if (!WebPSaveImage(&buffer, format, out_file)) {
Packit 9c6abc
          fprintf(stderr, "Error while saving image '%s'\n", out_file);
Packit 9c6abc
          error = 1;
Packit 9c6abc
        }
Packit 9c6abc
        WebPFreeDecBuffer(&buffer);
Packit 9c6abc
      }
Packit 9c6abc
      ClearAnimatedImage(&image);
Packit 9c6abc
    }
Packit 9c6abc
  }
Packit 9c6abc
  return error ? 1 : 0;
Packit 9c6abc
}