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