• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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@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 
help(const char * s)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 
main(int argc,char * argv[])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