1 // Copyright (c) the JPEG XL Project Authors. All rights reserved.
2 //
3 // Use of this source code is governed by a BSD-style
4 // license that can be found in the LICENSE file.
5
6 #ifndef TOOLS_ARGS_H_
7 #define TOOLS_ARGS_H_
8
9 // Helpers for parsing command line arguments. No include guard needed.
10
11 #include <stdio.h>
12 #include <string.h>
13
14 #include <string>
15 #include <vector>
16
17 #include "lib/extras/color_hints.h"
18 #include "lib/jxl/base/override.h"
19 #include "lib/jxl/base/status.h"
20 #include "lib/jxl/codec_in_out.h" // DecoderHints
21 #include "lib/jxl/gaborish.h"
22 #include "lib/jxl/modular/options.h"
23
24 namespace jpegxl {
25 namespace tools {
26
ParseOverride(const char * arg,jxl::Override * out)27 static inline bool ParseOverride(const char* arg, jxl::Override* out) {
28 const std::string s_arg(arg);
29 if (s_arg == "1") {
30 *out = jxl::Override::kOn;
31 return true;
32 }
33 if (s_arg == "0") {
34 *out = jxl::Override::kOff;
35 return true;
36 }
37 fprintf(stderr, "Invalid flag, %s must be 0 or 1\n", arg);
38 return JXL_FAILURE("Args");
39 }
40
ParseUnsigned(const char * arg,size_t * out)41 static inline bool ParseUnsigned(const char* arg, size_t* out) {
42 char* end;
43 *out = static_cast<size_t>(strtoull(arg, &end, 0));
44 if (end[0] != '\0') {
45 fprintf(stderr, "Unable to interpret as unsigned integer: %s.\n", arg);
46 return JXL_FAILURE("Args");
47 }
48 return true;
49 }
50
ParseUint32(const char * arg,uint32_t * out)51 static inline bool ParseUint32(const char* arg, uint32_t* out) {
52 size_t value = 0;
53 bool ret = ParseUnsigned(arg, &value);
54 if (ret) *out = value;
55 return ret;
56 }
57
ParseSigned(const char * arg,int * out)58 static inline bool ParseSigned(const char* arg, int* out) {
59 char* end;
60 *out = static_cast<int>(strtol(arg, &end, 0));
61 if (end[0] != '\0') {
62 fprintf(stderr, "Unable to interpret as signed integer: %s.\n", arg);
63 return JXL_FAILURE("Args");
64 }
65 return true;
66 }
67
ParseFloat(const char * arg,float * out)68 static inline bool ParseFloat(const char* arg, float* out) {
69 char* end;
70 *out = static_cast<float>(strtod(arg, &end));
71 if (end[0] != '\0') {
72 fprintf(stderr, "Unable to interpret as float: %s.\n", arg);
73 return JXL_FAILURE("Args");
74 }
75 return true;
76 }
77
ParseFloatPair(const char * arg,std::pair<float,float> * out)78 static inline bool ParseFloatPair(const char* arg,
79 std::pair<float, float>* out) {
80 int parsed = sscanf(arg, "%f,%f", &out->first, &out->second);
81 if (parsed == 1) {
82 out->second = out->first;
83 } else if (parsed != 2) {
84 fprintf(stderr,
85 "Unable to interpret as float pair separated by a comma: %s.\n",
86 arg);
87 return JXL_FAILURE("Args");
88 }
89 return true;
90 }
91
ParseDouble(const char * arg,double * out)92 static inline bool ParseDouble(const char* arg, double* out) {
93 char* end;
94 *out = static_cast<double>(strtod(arg, &end));
95 if (end[0] != '\0') {
96 fprintf(stderr, "Unable to interpret as double: %s.\n", arg);
97 return JXL_FAILURE("Args");
98 }
99 return true;
100 }
101
ParseAndAppendKeyValue(const char * arg,jxl::ColorHints * out)102 static inline bool ParseAndAppendKeyValue(const char* arg,
103 jxl::ColorHints* out) {
104 const char* eq = strchr(arg, '=');
105 if (!eq) {
106 fprintf(stderr, "Expected argument as 'key=value' but received '%s'\n",
107 arg);
108 return false;
109 }
110 std::string key(arg, eq);
111 out->Add(key, std::string(eq + 1));
112 return true;
113 }
114
ParsePredictor(const char * arg,jxl::Predictor * out)115 static inline bool ParsePredictor(const char* arg, jxl::Predictor* out) {
116 char* end;
117 size_t p = static_cast<size_t>(strtoull(arg, &end, 0));
118 if (end[0] != '\0') {
119 fprintf(stderr, "Invalid predictor: %s.\n", arg);
120 return JXL_FAILURE("Args");
121 }
122 if (p >= jxl::kNumModularPredictors) {
123 fprintf(stderr, "Invalid predictor value %zu, must be less than %zu.\n", p,
124 jxl::kNumModularPredictors);
125 return JXL_FAILURE("Args");
126 }
127 *out = static_cast<jxl::Predictor>(p);
128 return true;
129 }
130
ParseString(const char * arg,std::string * out)131 static inline bool ParseString(const char* arg, std::string* out) {
132 out->assign(arg);
133 return true;
134 }
135
ParseCString(const char * arg,const char ** out)136 static inline bool ParseCString(const char* arg, const char** out) {
137 *out = arg;
138 return true;
139 }
140
SetBooleanTrue(bool * out)141 static inline bool SetBooleanTrue(bool* out) {
142 *out = true;
143 return true;
144 }
145
SetBooleanFalse(bool * out)146 static inline bool SetBooleanFalse(bool* out) {
147 *out = false;
148 return true;
149 }
150
IncrementUnsigned(size_t * out)151 static inline bool IncrementUnsigned(size_t* out) {
152 (*out)++;
153 return true;
154 }
155
156 } // namespace tools
157 } // namespace jpegxl
158
159 #endif // TOOLS_ARGS_H_
160