r184: *** empty log message ***
[ctsim.git] / tools / if2img.cpp
1 /*****************************************************************************
2 ** FILE IDENTIFICATION
3 **
4 **   Name:          if2img.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: if2img.cpp,v 1.6 2000/08/25 15:59:13 kevin Exp $
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: if2img.cpp,v 1.6 2000/08/25 15:59:13 kevin Exp $";
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_GIF, O_FORMAT_PNG, O_FORMAT_PNG16, O_FORMAT_PGM, O_FORMAT_PGMASC, O_FORMAT_DISP };
67 static const char O_FORMAT_GIF_STR[]="gif";
68 static const char O_FORMAT_PNG_STR[]="png" ;
69 static const char O_FORMAT_PNG16_STR[]="png16" ;
70 static const char O_FORMAT_PGM_STR[]="pgm";
71 static const char O_FORMAT_PGMASC_STR[]="pgmasc";
72 static const char O_FORMAT_DISP_STR[]="disp";
73
74 void 
75 if2img_usage (const char *program)
76 {
77   cout << "usage: " << fileBasename(program) << " ifname outfile [OPTIONS]" << endl;
78   cout << "Convert IF file to an image file" << endl;
79   cout << endl;
80   cout << "     ifname     Name of input file" << endl;
81   cout << "     outfile    Name of output file" << endl;
82   cout << "     --format   Output format" << endl;
83   cout << "         pgm    PGM (portable graymap) format (default)" << endl;
84   cout << "         pgmasc PGM (portable graymap) ASCII format" << endl;
85 #ifdef HAVE_PNG
86   cout << "         png    PNG (8-bit) format" << endl;
87   cout << "         png16  PNG (16-bit) format" << endl;
88 #endif
89 #if HAVE_G2
90   cout << "         gif    GIF format" << endl;
91 #endif
92   cout << "         disp   Display on screen" << endl;
93   cout << "     --center   Center of window" << endl;
94   cout << "         median Median is center of window (default)" << endl;
95   cout << "         mode   Mode is center of window" << endl;
96   cout << "         mean   Mean is center of window" << endl;
97   cout << "     --auto     Set auto window" << endl;
98   cout << "         full   Use full window (default)" << endl;
99   cout << "         std0.1 Use 0.1 standard deviation about center" << endl;
100   cout << "         std0.5 Use 0.5 standard deviation about center" << endl;
101   cout << "         std1   Use one standard deviation about center" << endl;
102   cout << "         std2   Use two standard deviations about center" << endl;
103   cout << "         std3   Use three standard deviations about center" << endl;
104   cout << "     --scale    Scaling factor for output size" << endl;
105   cout << "     --min      Set minimum intensity" << endl;
106   cout << "     --max      Set maximum intensity" << endl;
107   cout << "     --stats    Print image statistics" << endl;
108   cout << "     --labels   Print image labels" << endl;
109   cout << "     --debug    Set debug mode" << endl;
110   cout << "     --verbose  Set verbose mode" << endl;
111   cout << "     --version  Print version" << endl;
112   cout << "     --help     Print this help message" << endl;
113 }
114
115
116 int 
117 if2img_main (int argc, char *const argv[])
118 {
119   ImageFile* pim = NULL;
120   double densmin = HUGE_VAL, densmax = -HUGE_VAL;
121   char *in_file, *out_file;
122   int opt_verbose = 0;
123   int opt_scale = 1;
124   int opt_auto = O_AUTO_FULL;
125   int opt_set_max = 0;
126   int opt_set_min = 0;
127   int opt_stats = 0;
128   int opt_debug = 0;
129   int opt_center = O_CENTER_MEDIAN;
130   int opt_format = O_FORMAT_PGM;
131   int opt_labels = 0;
132
133   while (1)
134     {
135       int c = getopt_long (argc, argv, "", my_options, NULL);
136       char *endptr = NULL;
137       char *endstr;
138       
139       if (c == -1)
140         break;
141       
142       switch (c)
143         {
144         case O_MIN:
145           opt_set_min = 1;
146           densmin = strtod(optarg, &endptr);
147           endstr = optarg + strlen(optarg);
148           if (endptr != endstr)
149             {
150               sys_error (ERR_SEVERE, "Error setting --min to %s", optarg);
151               if2img_usage(argv[0]);
152               return (1);
153             }
154           break;
155         case O_MAX:
156           opt_set_max = 1;
157           densmax = strtod(optarg, &endptr);
158           endstr = optarg + strlen(optarg);
159           if (endptr != endstr)
160             {
161               sys_error (ERR_SEVERE, "Error setting --max to %s", optarg);
162               if2img_usage(argv[0]);
163               return (1);
164             }
165           break;
166         case O_SCALE:
167           opt_scale = strtol(optarg, &endptr, 10);
168           endstr = optarg + strlen(optarg);
169           if (endptr != endstr)
170             {
171               sys_error (ERR_SEVERE, "Error setting --scale to %s", optarg);
172               if2img_usage(argv[0]);
173               return (1);
174             }
175           break;
176         case O_AUTO:
177           if (strcmp(optarg, O_AUTO_FULL_STR) == 0)
178             opt_auto = O_AUTO_FULL;
179           else if (strcmp(optarg, O_AUTO_STD1_STR) == 0)
180             opt_auto = O_AUTO_STD1;
181           else if (strcmp(optarg, O_AUTO_STD0_5_STR) == 0)
182             opt_auto = O_AUTO_STD0_5;
183           else if (strcmp(optarg, O_AUTO_STD0_1_STR) == 0)
184             opt_auto = O_AUTO_STD0_1;
185           else if (strcmp(optarg, O_AUTO_STD2_STR) == 0)
186             opt_auto = O_AUTO_STD2;
187           else if (strcmp(optarg, O_AUTO_STD3_STR) == 0)
188             opt_auto = O_AUTO_STD3;
189           else
190             {
191               sys_error (ERR_SEVERE, "Invalid auto mode %s", optarg);
192               if2img_usage(argv[0]);
193               return (1);
194             }
195                 break;
196         case O_CENTER:
197           if (strcmp(optarg, O_CENTER_MEDIAN_STR) == 0)
198             opt_center = O_CENTER_MEDIAN;
199           else if (strcmp(optarg, O_CENTER_MEAN_STR) == 0)
200             opt_center = O_CENTER_MEAN;
201           else if (strcmp(optarg, O_CENTER_MODE_STR) == 0)
202             opt_center = O_CENTER_MODE;
203           else
204             {
205               sys_error (ERR_SEVERE, "Invalid center mode %s", optarg);
206               if2img_usage(argv[0]);
207               return (1);
208             }
209           break;
210         case O_FORMAT:
211           if (strcmp(optarg, O_FORMAT_PGM_STR) == 0)
212             opt_format = O_FORMAT_PGM;
213           else if (strcmp(optarg, O_FORMAT_PGMASC_STR) == 0)
214             opt_format = O_FORMAT_PGMASC;
215 #if HAVE_PNG
216           else if (strcmp(optarg, O_FORMAT_PNG_STR) == 0)
217             opt_format = O_FORMAT_PNG;
218           else if (strcmp(optarg, O_FORMAT_PNG16_STR) == 0)
219             opt_format = O_FORMAT_PNG16;
220 #endif
221 #if HAVE_GIF
222           else if (strcmp(optarg, O_FORMAT_GIF_STR) == 0)
223             opt_format = O_FORMAT_GIF;
224 #endif
225           else if (strcmp(optarg, O_FORMAT_DISP_STR) == 0)
226             opt_format = O_FORMAT_DISP;
227           else {
228               sys_error (ERR_SEVERE, "Invalid format mode %s", optarg);
229               if2img_usage(argv[0]);
230               return (1);
231             }
232           break;
233         case O_LABELS:
234           opt_labels = 1;
235           break;
236         case O_VERBOSE:
237           opt_verbose = 1;
238           break;
239         case O_DEBUG:
240           opt_debug = 1;
241           break;
242         case O_STATS:
243           opt_stats = 1;
244           break;
245         case O_VERSION:
246 #ifdef VERSION
247           cout << "Version " << VERSION << endl << g_szIdStr << endl;
248 #else
249           cout << "Unknown version number" << endl;
250 #endif
251           return (0);
252         case O_HELP:
253         case '?':
254           if2img_usage(argv[0]);
255           return (0);
256         default:
257           if2img_usage(argv[0]);
258           return (1);
259         }
260     }
261
262 #if HAVE_SGP
263   if (optind + 1 == argc)
264     opt_format = O_FORMAT_DISP;  // display image if no options
265 #endif
266
267   if ((opt_format == O_FORMAT_DISP && optind + 1 != argc) 
268       || (opt_format != O_FORMAT_DISP && optind + 2 != argc)) {
269     if2img_usage(argv[0]);
270     return (1);
271   }
272   
273   in_file = argv[optind];
274
275   if (opt_format != O_FORMAT_DISP)
276       out_file = argv[optind+1];
277   else out_file = NULL;
278
279   pim = new ImageFile ();
280   ImageFile& im = *pim;
281   if (! im.fileRead(in_file)) {
282     sys_error (ERR_FATAL, "File %s does not exist", in_file);
283     return (1);
284   }
285
286   if (opt_labels)
287     im.printLabels(cout);
288
289   if (opt_stats || (! (opt_set_max && opt_set_min))) {
290       double min, max, mean, mode, median, stddev;
291       double window = 0;
292       im.statistics(min, max, mean, mode, median, stddev);
293     
294       if (opt_auto == O_AUTO_FULL) {
295         if (! opt_set_max)
296             densmax = max;
297         if (! opt_set_min)
298             densmin = min;
299       }
300       if (opt_stats || opt_auto != O_AUTO_FULL) {
301
302           if (opt_auto == O_AUTO_FULL)
303               ;
304           else if (opt_auto == O_AUTO_STD1)
305               window = stddev;
306           else if (opt_auto == O_AUTO_STD0_1)
307               window = stddev * 0.1;
308           else if (opt_auto == O_AUTO_STD0_5)
309               window = stddev * 0.5;
310           else if (opt_auto == O_AUTO_STD2)
311               window = stddev * 2;
312           else if (opt_auto == O_AUTO_STD3)
313               window = stddev * 3;
314           else {
315               sys_error (ERR_SEVERE, "Internal Error: Invalid auto mode %d", opt_auto);
316               return (1);
317           }
318       }
319       if (opt_stats) {
320           cout <<"nx: " << im.nx() << endl;
321           cout <<"ny: " << im.ny() << endl;
322           cout <<"min: " << min << endl;
323           cout <<"max: " << max << endl;
324           cout <<"mean: " << mean << endl;
325           cout <<"mode: " << mode << endl;
326           cout <<"stddev: " << stddev << endl;
327       }
328       if (opt_auto != O_AUTO_FULL) {
329           double center;
330           
331           if (opt_center == O_CENTER_MEDIAN)
332               center = median;
333           else if (opt_center == O_CENTER_MODE)
334               center = mode;
335           else if (opt_center == O_CENTER_MEAN)
336               center = mean;
337           else {
338               sys_error (ERR_SEVERE, "Internal Error: Invalid center mode %d", opt_center);
339               return (1);
340           }
341           if (! opt_set_max)
342               densmax = center + window;
343           if (! opt_set_min)
344               densmin = center - window;
345       }
346   }
347   
348   if (opt_stats) {
349     cout << "min display: " << densmin << endl;
350     cout << "max display: " << densmax << endl;
351   }
352   
353   if (opt_format == O_FORMAT_PGM)
354     im.writeImagePGM (out_file, opt_scale, opt_scale, densmin, densmax);
355   else if (opt_format == O_FORMAT_PGMASC)
356     im.writeImagePGMASCII (out_file, opt_scale, opt_scale, densmin, densmax);
357 #if HAVE_PNG
358   else if (opt_format == O_FORMAT_PNG)
359     im.writeImagePNG (out_file, 8, opt_scale, opt_scale, densmin, densmax);
360   else if (opt_format == O_FORMAT_PNG16)
361     im.writeImagePNG (out_file, 16, opt_scale, opt_scale, densmin, densmax);
362 #endif
363 #if HAVE_GIF
364   else if (opt_format == O_FORMAT_GIF) 
365     im.writeImageGIF (out_file, opt_scale, opt_scale, densmin, densmax);
366 #endif
367   else if (opt_format == O_FORMAT_DISP) {
368 #if HAVE_SGP
369     im.displayScaling (opt_scale, densmin, densmax);
370     cout << "Press enter to continue\n";
371     cio_kb_getc();
372 #endif
373   }
374   else
375     {
376       sys_error (ERR_SEVERE, "Internal Error: Invalid format mode %d", opt_format);
377       return (1);
378     }
379   return (0);
380 }
381
382
383 #ifndef NO_MAIN
384 int 
385 main (int argc, char *const argv[])
386 {
387   int retval = 1;
388
389   try {
390     retval = if2img_main(argc, argv);
391   } catch (exception e) {
392     cerr << "Exception: " << e.what() << endl;
393   } catch (...) {
394     cerr << "Unknown exception" << endl;
395   }
396
397   return (retval);
398 }
399 #endif