1 // Copyright 2012 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 //  Utility functions used by the example programs.
11 //
12 
13 #include "./example_util.h"
14 
15 #include <assert.h>
16 #include <stdio.h>
17 #include <stdlib.h>
18 #include <string.h>
19 
20 #include "webp/mux_types.h"
21 #include "../imageio/imageio_util.h"
22 
23 //------------------------------------------------------------------------------
24 // String parsing
25 
ExUtilGetUInt(const char * const v,int base,int * const error)26 uint32_t ExUtilGetUInt(const char* const v, int base, int* const error) {
27   char* end = NULL;
28   const uint32_t n = (v != NULL) ? (uint32_t)strtoul(v, &end, base) : 0u;
29   if (end == v && error != NULL && !*error) {
30     *error = 1;
31     fprintf(stderr, "Error! '%s' is not an integer.\n",
32             (v != NULL) ? v : "(null)");
33   }
34   return n;
35 }
36 
ExUtilGetInt(const char * const v,int base,int * const error)37 int ExUtilGetInt(const char* const v, int base, int* const error) {
38   return (int)ExUtilGetUInt(v, base, error);
39 }
40 
ExUtilGetInts(const char * v,int base,int max_output,int output[])41 int ExUtilGetInts(const char* v, int base, int max_output, int output[]) {
42   int n, error = 0;
43   for (n = 0; v != NULL && n < max_output; ++n) {
44     const int value = ExUtilGetInt(v, base, &error);
45     if (error) return -1;
46     output[n] = value;
47     v = strchr(v, ',');
48     if (v != NULL) ++v;   // skip over the trailing ','
49   }
50   return n;
51 }
52 
ExUtilGetFloat(const char * const v,int * const error)53 float ExUtilGetFloat(const char* const v, int* const error) {
54   char* end = NULL;
55   const float f = (v != NULL) ? (float)strtod(v, &end) : 0.f;
56   if (end == v && error != NULL && !*error) {
57     *error = 1;
58     fprintf(stderr, "Error! '%s' is not a floating point number.\n",
59             (v != NULL) ? v : "(null)");
60   }
61   return f;
62 }
63 
64 //------------------------------------------------------------------------------
65 
ResetCommandLineArguments(int argc,const char * argv[],CommandLineArguments * const args)66 static void ResetCommandLineArguments(int argc, const char* argv[],
67                                       CommandLineArguments* const args) {
68   assert(args != NULL);
69   args->argc_ = argc;
70   args->argv_ = argv;
71   args->own_argv_ = 0;
72   WebPDataInit(&args->argv_data_);
73 }
74 
ExUtilDeleteCommandLineArguments(CommandLineArguments * const args)75 void ExUtilDeleteCommandLineArguments(CommandLineArguments* const args) {
76   if (args != NULL) {
77     if (args->own_argv_) {
78       free((void*)args->argv_);
79       WebPDataClear(&args->argv_data_);
80     }
81     ResetCommandLineArguments(0, NULL, args);
82   }
83 }
84 
85 #define MAX_ARGC 16384
ExUtilInitCommandLineArguments(int argc,const char * argv[],CommandLineArguments * const args)86 int ExUtilInitCommandLineArguments(int argc, const char* argv[],
87                                    CommandLineArguments* const args) {
88   if (args == NULL || argv == NULL) return 0;
89   ResetCommandLineArguments(argc, argv, args);
90   if (argc == 1 && argv[0][0] != '-') {
91     char* cur;
92     const char sep[] = " \t\r\n\f\v";
93 
94 #if defined(_WIN32) && defined(_UNICODE)
95     fprintf(stderr,
96             "Error: Reading arguments from a file is a feature unavailable "
97             "with Unicode binaries.\n");
98     return 0;
99 #endif
100 
101     if (!ExUtilReadFileToWebPData(argv[0], &args->argv_data_)) {
102       return 0;
103     }
104     args->own_argv_ = 1;
105     args->argv_ = (const char**)malloc(MAX_ARGC * sizeof(*args->argv_));
106     if (args->argv_ == NULL) return 0;
107 
108     argc = 0;
109     for (cur = strtok((char*)args->argv_data_.bytes, sep);
110          cur != NULL;
111          cur = strtok(NULL, sep)) {
112       if (argc == MAX_ARGC) {
113         fprintf(stderr, "ERROR: Arguments limit %d reached\n", MAX_ARGC);
114         return 0;
115       }
116       assert(strlen(cur) != 0);
117       args->argv_[argc++] = cur;
118     }
119     args->argc_ = argc;
120   }
121   return 1;
122 }
123 
124 //------------------------------------------------------------------------------
125 
ExUtilReadFileToWebPData(const char * const filename,WebPData * const webp_data)126 int ExUtilReadFileToWebPData(const char* const filename,
127                              WebPData* const webp_data) {
128   const uint8_t* data;
129   size_t size;
130   if (webp_data == NULL) return 0;
131   if (!ImgIoUtilReadFile(filename, &data, &size)) return 0;
132   webp_data->bytes = data;
133   webp_data->size = size;
134   return 1;
135 }
136