Home | History | Annotate | Download | only in examples
      1 // Copyright 2010 Google Inc.
      2 //
      3 // This code is licensed under the same terms as WebM:
      4 //  Software License Agreement:  http://www.webmproject.org/license/software/
      5 //  Additional IP Rights Grant:  http://www.webmproject.org/license/additional/
      6 // -----------------------------------------------------------------------------
      7 //
      8 //  simple command-line example calling libwebpdecode to
      9 //  decode a WebP image into a PPM image.
     10 //
     11 //  Compile with:     gcc -o dwebp dwebp.c -lwebpdecode
     12 //
     13 // Author: Skal (pascal.massimino (at) gmail.com)
     14 
     15 #include <assert.h>
     16 #include <stdio.h>
     17 #include <stdlib.h>
     18 #include <string.h>
     19 
     20 #include "webp/decode.h"
     21 
     22 #if defined(__cplusplus) || defined(c_plusplus)
     23 extern "C" {
     24 #endif
     25 
     26 //-----------------------------------------------------------------------------
     27 
     28 static void help(const char *s) {
     29   printf("Usage: dwebp "
     30          "[options] [in_file] [-h] [-raw] [-o ppm_file]\n\n"
     31          " -raw:  save the raw YUV samples as a grayscale PGM\n"
     32          "        file with IMC4 layout.\n"
     33         );
     34 }
     35 
     36 int main(int argc, char *argv[]) {
     37   const char *in_file = NULL;
     38   const char *out_file = NULL;
     39   int raw_output = 0;
     40 
     41   int width, height, stride, uv_stride;
     42   uint8_t* out = NULL, *u = NULL, *v = NULL;
     43 
     44   int c;
     45   for (c = 1; c < argc; ++c) {
     46     if (!strcmp(argv[c], "-h")) {
     47       help(argv[0]);
     48       return 0;
     49     } else if (!strcmp(argv[c], "-o") && c < argc - 1) {
     50       out_file = argv[++c];
     51     } else if (!strcmp(argv[c], "-raw")) {
     52       raw_output = 1;
     53     } else if (argv[c][0] == '-') {
     54       printf("Unknown option '%s'\n", argv[c]);
     55       help(argv[0]);
     56       return -1;
     57     } else {
     58       in_file = argv[c];
     59     }
     60   }
     61 
     62   if (in_file == NULL) {
     63     printf("missing input file!!\n");
     64     help(argv[0]);
     65     return -1;
     66   }
     67 
     68   {
     69     uint32_t data_size = 0;
     70     void* data = NULL;
     71     FILE* const in = fopen(in_file, "rb");
     72     if (!in) {
     73       printf("cannot open input file '%s'\n", in_file);
     74       return 1;
     75     }
     76     fseek(in, 0, SEEK_END);
     77     data_size = ftell(in);
     78     fseek(in, 0, SEEK_SET);
     79     data = malloc(data_size);
     80     const int ok = (fread(data, data_size, 1, in) == 1);
     81     fclose(in);
     82     if (!ok) {
     83       free(data);
     84       return -1;
     85     }
     86 
     87     if (!raw_output) {
     88       out = WebPDecodeRGB(data, data_size, &width, &height);
     89     } else {
     90       out = WebPDecodeYUV(data, data_size, &width, &height,
     91                           &u, &v, &stride, &uv_stride);
     92     }
     93     free(data);
     94   }
     95 
     96   if (!out) {
     97     printf("Decoding of %s failed.\n", in_file);
     98     return -1;
     99   }
    100 
    101   if (out_file) {
    102     FILE* const fout = fopen(out_file, "wb");
    103     if (fout) {
    104       int ok = 1;
    105       if (!raw_output) {
    106         fprintf(fout, "P6\n%d %d\n255\n", width, height);
    107         ok &= (fwrite(out, width * height, 3, fout) == 3);
    108       } else {
    109         // Save a grayscale PGM file using the IMC4 layout
    110         // (http://www.fourcc.org/yuv.php#IMC4). This is a very
    111         // convenient format for viewing the samples, esp. for
    112         // odd dimensions.
    113         int y;
    114         const int uv_width = (width + 1) / 2;
    115         const int uv_height = (height + 1) / 2;
    116         const int out_stride = (width + 1) & ~1;
    117         fprintf(fout, "P5\n%d %d\n255\n", out_stride, height + uv_height);
    118         for (y = 0; ok && y < height; ++y) {
    119           ok &= (fwrite(out + y * stride, width, 1, fout) == 1);
    120           if (width & 1) fputc(0, fout);    // padding byte
    121         }
    122         for (y = 0; ok && y < uv_height; ++y) {
    123           ok &= (fwrite(u + y * uv_stride, uv_width, 1, fout) == 1);
    124           ok &= (fwrite(v + y * uv_stride, uv_width, 1, fout) == 1);
    125         }
    126       }
    127       fclose(fout);
    128       if (ok) {
    129         printf("Saved file %s\n", out_file);
    130       } else {
    131         printf("Error writing file %s !!\n", out_file);
    132       }
    133     } else {
    134       printf("Error opening output file %s\n", out_file);
    135     }
    136   }
    137   printf("Decoded %s. Dimensions: %d x %d.\n", in_file, width, height);
    138   free(out);
    139 
    140   return 0;
    141 }
    142 
    143 //-----------------------------------------------------------------------------
    144 
    145 #if defined(__cplusplus) || defined(c_plusplus)
    146 }    // extern "C"
    147 #endif
    148