Automatic Color Enhancement
acecli.c
Go to the documentation of this file.
1 
25 #include <math.h>
26 #include <string.h>
27 #include <ctype.h>
28 #ifdef _OPENMP
29 #include "omp.h"
30 #endif
31 #include "ace.h"
32 #include "imageio.h"
33 
34 #define VERBOSE 0
35 
36 
38 typedef struct
39 {
41  char *input_file;
43  char *output_file;
47  float alpha;
49  char *omega_string;
51  char *method;
55 
56 
57 int parse_params(program_params *param, int argc, char *argv[]);
58 
61 {
62  puts("ACE automatic color enhancement, P. Getreuer 2012");
63 #ifdef _OPENMP
64  printf("Using OpenMP with %d threads\n", omp_get_max_threads());
65 #endif
66  puts("\nSyntax: ace [options] <input file> <output file>\n\n"
67  "Only " READIMAGE_FORMATS_SUPPORTED " images are supported.\n");
68  puts("Options:");
69  puts(" -a <number> alpha, stronger implies stronger enhancement");
70  puts(" -w <omega> omega, spatial weighting function, choices are");
71  puts(" 1/r default ACE, omega(x,y) = 1/sqrt(x^2+y^2)");
72  puts(" 1 constant, omega(x,y) = 1");
73  puts(" G:# Gaussian, where # specifies sigma,");
74  puts(" omega(x,y) = exp(-(x^2+y^2)/(2 sigma^2))");
75  puts(" -m <method> method to use for fast computation, choices are");
76  puts(" interp:# interpolate s_a(L - I(x)) with # levels\n");
77  puts(" poly:# polynomial s_a with degree #");
78 #ifdef USE_LIBJPEG
79  puts(" -q <number> quality for saving JPEG images (0 to 100)\n");
80 #endif
81  puts("Example: ");
82  puts(" ace -a 5 -w 1/r -m interp:12 input.bmp output.bmp\n");
83 }
84 
85 #include "omp.h"
86 
87 int main(int argc, char *argv[])
88 {
89  program_params param;
90  float *f = NULL, *u = NULL;
91  unsigned long time_start;
92  int width, height;
93  int status = 1, success;
94 
95  if(!parse_params(&param, argc, argv))
96  return 0;
97 
98  /* Read the input image */
99  if(!(f = (float *)read_image(&width, &height, param.input_file,
100  IMAGEIO_FLOAT | IMAGEIO_PLANAR | IMAGEIO_RGB)))
101  goto fail;
102 
103  /* Allocate the output image */
104  if(!(u = (float *)Malloc(sizeof(float)*3*
105  ((long int)width)*((long int)height))))
106  goto fail;
107 
108  printf("Enhancing %dx%d image, alpha = %.4f, omega = %s\n",
109  width, height, param.alpha, param.omega_string);
110 #ifdef _OPENMP
111  printf("Using OpenMP with %d threads\n", omp_get_max_threads());
112 #endif
113  time_start = Clock();
114 
115  /* ACE enhancement */
116  if(!param.method || !strcmp(param.method, "interp"))
117  {
118  printf("Interpolation with %d levels\n", param.method_param);
119  success = ace_enhance_image_interp(u, f, width, height,
120  param.alpha, param.omega_string, param.method_param);
121  }
122  else
123  {
124  printf("Degree %d polynomial approximation\n", param.method_param);
125  success = ace_enhance_image_poly(u, f, width, height,
126  param.alpha, param.omega_string, param.method_param);
127  }
128 
129  if(!success)
130  {
131  ErrorMessage("Error in computation.\n");
132  goto fail;
133  }
134 
135  printf("CPU Time: %.3f s\n", 0.001f*(Clock() - time_start));
136 
137  /* Write the output image */
138  if(!write_image(u, width, height, param.output_file,
139  IMAGEIO_FLOAT | IMAGEIO_PLANAR | IMAGEIO_RGB, param.jpeg_quality))
140  goto fail;
141 #if VERBOSE > 0
142  else
143  printf("Output written to \"%s\".\n", param.output_file);
144 #endif
145 
146  status = 0; /* Finished successfully, set exit status to zero. */
147 
148 fail:
149  Free(u);
150  Free(f);
151  return status;
152 }
153 
154 
155 int parse_params(program_params *param, int argc, char *argv[])
156 {
157  static char *default_output_file = (char *)"out.bmp";
158  static char *default_omega = (char *)"1/r";
159  char *option_string;
160  char option_char;
161  int i;
162 
163  if(argc < 2)
164  {
165  print_usage();
166  return 0;
167  }
168 
169  /* Set parameter defaults */
170  param->input_file = NULL;
171  param->output_file = default_output_file;
172  param->jpeg_quality = 85;
173  param->alpha = 5;
174  param->omega_string = default_omega;
175  param->method = NULL;
176  param->method_param = 8;
177 
178  for(i = 1; i < argc;)
179  {
180  if(argv[i] && argv[i][0] == '-')
181  {
182  if((option_char = argv[i][1]) == 0)
183  {
184  ErrorMessage("Invalid parameter format.\n");
185  return 0;
186  }
187 
188  if(argv[i][2])
189  option_string = &argv[i][2];
190  else if(++i < argc)
191  option_string = argv[i];
192  else
193  {
194  ErrorMessage("Invalid parameter format.\n");
195  return 0;
196  }
197 
198  switch(option_char)
199  {
200  case 'a': /* Read slope parameter alpha */
201  param->alpha = atof(option_string);
202  break;
203  case 'w': /* Read spatial weighting omega */
204  param->omega_string = option_string;
205  break;
206  case 'm': /* Read method string */
207  {
208  char *method_param;
209  param->method = option_string;
210 
211  if((method_param = strchr(param->method, ':')))
212  {
213  *(method_param++) = '\0';
214  param->method_param = atoi(method_param);
215  }
216  else
217  param->method_param = -1;
218 
219  if(!strcmp(param->method, "interp"))
220  {
221  if(param->method_param == -1)
222  param->method_param = 8;
223  else if(param->method_param < 2)
224  {
225  ErrorMessage("Interpolation levels must be"
226  " at least 2.\n");
227  return 0;
228  }
229  }
230  else if(!strcmp(param->method, "poly"))
231  {
232  if(param->method_param == -1)
233  param->method_param = 9;
234  else if(param->method_param % 2 == 0
235  || param->method_param < 3
236  || param->method_param > 11)
237  {
238  ErrorMessage("Polynomial degree must be"
239  " 3, 5, 7, 9, or 11.\n");
240  return 0;
241  }
242  }
243  else
244  {
245  ErrorMessage("Unknown method \"%s\".\n",
246  param->method);
247  return 0;
248  }
249  }
250  break;
251 
252 #ifdef USE_LIBJPEG
253  case 'q':
254  param->jpeg_quality = atoi(option_string);
255 
256  if(param->jpeg_quality <= 0 || param->jpeg_quality > 100)
257  {
258  ErrorMessage("JPEG quality must be between 0 and 100.\n");
259  return 0;
260  }
261  break;
262 #endif
263  case '-':
264  print_usage();
265  return 0;
266  default:
267  if(isprint(option_char))
268  ErrorMessage("Unknown option \"-%c\".\n", option_char);
269  else
270  ErrorMessage("Unknown option.\n");
271 
272  return 0;
273  }
274 
275  i++;
276  }
277  else
278  {
279  if(!param->input_file)
280  param->input_file = argv[i];
281  else
282  param->output_file = argv[i];
283 
284  i++;
285  }
286  }
287 
288  if(!param->input_file)
289  {
290  print_usage();
291  return 0;
292  }
293 
294  return 1;
295 }