1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2 * Copyright by The HDF Group. *
3 * Copyright by the Board of Trustees of the University of Illinois. *
4 * All rights reserved. *
5 * *
6 * This file is part of HDF. The full HDF copyright notice, including *
7 * terms governing use, modification, and redistribution, is contained in *
8 * the COPYING file, which can be found at the root of the source code *
9 * distribution tree, or in https://support.hdfgroup.org/ftp/HDF/releases/. *
10 * If you do not have access to either file, you may request a copy from *
11 * help@hdfgroup.org. *
12 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
13
14 /*
15 * Name:
16 * hdfimport (previously fp2hdf)
17 *
18 * Purpose:
19 * To convert floating point and/or integer data to HDF Scientific Data Set (SDS)
20 * and/or 8-bit Raster Image Set (RIS8) format, storing the results
21 * in an HDF file. The image data can be scaled about the mean value.
22 *
23 * -------------
24 * floating point data | | ----------> RIS8
25 * (SDS, ASCII text, or ---> | hdfimport | and/or
26 * native floating point) | | ----------> SDS
27 * -------------
28 * AND / OR
29 * ---------------
30 * integer data | |
31 * (ASCII text, or ---> | hdfimport | ----------> SDS
32 * binary integer) | |
33 * --------------
34 * Synopsis:
35 * hdfimport -h[elp], OR
36 * hdfimport <infile> [ [-t[ype] <output-type> | -n] [<infile> [-t[ype] <output-type> | -n ]]...]
37 * -o[utfile] <outfile> [-r[aster] [ras_opts ...]] [-f[loat]]
38 *
39 * -h[elp]:
40 * Print this summary of usage, and exit.
41 *
42 * <infile(s)>:
43 * Name of the input file(s), containing a single
44 * two-dimensional or three-dimensional floating point array
45 * in either ASCII text, native floating point, native integer
46 * or HDF SDS format. If an HDF file is used for input, it
47 * must contain an SDS. The SDS need only contain a dimension
48 * record and the data, but if it also contains maximum and
49 * minimum values and/or scales for each axis, these will
50 * be used. If the input format is ASCII text or native
51 * floating point or native integer, see "Notes" below on
52 * how it must be organized.
53 *
54 * -t[ype] <output_type>:
55 * Optionally used for every input ASCII file to specify the
56 * data type of the data-set to be written. If not specified
57 * default data type is 32-bit floating point. <output-type>
58 * can be any of the following: FP32 (default), FP64, INT32
59 * INT16, INT8. It can be used only with ASCII files.
60 *
61 * -n:
62 * This option is to be used only if the binary input file
63 * contains 64-bit floating point data and the default
64 * behaviour (default behaviour is to write it to a 32-bit
65 * floating point data-set) should be overridden to write
66 * it to a 64-bit floating point data-set.
67 *
68 * -o[utfile] <outfile>:
69 * Data from one or more input files are stored as one or
70 * more data sets and/or images in one HDF output file,
71 * "outfile".
72 *
73 * -r[aster]:
74 * Store output as a raster image set in the output file.
75 *
76 * -f[loat]:
77 * Store output as a scientific data set in the output file.
78 * This is the default if the "-r" option is not specified.
79 *
80 * ras_opts ...
81 *
82 * -e[xpand] <horiz> <vert> [<depth>]:
83 * Expand float data via pixel replication to produce the
84 * image(s). "horiz" and "vert" give the horizontal and
85 * vertical resolution of the image(s) to be produced; and
86 * optionally, "depth" gives the number of images or depth
87 * planes (for 3D input data).
88 *
89 * -i[nterp] <horiz> <vert> [<depth>]:
90 * Apply bilinear, or trilinear, interpolation to the float
91 * data to produce the image(s). "horiz", "vert", and "depth"
92 * must be greater than or equal to the dimensions of the
93 * original dataset.
94 * If max and min are supplied in input file, this option clips
95 * values that are greater than max or less then min, setting
96 * them to the max and min, respectively.
97 *
98 * -p[alfile] <palfile>:
99 * Store the palette with the image. Get the palette from
100 * "palfile"; which may be an HDF file containing a palette,
101 * or a file containing a raw palette.
102 *
103 * -m[ean] <mean>:
104 * If a floating point mean value is given, the image will be
105 * scaled about the mean. The new extremes (newmax and newmin),
106 * as given by:
107 *
108 * newmax = mean + max(abs(max-mean), abs(mean-min))
109 * newmin = mean - max(abs(max-mean), abs(mean-min))
110 *
111 * will be equidistant from the mean value. If no mean value
112 * is given, then the mean will be: 0.5 * (max + min)
113 *
114 * Notes:
115 * If the input file format is ASCII text or native floating point or native integer(32-bit,
116 * 16-bit, 8-bit), it
117 * must have the following input fields:
118 *
119 * format
120 * nplanes
121 * nrows
122 * ncols
123 * max_value
124 * min_value
125 * [plane1 plane2 plane3 ...]
126 * row1 row2 row3 ...
127 * col1 col2 col3 ...
128 * data1 data2 data3 ...
129 * ...
130 *
131 * Where:
132 * format:
133 * Format designator ("TEXT", "FP32", "FP64", "IN32", "IN16", "IN08").
134 * nplanes, nrows, ncols:
135 * Dimensions are specified in the order slowest changing dimension first.
136 * ncols is dimension of the fastest changing dimension. (horizontal axis
137 * or X-axis in a 3D scale)
138 * nrows corresponds to dimension of the vertical axis or Y-axis in a 3D
139 * scale.
140 * nplanes corresponds to the slowest changing dimension i.e. dimension of
141 * the depth axis or the Z-axis in a 3D scale ("1" for 2D input).
142 * max_value:
143 * Maximum data value.
144 * min_value:
145 * Minimum data value.
146 * plane1, plane2, plane3, ...:
147 * Scales for depth axis.
148 * row1, row2, row3, ...:
149 * Scales for the vertical axis.
150 * col1, col2, col3, ...:
151 * Scales for the horizontal axis.
152 * data1, data2, data3, ...:
153 * The data ordered by rows, left to right and top
154 * to bottom; then optionally, ordered by planes,
155 * front to back.
156 *
157 * For FP32 and FP64 input format, "format", "nplanes", "nrows", "ncols",
158 * and "nplanes" are native integers; where "format" is the integer
159 * representation of the appropriate 4-character string (0x46503332 for
160 * "FP32" and 0x46503634 for "FP64"). The remaining input fields are
161 * composed of native 32-bit floating point values for FP32 input format,
162 * or native 64-bit floating point values for FP64 input format.
163 *
164 * For IN32, IN16 and IN08 input format, "format", "nplanes", "nrows", "ncols",
165 * and "nplanes" are native integers; where "format" is the integer
166 * representation of the appropriate 4-character string. The remaining input
167 * fields are composed of native 32-bit integer values for IN32 input format,
168 * or native 16-bit integer values for IN16 input format or native 8-bit
169 * integer values for IN08 input format.
170 *
171 * Source Availability:
172 * This program is in the public domain, and was developed and made
173 * available by the National Center for Supercomputing Applications,
174 * University of Illinois, Urbana-Champaign (ftp.ncsa.uiuc.edu).
175 *
176 * History:
177 * Beta version: 17-May-89
178 * (by Mike Folk mfolk@ncsa.uiuc.edu)
179 * Revision to put in the mean option: 15-Sep-89
180 * (by Glen Mortensen gam@inel.gov)
181 * Officially released: 01-Dec-89
182 * (by NCSA ftp.ncsa.uiuc.edu)
183 * Revision to fix some bugs: 16-Mar-90
184 * (by Mike Folk mfolk@ncsa.uiuc.edu)
185 * Revision to support 3D and native fp input: 15-May-90
186 * (by Bob Weaver baw@inel.gov)
187 * Revision to fix bug in interp() : 17-Oct-90
188 * (by Fred Walsteijn nwalstyn@fys.ruu.n)
189 * Revision to fix bug in interp() : 23-Nov-90
190 * Now it clips values outside of max and min.
191 * (by Fred Walsteijn nwalstyn@fys.ruu.n)
192 * Revision to start to use HDF 3.2 (and 3.3) library: 22-Jun-93
193 * Still lots to do to support other number types.
194 * (by Chris Houck chouck@ncsa.uiuc.edu)
195 * Revision to incorporate 32-bit integer, 16-bit integer, 08-Jan-02
196 * 8-bit integer data types and converting 64-bit
197 * input data to 64-bit output data.
198 * (by Pankaj Kamat pkamat@uiuc.edu)
199 */
200
201 #include "hdf.h"
202 #include "hfile.h"
203 #include <stdio.h>
204 #ifndef MIPSEL
205 #include <math.h>
206 #endif /* MIPSEL */
207 #include <string.h>
208 #include <ctype.h>
209 #include <mfhdf.h>
210
211 #ifdef H4_HAVE_SYS_STAT_H
212 # include <sys/stat.h>
213 #endif
214
215 #ifdef H4_HAVE_FCNTL_H
216 # include <fcntl.h>
217 #endif
218
219 /*
220 * global macros
221 */
222 #define EXPAND 1 /* -e: expand image with pixel replication */
223 #define INTERP 2 /* -i: expand image with interpolation */
224 #define NAME_LEN 255
225
226 /*
227 * structure definition to associate input files with the output data types
228 */
229 struct infilesformat
230 {
231 char filename[NAME_LEN];
232 int outtype; /* if the value is "" output type will be FP32. Applicable only to TEXT Files*/
233 int32 handle; /* added to facilitate the use of SD interface -BMR 2006/08/18 */
234 };
235 /*
236 * structure definition for command line options
237 */
238 struct Options
239 {
240 struct infilesformat infiles[30]; /* structure to hold the list of input file names. Limited to 30*/
241 char outfile[32]; /* output file name */
242 char palfile[32]; /* palette file name, if any */
243 int fcount; /* number of input files */
244 int to_float; /* float output is desired */
245 int to_image; /* image output is desired */
246 int to_int;
247 int pal; /* output palette with image */
248 int ctm; /* color transform method: EXPAND or INTERP */
249 int exh; /* horizontal expansion factor */
250 int exv; /* vertical expansion factor */
251 int exd; /* depth expansion factor */
252 int hres; /* horizontal resolution of output image */
253 int vres; /* vertical resolution of output image */
254 int dres; /* depth resolution of output image */
255 int mean; /* scale image around a mean */
256 float32 meanval; /* mean value to scale the image around */
257
258 };
259
260 /* Additional Structures to handle different data types */
261 struct int16set /* variables for an INT 16 data set */
262 {
263 int16 max;
264 int16 min;
265 int16 *hscale;
266 int16 *vscale;
267 int16 *dscale;
268 };
269
270 struct int32set /* variables for an INT 32 data set */
271 {
272 int32 max;
273 int32 min;
274 int32 *hscale;
275 int32 *vscale;
276 int32 *dscale;
277 };
278
279 struct fp64set /* variables for a FLOAT 64 data set */
280 {
281 float64 max;
282 float64 min;
283 float64 *hscale;
284 float64 *vscale;
285 float64 *dscale;
286 };
287
288 struct int8set /* variables for an INT 8 data set */
289 {
290 int8 max;
291 int8 min;
292 int8 *hscale;
293 int8 *vscale;
294 int8 *dscale;
295 };
296
297 /*
298 * structure definition for the input data
299 */
300 struct Input
301 {
302 int is_hdf; /* HDF file format flag */
303 int is_text; /* ASCII text format flag */
304 int is_fp32; /* 32-bit native floating point format flag */
305 int is_fp64; /* 64-bit native floating point format flag */
306 int is_int32; /* 32-bit int */
307 int is_int16; /* 16-bit int */
308 int32 rank; /* number of input data dimensions */
309 int32 dims[3]; /* input dimensions - ncols, nrows, nplanes */
310 int is_vscale; /* vertical axis scales in the input */
311 int is_hscale; /* horizontal axis scales in the input */
312 int is_dscale; /* depth axis scales in the input */
313 float32 max; /* maximum value of the data */
314 float32 min; /* minimum value of the data */
315 float32 *hscale; /* horizontal scales for fp32*/
316 float32 *vscale; /* vertical scales for fp32*/
317 float32 *dscale; /* depth scales for fp32*/
318 struct int32set in32s;
319 struct int16set in16s;
320 struct int8set in8s;
321 struct fp64set fp64s;
322 VOIDP data; /* input data */
323 int outtype;
324 };
325
326
327 /*
328 * structure definition for the output raster images
329 */
330 struct Raster
331 {
332 int hres; /* horizontal resolution of the image */
333 int vres; /* vertical resolution of the image */
334 int dres; /* depth resolution of the image */
335 unsigned char *image;
336 };
337
338 /*
339 * constants to represent data types
340 */
341
342 #define FP_32 0
343 #define FP_64 1
344 #define INT_32 2
345 #define INT_16 3
346 #define INT_8 4
347 #define NO_NE 5
348
349
350 /*
351 * state table tokens
352 */
353 #define FILNAME 0 /* filename */
354 #define OPT_o 1 /* output filename */
355 #define OPT_r 2 /* convert to image */
356 #define OPT_e 3 /* expand image via pixel replication */
357 #define OPT_i 4 /* make interpolated image */
358 #define NUMBR 5 /* resolution of enlarged image */
359 #define OPT_p 6 /* palette filename */
360 #define OPT_f 7 /* convert to float (default) */
361 #define OPT_h 8 /* request for explanation */
362 #define OPT_m 9 /* mean to scale around */
363 #define OPT_t 10 /* datatype of the SDS to be written */
364 #define OPT_n 11 /* for a FLOAT 64 binary input file to be accepted as FLOAT 64 SDS (default behaviour is writing it as FLOAT 32 SDS */
365 #define ERR 20 /* invalid token */
366
367 /*
368 * state table for parsing the command line.
369 */
370 static int state_table[19][12] =
371 {
372
373 /* token ordering:
374 FILNAME OPT_o OPT_r OPT_e OPT_i NUMBR OPT_p OPT_f
375 OPT_h OPT_m OPT_z */
376
377 /* state 0: start */
378 {1, ERR, ERR, ERR, ERR, ERR, ERR, ERR,
379 14, ERR, ERR, ERR},
380
381 /* state 1: input files */
382 {1, 2, ERR, ERR, ERR, ERR, ERR, ERR,
383 ERR, ERR, 17, 18},
384
385 /* state 2: -o[utfile] */
386 {3, ERR, ERR, ERR, ERR, ERR, ERR, ERR,
387 ERR, ERR, ERR, ERR},
388
389 /* state 3: outfile */
390 {ERR, ERR, 4, ERR, ERR, ERR, ERR, 13,
391 ERR, ERR, ERR, ERR},
392
393 /* state 4: -r[aster] */
394 {ERR, ERR, ERR, 5, 9, ERR, 10, 12,
395 ERR, 15, ERR, ERR},
396
397 /* state 5: -e[xpand] */
398 {ERR, ERR, ERR, ERR, ERR, 6, ERR, ERR,
399 ERR, ERR, ERR, ERR},
400
401 /* state 6: -e[xpand] or -i[nterp] option argument */
402 {ERR, ERR, ERR, ERR, ERR, 7, ERR, ERR,
403 ERR, ERR, ERR, ERR},
404
405 /* state 7: -e[xpand] or -i[nterp] option argument */
406 {ERR, ERR, ERR, ERR, ERR, 8, 10, 12,
407 ERR, 15, ERR, ERR},
408
409 /* state 8: -e[xpand] or -i[nterp] option argument */
410 {ERR, ERR, ERR, ERR, ERR, ERR, 10, 12,
411 ERR, 15, ERR, ERR},
412
413 /* state 9: -i[nterp] */
414 {ERR, ERR, ERR, ERR, ERR, 6, ERR, ERR,
415 ERR, ERR, ERR, ERR},
416
417 /* state 10: -p[alfile] */
418 {11, ERR, ERR, ERR, ERR, ERR, ERR, ERR,
419 ERR, ERR, ERR, ERR},
420
421 /* state 11: palfile */
422 {ERR, ERR, ERR, 5, 9, ERR, ERR, 12,
423 ERR, 15, ERR, ERR},
424
425 /* state 12: -f[loat] (after -r[aster]) */
426 {ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR,
427 ERR, ERR, ERR, ERR},
428
429 /* state 13: -f[loat] */
430 {ERR, ERR, 4, ERR, ERR, ERR, ERR, ERR,
431 ERR, ERR, ERR, ERR},
432
433 /* state 14: -h[elp] */
434 {ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR,
435 ERR, ERR, ERR, ERR},
436
437 /* state 15: -m[ean] */
438 {ERR, ERR, ERR, ERR, ERR, 16, ERR, ERR,
439 ERR, ERR, ERR, ERR},
440
441 /* state 16: mean */
442 {ERR, ERR, ERR, 5, 9, ERR, 10, 12,
443 ERR, ERR, ERR, ERR},
444
445 /* state 17: output type for data set */
446 {1, 2, ERR, ERR, ERR, ERR, ERR, ERR,
447 ERR, ERR, ERR, ERR},
448
449 /* state 18: override default behaviour for FP 64 */
450 {1, 2, ERR, ERR, ERR, ERR, ERR, ERR,
451 ERR, ERR, ERR, ERR}
452
453
454 };
455
456 /* static local functions */
457 static int gtoken(char *s);
458 static int process(struct Options *opt);
459 static int gfloat(char *infile, FILE * strm, float32 *fp32, struct Input *in);
460 static int gint(char *infile, FILE * strm, int32 *ival, struct Input *in);
461 static int isnum(char *s);
462 static int gdata(struct infilesformat infile_info, struct Input *in, FILE *strm, int *is_maxmin);
463 static int gdimen(struct infilesformat infile_info, struct Input *in, FILE *strm);
464 static int gmaxmin(struct infilesformat infile_info, struct Input *in, FILE *strm, int *is_maxmin);
465 static int gscale(struct infilesformat infile_info, struct Input *in, FILE *strm, int *is_scale);
466 static int gtype(char *infile, struct Input *in, FILE **strm);
467 static int indexes(float32 *scale, int dim, int *idx, int res);
468 static int interp(struct Input *in, struct Raster *im);
469 static int palette(char *palfile);
470 static int pixrep(struct Input *in, struct Raster *im);
471
472 /*
473 * functions with non-integer return types
474 */
475 void help(char *);
476 void mean(struct Input *, struct Options *);
477 void usage(char *);
478
479 /*
480 * Additional functions defined to incorporate the revisions (pkamat)
481 */
482 static int gfloat64(char *infile, FILE * strm, float64 *fp64, struct Input *in);
483 static int gint32(char *infile, FILE * strm, int32 *ival, struct Input *in);
484 static int gint16(char *infile, FILE * strm, int16 *ival, struct Input *in);
485 static int gint8(char *infile, FILE * strm, int8 *ival, struct Input *in);
486 static int init_scales(struct Input * in);
487 void fpdeallocate(struct Input *in, struct Raster *im, struct Options *opt);
488
489 /*
490 * Name:
491 * main
492 *
493 * Purpose:
494 * The driver for "hdfimport".
495 *
496 * Revision (pkamat):
497 * Changes to the state table to handle -t option and the -n option.
498 * Also, a different structure used for holding input files.
499 */
500 int
main(int argc,char * argv[])501 main(int argc, char *argv[])
502 {
503 struct Options opt;
504 int i,k;
505 int outfile_named = FALSE;
506 int token;
507 int state = 0;
508 int flag = 0;
509 char types [5][6] = { "FP32", "FP64", "INT32", "INT16", "INT8" };
510
511 const char *err1 = "Invalid number of arguments: %d.\n";
512 const char *err2 = "Error in state table.\n";
513 const char *err3 = "No output file given.\n";
514 const char *err4 = "Program aborted.\n";
515 /* const char *err5 = "Cannot allooacte memory.\n"; */
516 /*
517 * set 'stdout' and 'stderr' to line-buffering mode
518 */
519 (void) HDsetvbuf(stderr, (char *) NULL, _IOLBF, 0);
520 (void) HDsetvbuf(stdout, (char *) NULL, _IOLBF, 0);
521
522 /*
523 * validate the number of command line arguments
524 */
525 if (argc < 2)
526 {
527 (void) fprintf(stderr, err1, argc);
528 usage(argv[0]);
529 goto err;
530 }
531
532 opt.to_image = FALSE; /* default: no image */
533 opt.to_float = FALSE; /* default: make float if no image */
534 /* Set FALSE here. Will be set TRUE */
535 /* after confirming image option is not set. */
536 opt.ctm = EXPAND; /* default: pixel replication */
537 opt.hres = 0; /* default: no expansion values */
538 opt.vres = 0;
539 opt.dres = 0;
540 opt.pal = FALSE; /* default: no palette */
541 opt.mean = FALSE; /* default: no mean given */
542 opt.fcount = 0; /* to count number of input files */
543
544 /*
545 * parse the command line
546 */
547 for (i = 1; i < argc; i++)
548 {
549 if (strcmp(argv[i], "-V") == 0) {
550 printf("%s, %s\n\n", argv[0], LIBVER_STRING );
551 exit(0);
552 }
553
554 if ((token = gtoken(argv[i])) == ERR)
555 {
556 usage(argv[0]);
557 goto err;
558 }
559
560 state = state_table[state][token];
561
562 switch (state)
563 {
564 case 1: /* counting input files */
565 (void) HDstrcpy(opt.infiles[opt.fcount].filename, argv[i]);
566 opt.infiles[opt.fcount].outtype = NO_NE;
567 opt.fcount++;
568 break;
569 case 2: /* -o found; look for outfile */
570 break;
571 case 3: /* get outfile name */
572 (void) HDstrcpy(opt.outfile, argv[i]);
573 outfile_named = TRUE;
574 break;
575 case 4: /* -r found */
576 opt.to_image = TRUE;
577 break;
578 case 5: /* -e found */
579 opt.ctm = EXPAND;
580 break;
581 case 6: /* horizontal resolution */
582 opt.hres = atoi(argv[i]);
583 break;
584 case 7: /* vertical resolution */
585 opt.vres = atoi(argv[i]);
586 break;
587 case 8: /* depth resolution */
588 opt.dres = atoi(argv[i]);
589 break;
590 case 9: /* -i found */
591 opt.ctm = INTERP;
592 break;
593 case 10: /* -p found */
594 opt.pal = TRUE;
595 break;
596 case 11: /* get pal filename */
597 (void) HDstrcpy(opt.palfile, argv[i]);
598 break;
599 case 12: /* -f found (after a -r) */
600 case 13: /* -f found (no -r yet) */
601 opt.to_float = TRUE;
602 break;
603 case 14: /* -h found; help, then exit */
604 help(argv[0]);
605 exit(0);
606 case 15: /* -m found */
607 opt.mean = TRUE;
608 break;
609 case 16: /* mean value */
610 opt.meanval = (float32)atof(argv[i]);
611 break;
612 case 17: /* -t found */
613 i++;
614 flag = 0;
615 for (k=0; ((k<=4) && (!flag)); k++)
616 if (!strcmp(argv[i], types[k])) flag = 1;
617 if (flag)
618 opt.infiles[opt.fcount-1].outtype = k-1;
619 else
620 {
621 usage(argv[0]);
622 goto err;
623 }
624 break;
625 case 18: /* -n found */
626 opt.infiles[opt.fcount-1].outtype = FP_64;
627 break;
628 case ERR: /* command syntax error */
629 default:
630 (void) fprintf(stderr, "%s", err2);
631 usage(argv[0]);
632 goto err;
633 }
634 }
635
636 /*
637 * make sure an output file was specified
638 */
639 if (!outfile_named)
640 {
641 (void) fprintf(stderr, "%s", err3);
642 usage(argv[0]);
643 goto err;
644 }
645
646 if (!opt.to_image)
647 opt.to_float = TRUE;
648
649 /*
650 * process the input files
651 */
652 if (process(&opt))
653 goto err;
654
655 return(0);
656
657 err:
658 (void) fprintf(stderr, "%s", err4);
659 return(1);
660 }
661
662 /*
663 * Name:
664 * gdata
665 *
666 * Purpose:
667 * Get the input data.
668 *
669 * Revision(pkamat):
670 * Modified to read in data of type INT 32, INT 16, INT 8
671 * in addition to FP 32 and FP 64.
672 * Revision: (bmribler - 2006/8/18)
673 * Replaced first parameter with 'struct infilesformat' to use both
674 * the file name and the SD identifier (handle.)
675 */
676 static int
gdata(struct infilesformat infile_info,struct Input * in,FILE * strm,int * is_maxmin)677 gdata(struct infilesformat infile_info, struct Input *in, FILE *strm, int *is_maxmin)
678 {
679 int32 i, j, k;
680 float32 *fp32;
681 int32 *in32;
682 int16 *in16;
683 float64 *fp64;
684 int8 *in8;
685 int32 hdfdims[3], start[3]; /* order: ZYX or YX */
686 int32 sd_id, sds_id, sd_index, dim_id;
687 int32 len = in->dims[0] * in->dims[1] * in->dims[2];
688 char infile[NAME_LEN];
689 intn status;
690 const char *err1 = "Unable to get input data from file: %s.\n";
691
692 /*
693 * extract the input data from the input file
694 */
695 if (in->is_hdf == TRUE)
696 {
697 sd_id = infile_info.handle;
698 strcpy(infile, infile_info.filename);
699 sd_index = 0;
700 sds_id = SDselect (sd_id, sd_index);
701
702 /*
703 * hdfdims is ordered: ZYX or YX
704 * in->dims is ordered: XYZ
705 */
706 if (in->rank == 2)
707 {
708 hdfdims[0] = in->dims[1];
709 hdfdims[1] = in->dims[0];
710 start[0] = start[1] = 0;
711 }
712 else
713 {
714 hdfdims[0] = in->dims[2];
715 hdfdims[1] = in->dims[1];
716 hdfdims[2] = in->dims[0];
717 start[0] = start[1] = start[2] = 0;
718 }
719
720 status = SDreaddata (sds_id, start, NULL, hdfdims, in->data);
721 if (status == FAIL)
722 {
723 (void) fprintf(stderr, err1, infile);
724 goto err;
725 }
726 }
727 else
728 {
729 if (in->outtype == FP_32)
730 {
731 for (k = 0, fp32 = (float32 *) in->data; k < in->dims[2]; k++)
732 {
733 for (j = 0; j < in->dims[1]; j++)
734 {
735 for (i = 0; i < in->dims[0]; i++, fp32++)
736 {
737 if (gfloat(infile, strm, fp32, in))
738 {
739 (void) fprintf(stderr, err1, infile);
740 goto err;
741 }
742 }
743 }
744 }
745 if (*is_maxmin == FALSE)
746 {
747 in->min = in->max = *(float32*) in->data;
748 for (i = 1; i< len; i++)
749 {
750 if (((float32 *) in->data)[i] > in->max)
751 in->max = ((float32 *) in->data)[i];
752 if (((float32*) in->data)[i] < in->min)
753 in->min = ((float32*) in->data)[i];
754 }
755 *is_maxmin = TRUE;
756 }
757 }
758 if (in->outtype == INT_32)
759 {
760 for (k = 0, in32 = (int32 *) in->data; k < in->dims[2] ; k++)
761 {
762 for (j= 0; j < in->dims[1]; j++)
763 {
764 for (i =0; i < in->dims[0]; i++, in32++)
765 {
766 if (gint32(infile, strm, in32, in))
767 {
768 (void) fprintf(stderr, err1, infile);
769 goto err;
770 }
771 }
772 }
773 }
774 if (*is_maxmin == FALSE)
775 {
776 in->in32s.min = in->in32s.max = *(int32 *) in->data;
777 for (i = 1; i<len; i++)
778 {
779 if (((int32 *) in->data)[i] > in->in32s.max)
780 in->in32s.max = ((int32 *) in->data)[i];
781 if (((int32 *) in->data)[i] < in->in32s.min)
782 in->in32s.min = ((int32 *) in->data)[i];
783 }
784 *is_maxmin = TRUE;
785 }
786 }
787 if (in->outtype == INT_16)
788 {
789 for (k = 0, in16 = (int16 *) in->data; k < in->dims[2] ; k++)
790 {
791 for (j= 0; j < in->dims[1]; j++)
792 {
793 for (i =0; i < in->dims[0]; i++, in16++)
794 {
795 if (gint16(infile, strm, in16, in))
796 {
797 (void) fprintf(stderr, err1, infile);
798 goto err;
799 }
800 }
801 }
802 }
803 if (*is_maxmin == FALSE)
804 {
805 in->in16s.min = in->in16s.max = *(int16 *) in->data;
806 for (i = 1; i<len; i++)
807 {
808 if (((int16 *) in->data)[i] > in->in16s.max)
809 in->in16s.max = ((int16 *) in->data)[i];
810 if (((int16 *) in->data)[i] < in->in16s.min)
811 in->in16s.min = ((int16 *) in->data)[i];
812 }
813 *is_maxmin = TRUE;
814 }
815 }
816
817 if (in->outtype == INT_8)
818 {
819 for (k = 0, in8 = (int8 *) in->data; k < in->dims[2] ; k++)
820 {
821 for (j= 0; j < in->dims[1]; j++)
822 {
823 for (i =0; i < in->dims[0]; i++, in8++)
824 {
825 if (gint8(infile, strm, in8, in))
826 {
827 (void) fprintf(stderr, err1, infile);
828 goto err;
829 }
830 }
831 }
832 }
833 if (*is_maxmin == FALSE)
834 {
835 in->in8s.min = in->in8s.max = *(int8 *) in->data;
836 for (i = 1; i<len; i++)
837 {
838 if (((int8 *) in->data)[i] > in->in8s.max)
839 in->in8s.max = ((int8 *) in->data)[i];
840 if (((int8 *) in->data)[i] < in->in8s.min)
841 in->in8s.min = ((int8 *) in->data)[i];
842 }
843 *is_maxmin = TRUE;
844 }
845 }
846
847 if (in->outtype == FP_64)
848 {
849 for (k = 0, fp64 = (float64 *) in->data; k < in->dims[2]; k++)
850 {
851 for (j = 0; j < in->dims[1]; j++)
852 {
853 for (i = 0; i < in->dims[0]; i++, fp64++)
854 {
855 if (gfloat64(infile, strm, fp64, in))
856 {
857 (void) fprintf(stderr, err1, infile);
858 goto err;
859 }
860 }
861 }
862 }
863 if (*is_maxmin == FALSE)
864 {
865 in->fp64s.min = in->fp64s.max = *(float64*) in->data;
866 for (i = 1; i< len; i++)
867 {
868 if (((float64 *) in->data)[i] > in->fp64s.max)
869 in->fp64s.max = ((float64*) in->data)[i];
870 if (((float64*) in->data)[i] < in->fp64s.min)
871 in->fp64s.min = ((float64*) in->data)[i];
872 }
873 *is_maxmin = TRUE;
874 }
875 }
876
877 /* } */
878 (void) fclose(strm);
879 }
880
881 #ifdef DEBUG
882 (void) printf("\tdata:");
883 for (k = 0, fp32 = in->data; k < in->dims[2]; k++)
884 {
885 (void) printf("\n");
886 for (j = 0; j < in->dims[1]; j++)
887 {
888 (void) printf("\n\t");
889 for (i = 0; i < in->dims[0]; i++, fp32++)
890 (void) printf("%E ", *fp32);
891 }
892 }
893 (void) printf("\n\n\n");
894 #endif /* DEBUG */
895
896 return (0);
897
898 err:
899 return (1);
900 }
901
902 /*
903 * Name:
904 * gdimen
905 *
906 * Purpose:
907 * Determine the input data dimensions.
908 * Revision: (bmribler - 2006/8/18)
909 * Used the SD interface instead of DFSD.
910 * Replaced first parameter with 'struct infilesformat' to use both
911 * the file name and the SD identifier (handle.)
912 */
913
914 static int
gdimen(struct infilesformat infile_info,struct Input * in,FILE * strm)915 gdimen(struct infilesformat infile_info, struct Input *in, FILE *strm)
916 {
917 int32 hdfdims[3]; /* order: ZYX or YX */
918 intn status; /* returned value from APIs */
919 char infile[NAME_LEN];
920 char *sds_name=NULL;
921 int32 rank, nattrs, dtype; /* rank, num of attrs, data type */
922
923 const char *err1 = "Unable to get data dimensions from file: %s.\n";
924 const char *err2 = "Invalid data rank of %d in file: %s.\n";
925 const char *err3 = "Dimension(s) is less than '2' in file: %s.\n";
926 const char *err4 = "Unexpected number type from file: %s.\n";
927 const char *err5 = "Unable to get the length of the SDS' name: index %d.\n";
928 const char *err6 = "Unable to allocate dynamic memory.\n";
929 const char *err7 = "Failed to open the SDS.\n";
930
931 /*
932 * extract the rank and dimensions of the HDF input file
933 */
934 if (in->is_hdf == TRUE)
935 {
936 int32 sds_id, sd_index;
937 int32 sd_id = infile_info.handle; /* shortcut for handle from SDstart */
938 char *infile = infile_info.filename; /* shortcut for input filename */
939 uint16 name_len = 0;
940 intn status = FAIL;
941
942 /* get the dimension information of the only SDS in the file */
943 sd_index = 0;
944 sds_id = SDselect (sd_id, sd_index);
945 if (sds_id == FAIL)
946 {
947 (void) fprintf(stderr, "%s", err7);
948 goto err;
949 }
950
951 /* get the SDS name's length and allocate sufficient space for
952 the name's buffer */
953 status = SDgetnamelen(sds_id, &name_len);
954 if (status == FAIL)
955 {
956 (void) fprintf(stderr, err5, sd_index);
957 goto err;
958 }
959 sds_name = (char *)HDmalloc(name_len+1);
960 if (sds_name == NULL)
961 {
962 (void) fprintf(stderr, "%s", err6);
963 goto err;
964 }
965
966 /* obtain the SDS' information */
967 status = SDgetinfo(sds_id, sds_name, &rank, hdfdims, &dtype, &nattrs);
968 if (status == FAIL)
969 {
970 (void) fprintf(stderr, err1, infile);
971 goto err;
972 }
973 in->rank = (int)rank;
974
975 /* don't know how to deal with other numbers yet */
976 if (dtype != DFNT_FLOAT32)
977 {
978 (void) fprintf(stderr, err4, infile);
979 goto err;
980 }
981
982 /*
983 * hdfdims is ordered: ZYX or YX
984 * in->dims is ordered: XYZ
985 */
986 if (in->rank == 2)
987 {
988 in->dims[0] = hdfdims[1];
989 in->dims[1] = hdfdims[0];
990 in->dims[2] = 1;
991 }
992 else if (in->rank == 3)
993 {
994 in->dims[0] = hdfdims[2];
995 in->dims[1] = hdfdims[1];
996 in->dims[2] = hdfdims[0];
997 }
998 else
999 {
1000 (void) fprintf(stderr, err2, in->rank, infile);
1001 goto err;
1002 }
1003
1004 /*
1005 * get the rank and dimensions from files of other input formats
1006 *
1007 */
1008 }
1009 else
1010 {
1011 if (gint(infile, strm, &in->dims[2], in))
1012 {
1013 (void) fprintf(stderr, err1, infile);
1014 goto err;
1015 }
1016 if (in->dims[2] > 1)
1017 in->rank = 3;
1018 else
1019 in->rank = 2;
1020 if (gint(infile, strm, &in->dims[1], in))
1021 {
1022 (void) fprintf(stderr, err1, infile);
1023 goto err;
1024 }
1025 if (gint(infile, strm, &in->dims[0], in))
1026 {
1027 (void) fprintf(stderr, err1, infile);
1028 goto err;
1029 }
1030 }
1031
1032 /*
1033 * validate dimension sizes
1034 */
1035 if ((in->dims[0] < 2) || (in->dims[1] < 2))
1036 {
1037 (void) fprintf(stderr, err3, infile);
1038 goto err;
1039 }
1040
1041 #ifdef DEBUG
1042 (void) printf("\nInput Information ...\n\n");
1043 (void) printf("\trank:\n\n\t%d\n\n", in->rank);
1044 (void) printf("\tdimensions (nplanes,nrows,ncols):\n\n");
1045 (void) printf("\t%d %d %d\n\n", in->dims[2], in->dims[1], in->dims[0]);
1046 #endif /* DEBUG */
1047
1048 if (sds_name != NULL) HDfree(sds_name);
1049 return (0);
1050
1051 err:
1052 if (sds_name != NULL) HDfree(sds_name);
1053 return (1);
1054 }
1055
1056 /*
1057 * Name:
1058 * gfloat
1059 *
1060 * Purpose:
1061 * Read in a single floating point value from the input stream. The
1062 * input format may either be ASCII text , 32-bit native floating point,
1063 * or 64-bit native floating point.
1064 */
1065 static int
gfloat(char * infile,FILE * strm,float32 * fp32,struct Input * in)1066 gfloat(char *infile, FILE * strm, float32 *fp32, struct Input *in)
1067 {
1068 float64 fp64=0.0;
1069
1070 const char *err1 = "Unable to get 'float' value from file: %s.\n";
1071
1072 if (in->is_text == TRUE)
1073 {
1074 if (fscanf(strm, "%e", fp32) != 1)
1075 {
1076 (void) fprintf(stderr, err1, infile);
1077 goto err;
1078 }
1079 }
1080 else if (in->is_fp32 == TRUE)
1081 {
1082 if (fread((char *) fp32, sizeof(float32), 1, strm) != 1)
1083 {
1084 (void) fprintf(stderr, err1, infile);
1085 goto err;
1086 }
1087 }
1088 else
1089 {
1090 if (fread((char *) &fp64, sizeof(float64), 1, strm) != 1)
1091 {
1092 (void) fprintf(stderr, err1, infile);
1093 goto err;
1094 }
1095 *fp32 = (float32) fp64;
1096 }
1097
1098 return (0);
1099
1100 err:
1101 return (1);
1102 }
1103
1104 /*
1105 * Name: (pkamat - New function)
1106 * gfloat64
1107 *
1108 * Purpose:
1109 * Read in a double floating point value from the input stream. The
1110 * input format may either be ASCII text ,
1111 * or 64-bit native floating point.
1112 */
1113
1114 static int
gfloat64(char * infile,FILE * strm,float64 * fp64,struct Input * in)1115 gfloat64(char *infile, FILE * strm, float64 *fp64, struct Input *in)
1116 {
1117 const char *err1 = "Unable to get 'float' value from file: %s.\n";
1118
1119 if (in->is_text == TRUE)
1120 {
1121 if (fscanf(strm, "%le", fp64) != 1)
1122 {
1123 (void) fprintf(stderr, err1, infile);
1124 goto err;
1125 }
1126 }
1127 else
1128 {
1129 if (fread((char *) fp64, sizeof(float64), 1, strm) != 1)
1130 {
1131 (void) fprintf(stderr, err1, infile);
1132 goto err;
1133 }
1134 }
1135
1136 return (0);
1137
1138 err:
1139 return (1);
1140 }
1141
1142 /*
1143 * Name:
1144 * gint
1145 *
1146 * Purpose:
1147 * Read in a single integer value from the input stream. The input
1148 * format may either be ASCII text or a native BCD of type integer.
1149 */
1150 static int
gint(char * infile,FILE * strm,int32 * ival,struct Input * in)1151 gint(char *infile, FILE * strm, int32 *ival, struct Input *in)
1152 {
1153 const char *err1 = "Unable to get 'int' value from file: %s.\n";
1154 /*
1155 * process TEXT-formatted input
1156 */
1157 if (in->is_text == TRUE)
1158 {
1159 if (fscanf(strm, "%d", ival) != 1)
1160 {
1161 (void) fprintf(stderr, err1, infile);
1162 goto err;
1163 }
1164
1165 /*
1166 * process BCD-formatted input
1167 */
1168 }
1169 else
1170 {
1171 if (fread((char *) ival, sizeof(int), 1, strm) != 1)
1172 {
1173 (void) fprintf(stderr, err1, infile);
1174 goto err;
1175 }
1176 }
1177
1178 return (0);
1179
1180 err:
1181 return (1);
1182 }
1183
1184 /*
1185 * Name: (pkamat - New function)
1186 * gint32
1187 *
1188 * Purpose:
1189 * Read in a single 32-bit integer value from the input stream. The input
1190 * format may either be ASCII text or a native BCD of type integer.
1191 */
1192
1193 static int
gint32(char * infile,FILE * strm,int32 * ival,struct Input * in)1194 gint32(char *infile, FILE * strm, int32 *ival, struct Input *in)
1195 {
1196 const char *err1 = "Unable to get 'int32' value from file: %s.\n";
1197 /*
1198 * process TEXT-formatted input
1199 */
1200 if (in->is_text == TRUE)
1201 {
1202 if (fscanf(strm, "%d", ival) != 1)
1203 {
1204 (void) fprintf(stderr, err1, infile);
1205 goto err;
1206 }
1207
1208 /*
1209 * process BCD-formatted input
1210 */
1211 }
1212 else
1213 {
1214 if (fread((char *) ival, sizeof(int32), 1, strm) != 1)
1215 {
1216 (void) fprintf(stderr, err1, infile);
1217 goto err;
1218 }
1219 }
1220
1221 return (0);
1222
1223 err:
1224 return (1);
1225 }
1226
1227 /*
1228 * Name: (pkamat - New function)
1229 * gint16
1230 *
1231 * Purpose:
1232 * Read in a single 16-bit integer value from the input stream. The input
1233 * format may either be ASCII text or a native BCD of type 16-bit integer.
1234 */
1235
1236 static int
gint16(char * infile,FILE * strm,int16 * ival,struct Input * in)1237 gint16(char *infile, FILE * strm, int16 *ival, struct Input *in)
1238 {
1239 const char *err1 = "Unable to get 'int16' value from file: %s.\n";
1240
1241 if (in->is_text == TRUE)
1242 {
1243 if (fscanf(strm, "%hd", ival) != 1)
1244 {
1245 (void) fprintf(stderr, err1, infile);
1246 goto err;
1247 }
1248 }
1249
1250 else
1251 {
1252 if (fread((char *) ival, sizeof(int16), 1, strm) != 1)
1253 {
1254 (void) fprintf(stderr, err1, infile);
1255 goto err;
1256 }
1257 }
1258
1259
1260 return (0);
1261
1262 err:
1263 return (1);
1264 }
1265
1266 /*
1267 * Name: (pkamat - New function)
1268 * gint8
1269 *
1270 * Purpose:
1271 * Read in a single 8-bit integer value from the input stream. The input
1272 * format may either be ASCII text or a native BCD of type 8-bit integer.
1273 */
1274
1275 static int
gint8(char * infile,FILE * strm,int8 * ival,struct Input * in)1276 gint8(char *infile, FILE * strm, int8 *ival, struct Input *in)
1277 {
1278 const char *err1 = "Unable to get 'int8' value from file: %s.\n";
1279 int16 temp;
1280
1281 if (in->is_text == TRUE)
1282 {
1283 if (fscanf(strm, "%hd", &temp) != 1)
1284 {
1285 (void) fprintf(stderr, err1, infile);
1286 goto err;
1287 }
1288 *ival = (int8) temp;
1289 }
1290 else
1291 {
1292 if (fread((char *) ival, sizeof(int8), 1, strm) != 1)
1293 {
1294 (void) fprintf(stderr, err1, infile);
1295 goto err;
1296 }
1297 }
1298 return (0);
1299
1300 err:
1301 return (1);
1302 }
1303 /*
1304 * Name:
1305 * gmaxmin
1306 *
1307 * Purpose:
1308 * Extract the maximum and minimum data values from the input file.
1309 * Supports 32-bit integer, 16-bit integer, 8-bit integer, 32-bit float, 64-bit float
1310 * Revision: (pvn) March 14, 2006
1311 * Used the SD interface instead of DFSD
1312 * Revision: (bmribler - 2006/8/18)
1313 * Removed SDstart call here, used passed-in SD id from process() instead.
1314 * Replaced first parameter with 'struct infilesformat' to use both
1315 * the file name and the SD identifier (handle.)
1316 */
1317 static int
gmaxmin(struct infilesformat infile_info,struct Input * in,FILE * strm,int * is_maxmin)1318 gmaxmin(struct infilesformat infile_info, struct Input *in, FILE *strm, int *is_maxmin)
1319 {
1320 const char *err1 = "Unable to get max/min values from file: %s.\n";
1321
1322 /*
1323 * extract the max/min values from the input file
1324 */
1325 if (in->is_hdf == TRUE)
1326 {
1327 int32 sds_id, sd_index = 0;
1328 intn status;
1329
1330 sds_id = SDselect(infile_info.handle, sd_index);
1331 status = SDgetrange(sds_id, &in->max, &in->min);
1332 if (status != FAIL)
1333 {
1334 if (in->max > in->min)
1335 *is_maxmin = TRUE;
1336 }
1337
1338 /* terminate access to the array. */
1339 if (SDendaccess(sds_id)==FAIL)
1340 goto err;
1341 }
1342 else /* input file is not an HDF file */
1343 {
1344 char *infile = infile_info.filename;
1345 if (in->outtype == FP_32)
1346 {
1347 if (gfloat(infile, strm, &in->max, in))
1348 {
1349 (void) fprintf(stderr, err1, infile);
1350 goto err;
1351 }
1352 if (gfloat(infile, strm, &in->min, in))
1353 {
1354 (void) fprintf(stderr, err1, infile);
1355 goto err;
1356 }
1357 if (in->max > in->min)
1358 *is_maxmin = TRUE;
1359 }
1360 if (in->outtype == FP_64)
1361 {
1362 if (gfloat64(infile, strm, &in->fp64s.max, in))
1363 {
1364 (void) fprintf(stderr, err1, infile);
1365 goto err;
1366 }
1367 if (gfloat64(infile, strm, &in->fp64s.min, in))
1368 {
1369 (void) fprintf(stderr, err1, infile);
1370 goto err;
1371 }
1372 if (in->fp64s.max > in->fp64s.min)
1373 *is_maxmin = TRUE;
1374 }
1375 if (in->outtype == INT_32)
1376 {
1377 if (gint32(infile, strm, &in->in32s.max, in))
1378 {
1379 (void) fprintf(stderr, err1, infile);
1380 goto err;
1381 }
1382 if (gint32(infile, strm, &in->in32s.min, in))
1383 {
1384 (void) fprintf(stderr, err1, infile);
1385 goto err;
1386 }
1387 if (in->in32s.max > in->in32s.min)
1388 *is_maxmin = TRUE;
1389 }
1390
1391 if (in->outtype == INT_16)
1392 {
1393 if (gint16(infile, strm, &in->in16s.max, in))
1394 {
1395 (void) fprintf(stderr, err1, infile);
1396 goto err;
1397 }
1398 if (gint16(infile, strm, &in->in16s.min, in))
1399 {
1400 (void) fprintf(stderr, err1, infile);
1401 goto err;
1402 }
1403 if (in->in16s.max > in->in16s.min)
1404 *is_maxmin = TRUE;
1405 }
1406
1407 if (in->outtype == INT_8)
1408 {
1409 if (gint8(infile, strm, &in->in8s.max, in))
1410 {
1411 (void) fprintf(stderr, err1, infile);
1412 goto err;
1413 }
1414 if (gint8(infile, strm, &in->in8s.min, in))
1415 {
1416 (void) fprintf(stderr, err1, infile);
1417 goto err;
1418 }
1419 if (in->in8s.max > in->in8s.min)
1420 *is_maxmin = TRUE;
1421 }
1422 }
1423
1424 #ifdef DEBUG
1425 (void) printf("\tinput maximum/minimum values:\n\n");
1426 (void) printf("\t%E %E\n\n", in->max, in->min);
1427 #endif /* DEBUG */
1428
1429 return (0);
1430
1431 err:
1432 return (1);
1433 }
1434
1435 /*
1436 * Name:
1437 * gscale
1438 *
1439 * Purpose:
1440 * Determine the scale for each axis.
1441 *
1442 * Revision: (pkamat)
1443 * Modified to support 32-bit integer, 16-bit integer, 8-bit integer in
1444 * addition to 32-bit float and 64-bit float
1445 * Revision: (pvn) March 14, 2006
1446 * Used the SD interface instead of DFSD
1447 * Revision: (bmribler - 2006/8/18)
1448 * Removed SDstart call here, used passed-in SD id from process() instead.
1449 * Replaced first parameter with 'struct infilesformat' to use both
1450 * the file name and the SD identifier (handle.)
1451 */
1452 static int
gscale(struct infilesformat infile_info,struct Input * in,FILE * strm,int * is_scale)1453 gscale(struct infilesformat infile_info, struct Input *in, FILE *strm, int *is_scale)
1454 {
1455 int i;
1456 int32 hdfdims[3]; /* order: ZYX or YX */
1457
1458 const char *err1 = "Unable to get axis scale from file: %s.\n";
1459
1460 *is_scale = TRUE;
1461
1462 /*
1463 * hdfdims is ordered: ZYX or YX
1464 * in->dims is ordered: XYZ
1465 */
1466 if (in->rank == 2)
1467 {
1468 hdfdims[0] = in->dims[1];
1469 hdfdims[1] = in->dims[0];
1470 }
1471 else
1472 {
1473 hdfdims[0] = in->dims[2];
1474 hdfdims[1] = in->dims[1];
1475 hdfdims[2] = in->dims[0];
1476 }
1477
1478 /*
1479 * extract the scale values from the input file
1480 */
1481 if (in->is_hdf == TRUE)
1482 {
1483 int32 sds_id, dim_id, sd_index = 0;
1484 int32 sd_id = infile_info.handle; /* shortcut for handle from SDstart */
1485
1486 /* select the SDS */
1487 sds_id = SDselect (sd_id, sd_index);
1488
1489 /* if the SDS is two-dimensional... */
1490 if (in->rank == 2)
1491 {
1492 /* select the dimension */
1493 dim_id = SDgetdimid (sds_id, 0);
1494 if (SDgetdimscale (dim_id, in->vscale)==FAIL)
1495 goto err;
1496
1497 dim_id = SDgetdimid (sds_id, 1);
1498 if (SDgetdimscale (dim_id, in->hscale)==FAIL)
1499 goto err;
1500
1501 }
1502 else /* ...three-dimensional... */
1503 {
1504 dim_id = SDgetdimid (sds_id, 0);
1505 if (SDgetdimscale (dim_id, in->dscale)==FAIL)
1506 goto err;
1507
1508 dim_id = SDgetdimid (sds_id, 1);
1509 if (SDgetdimscale (dim_id, in->vscale)==FAIL)
1510 goto err;
1511
1512 dim_id = SDgetdimid (sds_id, 2);
1513 if (SDgetdimscale (dim_id, in->hscale)==FAIL)
1514 goto err;
1515 }
1516
1517 /* terminate access to the array. */
1518 if (SDendaccess(sds_id)==FAIL)
1519 goto err;
1520 }
1521 else /* input file is not an HDF file */
1522 {
1523 char infile[NAME_LEN];
1524 strcpy(infile, infile_info.filename);
1525 switch(in->outtype)
1526 {
1527 case 0: /* 32-bit float */
1528 if (in->rank == 2)
1529 {
1530 for (i = 0; i < hdfdims[0]; i++)
1531 {
1532 if (gfloat(infile, strm, &in->vscale[i], in))
1533 {
1534 (void) fprintf(stderr, err1, infile);
1535 goto err;
1536 }
1537 }
1538 in->vscale[i] = in->vscale[i - 1];
1539 for (i = 0; i < hdfdims[1]; i++)
1540 {
1541 if (gfloat(infile, strm, &in->hscale[i], in))
1542 {
1543 (void) fprintf(stderr, err1, infile);
1544 goto err;
1545 }
1546 }
1547
1548 in->hscale[i] = in->hscale[i - 1];
1549 }
1550 else
1551 {
1552 for (i = 0; i < hdfdims[0]; i++)
1553 {
1554 if (gfloat(infile, strm, &in->dscale[i], in))
1555 {
1556 (void) fprintf(stderr, err1, infile);
1557 goto err;
1558 }
1559 }
1560 in->dscale[i] = in->dscale[i - 1];
1561 for (i = 0; i < hdfdims[1]; i++)
1562 {
1563 if (gfloat(infile, strm, &in->vscale[i], in))
1564 {
1565 (void) fprintf(stderr, err1, infile);
1566 goto err;
1567 }
1568 }
1569 in->vscale[i] = in->vscale[i - 1];
1570 for (i = 0; i < hdfdims[2]; i++)
1571 {
1572 if (gfloat(infile, strm, &in->hscale[i], in))
1573 {
1574 (void) fprintf(stderr, err1, infile);
1575 goto err;
1576 }
1577 }
1578 in->hscale[i] = in->hscale[i - 1];
1579 }
1580 break;
1581
1582 case 1: /* 64-bit float */
1583 if (in->rank == 2)
1584 {
1585 for (i = 0; i < hdfdims[0]; i++)
1586 {
1587 if (gfloat64(infile, strm, &in->fp64s.vscale[i], in))
1588 {
1589 (void) fprintf(stderr, err1, infile);
1590 goto err;
1591 }
1592 }
1593 in->fp64s.vscale[i] = in->fp64s.vscale[i - 1];
1594 for (i = 0; i < hdfdims[1]; i++)
1595 {
1596 if (gfloat64(infile, strm, &in->fp64s.hscale[i], in))
1597 {
1598 (void) fprintf(stderr, err1, infile);
1599 goto err;
1600 }
1601 }
1602 in->fp64s.hscale[i] = in->fp64s.hscale[i - 1];
1603 }
1604 else
1605 {
1606 for (i = 0; i < hdfdims[0]; i++)
1607 {
1608 if (gfloat64(infile, strm, &in->fp64s.dscale[i], in))
1609 {
1610 (void) fprintf(stderr, err1, infile);
1611 goto err;
1612 }
1613 }
1614 in->fp64s.dscale[i] = in->fp64s.dscale[i - 1];
1615
1616 for (i = 0; i < hdfdims[1]; i++)
1617 {
1618 if (gfloat64(infile, strm, &in->fp64s.vscale[i], in))
1619 {
1620 (void) fprintf(stderr, err1, infile);
1621 goto err;
1622 }
1623 }
1624 in->fp64s.vscale[i] = in->fp64s.vscale[i - 1];
1625
1626 for (i = 0; i < hdfdims[2]; i++)
1627 {
1628 if (gfloat64(infile, strm, &in->fp64s.hscale[i], in))
1629 {
1630 (void) fprintf(stderr, err1, infile);
1631 goto err;
1632 }
1633 }
1634 in->fp64s.hscale[i] = in->fp64s.hscale[i - 1];
1635 }
1636 break;
1637
1638 case 2: /* 32-bit integer */
1639 if (in->rank == 2)
1640 {
1641 for (i = 0; i < hdfdims[0]; i++)
1642 {
1643 if (gint32(infile, strm, &in->in32s.vscale[i], in))
1644 {
1645 (void) fprintf(stderr, err1, infile);
1646 goto err;
1647 }
1648
1649 }
1650 in->in32s.vscale[i] = in->in32s.vscale[i - 1];
1651 for (i = 0; i < hdfdims[1]; i++)
1652 {
1653 if (gint32(infile, strm, &in->in32s.hscale[i], in))
1654 {
1655 (void) fprintf(stderr, err1, infile);
1656 goto err;
1657 }
1658 }
1659 in->in32s.hscale[i] = in->in32s.hscale[i - 1];
1660 }
1661
1662 else
1663 {
1664 for (i = 0; i < hdfdims[0]; i++)
1665 {
1666 if (gint32(infile, strm, &in->in32s.dscale[i], in))
1667 {
1668 (void) fprintf(stderr, err1, infile);
1669 goto err;
1670 }
1671 }
1672 in->in32s.dscale[i] = in->in32s.dscale[i - 1];
1673 for (i = 0; i < hdfdims[1]; i++)
1674 {
1675 if (gint32(infile, strm, &in->in32s.vscale[i], in))
1676 {
1677 (void) fprintf(stderr, err1, infile);
1678 goto err;
1679 }
1680 }
1681 in->in32s.vscale[i] = in->in32s.vscale[i - 1];
1682 for (i = 0; i < hdfdims[2]; i++)
1683 {
1684 if (gint32(infile, strm, &in->in32s.hscale[i], in))
1685 {
1686 (void) fprintf(stderr, err1, infile);
1687 goto err;
1688 }
1689 }
1690 in->in32s.hscale[i] = in->in32s.hscale[i - 1];
1691 }
1692 break;
1693
1694 case 3: /* 16-bit integer */
1695 if (in->rank == 2)
1696 {
1697 for (i = 0; i < hdfdims[0]; i++)
1698 {
1699 if (gint16(infile, strm, &in->in16s.vscale[i], in))
1700 {
1701 (void) fprintf(stderr, err1, infile);
1702 goto err;
1703 }
1704 }
1705 in->in16s.vscale[i] = in->in16s.vscale[i - 1];
1706 for (i = 0; i < hdfdims[1]; i++)
1707 {
1708 if (gint16(infile, strm, &in->in16s.hscale[i], in))
1709 {
1710 (void) fprintf(stderr, err1, infile);
1711 goto err;
1712 }
1713 }
1714 in->in16s.hscale[i] = in->in16s.hscale[i - 1];
1715 }
1716
1717 else
1718 {
1719 for (i = 0; i < hdfdims[0]; i++)
1720 {
1721 if (gint16(infile, strm, &in->in16s.dscale[i], in))
1722 {
1723 (void) fprintf(stderr, err1, infile);
1724 goto err;
1725 }
1726 }
1727 in->in16s.dscale[i] = in->in16s.dscale[i - 1];
1728 for (i = 0; i < hdfdims[1]; i++)
1729 {
1730 if (gint16(infile, strm, &in->in16s.vscale[i], in))
1731 {
1732 (void) fprintf(stderr, err1, infile);
1733 goto err;
1734 }
1735 }
1736 in->in16s.vscale[i] = in->in16s.vscale[i - 1];
1737 for (i = 0; i < hdfdims[2]; i++)
1738 {
1739 if (gint16(infile, strm, &in->in16s.hscale[i], in))
1740 {
1741 (void) fprintf(stderr, err1, infile);
1742 goto err;
1743 }
1744 }
1745 in->in16s.hscale[i] = in->in16s.hscale[i - 1];
1746 }
1747 break;
1748
1749 case 4: /* 8-bit integer */
1750 if (in->rank == 2)
1751 {
1752 for (i = 0; i < hdfdims[0]; i++)
1753 {
1754 if (gint8(infile, strm, &in->in8s.vscale[i], in))
1755 {
1756 (void) fprintf(stderr, err1, infile);
1757 goto err;
1758 }
1759 }
1760 in->in8s.vscale[i] = in->in8s.vscale[i - 1];
1761 for (i = 0; i < hdfdims[1]; i++)
1762 {
1763 if (gint8(infile, strm, &in->in8s.hscale[i], in))
1764 {
1765 (void) fprintf(stderr, err1, infile);
1766 goto err;
1767 }
1768 }
1769 in->in8s.hscale[i] = in->in8s.hscale[i - 1];
1770 }
1771
1772 else
1773 {
1774 for (i = 0; i < hdfdims[0]; i++)
1775 {
1776 if (gint8(infile, strm, &in->in8s.dscale[i], in))
1777 {
1778 (void) fprintf(stderr, err1, infile);
1779 goto err;
1780 }
1781 }
1782 in->in8s.dscale[i] = in->in8s.dscale[i - 1];
1783 for (i = 0; i < hdfdims[1]; i++)
1784 {
1785 if (gint8(infile, strm, &in->in8s.vscale[i], in))
1786 {
1787 (void) fprintf(stderr, err1, infile);
1788 goto err;
1789 }
1790 }
1791 in->in8s.vscale[i] = in->in8s.vscale[i - 1];
1792 for (i = 0; i < hdfdims[2]; i++)
1793 {
1794 if (gint8(infile, strm, &in->in8s.hscale[i], in))
1795 {
1796 (void) fprintf(stderr, err1, infile);
1797 goto err;
1798 }
1799 }
1800 in->in8s.hscale[i] = in->in8s.hscale[i - 1];
1801 }
1802 break;
1803 }
1804 }
1805
1806 #ifdef DEBUG
1807 if (in->rank == 2)
1808 {
1809 (void) printf("\tscales of the axes (vert,horiz):\n\n\t");
1810 for (i = 0; i < hdfdims[0]; i++)
1811 (void) printf("%E ", in->vscale[i]);
1812 (void) printf("\n\t");
1813 for (i = 0; i < hdfdims[1]; i++)
1814 (void) printf("%E ", in->hscale[i]);
1815 }
1816 else
1817 {
1818 (void) printf("\tscales of the axes (depth,vert,horiz):\n\n\t");
1819 for (i = 0; i < hdfdims[0]; i++)
1820 (void) printf("%E ", in->dscale[i]);
1821 (void) printf("\n\t");
1822 for (i = 0; i < hdfdims[1]; i++)
1823 (void) printf("%E ", in->vscale[i]);
1824 (void) printf("\n\t");
1825 for (i = 0; i < hdfdims[2]; i++)
1826 (void) printf("%E ", in->hscale[i]);
1827 }
1828 (void) printf("\n\n\n");
1829 #endif /* DEBUG */
1830
1831 return (0);
1832
1833 err:
1834 return (1);
1835 }
1836
1837 /*
1838 * Name:
1839 * gtoken
1840 *
1841 * Purpose:
1842 * Return the token identifier associated with the command line
1843 * argument.
1844 */
1845 static int
gtoken(char * s)1846 gtoken(char *s)
1847 {
1848 size_t len;
1849 int token;
1850
1851 const char *err1 = "Illegal argument: %s.\n";
1852
1853 /*
1854 * identify the token type
1855 */
1856 if (s[0] == '-')
1857 { /* option name (or negative number) */
1858 token = ERR;
1859 len = HDstrlen(&s[1]);
1860 switch (s[1])
1861 {
1862 case 'o':
1863 if (!HDstrncmp("outfile", &s[1], len))
1864 token = OPT_o;
1865 break;
1866 case 'r':
1867 if (!HDstrncmp("raster", &s[1], len))
1868 token = OPT_r;
1869 break;
1870 case 'e':
1871 if (!HDstrncmp("expand", &s[1], len))
1872 token = OPT_e;
1873 break;
1874 case 'i':
1875 if (!HDstrncmp("interp", &s[1], len))
1876 token = OPT_i;
1877 break;
1878 case 'p':
1879 if (!HDstrncmp("palfile", &s[1], len))
1880 token = OPT_p;
1881 break;
1882 case 'f':
1883 if (!HDstrncmp("float", &s[1], len))
1884 token = OPT_f;
1885 break;
1886 case 'h':
1887 if (!HDstrncmp("help", &s[1], len))
1888 token = OPT_h;
1889 break;
1890 case 'm':
1891 if (!HDstrncmp("mean", &s[1], len))
1892 token = OPT_m;
1893 break;
1894 case 'n':
1895 token = OPT_n;
1896 break;
1897 case 't':
1898 token = OPT_t;
1899 break;
1900 default:
1901 if (isnum(s)) /* negative number? */
1902 token = NUMBR;
1903 }
1904 if (token == ERR)
1905 (void) fprintf(stderr, err1, s);
1906
1907 }
1908 else if (isnum(s)) /* positive number */
1909 token = NUMBR;
1910 else /* filename */
1911 token = FILNAME;
1912
1913 return (token);
1914 }
1915
1916 /*
1917 * Name:
1918 * gtype
1919 *
1920 * Purpose:
1921 * Determine the type of the input file (HDF, TEXT, FP32, FP64)
1922 *
1923 * Revision: (pkamat)
1924 * Modified to support INT32, INT16, INT8 formats.
1925 * Also determines and validates the outtype type of the data-set
1926 */
1927 static int
gtype(char * infile,struct Input * in,FILE ** strm)1928 gtype(char *infile, struct Input *in, FILE **strm)
1929 {
1930 char buf[8];
1931
1932 const char *err1 = "Unable to open file: %s.\n";
1933 const char *err2 = "Unable to get format tag from file: %s.\n";
1934 const char *err3 = "Invalid file format in file: %s.\n";
1935 const char *err4 = "Invalid use of -t or -n options. Can be used only for TEXT files or for FP64 binary files\n";
1936
1937 /*
1938 * determine the input file format
1939 */
1940 if (Hishdf(infile))
1941 in->is_hdf = TRUE;
1942 else
1943 {
1944 if ((*strm = fopen(infile, "r")) == NULL)
1945 {
1946 (void) fprintf(stderr, err1, infile);
1947 goto err;
1948 }
1949 if (fread(buf, 4, 1, *strm) != 1)
1950 {
1951 (void) fprintf(stderr, err2, infile);
1952 goto err;
1953 }
1954 if (!HDmemcmp("TEXT", buf, 4) || !HDmemcmp("text", buf, 4))
1955 {
1956 in->is_text = TRUE;
1957 if (in->outtype == NO_NE)
1958 in->outtype = FP_32;
1959
1960 }
1961 else
1962 {
1963 if (!HDmemcmp("FP64", buf, 4) ||
1964 !HDmemcmp("fp64", buf, 4))
1965 {
1966 in->is_fp64 = TRUE;
1967 if (in->outtype != FP_64)
1968 if (in->outtype != NO_NE)
1969 {
1970 (void) fprintf(stderr, err4, infile);
1971 goto err;
1972 }
1973 else in->outtype = FP_32;
1974 }
1975 else
1976 {
1977 if (in->outtype != NO_NE)
1978 {
1979 (void) fprintf(stderr, err4, infile);
1980 goto err;
1981 }
1982 if (!HDmemcmp("FP32", buf, 4) || !HDmemcmp("fp32", buf, 4))
1983 {
1984 in->is_fp32 = TRUE;
1985 in->outtype = FP_32;
1986
1987 }
1988
1989 else if (!HDmemcmp("IN32", buf, 4) ||
1990 !HDmemcmp("in32", buf, 4))
1991 in->outtype = INT_32;
1992 else if (!HDmemcmp("IN16", buf, 4) ||
1993 !HDmemcmp("in16", buf, 4))
1994 in->outtype = INT_16;
1995 else if (!HDmemcmp("IN08", buf, 4) ||
1996 !HDmemcmp("in08", buf, 4))
1997 in->outtype = INT_8;
1998 else
1999 {
2000 (void) fprintf(stderr, err3, infile);
2001 goto err;
2002 }
2003 if (in->outtype == NO_NE)
2004 {
2005 (void) fprintf(stderr, err4, infile);
2006 goto err;
2007 }
2008 }
2009 }
2010 }
2011
2012 return (0);
2013
2014 err:
2015 return (1);
2016 }
2017
2018 /*
2019 * Name:
2020 * help
2021 *
2022 * Purpose:
2023 * Print a helpful summary of command usage and features.
2024 */
2025 void
help(char * name)2026 help(char *name)
2027 {
2028 (void) printf("Name:\n");
2029 (void) printf("\t%s (previously fp2hdf)\n\n", name);
2030 (void) printf("Purpose:\n");
2031 (void) printf("\tTo convert floating point data to HDF Scientific ");
2032 (void) printf("Data Set (SDS)\n");
2033 (void) printf("\tand/or 8-bit Raster Image Set (RIS8) format, ");
2034 (void) printf("storing the results\n");
2035 (void) printf("\tin an HDF file. The image data can be scaled ");
2036 (void) printf("about a mean value.\n\n");
2037
2038 (void) fprintf (stderr, "Synopsis:");
2039 (void) fprintf (stderr, "\n\t%s -h[elp]", name);
2040 (void) fprintf (stderr, "\n\t\tPrint this summary of usage and exit.");
2041 (void) fprintf (stderr, "\n\t\t");
2042 (void) fprintf (stderr, "\n\t%s -V", name);
2043 (void) fprintf (stderr, "\n\t\tPrint version of the HDF4 library and exit.");
2044 (void) fprintf (stderr, "\n\t\t");
2045 (void) fprintf (stderr, "\n\t%s <infile> [ [-t[ype] <output-type> | -n] [<infile> [-t[ype] <output-type> | -n]...]", name);
2046 (void) fprintf (stderr, "\n\t\t\t\t\t-o[utfile] <outfile> [-r[aster] [ras_opts ...]] [-f[loat]]");
2047
2048 (void) fprintf (stderr, "\n\n\t<infile(s)>:");
2049 (void) fprintf (stderr, "\n\t\tName of the input file(s), containing a single ");
2050 (void) fprintf (stderr, "\n\t\ttwo-dimensional or three-dimensional floating point array ");
2051 (void) fprintf (stderr, "\n\t\tin either ASCII text, native floating point, native integer ");
2052 (void) fprintf (stderr, "\n\t\tor HDF SDS format. If an HDF file is used for input, it ");
2053 (void) fprintf (stderr, "\n\t\tmust contain an SDS. The SDS need only contain a dimension ");
2054 (void) fprintf (stderr, "\n\t\trecord and the data, but if it also contains maximum and ");
2055 (void) fprintf (stderr, "\n\t\tminimum values and/or scales for each axis, these will ");
2056 (void) fprintf (stderr, "\n\t\tbe used. If the input format is ASCII text or native ");
2057 (void) fprintf (stderr, "\n\t\tfloating point or native integer, see \"Notes\" below on ");
2058 (void) fprintf (stderr, "\n\t\thow it must be organized.");
2059
2060 (void) fprintf (stderr, "\n\n\t-t[ype] <output_type>: ");
2061 (void) fprintf (stderr, "\n\t\tOptionally used for every input ASCII file to specify the ");
2062 (void) fprintf (stderr, "\n\t\tdata type of the data-set to be written. If not specified ");
2063 (void) fprintf (stderr, "\n\t\tdefault data type is 32-bit floating point. <output-type>");
2064 (void) fprintf (stderr, "\n\t\tcan be any of the following: FP32 (default), FP64, INT32");
2065 (void) fprintf (stderr, "\n\t\tINT16, INT8. It can be used only with ASCII files.");
2066
2067 (void) fprintf (stderr, "\n\n\t-n: ");
2068 (void) fprintf (stderr, "\n\t\tThis option is to be used only if the binary input file ");
2069 (void) fprintf (stderr, "\n\t\tcontains 64-bit floating point data and the default");
2070 (void) fprintf (stderr, "\n\t\tbehaviour (default behaviour is to write it to a 32-bit");
2071 (void) fprintf (stderr, "\n\t\tfloating point data-set) should be overridden to write ");
2072 (void) fprintf (stderr, "\n\t\tit to a 64-bit floating point data-set.");
2073
2074 (void) fprintf (stderr, "\n\n\t-o[utfile] <outfile>:");
2075 (void) fprintf (stderr, "\n\t\tData from one or more input files are stored as one or");
2076 (void) fprintf (stderr, "\n\t\tmore data sets and/or images in one HDF output file,");
2077 (void) fprintf (stderr, "\n\t\t\"outfile\".");
2078
2079 (void) fprintf (stderr, "\n\n\t-r[aster]:");
2080 (void) fprintf (stderr, "\n\t\tStore output as a raster image set in the output file.");
2081
2082 (void) fprintf (stderr, "\n\n\t-f[loat]:");
2083 (void) fprintf (stderr, "\n\tStore output as a scientific data set in the output file.");
2084 (void) fprintf (stderr, "\n\tThis is the default if the \"-r\" option is not specified.");
2085
2086 (void) fprintf (stderr, "\n\n\tras_opts ...");
2087 (void) fprintf (stderr, "\n\n\t-e[xpand] <horiz> <vert> [<depth>]:");
2088 (void) fprintf (stderr, "\n\tExpand float data via pixel replication to produce the");
2089 (void) fprintf (stderr, "\n\timage(s). \"horiz\" and \"vert\" give the horizontal and");
2090 (void) fprintf (stderr, "\n\tvertical resolution of the image(s) to be produced; and");
2091 (void) fprintf (stderr, "\n\toptionally, \"depth\" gives the number of images or depth");
2092 (void) fprintf (stderr, "\n\tplanes (for 3D input data).");
2093
2094 (void) fprintf (stderr, "\n\n\t-i[nterp] <horiz> <vert> [<depth>]:");
2095 (void) fprintf (stderr, "\n\t\tApply bilinear, or trilinear, interpolation to the float");
2096 (void) fprintf (stderr, "\n\t\tdata to produce the image(s). \"horiz\", \"vert\", and \"depth\"");
2097 (void) fprintf (stderr, "\n\t\tmust be greater than or equal to the dimensions of the");
2098 (void) fprintf (stderr, "\n\t\toriginal dataset.");
2099 (void) fprintf (stderr, "\n\t\tIf max and min are supplied in input file, this option clips");
2100 (void) fprintf (stderr, "\n\t\tvalues that are greater than max or less then min, setting");
2101 (void) fprintf (stderr, "\n\t\tthem to the max and min, respectively.");
2102
2103 (void) fprintf (stderr, "\n\n\t-p[alfile] <palfile>:");
2104 (void) fprintf (stderr, "\n\t\tStore the palette with the image. Get the palette from");
2105 (void) fprintf (stderr, "\n\t\t\"palfile\"; which may be an HDF file containing a palette,");
2106 (void) fprintf (stderr, "\n\t\tor a file containing a raw palette.");
2107
2108 (void) fprintf (stderr, "\n\n\t-m[ean] <mean>:");
2109 (void) fprintf (stderr, "\n\t\tIf a floating point mean value is given, the image will be");
2110 (void) fprintf (stderr, "\n\t\tscaled about the mean. The new extremes (newmax and newmin),");
2111 (void) fprintf (stderr, "\n\t\tas given by:");
2112
2113 (void) fprintf (stderr, "\n\n\t\t\tnewmax = mean + max(abs(max-mean), abs(mean-min))");
2114 (void) fprintf (stderr, "\n\t\t\tnewmin = mean - max(abs(max-mean), abs(mean-min))");
2115
2116 (void) fprintf (stderr, "\n\n\t\twill be equidistant from the mean value. If no mean value");
2117 (void) fprintf (stderr, "\n\t\tis given, then the mean will be: 0.5 (max + min)");
2118
2119 (void) fprintf (stderr, "\n\n\tNotes:");
2120 (void) fprintf (stderr, "\n\t\tIf the input file format is ASCII text or native floating point or native integer(32-bit,");
2121 (void) fprintf (stderr, "\n\t\t16-bit, 8-bit), it");
2122 (void) fprintf (stderr, "\n\t\tmust have the following input fields:");
2123
2124 (void) fprintf (stderr, "\n\t\tformat");
2125 (void) fprintf (stderr, "\n\t\tnplanes");
2126 (void) fprintf (stderr, "\n\t\tnrows");
2127 (void) fprintf (stderr, "\n\t\tcols");
2128 (void) fprintf (stderr, "\n\t\tmax_value");
2129 (void) fprintf (stderr, "\n\t\tmin_value");
2130 (void) fprintf (stderr, "\n\t\t[plane1 plane2 plane3 ...]");
2131 (void) fprintf (stderr, "\n\t\trow1 row2 row3 ...");
2132 (void) fprintf (stderr, "\n\t\tcol1 col2 col3 ...");
2133 (void) fprintf (stderr, "\n\t\tdata1 data2 data3 ...");
2134
2135 (void) fprintf (stderr, "\n\n\t\tWhere:");
2136 (void) fprintf (stderr, "\n\n\t\tformat:");
2137 (void) fprintf (stderr, "\n\t\t\tFormat designator (\"TEXT\", \"FP32\", \"FP64\", \"IN32\", \"IN16\", \"IN08\").");
2138 (void) fprintf (stderr, "\n\t\t\tnplanes, nrows, ncols:");
2139 (void) fprintf (stderr, "\n\t\t\tDimensions are specified in the order slowest changing dimension first.");
2140 (void) fprintf (stderr, "\n\t\t\tncols is dimension of the fastest changing dimension. (horizontal axis");
2141 (void) fprintf (stderr, "\n\t\t\tor X-axis in a 3D scale)");
2142 (void) fprintf (stderr, "\n\t\t\tnrows corresponds to dimension of the vertical axis or Y-axis in a 3D ");
2143 (void) fprintf (stderr, "\n\t\t\tscale.");
2144 (void) fprintf (stderr, "\n\t\t\tnplanes corresponds to the slowest changing dimension i.e. dimension of ");
2145 (void) fprintf (stderr, "\n\t\t\tthe depth axis or the Z-axis in a 3D scale (\"1\" for 2D input).");
2146 (void) fprintf (stderr, "\n\t\tmax_value:");
2147 (void) fprintf (stderr, "\n\t\t\tMaximum data value.");
2148 (void) fprintf (stderr, "\n\t\tmin_value:");
2149 (void) fprintf (stderr, "\n\t\t\tMinimum data value.");
2150 (void) fprintf (stderr, "\n\t\tplane1, plane2, plane3, ...:");
2151 (void) fprintf (stderr, "\n\t\t\tScales for depth axis.");
2152 (void) fprintf (stderr, "\n\t\trow1, row2, row3, ...:");
2153 (void) fprintf (stderr, "\n\t\t\tScales for the vertical axis.");
2154 (void) fprintf (stderr, "\n\t\tcol1, col2, col3, ...:");
2155 (void) fprintf (stderr, "\n\t\t\tScales for the horizontal axis.");
2156 (void) fprintf (stderr, "\n\t\tdata1, data2, data3, ...:");
2157 (void) fprintf (stderr, "\n\t\t\tThe data ordered by rows, left to right and top");
2158 (void) fprintf (stderr, "\n\t\t\tto bottom; then optionally, ordered by planes,");
2159 (void) fprintf (stderr, "\n\t\t\tfront to back.");
2160
2161 (void) fprintf (stderr, "\n\n\t\tFor FP32 and FP64 input format, \"format\", \"nplanes\", \"nrows\", \"ncols\",");
2162 (void) fprintf (stderr, "\n\t\tand \"nplanes\" are native integers; where \"format\" is the integer");
2163 (void) fprintf (stderr, "\n\t\trepresentation of the appropriate 4-character string (0x46503332 for");
2164 (void) fprintf (stderr, "\n\t\t\"FP32\" and 0x46503634 for \"FP64\"). The remaining input fields are");
2165 (void) fprintf (stderr, "\n\t\tcomposed of native 32-bit floating point values for FP32 input format,");
2166 (void) fprintf (stderr, "\n\t\tor native 64-bit floating point values for FP64 input format.");
2167
2168 (void) fprintf (stderr, "\n\n\tFor IN32, IN16 and IN08 input format, \"format\", \"nplanes\", \"nrows\", \"ncols\",");
2169 (void) fprintf (stderr, "\n\t\tand \"nplanes\" are native integers; where \"format\" is the integer");
2170 (void) fprintf (stderr, "\n\t\trepresentation of the appropriate 4-character string. The remaining input ");
2171 (void) fprintf (stderr, "\n\t\tfields are composed of native 32-bit integer values for IN32 input format,");
2172 (void) fprintf (stderr, "\n\t\tor native 16-bit integer values for IN16 input format or native 8-bit ");
2173 (void) fprintf (stderr, "\n\t\tinteger values for IN08 input format.");
2174
2175 (void) printf("\nExamples:\n");
2176 (void) printf("\tConvert floating point data in \"f1.txt\" to SDS ");
2177 (void) printf("format, and store it\n");
2178 (void) printf("\tas an SDS in HDF file \"o1\":\n\n");
2179 (void) printf("\t\t%s f1.txt -o o1\n\n", name);
2180 (void) printf("\tConvert floating point data in \"f2.hdf\" to ");
2181 (void) printf("8-bit raster format, and\n");
2182 (void) printf("\tstore it as an RIS8 in HDF file \"o2\":\n\n");
2183 (void) printf("\t\t%s f2.hdf -o o2 -r\n\n", name);
2184 (void) printf("\tConvert floating point data in \"f3.bin\" to ");
2185 (void) printf("8-bit raster format and\n");
2186 (void) printf("\tSDS format, and store both the RIS8 and the SDS ");
2187 (void) printf("in HDF file \"o3\":\n\n");
2188 (void) printf("\t\t%s f3.bin -o o3 -r -f\n\n", name);
2189 (void) printf("\tConvert floating point data in \"f4\" to a ");
2190 (void) printf("500x600 raster image, and\n");
2191 (void) printf("\tstore the RIS8 in HDF file \"o4\". Also store a ");
2192 (void) printf("palette from \"palfile\"\n");
2193 (void) printf("\twith the image:\n\n");
2194 (void) printf("\t\t%s f4 -o o4 -r -e 500 600 -p palfile\n\n", name);
2195 (void) printf("\tConvert floating point data in \"f5\" to 200 ");
2196 (void) printf("planes of 500x600 raster\n");
2197 (void) printf("\timages, and store the RIS8 in HDF file \"o5\". ");
2198 (void) printf("Also scale the image\n");
2199 (void) printf("\tdata so that it is centered about a mean value ");
2200 (void) printf("of 10.0:\n\n");
2201 (void) printf("\t\t%s f5 -o o5 -r -i 500 600 200 -m 10.0\n", name);
2202
2203 return;
2204 }
2205
2206 /*
2207 * Name:
2208 * indexes
2209 *
2210 * Purpose:
2211 * For each pixel location along an axis, determine the nearest
2212 * scale value neighbor. Return a list of indexes into the scale
2213 * array.
2214 */
2215 static int
indexes(float32 * scale,int dim,int * idx,int res)2216 indexes(float32 *scale, int dim, int *idx, int res)
2217 {
2218 int i, j;
2219 float32 *midpt;
2220 float32 loc;
2221 float32 delta;
2222
2223 const char *err1 = "Unable to allocate dynamic memory.\n";
2224 /*
2225 * determine the midpoints between scale values
2226 */
2227 if ((midpt = (float32 *) HDmalloc((size_t) dim * sizeof(float32))) == NULL)
2228 {
2229 (void) fprintf(stderr, "%s", err1);
2230 goto err;
2231 }
2232 for (i = 0; i < dim - 1; i++)
2233 midpt[i] = (scale[i] + scale[i + 1]) * (float32)0.5;
2234 midpt[dim - 1] = scale[dim - 1] + (scale[dim - 1] - midpt[dim - 2]);
2235
2236 /*
2237 * determine the distance between pixel locations
2238 */
2239 delta = (scale[dim - 1] - scale[0]) / (float32)(res - 1);
2240
2241 /*
2242 * compute indexes, keeping the index the same until the location
2243 * extends beyond the midpoint
2244 */
2245 for (i = 1, j = 0, idx[0] = 0, loc = scale[0]; i < res; i++)
2246 {
2247 loc += delta;
2248 idx[i] = idx[i - 1];
2249 while (loc >= midpt[j])
2250 {
2251 idx[i] += 1;
2252 j += 1;
2253 }
2254 }
2255
2256 /*
2257 * free dynamically allocated memory
2258 */
2259 HDfree((char *) midpt);
2260
2261 return (0);
2262
2263 err:
2264 return (1);
2265 }
2266
2267 /*
2268 * Name:
2269 * interp
2270 *
2271 * Purpose:
2272 * Use a bilinear, or trilinear, interpolation scheme to construct
2273 * the raster image(s).
2274 *
2275 * Bug revision: the line that previously read:
2276 *
2277 * hratio[i] = ((hrange > 0) ? 1.0 : -1.0) * (in->hscale[j+1] -
2278 * loc) / (in->hscale[j+1] - in->hscale[j]);
2279 * has been changed to read:
2280 * hratio[i] = (in->hscale[j+1] - loc) / (in->hscale[j+1] - in->hscale[j]);
2281 *
2282 * Similar changes were made to the corresponding lines for
2283 * computing vratio and dratio.
2284 *
2285 * Bug revision: If values occur that are outside the ranges of the
2286 * max and min values provided, these values are now "clipped" to
2287 * be the same as the max and min, respectively.
2288 */
2289
2290 static int
interp(struct Input * in,struct Raster * im)2291 interp(struct Input *in, struct Raster *im)
2292 {
2293 int i, j, k, m;
2294 int *hinc, *voff, *doff = NULL;
2295 float32 pix;
2296 float32 loc;
2297 float32 range;
2298 float32 ratio;
2299 float32 hrange, vrange, drange = (float32)0.0;
2300 float32 hdelta, vdelta, ddelta = (float32)0.0;
2301 float32 t1, t2, t3, t4, t5, t6;
2302 float32 *hratio, *vratio, *dratio = NULL;
2303 float32 *pt[8];
2304 unsigned char *ip = im->image;
2305
2306 const char *err1 = "Unable to allocate dynamic memory.\n";
2307
2308 /*
2309 * determine the range of pixel locations
2310 */
2311 range = in->max - in->min;
2312 ratio = (float32)237.9 / range;
2313 hrange = in->hscale[in->dims[0] - 1] - in->hscale[0];
2314 vrange = in->vscale[in->dims[1] - 1] - in->vscale[0];
2315 if (in->rank == 3)
2316 drange = in->dscale[in->dims[2] - 1] - in->dscale[0];
2317
2318 /*
2319 * determine the distance between pixel locations
2320 */
2321 hdelta = hrange / (float32)(im->hres - 1);
2322 vdelta = vrange / (float32)(im->vres - 1);
2323 if (in->rank == 3)
2324 ddelta = drange / (float32)(im->dres - 1);
2325
2326 /*
2327 * allocate dynamic memory for the interpolation ratio buffers
2328 */
2329 if ((hratio = (float32 *) HDmalloc((size_t) im->hres * sizeof(float32))) == NULL)
2330 {
2331 (void) fprintf(stderr, "%s", err1);
2332 goto err;
2333 }
2334 if ((vratio = (float32 *) HDmalloc((unsigned int) im->vres *
2335 sizeof(float32))) == NULL)
2336 {
2337 (void) fprintf(stderr, "%s", err1);
2338 goto err;
2339 }
2340 if (in->rank == 3)
2341 {
2342 if ((dratio = (float32 *) HDmalloc((unsigned int) im->dres *
2343 sizeof(float32))) == NULL)
2344 {
2345 (void) fprintf(stderr, "%s", err1);
2346 goto err;
2347 }
2348 }
2349
2350 /*
2351 * allocate dynamic memory for the pixel location offset/increment
2352 * buffers
2353 */
2354 if ((hinc = (int *) HDmalloc((unsigned int) im->hres *
2355 sizeof(int))) == NULL)
2356 {
2357 (void) fprintf(stderr, "%s", err1);
2358 goto err;
2359 }
2360 if ((voff = (int *) HDmalloc((unsigned int) (im->vres + 1) *
2361 sizeof(int))) == NULL)
2362 {
2363 (void) fprintf(stderr, "%s", err1);
2364 goto err;
2365 }
2366 if (in->rank == 3)
2367 {
2368 if ((doff = (int *) HDmalloc((unsigned int) (im->dres + 1) *
2369 sizeof(int))) == NULL)
2370 {
2371 (void) fprintf(stderr, "%s", err1);
2372 goto err;
2373 }
2374 }
2375
2376 /*
2377 * compute the interpolation ratios and pixel location
2378 * offsets/increments for each axis
2379 */
2380 for (i = 0, j = 0; i < im->hres; i++)
2381 {
2382 loc = hdelta * (float) i + in->hscale[0];
2383 hinc[i] = 0;
2384 while ((j < (in->dims[0] - 2)) && ((hrange > (float32)0.0) ?
2385 (in->hscale[j + 1] < loc) : (in->hscale[j + 1] > loc)))
2386 {
2387 hinc[i] += 1;
2388 j += 1;
2389 }
2390 hratio[i] = (in->hscale[j + 1] - loc) / (in->hscale[j + 1] - in->hscale[j]);
2391 }
2392 for (i = 0, j = 0, voff[0] = 0; i < im->vres; i++)
2393 {
2394 loc = vdelta * (float) i + in->vscale[0];
2395 while ((j < (in->dims[1] - 2)) && ((vrange > (float32)0.0) ?
2396 (in->vscale[j + 1] < loc) : (in->vscale[j + 1] > loc)))
2397 {
2398 voff[i] += 1;
2399 j += 1;
2400 }
2401 vratio[i] = (in->vscale[j + 1] - loc) / (in->vscale[j + 1] - in->vscale[j]);
2402 voff[i + 1] = voff[i];
2403 }
2404 if (in->rank == 3)
2405 {
2406 for (i = 0, j = 0, doff[0] = 0; i < im->dres; i++)
2407 {
2408 loc = ddelta * (float) i + in->dscale[0];
2409 while ((j < (in->dims[2] - 2)) && ((drange > (float32)0.0) ?
2410 (in->dscale[j + 1] < loc) : (in->dscale[j + 1] > loc)))
2411 {
2412 doff[i] += 1;
2413 j += 1;
2414 }
2415 dratio[i] = (in->dscale[j + 1] - loc) /
2416 (in->dscale[j + 1] - in->dscale[j]);
2417 doff[i + 1] = doff[i];
2418 }
2419 }
2420
2421 /*
2422 * do the interpolation for each point in the target image, taking
2423 * advantage of the fact that the target is evenly spaced along each
2424 * axis
2425 */
2426 if (in->rank == 2)
2427 {
2428 for (i = 0; i < im->vres; i++)
2429 {
2430 pt[0] = (float32 *) in->data + (in->dims[0] * voff[i]);
2431 pt[1] = pt[0] + 1;
2432 pt[2] = pt[0] + in->dims[0];
2433 pt[3] = pt[2] + 1;
2434 for (j = 0; j < im->hres; j++)
2435 {
2436 for (m = 0; m < 4; m++)
2437 pt[m] += hinc[j];
2438 t1 = *pt[2] - ((*pt[2] - *pt[0]) * vratio[i]);
2439 t2 = *pt[3] - ((*pt[3] - *pt[1]) * vratio[i]);
2440 pix = t2 - ((t2 - t1) * hratio[j]);
2441 if (pix > in->max)
2442 pix = in->max; /* clip (bug fix) */
2443 if (pix < in->min)
2444 pix = in->min; /* ditto */
2445 *ip++ = (unsigned char)((ratio * (pix - in->min)) + (float32)1.5);
2446 }
2447 }
2448 }
2449 else
2450 { /* rank == 3 */
2451 for (i = 0; i < im->dres; i++)
2452 {
2453 for (j = 0; j < im->vres; j++)
2454 {
2455 pt[0] = (float32 *) in->data + (in->dims[0] * voff[j]) +
2456 (in->dims[0] * in->dims[1] * doff[i]);
2457 pt[1] = pt[0] + 1;
2458 pt[2] = pt[0] + in->dims[0];
2459 pt[3] = pt[2] + 1;
2460 pt[4] = pt[0] + (in->dims[0] * in->dims[1]);
2461 pt[5] = pt[4] + 1;
2462 pt[6] = pt[4] + in->dims[0];
2463 pt[7] = pt[6] + 1;
2464 for (k = 0; k < im->hres; k++)
2465 {
2466 for (m = 0; m < 8; m++)
2467 pt[m] += hinc[k];
2468 t1 = *pt[4] - ((*pt[4] - *pt[0]) *
2469 dratio[i]);
2470 t2 = *pt[6] - ((*pt[6] - *pt[2]) *
2471 dratio[i]);
2472 t3 = *pt[5] - ((*pt[5] - *pt[1]) *
2473 dratio[i]);
2474 t4 = *pt[7] - ((*pt[7] - *pt[3]) *
2475 dratio[i]);
2476 t5 = t2 - ((t2 - t1) * vratio[j]);
2477 t6 = t4 - ((t4 - t3) * vratio[j]);
2478 pix = t6 - ((t6 - t5) * hratio[k]);
2479 if (pix > in->max)
2480 pix = in->max; /* clip (bug fix) */
2481 if (pix < in->min)
2482 pix = in->min; /* ditto */
2483 *ip++ = (unsigned char)((ratio * (pix - in->min)) + (float32)1.5);
2484 }
2485 }
2486 }
2487 }
2488
2489 /*
2490 * free dynamically allocated memory
2491 */
2492 HDfree((char *) hratio);
2493 HDfree((char *) vratio);
2494 if (in->rank == 3)
2495 HDfree((char *) dratio);
2496 HDfree((char *) hinc);
2497 HDfree((char *) voff);
2498 if (in->rank == 3)
2499 HDfree((char *) doff);
2500
2501 return (0);
2502
2503 err:
2504 return (1);
2505 }
2506
2507 /*
2508 * Name:
2509 * isnum
2510 *
2511 * Purpose:
2512 * Determine whether or not the string is representative of an
2513 * integer or floating point number. If it is, a non-zero value
2514 * is returned. A leading (-) to denote sign is acceptable.
2515 */
2516 static int
isnum(char * s)2517 isnum(char *s)
2518 {
2519 char *cp;
2520 int rval = FALSE;
2521
2522 /*
2523 * check to see if its a floating point number
2524 */
2525 cp = s;
2526 (void) strtod(s, &cp);
2527 if ((*cp == '\0') && (cp != s))
2528 rval = TRUE;
2529
2530 /*
2531 * check to see if its an integer number (radix 8, 10, or 16)
2532 */
2533 else
2534 {
2535 cp = s;
2536 (void) strtol(s, &cp, 0);
2537 if ((*cp == '\0') && (cp != s))
2538 rval = TRUE;
2539 }
2540
2541 return (rval);
2542 }
2543
2544 /*
2545 * Name:
2546 * mean
2547 *
2548 * Purpose:
2549 * Reset the maximum and minimum data values to be symmetric about
2550 * the user-specified mean value.
2551 */
2552 void
mean(struct Input * in,struct Options * opt)2553 mean(struct Input *in,struct Options * opt)
2554 {
2555 float32 delta, delta_max, delta_min;
2556
2557 delta_max = (float32)fabs((double)(in->max - opt->meanval));
2558 delta_min = (float32)fabs((double)(opt->meanval - in->min));
2559 delta = (delta_max > delta_min) ? delta_max : delta_min;
2560
2561 in->max = opt->meanval + delta;
2562 in->min = opt->meanval - delta;
2563
2564 return;
2565 }
2566
2567 /*
2568 * Name:
2569 * palette
2570 *
2571 * Purpose:
2572 * Process the (user specified) palette input file.
2573 */
2574 static int
palette(char * palfile)2575 palette(char *palfile)
2576 {
2577 unsigned char *color;
2578 unsigned char pal[1024], red[256], green[256], blue[256];
2579 FILE *strm;
2580 int i;
2581
2582 const char *err1 = "Unable to get palette from file: %s.\n";
2583 const char *err2 = "Unable to open palette file: %s.\n";
2584 const char *err3 = "Unable to set default palette.\n";
2585
2586 /*
2587 * extract a palette from an HDF file
2588 */
2589 if (Hishdf(palfile))
2590 {
2591 if (DFPgetpal(palfile, pal))
2592 {
2593 (void) fprintf(stderr, err1, palfile);
2594 goto err;
2595 }
2596
2597 /*
2598 * read in a raw palette file
2599 */
2600 }
2601 else
2602 {
2603 if ((strm = fopen(palfile, "r")) == NULL)
2604 {
2605 (void) fprintf(stderr, err2, palfile);
2606 goto err;
2607 }
2608 if (fread((char *) red, 1, 256, strm) != 256)
2609 {
2610 (void) fprintf(stderr, err1, palfile);
2611 goto err;
2612 }
2613 else if (fread((char *) green, 1, 256, strm) != 256)
2614 {
2615 (void) fprintf(stderr, err1, palfile);
2616 goto err;
2617 }
2618 else if (fread((char *) blue, 1, 256, strm) != 256)
2619 {
2620 (void) fprintf(stderr, err1, palfile);
2621 goto err;
2622 }
2623 (void) fclose(strm);
2624
2625 /*
2626 * interleave the R,G,B values
2627 */
2628 color = pal;
2629 for (i = 0; i < 256; i++)
2630 {
2631 *color++ = red[i];
2632 *color++ = green[i];
2633 *color++ = blue[i];
2634 }
2635 }
2636
2637 /*
2638 * set up the palette as the default for subsequent images
2639 */
2640 if (DFR8setpalette(pal))
2641 {
2642 (void) fprintf(stderr, "%s", err3);
2643 goto err;
2644 }
2645
2646 return (0);
2647
2648 err:
2649 return (1);
2650 }
2651
2652 /*
2653 * Name:
2654 * pixrep
2655 *
2656 * Purpose:
2657 * Expand the image(s) to the desired resolution using pixel
2658 * replication.
2659 */
2660 static int
pixrep(struct Input * in,struct Raster * im)2661 pixrep(struct Input *in, struct Raster *im)
2662 {
2663 int *hidx, *vidx, *didx;
2664 int ovidx, odidx;
2665 int dummy;
2666 int32 i, j, k;
2667 float32 *dp;
2668 float32 range;
2669 float32 ratio;
2670 unsigned char *ip, *plane, *row, *pix;
2671
2672 const char *err1 = "Unable to dynamically allocate memory.\n";
2673 dp = (float32 *) in->data;
2674 ip = im->image;
2675 range = in->max - in->min;
2676 ratio = (float32)237.9 / range;
2677
2678 /*
2679 * determine the scale indexes of the horizontal pixel locations
2680 */
2681 if ((hidx = (int *) HDmalloc((unsigned int) (im->hres + 1) * sizeof(int))) == NULL)
2682 {
2683 (void) fprintf(stderr, "%s", err1);
2684 goto err;
2685 }
2686
2687 if (indexes(in->hscale, in->dims[0], hidx, im->hres))
2688 goto err;
2689
2690 /*
2691 * determine the scale indexes of the vertical pixel locations
2692 */
2693 if ((vidx = (int *) HDmalloc((unsigned int) (im->vres + 1) *
2694 sizeof(int))) == NULL)
2695 {
2696 (void) fprintf(stderr, "%s", err1);
2697 goto err;
2698 }
2699
2700 if (indexes(in->vscale, in->dims[1], vidx, im->vres))
2701 goto err;
2702
2703 /*
2704 * determine the scale indexes of the depth plane locations
2705 */
2706 dummy = 0;
2707 didx = &dummy;
2708 if (in->rank == 3)
2709 {
2710 if ((didx = (int *) HDmalloc((unsigned int) (im->dres + 1) *
2711 sizeof(int))) == NULL)
2712 {
2713 (void) fprintf(stderr, "%s", err1);
2714 goto err;
2715 }
2716
2717 if (indexes(in->dscale, in->dims[2], didx, im->dres))
2718 goto err;
2719 }
2720
2721 /*
2722 * compute the expanded image
2723 */
2724 if ((pix = (unsigned char *) HDmalloc((unsigned int) (in->dims[0] + 1))) ==
2725 NULL)
2726 {
2727 (void) fprintf(stderr, "%s", err1);
2728 goto err;
2729 }
2730 for (k = 0, odidx = didx[0] - 1; k < im->dres; k++)
2731 {
2732 /*
2733 * construct a new depth plane
2734 */
2735 if (didx[k] > odidx)
2736 {
2737 for (j = 0, ovidx = vidx[0] - 1; j < im->vres; j++)
2738 {
2739 /*
2740 * construct a new row
2741 */
2742 if (vidx[j] > ovidx)
2743 {
2744 for (i = 0; i < in->dims[0]; i++)
2745 pix[i] = (unsigned char )((ratio * (*dp++ - in->min)) + (float32)1.5);
2746 for (i = 0; i < im->hres; i++)
2747 *ip++ = pix[hidx[i]];
2748 /*
2749 * repeat the previous row
2750 */
2751 }
2752 else
2753 {
2754 row = ip - im->hres;
2755 for (i = 0; i < im->hres; i++)
2756 *ip++ = *row++;
2757 }
2758 ovidx = vidx[j];
2759 }
2760 /*
2761 * repeat the previous depth plane
2762 */
2763 }
2764 else
2765 {
2766 plane = ip - (im->hres * im->vres);
2767 for (j = 0; j < im->vres; j++)
2768 for (i = 0; i < im->hres; i++)
2769 *ip++ = plane[(j * im->hres) + i];
2770 }
2771 odidx = didx[k];
2772 }
2773
2774 /*
2775 * free dynamically allocated space
2776 */
2777 HDfree((char *) hidx);
2778 HDfree((char *) vidx);
2779 if (in->rank == 3)
2780 HDfree((char *) didx);
2781 HDfree((char *) pix);
2782
2783 return (0);
2784
2785 err:
2786 return (1);
2787 }
2788
2789 /*
2790 * Name:
2791 * create_SDS
2792 *
2793 * Purpose:
2794 * This function contains common code that creates a two- or
2795 * three-dimensional dataset, used in function 'process.' It
2796 * was factored out to reduce the length of 'process.'
2797 * Returns the new SDS identifier, if success, and FAIL,
2798 * otherwise. (bmribler - 2006/8/18)
2799 */
2800 static int32
create_SDS(int32 sd_id,int32 nt,struct Input * in)2801 create_SDS(int32 sd_id, int32 nt, struct Input *in)
2802 {
2803 int32 sds_id;
2804
2805 if (in->rank == 2)
2806 {
2807 int32 edges[2];
2808 edges[0] = in->dims[1];
2809 edges[1] = in->dims[0];
2810 sds_id = SDcreate (sd_id, NULL, nt, in->rank, edges);
2811 }
2812 else
2813 {
2814 int32 edges[3];
2815 edges[0] = in->dims[2];
2816 edges[1] = in->dims[1];
2817 edges[2] = in->dims[0];
2818 sds_id = SDcreate (sd_id, NULL, nt, in->rank, edges);
2819 }
2820 return(sds_id);
2821 }
2822
2823 /*
2824 * Name:
2825 * alloc_data
2826 *
2827 * Purpose:
2828 * This function contains common code that allocates memory for
2829 * the data buffer to hold different types of data. It
2830 * was factored out to reduce the length of 'process.'
2831 * Returns SUCCEED or FAIL. (bmribler - 2006/8/18)
2832 */
2833 static intn
alloc_data(VOIDP * data,int32 len,int outtype)2834 alloc_data(VOIDP *data, int32 len, int outtype)
2835 {
2836 const char *alloc_err = "Unable to dynamically allocate memory.\n";
2837
2838 switch(outtype)
2839 {
2840 case 0: /* 32-bit float */
2841 case 5: /* NO_NE */
2842 if ((*data = (VOIDP) HDmalloc((size_t) len * sizeof(float32))) == NULL)
2843 {
2844 (void) fprintf(stderr, "%s", alloc_err);
2845 return FAIL;
2846 }
2847 break;
2848 case 1: /* 64-bit float */
2849 if ((*data = (VOIDP) HDmalloc((size_t) len * sizeof(float64))) == NULL)
2850 {
2851 (void) fprintf(stderr, "%s", alloc_err);
2852 return FAIL;
2853 }
2854 break;
2855 case 2: /* 32-bit integer */
2856 if ((*data = (VOIDP) HDmalloc((size_t) len * sizeof(int32))) == NULL)
2857 {
2858 (void) fprintf(stderr, "%s", alloc_err);
2859 return FAIL;
2860 }
2861 break;
2862 case 3: /* 16-bit integer */
2863 if ((*data = (VOIDP) HDmalloc((size_t) len * sizeof(int16))) == NULL)
2864 {
2865 (void) fprintf(stderr, "%s", alloc_err);
2866 return FAIL;
2867 }
2868 break;
2869 case 4: /* 8-bit integer */
2870 if ((*data = (VOIDP) HDmalloc((size_t) len * sizeof(int8))) == NULL)
2871 {
2872 (void) fprintf(stderr, "%s", alloc_err);
2873 return FAIL;
2874 }
2875 break;
2876 } /* end switch */
2877 return SUCCEED;
2878 } /* alloc_data */
2879
2880 /*
2881 * Name:
2882 * write_SDS
2883 *
2884 * Purpose:
2885 * This function contains common code, that writes a two- or
2886 * three-dimensional dataset, used in function 'process.' It
2887 * was factored out to reduce the length of 'process.'
2888 * Returns SUCCEED or FAIL. (bmribler - 2006/8/18)
2889 */
2890 static intn
write_SDS(int32 sds_id,struct Input * in)2891 write_SDS(int32 sds_id, struct Input *in)
2892 {
2893 const char *write_err = "Unable to write an SDS to the HDF output file\n";
2894 if (in->rank == 2)
2895 {
2896 int32 edges[2], start[2];
2897 edges[0] = in->dims[1];
2898 edges[1] = in->dims[0];
2899 start[0] = 0;
2900 start[1] = 0;
2901 if (SDwritedata(sds_id, start, NULL, edges, (VOIDP)in->data) != 0)
2902 {
2903 (void) fprintf(stderr, "%s", write_err);
2904 return FAIL;
2905 }
2906 }
2907 else
2908 {
2909 int32 edges[3], start[3];
2910 edges[0] = in->dims[2];
2911 edges[1] = in->dims[1];
2912 edges[2] = in->dims[0];
2913 start[0] = 0;
2914 start[1] = 0;
2915 start[2] = 0;
2916 if (SDwritedata(sds_id, start, NULL, edges, (VOIDP)in->data) != 0)
2917 {
2918 (void) fprintf(stderr, "%s", write_err);
2919 return FAIL;
2920 }
2921 }
2922 return SUCCEED;
2923 } /* write_SDS */
2924
2925 /*
2926 * Name:
2927 * set_dimensions
2928 *
2929 * Purpose:
2930 * This function contains the common code, that sets dimension scale
2931 * for a two- or three-dimensional dataset, used in function 'process.'
2932 * It was factored out to reduce the length of 'process.'
2933 * Returns SUCCEED or FAIL. (bmribler - 2006/8/18)
2934 */
2935 static intn
set_dimensions(int32 sds_id,struct Input * in,int32 nt,VOIDP dscale,VOIDP vscale,VOIDP hscale)2936 set_dimensions(int32 sds_id, struct Input *in, int32 nt, VOIDP dscale, VOIDP vscale, VOIDP hscale)
2937 {
2938 int32 dim_id, dim_index;
2939 const char *dim_err = "Unable to set dimension scales\n";
2940
2941 if (in->rank == 2)
2942 {
2943 int32 edges[2];
2944 intn status;
2945
2946 edges[0] = in->dims[1];
2947 edges[1] = in->dims[0];
2948
2949 dim_index = 0;
2950 dim_id = SDgetdimid (sds_id, dim_index);
2951
2952 if (SDsetdimscale(dim_id, edges[0], nt, (VOIDP)vscale) == FAIL)
2953 {
2954 (void) fprintf(stderr, "%s, dim index %d\n", dim_err, dim_index);
2955 return FAIL;
2956 }
2957
2958 dim_index = 1;
2959 dim_id = SDgetdimid (sds_id, dim_index);
2960
2961 if (SDsetdimscale(dim_id, edges[1], nt, hscale)!=0)
2962 {
2963 (void) fprintf(stderr, "%s, dim index %d\n", dim_err, dim_index);
2964 return FAIL;
2965 }
2966 }
2967 else
2968 {
2969 int32 edges[3];
2970 edges[0] = in->dims[2];
2971 edges[1] = in->dims[1];
2972 edges[2] = in->dims[0];
2973
2974 dim_index = 0;
2975 dim_id = SDgetdimid (sds_id, dim_index);
2976
2977 if (SDsetdimscale(dim_id, edges[0], nt, dscale)!=0)
2978 {
2979 (void) fprintf(stderr, "%s, dim index %d\n", dim_err, dim_index);
2980 return FAIL;
2981 }
2982 dim_index = 1;
2983 dim_id = SDgetdimid (sds_id, dim_index);
2984
2985 if (SDsetdimscale(dim_id, edges[1], nt, vscale)!=0)
2986 {
2987 (void) fprintf(stderr, "%s, dim index %d\n", dim_err, dim_index);
2988 return FAIL;
2989 }
2990 dim_index = 2;
2991 dim_id = SDgetdimid (sds_id, dim_index);
2992
2993 if (SDsetdimscale(dim_id, edges[2], nt, hscale)!=0)
2994 {
2995 (void) fprintf(stderr, "%s, dim index %d\n", dim_err, dim_index);
2996 return FAIL;
2997 }
2998 }
2999 return SUCCEED;
3000 } /* set_dimensions */
3001
3002 /*
3003 * Name:
3004 * process
3005 *
3006 * Purpose:
3007 * Process each input file.
3008 *
3009 * Revision: (pkamat)
3010 * Modified to support the writing of the data set in any of the
3011 * following types: INT32, INT16, INT8 and FP64
3012 * Modification: pvn: March, 3, 2006
3013 * handled the case of in->outtype == 5 (NO_NE), for hdf input type
3014 * current version assumes that datum is DFNT_FLOAT32 for this case
3015 * Revision: (bmribler - 2006/8/18)
3016 * - Modified to store the input SD identifier in 'struct infilesformat'
3017 * so the id can be passed into various functions, instead of
3018 * repeatedly calling SDstart in these functions.
3019 * - Factored out common codes to make this ~900-line function become
3020 * more readable and maintainable.
3021 */
3022 static int
process(struct Options * opt)3023 process(struct Options *opt)
3024 {
3025 struct Input in;
3026 struct Raster im;
3027 unsigned char *ip;
3028 int i, j;
3029 int is_maxmin;
3030 int is_scale;
3031 int32 len;
3032 FILE *strm;
3033 int32 hdf;
3034 int32 sd_id, sds_id;
3035 int32 start3[3], edges3[3], start2[2], edges2[2];
3036 int32 dim_index = 0, dim_id;
3037
3038 #ifdef DEBUG
3039 int h, v, d;
3040 #endif /* DEBUG */
3041
3042 const char *err1 = "Error creating HDF output file: %s.\n";
3043 const char *err1a = "Error opening the created HDF output file for writing, file %s.\n";
3044 const char *err2 = "Unable to dynamically allocate memory.\n";
3045 const char *err3a = "Warning: cannot make image smaller using -e ";
3046 const char *err3b = "option.\n\t %s resolution will be made the ";
3047 const char *err3c = "same as %s dimension of the\n\t dataset, ";
3048 const char *err3d = "which is: %d.\n\n";
3049 const char *err4 = "Unable to write an RIS8 to the HDF output file\n";
3050 const char *err5 = "Unable to write an SDS to the HDF output file\n";
3051 const char *err5a = "Unable to set range to an SDS\n";
3052 const char *err6a = "Unable to close the SDS\n";
3053 const char *err6 = "Unable to close the HDF output file\n";
3054 /*
3055 * process the palette file (if one was specified)
3056 */
3057 if (opt->pal == TRUE)
3058 if (palette(opt->palfile))
3059 goto err;
3060
3061 /*
3062 * create the HDF output file
3063 */
3064 if ((hdf = Hopen(opt->outfile, DFACC_CREATE, 0)) == FAIL)
3065 {
3066 (void) fprintf(stderr, err1, opt->outfile);
3067 goto err;
3068 }
3069 (void) Hclose(hdf);
3070
3071 /* new interface */
3072 if ((sd_id = SDstart(opt->outfile, DFACC_WRITE)) == FAIL)
3073 {
3074 (void) fprintf(stderr, err1a, opt->outfile);
3075 goto err;
3076 }
3077
3078 /*
3079 * main loop: process input files, one per pass
3080 */
3081
3082 for (i = 0; i < opt->fcount; i++)
3083 {
3084 /*
3085 * initialize key parameters
3086 */
3087 in.is_hdf = FALSE;
3088 in.is_text = FALSE;
3089 in.is_fp32 = FALSE;
3090 in.is_fp64 = FALSE;
3091 is_maxmin = FALSE;
3092 is_scale = FALSE;
3093 in.outtype = opt->infiles[i].outtype;
3094
3095 if (Hishdf(opt->infiles[i].filename))
3096 {
3097 in.is_hdf = TRUE;
3098 opt->infiles[i].handle = SDstart(opt->infiles[i].filename, DFACC_RDONLY);
3099 if (opt->infiles[i].handle == FAIL)
3100 {
3101 (void) fprintf(stderr, err1a, opt->infiles[i].filename);
3102 goto err;
3103 }
3104 }
3105 /*
3106 * get the file type, input data dimensions, and input data
3107 * max/min values
3108 */
3109
3110 if (gtype(opt->infiles[i].filename, &in, &strm))
3111 goto err;
3112
3113 if (gdimen(opt->infiles[i], &in, strm))
3114 goto err;
3115
3116 if (gmaxmin(opt->infiles[i], &in, strm, &is_maxmin))
3117 goto err;
3118
3119 /*
3120 * initialise the scale variables according to the output type
3121 * of data set
3122 */
3123 if (init_scales(&in))
3124 goto err;
3125
3126 /*
3127 * get the scale for each axis
3128 */
3129 if (gscale(opt->infiles[i], &in, strm, &is_scale))
3130 goto err;
3131
3132 /*
3133 * get the input data
3134 */
3135 len = in.dims[0] * in.dims[1] * in.dims[2];
3136
3137 /* allocate memory for in.data depending on in.outtype value */
3138 if (alloc_data(&(in.data), len, in.outtype) == FAIL)
3139 goto err;
3140
3141 if (gdata(opt->infiles[i], &in, strm, &is_maxmin))
3142 goto err;
3143
3144 /*
3145 * put the input data in the HDF output file, in SDS format
3146 */
3147 if (opt->to_float == TRUE)
3148 {
3149 intn status;
3150 switch(in.outtype)
3151 {
3152
3153 case 0: /* 32-bit float */
3154 case 5: /* NO_NE */
3155 /* create data-set */
3156 sds_id = create_SDS(sd_id, DFNT_FLOAT32, &in);
3157 if (sds_id == FAIL)
3158 goto err;
3159
3160 if (is_scale == TRUE)
3161 {
3162 /* set range */
3163 if (SDsetrange(sds_id, &in.max, &in.min)!=0)
3164 {
3165 (void) fprintf(stderr, "%s", err5a);
3166 goto err;
3167 }
3168
3169 /* set dimension scale */
3170 status = set_dimensions(sds_id, &in, DFNT_FLOAT32,
3171 (VOIDP)in.dscale, (VOIDP)in.vscale, (VOIDP)in.hscale);
3172 if (status == FAIL)
3173 goto err;
3174 }
3175
3176 /* write data to the data set */
3177 if (write_SDS(sds_id, &in) == FAIL)
3178 goto err;
3179 break;
3180
3181 case 1:/* 64-bit float */
3182
3183 /* create data-set */
3184 sds_id = create_SDS(sd_id, DFNT_FLOAT64, &in);
3185 if (sds_id == FAIL)
3186 goto err;
3187
3188 if (is_scale == TRUE)
3189 {
3190 /* set range */
3191 if (SDsetrange(sds_id, &in.fp64s.max, &in.fp64s.min)!=0)
3192 {
3193 (void) fprintf(stderr, "%s", err5a);
3194 goto err;
3195 }
3196
3197 /* set dimension scale */
3198 status = set_dimensions(sds_id, &in, DFNT_FLOAT64,
3199 (VOIDP)in.fp64s.dscale, (VOIDP)in.fp64s.vscale,
3200 (VOIDP)in.fp64s.hscale);
3201 if (status == FAIL)
3202 goto err;
3203 }
3204
3205 /* write data to the data set */
3206 if (write_SDS(sds_id, &in) == FAIL)
3207 goto err;
3208 break;
3209
3210 case 2: /* 32-bit integer */
3211
3212 /* create data-set */
3213 sds_id = create_SDS(sd_id, DFNT_INT32, &in);
3214 if (sds_id == FAIL)
3215 goto err;
3216
3217 if (is_scale == TRUE)
3218 {
3219 /* set range */
3220 if (SDsetrange(sds_id, &in.in32s.max, &in.in32s.min)!=0)
3221 {
3222 (void) fprintf(stderr, "%s", err5a);
3223 goto err;
3224 }
3225
3226 /* set dimension scale */
3227 status = set_dimensions(sds_id, &in, DFNT_INT32,
3228 (VOIDP)in.in32s.dscale, (VOIDP)in.in32s.vscale,
3229 (VOIDP)in.in32s.hscale);
3230 if (status == FAIL)
3231 goto err;
3232 }
3233
3234 /* write data to the data set */
3235 if (write_SDS(sds_id, &in) == FAIL)
3236 goto err;
3237 break;
3238
3239 case 3: /* 16-bit integer */
3240 /* create data-set */
3241 sds_id = create_SDS(sd_id, DFNT_INT16, &in);
3242 if (sds_id == FAIL)
3243 goto err;
3244
3245 if (is_scale == TRUE)
3246 {
3247 /* set range */
3248 if (SDsetrange(sds_id, &in.in16s.max, &in.in16s.min)!=0)
3249 {
3250 (void) fprintf(stderr, "%s", err5a);
3251 goto err;
3252 }
3253
3254 /* set dimension scale */
3255 status = set_dimensions(sds_id, &in, DFNT_INT16,
3256 (VOIDP)in.in16s.dscale, (VOIDP)in.in16s.vscale,
3257 (VOIDP)in.in16s.hscale);
3258 if (status == FAIL)
3259 goto err;
3260 }
3261
3262 /* write data to the data set */
3263 if (write_SDS(sds_id, &in) == FAIL)
3264 goto err;
3265 break;
3266
3267 case 4: /* 8-bit integer */
3268 /* create data-set */
3269 sds_id = create_SDS(sd_id, DFNT_INT8, &in);
3270 if (sds_id == FAIL)
3271 goto err;
3272
3273 if (is_scale == TRUE)
3274 {
3275 /* set range */
3276 if (SDsetrange(sds_id, &in.in8s.max, &in.in8s.min)!=0)
3277 {
3278 (void) fprintf(stderr, "%s", err5a);
3279 goto err;
3280 }
3281
3282 /* set dimension scale */
3283 status = set_dimensions(sds_id, &in, DFNT_INT8,
3284 (VOIDP)in.in8s.dscale, (VOIDP)in.in8s.vscale,
3285 (VOIDP)in.in8s.hscale);
3286 if (status == FAIL)
3287 goto err;
3288 }
3289
3290 /* write data to the data set */
3291 if (write_SDS(sds_id, &in) == FAIL)
3292 goto err;
3293 break;
3294 }
3295 /* close data set */
3296 if (SDendaccess(sds_id) == FAIL )
3297 {
3298 (void) fprintf(stderr, "%s", err6a);
3299 goto err;
3300 }
3301
3302 /* close the input file */
3303 if (in.is_hdf == TRUE)
3304 {
3305 if (SDend(opt->infiles[i].handle) == FAIL)
3306 {
3307 (void) fprintf(stderr, "SDend failed");
3308 goto err;
3309 }
3310 }
3311 } /* if opt->to_float == TRUE */
3312
3313 /*
3314 * put the input data in the HDF output file, in RIS8 format
3315 */
3316 if (opt->to_image == TRUE)
3317 {
3318 /*
3319 * allocate a buffer for the output image
3320 */
3321 im.hres = (opt->hres == 0) ? in.dims[0] : opt->hres;
3322 if ((im.hres < in.dims[0]) && (opt->ctm == EXPAND))
3323 {
3324 (void) fprintf(stderr, "%s", err3a);
3325 (void) fprintf(stderr, err3b, "Horiz.");
3326 (void) fprintf(stderr, err3c, "horiz.");
3327 (void) fprintf(stderr, err3d, in.dims[0]);
3328 im.hres = in.dims[0];
3329 opt->hres = in.dims[0];
3330 }
3331 im.vres = (opt->vres == 0) ? in.dims[1] : opt->vres;
3332 if ((im.vres < in.dims[1]) && (opt->ctm == EXPAND))
3333 {
3334 (void) fprintf(stderr, "%s", err3a);
3335 (void) fprintf(stderr, err3b, "Vert.");
3336 (void) fprintf(stderr, err3c, "vert.");
3337 (void) fprintf(stderr, err3d, in.dims[1]);
3338 im.vres = in.dims[1];
3339 opt->vres = in.dims[1];
3340 }
3341 im.dres = 1;
3342 if (in.rank == 3)
3343 {
3344 im.dres = (opt->dres == 0) ? in.dims[2] :
3345 opt->dres;
3346 if ((im.dres < in.dims[2]) &&
3347 (opt->ctm == EXPAND))
3348 {
3349 (void) fprintf(stderr, "%s", err3a);
3350 (void) fprintf(stderr, err3b, "Depth");
3351 (void) fprintf(stderr, err3c, "depth");
3352 (void) fprintf(stderr, err3d, in.dims[2]);
3353 im.dres = in.dims[2];
3354 opt->dres = in.dims[2];
3355 }
3356 }
3357 len = im.hres * im.vres * im.dres;
3358 if ((im.image = (unsigned char *) HDmalloc((unsigned int) len)) == NULL)
3359 {
3360 (void) fprintf(stderr, "%s", err2);
3361 goto err;
3362 }
3363
3364 /*
3365 * reset max/min symmetrically about the mean value
3366 */
3367 if (opt->mean == TRUE)
3368 mean(&in, opt);
3369
3370 /*
3371 * perform pixel replication or interpolation
3372 */
3373 if (opt->ctm == EXPAND)
3374 {
3375 if (pixrep(&in, &im))
3376 goto err;
3377 }
3378 else
3379 { /* INTERP */
3380 if (interp(&in, &im))
3381 goto err;
3382 }
3383
3384 len = im.hres * im.vres;
3385 for (j = 0, ip = im.image; j < im.dres; j++, ip += len)
3386 {
3387 if (DFR8addimage(opt->outfile, ip, im.hres,
3388 im.vres, DFTAG_RLE))
3389 {
3390 (void) fprintf(stderr, "%s", err4);
3391 goto err;
3392 }
3393 }
3394
3395 #ifdef DEBUG
3396 (void) printf("Output Raster Information ...\n\n");
3397 (void) printf("\tresolution (horiz,vert,[depth]):\n\n");
3398 if (in.rank == 2)
3399 (void) printf("\t%d %d\n\n", im.hres, im.vres);
3400 else
3401 (void) printf("\t%d %d %d\n\n", im.hres,
3402 im.vres, im.dres);
3403 if (opt->mean == TRUE)
3404 {
3405 (void) printf("\tadjusted max/min values:\n\n");
3406 (void) printf("\t%f %f\n\n", in.max, in.min);
3407 }
3408 (void) printf("\tcolor index values:");
3409 for (d = 0, ip = im.image; d < im.dres; d++)
3410 {
3411 (void) printf("\n");
3412 for (v = 0; v < im.vres; v++)
3413 {
3414 (void) printf("\n");
3415 for (h = 0; h < im.hres; h++, ip++)
3416 (void) printf("\t%d", *ip);
3417 }
3418 }
3419 (void) printf("\n");
3420 #endif /* DEBUG */
3421 }
3422 /*
3423 * free dynamically allocated space
3424 */
3425 fpdeallocate(&in,&im,opt);
3426 } /* end of for loop */
3427
3428 /* close the output file */
3429 if (SDend (sd_id) != 0)
3430 {
3431 (void) fprintf(stderr, "%s", err6);
3432 goto err;
3433 }
3434
3435 return (0);
3436
3437 err:
3438 return (1);
3439 }
3440
3441 /*
3442 * Name: (pkamat - New function)
3443 * fpdeallocate
3444 *
3445 * Purpose:
3446 * Deallocate memory of all data structures
3447 */
3448
fpdeallocate(struct Input * in,struct Raster * im,struct Options * opt)3449 void fpdeallocate(struct Input *in, struct Raster *im, struct Options *opt)
3450 {
3451 switch(in->outtype)
3452 {
3453 case 0 :
3454 HDfree((char *) in->hscale);
3455 HDfree((char *) in->vscale);
3456 if (in->rank == 3)
3457 HDfree((char *) in->dscale);
3458
3459 if (opt->to_image == TRUE)
3460 HDfree((char *) im->image);
3461 break;
3462
3463 case 1 :
3464 HDfree((char *) in->fp64s.hscale);
3465 HDfree((char *) in->fp64s.vscale);
3466 if (in->rank == 3)
3467 HDfree((char *) in->fp64s.dscale);
3468
3469 if (opt->to_image == TRUE)
3470 HDfree((char *) im->image);
3471 break;
3472
3473 case 2 :
3474 HDfree((char *) in->in32s.hscale);
3475 HDfree((char *) in->in32s.vscale);
3476 if (in->rank == 3)
3477 HDfree((char *) in->in32s.dscale);
3478 break;
3479
3480 case 3 :
3481 HDfree((char *) in->in16s.hscale);
3482 HDfree((char *) in->in16s.vscale);
3483 if (in->rank == 3)
3484 HDfree((char *) in->in16s.dscale);
3485 break;
3486
3487 case 4 :
3488 HDfree((char *) in->in8s.hscale);
3489 HDfree((char *) in->in8s.vscale);
3490 if (in->rank == 3)
3491 HDfree((char *) in->in8s.dscale);
3492 break;
3493
3494 }
3495 HDfree((char *) in->data);
3496
3497 }
3498
3499
3500 /*
3501 * Name: (pkamat - New function)
3502 * init_scales
3503 *
3504 * Purpose:
3505 * Initialise the data-structures to hold scale information
3506 * Modification: pvn: March, 3, 2006
3507 * handled the case of in->outtype == 5 (NO_NE), for hdf input type
3508 * current version assumes that datum is DFNT_FLOAT32 for this case
3509 */
init_scales(struct Input * in)3510 static int init_scales(struct Input * in)
3511 {
3512 const char *err1 = "Unable to dynamically allocate memory.\n";
3513 switch(in->outtype)
3514 {
3515 case 0: /* 32-bit float */
3516 case 5: /* NO_NE */
3517 if ((in->hscale = (float32 *) HDmalloc((size_t)
3518 (in->dims[0] + 1) * sizeof(float32))) == NULL)
3519 {
3520 (void) fprintf(stderr, "%s", err1);
3521 goto err;
3522 }
3523 if ((in->vscale = (float32 *) HDmalloc((size_t)
3524 (in->dims[1] + 1) * sizeof(float32))) == NULL)
3525 {
3526 (void) fprintf(stderr, "%s", err1);
3527 goto err;
3528 }
3529 if (in->rank == 3)
3530 {
3531 if ((in->dscale = (float32 *) HDmalloc((size_t)
3532 (in->dims[2] + 1) * sizeof(float32))) == NULL)
3533 {
3534 (void) fprintf(stderr, "%s", err1);
3535 goto err;
3536 }
3537 }
3538 break;
3539
3540 case 1: /* 64-bit float */
3541
3542 if ((in->fp64s.hscale = (float64 *) HDmalloc((size_t)
3543 (in->dims[0] + 1) * sizeof(float64))) == NULL)
3544 {
3545 (void) fprintf(stderr, "%s", err1);
3546 goto err;
3547 }
3548 if ((in->fp64s.vscale = (float64 *) HDmalloc((size_t)
3549 (in->dims[1] + 1) * sizeof(float64))) == NULL)
3550 {
3551 (void) fprintf(stderr, "%s", err1);
3552 goto err;
3553 }
3554 if (in->rank == 3)
3555 {
3556 if ((in->fp64s.dscale = (float64 *) HDmalloc((size_t)
3557 (in->dims[2] + 1) * sizeof(float64))) == NULL)
3558 {
3559 (void) fprintf(stderr, "%s", err1);
3560 goto err;
3561 }
3562 }
3563 break;
3564 case 2: /* 32-bit integer */
3565 if ((in->in32s.hscale = (int32 *) HDmalloc((size_t)
3566 (in->dims[0] + 1) * sizeof(int32))) == NULL)
3567 {
3568 (void) fprintf(stderr, "%s", err1);
3569 goto err;
3570 }
3571 if ((in->in32s.vscale = (int32 *) HDmalloc((size_t)
3572 (in->dims[1] + 1) * sizeof(int32))) == NULL)
3573 {
3574 (void) fprintf(stderr, "%s", err1);
3575 goto err;
3576 }
3577 if (in->rank == 3)
3578 {
3579 if ((in->in32s.dscale = (int32 *) HDmalloc((size_t)
3580 (in->dims[2] + 1) * sizeof(int32))) == NULL)
3581 {
3582 (void) fprintf(stderr, "%s", err1);
3583 goto err;
3584 }
3585 }
3586 break;
3587
3588 case 3: /* 16-bit integer */
3589 if ((in->in16s.hscale = (int16 *) HDmalloc((size_t)
3590 (in->dims[0] + 1) * sizeof(int16))) == NULL)
3591 {
3592 (void) fprintf(stderr, "%s", err1);
3593 goto err;
3594 }
3595 if ((in->in16s.vscale = (int16 *) HDmalloc((size_t)
3596 (in->dims[1] + 1) * sizeof(int16))) == NULL)
3597 {
3598 (void) fprintf(stderr, "%s", err1);
3599 goto err;
3600 }
3601 if (in->rank == 3)
3602 {
3603 if ((in->in16s.dscale = (int16 *) HDmalloc((size_t)
3604 (in->dims[2] + 1) * sizeof(int16))) == NULL)
3605 {
3606 (void) fprintf(stderr, "%s", err1);
3607 goto err;
3608 }
3609 }
3610 break;
3611
3612 case 4: /* 8-bit integer */
3613 if ((in->in8s.hscale = (int8 *) HDmalloc((size_t)
3614 (in->dims[0] + 1) * sizeof(int8))) == NULL)
3615 {
3616 (void) fprintf(stderr, "%s", err1);
3617 goto err;
3618 }
3619 if ((in->in8s.vscale = (int8 *) HDmalloc((size_t)
3620 (in->dims[1] + 1) * sizeof(int8))) == NULL)
3621 {
3622 (void) fprintf(stderr, "%s", err1);
3623 goto err;
3624 }
3625 if (in->rank == 3)
3626 {
3627 if ((in->in8s.dscale = (int8 *) HDmalloc((size_t)
3628 (in->dims[2] + 1) * sizeof(int8))) == NULL)
3629 {
3630 (void) fprintf(stderr, "%s", err1);
3631 goto err;
3632 }
3633 }
3634 break;
3635
3636 }
3637 return (0);
3638 err:
3639 return (1);
3640 }
3641
3642 /*
3643 * Name:
3644 * usage
3645 *
3646 * Purpose:
3647 * Print a summary of command usage.
3648 */
3649 void
usage(char * name)3650 usage(char *name)
3651 {
3652 (void) fprintf(stderr, "\nUsage:\t%s -h[elp], OR\n", name);
3653 (void) fprintf(stderr, "\t%s -V, OR\n", name);
3654 (void) fprintf(stderr, "\t%s <infile> [ [-t[ype] <output-type> | -n] ", name);
3655 (void) fprintf(stderr, "[<infile> [-t[ype] <output-type> | -n ]]...]\n");
3656 (void) fprintf(stderr, "\t\t\t\t\t-o[utfile] <outfile> [options..]\n");
3657 (void) fprintf(stderr, "\n\t-t[ype] <output_type>");
3658
3659 (void) fprintf(stderr, "\n\t\tOptionally used for every input ASCII file to specify the");
3660 (void) fprintf(stderr, "\n\t\tdata type of the data-set to be written. If not specified");
3661 (void) fprintf(stderr, "\n\t\tdefault data type is 32-bit floating point. <output-type>");
3662 (void) fprintf(stderr, "\n\t\tcan be any of the following: FP32 (default), FP64, INT32");
3663 (void) fprintf(stderr, "\n\t\tINT16, INT8. It can be used only with ASCII files.");
3664
3665 (void) fprintf(stderr, "\n\t-n");
3666 (void) fprintf(stderr, "\n\t\tThis option is to be used only if the binary input file ");
3667 (void) fprintf(stderr, "\n\t\tcontains 64-bit floating point data and the default");
3668 (void) fprintf(stderr, "\n\t\tbehaviour (default behaviour is to write it to a 32-bit");
3669 (void) fprintf(stderr, "\n\t\tfloating point data-set) should be overridden to write ");
3670 (void) fprintf(stderr, "\n\t\tit to a 64-bit floating point data-set.");
3671 (void) fprintf(stderr, "\n\n\toptions...\n");
3672 (void) fprintf(stderr, "\n\t-r[aster]:\n");
3673 (void) fprintf(stderr, "\t\tproduce an image. Could be ");
3674 (void) fprintf(stderr, "followed by:\n");
3675 (void) fprintf(stderr, "\t\t-e[xpand] <horiz> <vert> ");
3676 (void) fprintf(stderr, "[<depth>]:\n");
3677 (void) fprintf(stderr, "\t\t\t resolution with pixel ");
3678 (void) fprintf(stderr, "replication\n");
3679 (void) fprintf(stderr, "\t\t-i[nterp] <horiz> <vert> ");
3680 (void) fprintf(stderr, "[<depth>]:\n");
3681 (void) fprintf(stderr, "\t\t\tresolution with interpolation\n");
3682 (void) fprintf(stderr, "\t\t-p[alfile] <palfile>:\n");
3683 (void) fprintf(stderr, "\t\t\tinclude palette from palfile\n");
3684 (void) fprintf(stderr, "\t\t-m[ean] <meanval>:\n");
3685 (void) fprintf(stderr, "\t\t\tmean value to scale image ");
3686 (void) fprintf(stderr, "around\n");
3687 (void) fprintf(stderr, "\t-f[loat]:\n");
3688 (void) fprintf(stderr, "\t\tproduce floating point data\n\n");
3689 }
3690