r11859: Canonicalize whitespace
[ctsim.git] / tools / ifexport.cpp
1 /*****************************************************************************
2 ** FILE IDENTIFICATION
3 **
4 **   Name:          ifexport.cpp
5 **   Purpose:       Convert an image file to a viewable image
6 **   Programmer:    Kevin Rosenberg
7 **   Date Started:  April 2000
8 **
9 **  This is part of the CTSim program
10 **  Copyright (C) 1983-2000 Kevin Rosenberg
11 **
12 **  $Id$
13 **
14 **  This program is free software; you can redistribute it and/or modify
15 **  it under the terms of the GNU General Public License (version 2) as
16 **  published by the Free Software Foundation.
17 **
18 **  This program is distributed in the hope that it will be useful,
19 **  but WITHOUT ANY WARRANTY; without even the implied warranty of
20 **  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21 **  GNU General Public License for more details.
22 **
23 **  You should have received a copy of the GNU General Public License
24 **  along with this program; if not, write to the Free Software
25 **  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
26 ******************************************************************************/
27
28 #include "ct.h"
29
30
31 enum { O_SCALE, O_MIN, O_MAX, O_AUTO, O_CENTER, O_STATS, O_FORMAT, O_LABELS,
32        O_HELP, O_VERBOSE, O_VERSION, O_DEBUG };
33
34 static struct option my_options[] =
35 {
36   {"scale", 1, 0, O_SCALE},
37   {"min", 1, 0, O_MIN},
38   {"max", 1, 0, O_MAX},
39   {"auto", 1, 0, O_AUTO},
40   {"center", 1, 0, O_CENTER},
41   {"format", 1, 0, O_FORMAT},
42   {"labels", 0, 0, O_LABELS},
43   {"stats", 0, 0, O_STATS},
44   {"verbose", 0, 0, O_VERBOSE},
45   {"debug", 0, 0, O_DEBUG},
46   {"help", 0, 0, O_HELP},
47   {"version", 0, 0, O_VERSION},
48   {0, 0, 0, 0}
49 };
50
51 static const char* g_szIdStr = "$Id$";
52
53 enum { O_AUTO_FULL, O_AUTO_STD0_1, O_AUTO_STD0_5, O_AUTO_STD1, O_AUTO_STD2, O_AUTO_STD3 };
54 static const char O_AUTO_FULL_STR[]="full";
55 static const char O_AUTO_STD0_1_STR[]="std0.1";
56 static const char O_AUTO_STD0_5_STR[]="std0.5";
57 static const char O_AUTO_STD1_STR[]="std1";
58 static const char O_AUTO_STD2_STR[]="std2";
59 static const char O_AUTO_STD3_STR[]="std3";
60
61 enum { O_CENTER_MEDIAN, O_CENTER_MEAN, O_CENTER_MODE };
62 static const char O_CENTER_MEAN_STR[]="mean";
63 static const char O_CENTER_MODE_STR[]="mode";
64 static const char O_CENTER_MEDIAN_STR[]="median";
65
66 enum { O_FORMAT_PNG, O_FORMAT_PNG16, O_FORMAT_PGM, O_FORMAT_PGMASC, O_FORMAT_RAW };
67 static const char O_FORMAT_PNG_STR[]="png" ;
68 static const char O_FORMAT_PNG16_STR[]="png16" ;
69 static const char O_FORMAT_PGM_STR[]="pgm";
70 static const char O_FORMAT_PGMASC_STR[]="pgmasc";
71 static const char O_FORMAT_RAW_STR[]="raw";
72
73 void
74 ifexport_usage (const char *program)
75 {
76   std::cout << "usage: " << fileBasename(program) << " ifname outfile [OPTIONS]\n";
77   std::cout << "Convert IF file to an image file\n";
78   std::cout << std::endl;
79   std::cout << "     ifname     Name of input file\n";
80   std::cout << "     outfile    Name of output file\n";
81   std::cout << "     --format   Output format\n";
82   std::cout << "         pgm    PGM (portable graymap) format (default)\n";
83   std::cout << "         pgmasc PGM (portable graymap) ASCII format\n";
84 #ifdef HAVE_PNG
85   std::cout << "         png    PNG (8-bit) format\n";
86   std::cout << "         png16  PNG (16-bit) format\n";
87 #endif
88   std::cout << "     --center   Center of window\n";
89   std::cout << "         median Median is center of window (default)\n";
90   std::cout << "         mode   Mode is center of window\n";
91   std::cout << "         mean   Mean is center of window\n";
92   std::cout << "     --auto     Set auto window\n";
93   std::cout << "         full   Use full window (default)\n";
94   std::cout << "         std0.1 Use 0.1 standard deviation about center\n";
95   std::cout << "         std0.5 Use 0.5 standard deviation about center\n";
96   std::cout << "         std1   Use one standard deviation about center\n";
97   std::cout << "         std2   Use two standard deviations about center\n";
98   std::cout << "         std3   Use three standard deviations about center\n";
99   std::cout << "     --scale    Scaling factor for output size\n";
100   std::cout << "     --min      Set minimum intensity\n";
101   std::cout << "     --max      Set maximum intensity\n";
102   std::cout << "     --stats    Print image statistics\n";
103   std::cout << "     --labels   Print image labels\n";
104   std::cout << "     --debug    Set debug mode\n";
105   std::cout << "     --verbose  Set verbose mode\n";
106   std::cout << "     --version  Print version\n";
107   std::cout << "     --help     Print this help message\n";
108 }
109
110
111 int
112 ifexport_main (int argc, char *const argv[])
113 {
114   ImageFile* pim = NULL;
115   double densmin = HUGE_VAL, densmax = -HUGE_VAL;
116   char *in_file, *out_file;
117   int opt_verbose = 0;
118   int opt_scale = 1;
119   int opt_auto = O_AUTO_FULL;
120   int opt_set_max = 0;
121   int opt_set_min = 0;
122   int opt_stats = 0;
123   int opt_debug = 0;
124   int opt_center = O_CENTER_MEDIAN;
125   int opt_format = O_FORMAT_PGM;
126   int opt_labels = 0;
127
128   while (1)
129     {
130       int c = getopt_long (argc, argv, "", my_options, NULL);
131       char *endptr = NULL;
132       char *endstr;
133
134       if (c == -1)
135         break;
136
137       switch (c)
138         {
139         case O_MIN:
140           opt_set_min = 1;
141           densmin = strtod(optarg, &endptr);
142           endstr = optarg + strlen(optarg);
143           if (endptr != endstr)
144             {
145               sys_error (ERR_SEVERE, "Error setting --min to %s", optarg);
146               ifexport_usage(argv[0]);
147               return (1);
148             }
149           break;
150         case O_MAX:
151           opt_set_max = 1;
152           densmax = strtod(optarg, &endptr);
153           endstr = optarg + strlen(optarg);
154           if (endptr != endstr)
155             {
156               sys_error (ERR_SEVERE, "Error setting --max to %s", optarg);
157               ifexport_usage(argv[0]);
158               return (1);
159             }
160           break;
161         case O_SCALE:
162           opt_scale = strtol(optarg, &endptr, 10);
163           endstr = optarg + strlen(optarg);
164           if (endptr != endstr)
165             {
166               sys_error (ERR_SEVERE, "Error setting --scale to %s", optarg);
167               ifexport_usage(argv[0]);
168               return (1);
169             }
170           break;
171         case O_AUTO:
172           if (strcmp(optarg, O_AUTO_FULL_STR) == 0)
173             opt_auto = O_AUTO_FULL;
174           else if (strcmp(optarg, O_AUTO_STD1_STR) == 0)
175             opt_auto = O_AUTO_STD1;
176           else if (strcmp(optarg, O_AUTO_STD0_5_STR) == 0)
177             opt_auto = O_AUTO_STD0_5;
178           else if (strcmp(optarg, O_AUTO_STD0_1_STR) == 0)
179             opt_auto = O_AUTO_STD0_1;
180           else if (strcmp(optarg, O_AUTO_STD2_STR) == 0)
181             opt_auto = O_AUTO_STD2;
182           else if (strcmp(optarg, O_AUTO_STD3_STR) == 0)
183             opt_auto = O_AUTO_STD3;
184           else
185             {
186               sys_error (ERR_SEVERE, "Invalid auto mode %s", optarg);
187               ifexport_usage(argv[0]);
188               return (1);
189             }
190                 break;
191         case O_CENTER:
192           if (strcmp(optarg, O_CENTER_MEDIAN_STR) == 0)
193             opt_center = O_CENTER_MEDIAN;
194           else if (strcmp(optarg, O_CENTER_MEAN_STR) == 0)
195             opt_center = O_CENTER_MEAN;
196           else if (strcmp(optarg, O_CENTER_MODE_STR) == 0)
197             opt_center = O_CENTER_MODE;
198           else
199             {
200               sys_error (ERR_SEVERE, "Invalid center mode %s", optarg);
201               ifexport_usage(argv[0]);
202               return (1);
203             }
204           break;
205         case O_FORMAT:
206           if (strcmp(optarg, O_FORMAT_PGM_STR) == 0)
207             opt_format = O_FORMAT_PGM;
208           else if (strcmp(optarg, O_FORMAT_PGMASC_STR) == 0)
209             opt_format = O_FORMAT_PGMASC;
210 #if HAVE_PNG
211           else if (strcmp(optarg, O_FORMAT_PNG_STR) == 0)
212             opt_format = O_FORMAT_PNG;
213           else if (strcmp(optarg, O_FORMAT_PNG16_STR) == 0)
214             opt_format = O_FORMAT_PNG16;
215 #endif
216           else if (strcmp(optarg, O_FORMAT_RAW_STR) == 0)
217                 opt_format = O_FORMAT_RAW;
218 #if HAVE_GIF
219           else if (strcmp(optarg, O_FORMAT_GIF_STR) == 0)
220             opt_format = O_FORMAT_GIF;
221 #endif
222   else {
223               sys_error (ERR_SEVERE, "Invalid format mode %s", optarg);
224               ifexport_usage(argv[0]);
225               return (1);
226             }
227           break;
228         case O_LABELS:
229           opt_labels = 1;
230           break;
231         case O_VERBOSE:
232           opt_verbose = 1;
233           break;
234         case O_DEBUG:
235           opt_debug = 1;
236           break;
237         case O_STATS:
238           opt_stats = 1;
239           break;
240         case O_VERSION:
241 #ifdef VERSION
242           std::cout << "Version " << VERSION << std::endl << g_szIdStr << std::endl;
243 #else
244           std::cout << "Unknown version number\n";
245 #endif
246           return (0);
247         case O_HELP:
248         case '?':
249           ifexport_usage(argv[0]);
250           return (0);
251         default:
252           ifexport_usage(argv[0]);
253           return (1);
254         }
255     }
256
257   if (optind + 2 != argc) {
258     ifexport_usage(argv[0]);
259     return (1);
260   }
261
262   in_file = argv[optind];
263   out_file = argv[optind+1];
264
265   pim = new ImageFile ();
266   ImageFile& im = *pim;
267   if (! im.fileRead(in_file)) {
268     sys_error (ERR_FATAL, "File %s does not exist", in_file);
269     return (1);
270   }
271
272   if (opt_labels)
273     im.printLabels(std::cout);
274
275   if (opt_stats || (! (opt_set_max && opt_set_min))) {
276       double min, max, mean, mode, median, stddev;
277       double window = 0;
278       im.statistics(min, max, mean, mode, median, stddev);
279
280       if (opt_auto == O_AUTO_FULL) {
281         if (! opt_set_max)
282             densmax = max;
283         if (! opt_set_min)
284             densmin = min;
285       }
286       if (opt_stats || opt_auto != O_AUTO_FULL) {
287
288           if (opt_auto == O_AUTO_FULL)
289               ;
290           else if (opt_auto == O_AUTO_STD1)
291               window = stddev;
292           else if (opt_auto == O_AUTO_STD0_1)
293               window = stddev * 0.1;
294           else if (opt_auto == O_AUTO_STD0_5)
295               window = stddev * 0.5;
296           else if (opt_auto == O_AUTO_STD2)
297               window = stddev * 2;
298           else if (opt_auto == O_AUTO_STD3)
299               window = stddev * 3;
300           else {
301               sys_error (ERR_SEVERE, "Internal Error: Invalid auto mode %d", opt_auto);
302               return (1);
303           }
304       }
305       if (opt_stats) {
306           std::cout <<"nx: " << im.nx() << std::endl;
307           std::cout <<"ny: " << im.ny() << std::endl;
308           std::cout <<"min: " << min << std::endl;
309           std::cout <<"max: " << max << std::endl;
310           std::cout <<"mean: " << mean << std::endl;
311           std::cout <<"mode: " << mode << std::endl;
312           std::cout <<"stddev: " << stddev << std::endl;
313       }
314       if (opt_auto != O_AUTO_FULL) {
315           double center;
316
317           if (opt_center == O_CENTER_MEDIAN)
318               center = median;
319           else if (opt_center == O_CENTER_MODE)
320               center = mode;
321           else if (opt_center == O_CENTER_MEAN)
322               center = mean;
323           else {
324               sys_error (ERR_SEVERE, "Internal Error: Invalid center mode %d", opt_center);
325               return (1);
326           }
327           if (! opt_set_max)
328               densmax = center + window;
329           if (! opt_set_min)
330               densmin = center - window;
331       }
332   }
333
334   if (opt_stats) {
335     std::cout << "min display: " << densmin << std::endl;
336     std::cout << "max display: " << densmax << std::endl;
337   }
338
339   if (opt_format == O_FORMAT_PGM)
340     im.writeImagePGM (out_file, opt_scale, opt_scale, densmin, densmax);
341   else if (opt_format == O_FORMAT_PGMASC)
342     im.writeImagePGMASCII (out_file, opt_scale, opt_scale, densmin, densmax);
343 #if HAVE_PNG
344   else if (opt_format == O_FORMAT_PNG)
345     im.writeImagePNG (out_file, 8, opt_scale, opt_scale, densmin, densmax);
346   else if (opt_format == O_FORMAT_PNG16)
347     im.writeImagePNG (out_file, 16, opt_scale, opt_scale, densmin, densmax);
348 #endif
349 #if HAVE_GIF
350   else if (opt_format == O_FORMAT_GIF)
351     im.writeImageGIF (out_file, opt_scale, opt_scale, densmin, densmax);
352 #endif
353   else if (opt_format == O_FORMAT_RAW)
354         im.writeImageRaw (out_file, opt_scale, opt_scale);
355   else
356     {
357       sys_error (ERR_SEVERE, "Internal Error: Invalid format mode %d", opt_format);
358       return (1);
359     }
360   return (0);
361 }
362
363
364 #ifndef NO_MAIN
365 int
366 main (int argc, char *const argv[])
367 {
368   int retval = 1;
369
370   try {
371     retval = ifexport_main(argc, argv);
372   } catch (exception e) {
373           std::cerr << "Exception: " << e.what() << std::endl;
374   } catch (...) {
375           std::cerr << "Unknown exception\n";
376   }
377
378   return (retval);
379 }
380 #endif