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  *      fp2hdf
17  *
18  * Purpose:
19  *      To convert floating point 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  ---> |  fp2hdf   |   and/or
26  *      native floating point)     |           | ----------> SDS
27  *                                  -----------
28  *
29  * Synopsis:
30  *      fp2hdf -h[elp], OR
31  *      fp2hdf <infile> [<infile>...] -o[utfile] <outfile>
32  *             [-r[aster] [ras_opts ...]] [-f[loat]]
33  *
34  *      -h[elp]:
35  *              Print a helpful summary of usage, and exit.
36  *
37  *      <infile(s)>:
38  *              Input file(s), containing a single two-dimensional or
39  *              three-dimensional floating point array in either ASCII
40  *              text, native floating point, or HDF SDS format.  If an
41  *              HDF file is used for input, it must contain an SDS.
42  *              The SDS need only contain a dimension record and the
43  *              data, but if it also contains maximum and minimum values
44  *              and/or scales for each axis, these will be used.  If the
45  *              input format is ASCII text or native floating point, see
46  *              "Notes" below on how it must be organized.
47  *
48  *      -o[utfile] <outfile>:
49  *              Data from one or more input files are stored as one or
50  *              more data sets and/or images in one HDF output file,
51  *              "outfile".
52  *
53  *      -r[aster]:
54  *              Store output as a raster image set in the output file.
55  *
56  *      -f[loat]:
57  *              Store output as a scientific data set in the output file.
58  *              This is the default if the "-r" option is not specified.
59  *
60  *      ras_opts ...
61  *
62  *      -e[xpand] <horiz> <vert> [<depth>]:
63  *              Expand float data via pixel replication to produce the
64  *              image(s).  "horiz" and "vert" give the horizontal and
65  *              vertical resolution of the image(s) to be produced; and
66  *              optionally, "depth" gives the number of images or depth
67  *              planes (for 3D input data).
68  *
69  *      -i[nterp] <horiz> <vert> [<depth>]:
70  *              Apply bilinear, or trilinear, interpolation to the float
71  *              data to produce the image(s).  "horiz", "vert", and "depth"
72  *              must be greater than or equal to the dimensions of the
73  *              original dataset.
74  *      If max and min are supplied in input file, this option clips
75  *      values that are greater than max or less then min, setting
76  *      them to the max and min, respectively.
77  *
78  *      -p[alfile] <palfile>:
79  *              Store the palette with the image.  Get the palette from
80  *              "palfile"; which may be an HDF file containing a palette,
81  *              or a file containing a raw palette.
82  *
83  *      -m[ean] <mean>:
84  *              If a floating point mean value is given, the image will be
85  *              scaled about the mean.  The new extremes (newmax and newmin),
86  *              as given by:
87  *
88  *                 newmax = mean + max(abs(max-mean), abs(mean-min))
89  *                 newmin = mean - max(abs(max-mean), abs(mean-min))
90  *
91  *              will be equidistant from the mean value.  If no mean value
92  *              is given, then the mean will be:  0.5 * (max + min)
93  *
94  * Notes:
95  *      If the input file format is ASCII text or native floating point, it
96  *      must have the following input fields:
97  *
98  *              format
99  *              nplanes
100  *              nrows
101  *              ncols
102  *              max_value
103  *              min_value
104  *              [plane1 plane2 plane3 ...]
105  *              row1 row2 row3 ...
106  *              col1 col2 col3 ...
107  *              data1 data2 data3 ...
108  *              ...
109  *
110  *      Where:
111  *              format:
112  *                      Format designator ("TEXT", "FP32" or "FP64").
113  *              nplanes:
114  *                      Dimension of the depth axis ("1" for 2D input).
115  *              nrows:
116  *                      Dimension of the vertical axis.
117  *              ncols:
118  *                      Dimension of the horizontal axis.
119  *              max_value:
120  *                      Maximum data value.
121  *              min_value:
122  *                      Minimum data value.
123  *              plane1, plane2, plane3, ...:
124  *                      Scales for depth axis.
125  *              row1, row2, row3, ...:
126  *                      Scales for the vertical axis.
127  *              col1, col2, col3, ...:
128  *                      Scales for the horizontal axis.
129  *              data1, data2, data3, ...:
130  *                      The data ordered by rows, left to right and top
131  *                      to bottom; then optionally, ordered by planes,
132  *                      front to back.
133  *
134  *      For FP32 and FP64 input format, "format", "nplanes", "nrows", "ncols",
135  *      and "nplanes" are native integers; where "format" is the integer
136  *      representation of the appropriate 4-character string (0x46503332 for
137  *      "FP32" and 0x46503634 for "FP64").  The remaining input fields are
138  *      composed of native 32-bit floating point values for FP32 input format,
139  *      or native 64-bit floating point values for FP64 input format.
140  *
141  * Source Availability:
142  *      This program is in the public domain, and was developed and made
143  *      available by the National Center for Supercomputing Applications,
144  *      University of Illinois, Urbana-Champaign (ftp.ncsa.uiuc.edu).
145  *
146  * History:
147  *      Beta version:                                           17-May-89
148  *              (by Mike Folk mfolk@ncsa.uiuc.edu)
149  *      Revision to put in the mean option:                     15-Sep-89
150  *              (by Glen Mortensen gam@inel.gov)
151  *      Officially released:                                    01-Dec-89
152  *              (by NCSA ftp.ncsa.uiuc.edu)
153  *      Revision to fix some bugs:                              16-Mar-90
154  *              (by Mike Folk mfolk@ncsa.uiuc.edu)
155  *      Revision to support 3D and native fp input:             15-May-90
156  *              (by Bob Weaver baw@inel.gov)
157  *      Revision to fix bug in interp() :                    17-Oct-90
158  *              (by Fred Walsteijn nwalstyn@fys.ruu.n)
159  *      Revision to fix bug in interp() :                    23-Nov-90
160  *              Now it clips values outside of max and min.
161  *              (by Fred Walsteijn nwalstyn@fys.ruu.n)
162  *      Revision to start to use HDF 3.2 (and 3.3) library:  22-Jun-93
163  *              Still lots to do to support other number types.
164  *              (by Chris Houck chouck@ncsa.uiuc.edu)
165  *
166  */
167 
168 #include "hdf.h"
169 #include <stdio.h>
170 #ifndef MIPSEL
171 #include <math.h>
172 #endif /* MIPSEL */
173 #include <string.h>
174 #include <ctype.h>
175 
176 #ifdef H4_HAVE_SYS_STAT_H
177 # include <sys/stat.h>
178 #endif
179 
180 #ifdef H4_HAVE_FCNTL_H
181 # include <fcntl.h>
182 #endif
183 
184 /*
185  * global macros
186  */
187 #define EXPAND      1   /* -e: expand image with pixel replication */
188 #define INTERP      2   /* -i: expand image with interpolation */
189 
190 /*
191  * structure definition for command line options
192  */
193 struct Options
194   {
195       char      **infiles;      /* pointer to list of input file names */
196       char        outfile[32];  /* output file name */
197       char        palfile[32];  /* palette file name, if any */
198       int         fcount;       /* number of input files */
199       int         to_float;     /* float output is desired */
200       int         to_image;     /* image output is desired */
201       int         pal;          /* output palette with image */
202       int         ctm;          /* color transform method: EXPAND or INTERP */
203       int         exh;          /* horizontal expansion factor */
204       int         exv;          /* vertical expansion factor */
205       int         exd;          /* depth expansion factor */
206       int         hres;         /* horizontal resolution of output image */
207       int         vres;         /* vertical resolution of output image */
208       int         dres;         /* depth resolution of output image */
209       int         mean;         /* scale image around a mean */
210       float32     meanval;      /* mean value to scale the image around */
211   };
212 
213 /*
214  * structure definition for the input data
215  */
216 struct Input
217   {
218       int         is_hdf;       /* HDF file format flag */
219       int         is_text;      /* ASCII text format flag */
220       int         is_fp32;      /* 32-bit native floating point format flag */
221       int         is_fp64;      /* 64-bit native floating point format flag */
222       int         rank;         /* number of input data dimensions */
223       int         dims[3];      /* input dimensions - ncols, nrows, nplanes */
224       int         is_vscale;    /* vertical axis scales in the input */
225       int         is_hscale;    /* horizontal axis scales in the input */
226       int         is_dscale;    /* depth axis scales in the input */
227       float32     max;          /* maximum value of the data */
228       float32     min;          /* minimum value of the data */
229       float32    *hscale;       /* horizontal scales */
230       float32    *vscale;       /* vertical scales */
231       float32    *dscale;       /* depth scales */
232       VOIDP       data;         /* input data */
233   };
234 
235 /*
236  * structure definition for the output raster images
237  */
238 struct Raster
239   {
240       int         hres;         /* horizontal resolution of the image */
241       int         vres;         /* vertical resolution of the image */
242       int         dres;         /* depth resolution of the image */
243       unsigned char *image;
244   };
245 
246 /*
247  * state table tokens
248  */
249 #define FILNAME 0   /* filename */
250 #define OPT_o   1   /* output filename */
251 #define OPT_r   2   /* convert to image */
252 #define OPT_e   3   /* expand image via pixel replication */
253 #define OPT_i   4   /* make interpolated image */
254 #define NUMBR   5   /* resolution of enlarged image */
255 #define OPT_p   6   /* palette filename */
256 #define OPT_f   7   /* convert to float (default) */
257 #define OPT_h   8   /* request for explanation */
258 #define OPT_m   9   /* mean to scale around */
259 #define ERR 20  /* invalid token */
260 
261 /*
262  * state table for parsing the command line.
263  */
264 static int  state_table[17][10] =
265 {
266 
267     /* token ordering:
268        FILNAME      OPT_o   OPT_r   OPT_e   OPT_i   NUMBR   OPT_p   OPT_f
269        OPT_h        OPT_m   */
270 
271     /* state 0: start */
272     {1, ERR, ERR, ERR, ERR, ERR, ERR, ERR,
273     14, ERR},
274 
275     /* state 1: input files */
276     {1, 2, ERR, ERR, ERR, ERR, ERR, ERR,
277     ERR, ERR},
278 
279     /* state 2: -o[utfile] */
280     {3, ERR, ERR, ERR, ERR, ERR, ERR, ERR,
281     ERR, ERR},
282 
283     /* state 3: outfile */
284     {ERR, ERR, 4, ERR, ERR, ERR, ERR, 13,
285     ERR, ERR},
286 
287     /* state 4: -r[aster] */
288     {ERR, ERR, ERR, 5, 9, ERR, 10, 12,
289     ERR, 15},
290 
291     /* state 5: -e[xpand] */
292     {ERR, ERR, ERR, ERR, ERR, 6, ERR, ERR,
293     ERR, ERR},
294 
295     /* state 6: -e[xpand] or -i[nterp] option argument */
296     {ERR, ERR, ERR, ERR, ERR, 7, ERR, ERR,
297     ERR, ERR},
298 
299     /* state 7: -e[xpand] or -i[nterp] option argument */
300     {ERR, ERR, ERR, ERR, ERR, 8, 10, 12,
301     ERR, 15},
302 
303     /* state 8: -e[xpand] or -i[nterp] option argument */
304     {ERR, ERR, ERR, ERR, ERR, ERR, 10, 12,
305     ERR, 15},
306 
307     /* state 9: -i[nterp] */
308     {ERR, ERR, ERR, ERR, ERR, 6, ERR, ERR,
309     ERR, ERR},
310 
311     /* state 10: -p[alfile] */
312     {11, ERR, ERR, ERR, ERR, ERR, ERR, ERR,
313     ERR, ERR},
314 
315     /* state 11: palfile */
316     {ERR, ERR, ERR, 5, 9, ERR, ERR, 12,
317     ERR, 15},
318 
319     /* state 12: -f[loat] (after -r[aster]) */
320     {ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR,
321     ERR, ERR},
322 
323     /* state 13: -f[loat] */
324     {ERR, ERR, 4, ERR, ERR, ERR, ERR, ERR,
325     ERR, ERR},
326 
327     /* state 14: -h[elp] */
328     {ERR, ERR, ERR, ERR, ERR, ERR, ERR, ERR,
329     ERR, ERR},
330 
331     /* state 15: -m[ean] */
332     {ERR, ERR, ERR, ERR, ERR, 16, ERR, ERR,
333     ERR, ERR},
334 
335     /* state 16: mean */
336     {ERR, ERR, ERR, 5, 9, ERR, 10, 12,
337     ERR, ERR}
338 };
339 
340 /* static local functions */
341 static int  gtoken(char *s);
342 static int  process(struct Options *opt);
343 static int  gfloat(char *infile, FILE * strm, float32 *fp32, struct Input *in);
344 static int  gint(char *infile, FILE * strm, int *ival, struct Input *in);
345 static int  isnum(char *s);
346 static int  gdata(char *infile, struct Input *in, FILE *strm, int *is_maxmin);
347 static int  gdimen(char *infile, struct Input *inp, FILE *strm);
348 static int  gmaxmin(char *infile, struct Input *in, FILE *strm, int *is_maxmin);
349 static int  gscale(char *infile, struct Input *in, FILE *strm, int *is_scale);
350 static int  gtype(char *infile, struct Input *in, FILE **strm);
351 static int  indexes(float32 *scale, int dim, int *idx, int res);
352 static int  interp(struct Input *in, struct Raster *im);
353 static int  palette(char *palfile);
354 static int  pixrep(struct Input *in, struct Raster *im);
355 
356 /*
357  * functions with non-integer return types
358  */
359 void        help(char *);
360 void        mean(struct Input *, struct Options *);
361 void        usage(char *);
362 
363 /*
364  * Name:
365  *      main
366  *
367  * Purpose:
368  *      The driver for "fp2hdf".
369  */
370 int
main(int argc,char * argv[])371 main(int argc, char *argv[])
372 {
373     struct Options opt;
374     int         i;
375     int         outfile_named = FALSE;
376     int         token;
377     int         state = 0;
378 
379 
380     const char *err1 = "Invalid number of arguments:  %d.\n";
381     const char *err2 = "Error in state table.\n";
382     const char *err3 = "No output file given.\n";
383     const char *err4 = "Program aborted.\n";
384 
385 #if defined _WIN32
386     _fmode = _O_BINARY;
387 #endif
388 
389     /*
390      * set 'stdout' and 'stderr' to line-buffering mode
391      */
392     (void) setvbuf(stderr, (char *) NULL, _IOLBF, 0);
393     (void) setvbuf(stdout, (char *) NULL, _IOLBF, 0);
394 
395     /*
396      * validate the number of command line arguments
397      */
398     if (argc < 2)
399       {
400           (void) fprintf(stderr, err1, argc);
401           usage(argv[0]);
402           goto err;
403       }
404 
405     opt.to_image = FALSE;   /* default: no image */
406     opt.to_float = FALSE;   /* default: make float if no image */
407                 /* Set FALSE here.  Will be set TRUE */
408                 /* after confirming image option is not set.  */
409     opt.ctm = EXPAND;   /* default: pixel replication */
410     opt.hres = 0;   /* default: no expansion values */
411     opt.vres = 0;
412     opt.dres = 0;
413     opt.pal = FALSE;    /* default: no palette */
414     opt.mean = FALSE;   /* default: no mean given */
415     opt.fcount = 0;     /* to count number of input files */
416 
417     /*
418      * parse the command line
419      */
420     for (i = 1; i < argc; i++)
421       {
422           if ((token = gtoken(argv[i])) == ERR)
423             {
424                 usage(argv[0]);
425                 goto err;
426             }
427           state = state_table[state][token];
428           switch (state)
429             {
430                 case 1: /* counting input files */
431                     opt.fcount++;
432                     break;
433                 case 2: /* -o found; look for outfile */
434                     break;
435                 case 3: /* get outfile name */
436                     (void) HDstrcpy(opt.outfile, argv[i]);
437                     outfile_named = TRUE;
438                     break;
439                 case 4: /* -r found */
440                     opt.to_image = TRUE;
441                     break;
442                 case 5: /* -e found */
443                     opt.ctm = EXPAND;
444                     break;
445                 case 6: /* horizontal resolution */
446                     opt.hres = atoi(argv[i]);
447                     break;
448                 case 7: /* vertical resolution */
449                     opt.vres = atoi(argv[i]);
450                     break;
451                 case 8: /* depth resolution */
452                     opt.dres = atoi(argv[i]);
453                     break;
454                 case 9: /* -i found */
455                     opt.ctm = INTERP;
456                     break;
457                 case 10:    /* -p found */
458                     opt.pal = TRUE;
459                     break;
460                 case 11:    /* get pal filename */
461                     (void) HDstrcpy(opt.palfile, argv[i]);
462                     break;
463                 case 12:    /* -f found (after a -r) */
464                 case 13:    /* -f found (no -r yet) */
465                     opt.to_float = TRUE;
466                     break;
467                 case 14:    /* -h found; help, then exit */
468                     help(argv[0]);
469                     exit(0);
470                 case 15:    /* -m found */
471                     opt.mean = TRUE;
472                     break;
473                 case 16:    /* mean value */
474                     opt.meanval = (float32)atof(argv[i]);
475                     break;
476                 case ERR:   /* command syntax error */
477                 default:
478                     (void) fprintf(stderr, "%s", err2);
479                     usage(argv[0]);
480                     goto err;
481             }
482       }
483 
484     /*
485      * make sure an output file was specified
486      */
487     if (!outfile_named)
488       {
489           (void) fprintf(stderr, "%s", err3);
490           usage(argv[0]);
491           goto err;
492       }
493 
494     if (!opt.to_image)
495         opt.to_float = TRUE;
496     opt.infiles = argv + 1;
497 
498     /*
499      * process the input files
500      */
501     if (process(&opt))
502         goto err;
503 
504     return(0);
505 
506   err:
507     (void) fprintf(stderr, "%s", err4);
508     return(1);
509 }
510 
511 /*
512  * Name:
513  *      gdata
514  *
515  * Purpose:
516  *      Get the input data.
517  */
518 static int
gdata(char * infile,struct Input * in,FILE * strm,int * is_maxmin)519 gdata(char *infile, struct Input *in, FILE *strm, int *is_maxmin)
520 {
521     int32       i, j, k;
522     float32    *fp32;
523     int32       hdfdims[3];     /* order: ZYX or YX */
524     int32       len = in->dims[0] * in->dims[1] * in->dims[2];
525 
526     const char *err1 = "Unable to get input data from file: %s.\n";
527 
528     /*
529      * extract the input data from the input file
530      */
531     if (in->is_hdf == TRUE)
532       {
533           /*
534            * hdfdims is ordered: ZYX or YX
535            * in->dims is ordered: XYZ
536            */
537           if (in->rank == 2)
538             {
539                 hdfdims[0] = in->dims[1];
540                 hdfdims[1] = in->dims[0];
541             }
542           else
543             {
544                 hdfdims[0] = in->dims[2];
545                 hdfdims[1] = in->dims[1];
546                 hdfdims[2] = in->dims[0];
547             }
548 
549           if (DFSDgetdata(infile, in->rank, hdfdims, in->data))
550             {
551                 (void) fprintf(stderr, err1, infile);
552                 goto err;
553             }
554       }
555     else
556       {
557           for (k = 0, fp32 = (float32 *) in->data; k < in->dims[2]; k++)
558             {
559                 for (j = 0; j < in->dims[1]; j++)
560                   {
561                       for (i = 0; i < in->dims[0]; i++, fp32++)
562                         {
563                             if (gfloat(infile, strm, fp32, in))
564                               {
565                                   (void) fprintf(stderr, err1, infile);
566                                   goto err;
567                               }
568                         }
569                   }
570             }
571           (void) fclose(strm);
572       }
573 
574     /*
575      * derive the max/min values, if needed
576      */
577     if (*is_maxmin == FALSE)
578       {
579           in->min = in->max = *(float32 *) in->data;
580           for (i = 1; i < len; i++)
581             {
582                 if (((float32 *) in->data)[i] > in->max)
583                     in->max = ((float32 *) in->data)[i];
584                 if (((float32 *) in->data)[i] < in->min)
585                     in->min = ((float32 *) in->data)[i];
586             }
587           *is_maxmin = TRUE;
588       }
589 
590 #ifdef  DEBUG
591     (void) printf("\tdata:");
592     for (k = 0, fp32 = in->data; k < in->dims[2]; k++)
593       {
594           (void) printf("\n");
595           for (j = 0; j < in->dims[1]; j++)
596             {
597                 (void) printf("\n\t");
598                 for (i = 0; i < in->dims[0]; i++, fp32++)
599                     (void) printf("%E ", *fp32);
600             }
601       }
602     (void) printf("\n\n\n");
603 #endif /* DEBUG */
604 
605     return (0);
606 
607   err:
608     return (1);
609 }
610 
611 /*
612  * Name:
613  *      gdimen
614  *
615  * Purpose:
616  *      Determine the input data dimensions.
617  */
618 static int
gdimen(char * infile,struct Input * inp,FILE * strm)619 gdimen(char *infile, struct Input *inp, FILE *strm)
620 {
621     int32       hdfdims[3];     /* order: ZYX or YX */
622     int32       nt;             /* number type of input file */
623 
624     const char *err1 = "Unable to get data dimensions from file: %s.\n";
625     const char *err2 = "Invalid data rank of %d in file: %s.\n";
626     const char *err3 = "Dimension(s) is less than '2' in file: %s.\n";
627     const char *err4 = "Unexpected number type from file: %s.\n";
628 
629     /*
630      * extract the rank and dimensions of the HDF input file
631      */
632     if (inp->is_hdf == TRUE)
633       {
634           if (DFSDgetdims(infile, &inp->rank, hdfdims, 3) == FAIL)
635             {
636                 (void) fprintf(stderr, err1, infile);
637                 goto err;
638             }
639 
640           /* don't know how to deal with other numbers yet */
641           if (DFSDgetNT(&nt) == FAIL || nt != DFNT_FLOAT32)
642             {
643                 (void) fprintf(stderr, err4, infile);
644                 goto err;
645             }
646 
647           /*
648            * hdfdims is ordered: ZYX or YX
649            * inp->dims is ordered: XYZ
650            */
651           if (inp->rank == 2)
652             {
653                 inp->dims[0] = hdfdims[1];
654                 inp->dims[1] = hdfdims[0];
655                 inp->dims[2] = 1;
656             }
657           else if (inp->rank == 3)
658             {
659                 inp->dims[0] = hdfdims[2];
660                 inp->dims[1] = hdfdims[1];
661                 inp->dims[2] = hdfdims[0];
662             }
663           else
664             {
665                 (void) fprintf(stderr, err2, inp->rank, infile);
666                 goto err;
667             }
668 
669           /*
670            * get the rank and dimensions from a TEXT or native floating point
671            * format input file
672            */
673       }
674     else
675       {
676           if (gint(infile, strm, &inp->dims[2], inp))
677             {
678                 (void) fprintf(stderr, err1, infile);
679                 goto err;
680             }
681           if (inp->dims[2] > 1)
682               inp->rank = 3;
683           else
684               inp->rank = 2;
685           if (gint(infile, strm, &inp->dims[1], inp))
686             {
687                 (void) fprintf(stderr, err1, infile);
688                 goto err;
689             }
690           if (gint(infile, strm, &inp->dims[0], inp))
691             {
692                 (void) fprintf(stderr, err1, infile);
693                 goto err;
694             }
695       }
696 
697     /*
698      * validate dimension sizes
699      */
700     if ((inp->dims[0] < 2) || (inp->dims[1] < 2))
701       {
702           (void) fprintf(stderr, err3, infile);
703           goto err;
704       }
705 
706 #ifdef  DEBUG
707     (void) printf("\nInput Information ...\n\n");
708     (void) printf("\trank:\n\n\t%d\n\n", inp->rank);
709     (void) printf("\tdimensions (nplanes,nrows,ncols):\n\n");
710     (void) printf("\t%d %d %d\n\n", inp->dims[2], inp->dims[1], inp->dims[0]);
711 #endif /* DEBUG */
712 
713     return (0);
714 
715   err:
716     return (1);
717 }
718 
719 /*
720  * Name:
721  *      gfloat
722  *
723  * Purpose:
724  *      Read in a single floating point value from the input stream.  The
725  *      input format may either be ASCII text , 32-bit native floating point,
726  *      or 64-bit native floating point.
727  */
728 static int
gfloat(char * infile,FILE * strm,float32 * fp32,struct Input * in)729 gfloat(char *infile, FILE * strm, float32 *fp32, struct Input *in)
730 {
731     float64     fp64=0.0;
732 
733     const char *err1 = "Unable to get 'float' value from file: %s.\n";
734 
735     if (in->is_text == TRUE)
736       {
737 
738         if (fscanf(strm, "%e", fp32) != 1)
739             {
740                 (void) fprintf(stderr, err1, infile);
741                 goto err;
742             }
743       }
744     else if (in->is_fp32 == TRUE)
745       {
746 
747           if (fread((char *) fp32, sizeof(float32), 1, strm) != 1)
748             {
749                 (void) fprintf(stderr, err1, infile);
750                 goto err;
751             }
752       }
753     else
754       {
755           if (fread((char *) &fp64, sizeof(float64), 1, strm) != 1)
756             {
757                 (void) fprintf(stderr, err1, infile);
758                 goto err;
759             }
760           *fp32 = (float32) fp64;
761       }
762 
763     return (0);
764 
765   err:
766     return (1);
767 }
768 
769 /*
770  * Name:
771  *      gint
772  *
773  * Purpose:
774  *      Read in a single integer value from the input stream.  The input
775  *      format may either be ASCII text or a native BCD of type integer.
776  */
777 static int
gint(char * infile,FILE * strm,int * ival,struct Input * in)778 gint(char *infile, FILE * strm, int *ival, struct Input *in)
779 {
780     const char *err1 = "Unable to get 'int' value from file: %s.\n";
781 
782     /*
783      * process TEXT-formatted input
784      */
785     if (in->is_text == TRUE)
786       {
787           if (fscanf(strm, "%d", ival) != 1)
788             {
789                 (void) fprintf(stderr, err1, infile);
790                 goto err;
791             }
792 
793           /*
794            * process BCD-formatted input
795            */
796       }
797     else
798       {
799           if (fread((char *) ival, sizeof(int), 1, strm) != 1)
800             {
801                 (void) fprintf(stderr, err1, infile);
802                 goto err;
803             }
804       }
805 
806     return (0);
807 
808   err:
809     return (1);
810 }
811 
812 /*
813  * Name:
814  *      gmaxmin
815  *
816  * Purpose:
817  *      Extract the maximum and minimum data values from the input file.
818  */
819 static int
gmaxmin(char * infile,struct Input * in,FILE * strm,int * is_maxmin)820 gmaxmin(char *infile, struct Input *in, FILE *strm, int *is_maxmin)
821 {
822     const char *err1 = "Unable to get max/min values from file: %s.\n";
823 
824     /*
825      * extract the max/min values from the input file
826      */
827     if (in->is_hdf == TRUE)
828       {
829           if (!DFSDgetrange(&in->max, &in->min))
830               if (in->max > in->min)
831                   *is_maxmin = TRUE;
832       }
833     else
834       {
835           if (gfloat(infile, strm, &in->max, in))
836             {
837                 (void) fprintf(stderr, err1, infile);
838                 goto err;
839             }
840           if (gfloat(infile, strm, &in->min, in))
841             {
842                 (void) fprintf(stderr, err1, infile);
843                 goto err;
844             }
845           if (in->max > in->min)
846               *is_maxmin = TRUE;
847       }
848 
849 #ifdef  DEBUG
850     (void) printf("\tinput maximum/minimum values:\n\n");
851     (void) printf("\t%E %E\n\n", in->max, in->min);
852 #endif /* DEBUG */
853 
854     return (0);
855 
856   err:
857     return (1);
858 }
859 
860 /*
861  * Name:
862  *      gscale
863  *
864  * Purpose:
865  *      Determine the scale for each axis.
866  */
867 static int
gscale(char * infile,struct Input * in,FILE * strm,int * is_scale)868 gscale(char *infile, struct Input *in, FILE *strm, int *is_scale)
869 {
870     int         i;
871     int32       hdfdims[3];     /* order: ZYX or YX */
872 
873     const char *err1 = "Unable to get axis scale from file: %s.\n";
874 
875     *is_scale = TRUE;
876 
877     /*
878      * hdfdims is ordered: ZYX or YX
879      * in->dims is ordered: XYZ
880      */
881     if (in->rank == 2)
882       {
883           hdfdims[0] = in->dims[1];
884           hdfdims[1] = in->dims[0];
885       }
886     else
887       {
888           hdfdims[0] = in->dims[2];
889           hdfdims[1] = in->dims[1];
890           hdfdims[2] = in->dims[0];
891       }
892 
893     /*
894      * extract the scale values from the input file
895      */
896     if (in->is_hdf == TRUE)
897       {
898           if (in->rank == 2)
899             {
900                 if (DFSDgetdimscale(1, hdfdims[0], in->vscale))
901                   {
902                       *is_scale = FALSE;
903                       for (i = 0; i <= hdfdims[0]; i++)
904                           in->vscale[i] = (float32) i;
905                   }
906                 if (DFSDgetdimscale(2, hdfdims[1], in->hscale))
907                   {
908                       *is_scale = FALSE;
909                       for (i = 0; i <= hdfdims[1]; i++)
910                           in->hscale[i] = (float32) i;
911                   }
912             }
913           else
914             {
915                 if (DFSDgetdimscale(1, hdfdims[0], in->dscale))
916                   {
917                       *is_scale = FALSE;
918                       for (i = 0; i <= hdfdims[0]; i++)
919                           in->dscale[i] = (float32) i;
920                   }
921                 if (DFSDgetdimscale(2, hdfdims[1], in->vscale))
922                   {
923                       *is_scale = FALSE;
924                       for (i = 0; i <= hdfdims[1]; i++)
925                           in->vscale[i] = (float32) i;
926                   }
927                 if (DFSDgetdimscale(3, hdfdims[2], in->hscale))
928                   {
929                       *is_scale = FALSE;
930                       for (i = 0; i <= hdfdims[2]; i++)
931                           in->hscale[i] = (float32) i;
932                   }
933             }
934       }
935     else
936       {
937           if (in->rank == 2)
938             {
939                 for (i = 0; i < hdfdims[0]; i++)
940                   {
941                       if (gfloat(infile, strm, &in->vscale[i], in))
942                         {
943                             (void) fprintf(stderr, err1, infile);
944                             goto err;
945                         }
946                   }
947                 in->vscale[i] = in->vscale[i - 1];
948                 for (i = 0; i < hdfdims[1]; i++)
949                   {
950                       if (gfloat(infile, strm, &in->hscale[i], in))
951                         {
952                             (void) fprintf(stderr, err1, infile);
953                             goto err;
954                         }
955                   }
956                 in->hscale[i] = in->hscale[i - 1];
957             }
958           else
959             {
960                 for (i = 0; i < hdfdims[0]; i++)
961                   {
962                       if (gfloat(infile, strm, &in->dscale[i], in))
963                         {
964                             (void) fprintf(stderr, err1, infile);
965                             goto err;
966                         }
967                   }
968                 in->dscale[i] = in->dscale[i - 1];
969                 for (i = 0; i < hdfdims[1]; i++)
970                   {
971                       if (gfloat(infile, strm, &in->vscale[i], in))
972                         {
973                             (void) fprintf(stderr, err1, infile);
974                             goto err;
975                         }
976                   }
977                 in->vscale[i] = in->vscale[i - 1];
978                 for (i = 0; i < hdfdims[2]; i++)
979                   {
980                       if (gfloat(infile, strm, &in->hscale[i], in))
981                         {
982                             (void) fprintf(stderr, err1, infile);
983                             goto err;
984                         }
985                   }
986                 in->hscale[i] = in->hscale[i - 1];
987             }
988       }
989 
990 #ifdef  DEBUG
991     if (in->rank == 2)
992       {
993           (void) printf("\tscales of the axes (vert,horiz):\n\n\t");
994           for (i = 0; i < hdfdims[0]; i++)
995               (void) printf("%E ", in->vscale[i]);
996           (void) printf("\n\t");
997           for (i = 0; i < hdfdims[1]; i++)
998               (void) printf("%E ", in->hscale[i]);
999       }
1000     else
1001       {
1002           (void) printf("\tscales of the axes (depth,vert,horiz):\n\n\t");
1003           for (i = 0; i < hdfdims[0]; i++)
1004               (void) printf("%E ", in->dscale[i]);
1005           (void) printf("\n\t");
1006           for (i = 0; i < hdfdims[1]; i++)
1007               (void) printf("%E ", in->vscale[i]);
1008           (void) printf("\n\t");
1009           for (i = 0; i < hdfdims[2]; i++)
1010               (void) printf("%E ", in->hscale[i]);
1011       }
1012     (void) printf("\n\n\n");
1013 #endif /* DEBUG */
1014 
1015     return (0);
1016 
1017   err:
1018     return (1);
1019 }
1020 
1021 /*
1022  * Name:
1023  *      gtoken
1024  *
1025  * Purpose:
1026  *      Return the token identifier associated with the command line
1027  *      argument.
1028  */
1029 static int
gtoken(char * s)1030 gtoken(char *s)
1031 {
1032     size_t      len;
1033     int         token;
1034 
1035     const char *err1 = "Illegal argument: %s.\n";
1036 
1037     /*
1038      * identify the token type
1039      */
1040     if (s[0] == '-')
1041       {     /* option name (or negative number) */
1042           token = ERR;
1043           len = HDstrlen(&s[1]);
1044           switch (s[1])
1045             {
1046                 case 'o':
1047                     if (!HDstrncmp("outfile", &s[1], len))
1048                         token = OPT_o;
1049                     break;
1050                 case 'r':
1051                     if (!HDstrncmp("raster", &s[1], len))
1052                         token = OPT_r;
1053                     break;
1054                 case 'e':
1055                     if (!HDstrncmp("expand", &s[1], len))
1056                         token = OPT_e;
1057                     break;
1058                 case 'i':
1059                     if (!HDstrncmp("interp", &s[1], len))
1060                         token = OPT_i;
1061                     break;
1062                 case 'p':
1063                     if (!HDstrncmp("palfile", &s[1], len))
1064                         token = OPT_p;
1065                     break;
1066                 case 'f':
1067                     if (!HDstrncmp("float", &s[1], len))
1068                         token = OPT_f;
1069                     break;
1070                 case 'h':
1071                     if (!HDstrncmp("help", &s[1], len))
1072                         token = OPT_h;
1073                     break;
1074                 case 'm':
1075                     if (!HDstrncmp("mean", &s[1], len))
1076                         token = OPT_m;
1077                     break;
1078                 default:
1079                     if (isnum(s))   /* negative number? */
1080                         token = NUMBR;
1081             }
1082           if (token == ERR)
1083               (void) fprintf(stderr, err1, s);
1084 
1085       }
1086     else if (isnum(s))  /* positive number */
1087         token = NUMBR;
1088     else    /* filename */
1089         token = FILNAME;
1090 
1091     return (token);
1092 }
1093 
1094 /*
1095  * Name:
1096  *      gtype
1097  *
1098  * Purpose:
1099  *      Determine the type of the input file (HDF, TEXT, FP32 or FP64).
1100  */
1101 static int
gtype(char * infile,struct Input * in,FILE ** strm)1102 gtype(char *infile, struct Input *in, FILE **strm)
1103 {
1104     char        buf[8];
1105 
1106     const char *err1 = "Unable to open file: %s.\n";
1107     const char *err2 = "Unable to get format tag from file: %s.\n";
1108     const char *err3 = "Invalid file format in file: %s.\n";
1109 
1110     /*
1111      * determine the input file format
1112      */
1113     if (Hishdf(infile))
1114         in->is_hdf = TRUE;
1115     else
1116       {
1117           if ((*strm = fopen(infile, "r")) == NULL)
1118             {
1119                 (void) fprintf(stderr, err1, infile);
1120                 goto err;
1121             }
1122           if (fread(buf, 4, 1, *strm) != 1)
1123             {
1124                 (void) fprintf(stderr, err2, infile);
1125                 goto err;
1126             }
1127           if (!HDmemcmp("TEXT", buf, 4) || !HDmemcmp("text", buf, 4)) {
1128 #if defined _WIN32
1129             _fmode = _O_TEXT;
1130 #endif
1131               in->is_text = TRUE;
1132         }
1133           else
1134             {
1135                 rewind(*strm);
1136                 if (fread(buf, sizeof(int), 1, *strm) != 1)
1137                   {
1138                       (void) fprintf(stderr, err2, infile);
1139                       goto err;
1140                   }
1141                 if (!HDmemcmp("FP32", buf, 4) || !HDmemcmp("fp32", buf, 4))
1142                     in->is_fp32 = TRUE;
1143                 else if (!HDmemcmp("FP64", buf, 4) ||
1144                          !HDmemcmp("fp64", buf, 4))
1145                     in->is_fp64 = TRUE;
1146                 else
1147                   {
1148                       (void) fprintf(stderr, err3, infile);
1149                       goto err;
1150                   }
1151 
1152             }
1153       }
1154 
1155     return (0);
1156 
1157   err:
1158     return (1);
1159 }
1160 
1161 /*
1162  * Name:
1163  *      help
1164  *
1165  * Purpose:
1166  *      Print a helpful summary of command usage and features.
1167  */
1168 void
help(char * name)1169 help(char *name)
1170 {
1171     (void) printf("Name:\n");
1172     (void) printf("\t%s\n\n", name);
1173     (void) printf("Purpose:\n");
1174     (void) printf("\tTo convert floating point data to HDF Scientific ");
1175     (void) printf("Data Set (SDS)\n");
1176     (void) printf("\tand/or 8-bit Raster Image Set (RIS8) format, ");
1177     (void) printf("storing the results\n");
1178     (void) printf("\tin an HDF file.  The image data can be scaled ");
1179     (void) printf("about a mean value.\n\n");
1180     (void) printf("Version:\n");
1181     (void) printf("\tv1.1 (Apr 30, 1990)\n\n");
1182     (void) printf("Synopsis:\n");
1183     (void) printf("\t%s -h[elp], OR\n", name);
1184     (void) printf("\t%s <infile> [<infile>...] -o[utfile] ", name);
1185     (void) printf("<outfile>\n");
1186     (void) printf("\t\t[-r[aster] [ras_opts ...]] [-f[loat]]\n\n");
1187     (void) printf("\t-h[elp]:\n");
1188     (void) printf("\t\tPrint a helpful summary of usage, and exit.\n\n");
1189     (void) printf("\tinfile(s):\n");
1190     (void) printf("\t\tInput file(s), containing a single ");
1191     (void) printf("two-dimensional or\n");
1192     (void) printf("\t\tthree-dimensional floating point array in ");
1193     (void) printf("either ASCII\n");
1194     (void) printf("\t\ttext, native floating point, or HDF SDS format.  ");
1195     (void) printf("If an\n");
1196     (void) printf("\t\tHDF file is used for input, it must contain an ");
1197     (void) printf("SDS.\n");
1198     (void) printf("\t\tThe SDS need only contain a dimension record and ");
1199     (void) printf("the\n");
1200     (void) printf("\t\tdata, but if it also contains maximum and ");
1201     (void) printf("minimum values\n");
1202     (void) printf("\t\tand/or scales for each axis, these will be ");
1203     (void) printf("used.  If the\n");
1204     (void) printf("\t\tinput format is ASCII text or native floating ");
1205     (void) printf("point, see\n");
1206     (void) printf("\t\t\"Notes\" below on how it must be organized.\n\n");
1207     (void) printf("\t-o[utfile] <outfile>:\n");
1208     (void) printf("\t\tData from one or more input files are stored as ");
1209     (void) printf("one or\n");
1210     (void) printf("\t\tmore data sets and/or images in one HDF output ");
1211     (void) printf("file,\n\t\t\"outfile\".\n\n");
1212     (void) printf("\t-r[aster]:\n");
1213     (void) printf("\t\tStore output as a raster image set in the ");
1214     (void) printf("output file\n\n");
1215     (void) printf("\t-f[loat]:\n");
1216     (void) printf("\t\tStore output as a scientific data set in the ");
1217     (void) printf("the output file.\n");
1218     (void) printf("\t\tThis is the default if the \"-r\" option is not ");
1219     (void) printf("specified.\n\n");
1220     (void) printf("\tras_opts ...\n\n");
1221     (void) printf("\t-e[xpand] <horiz> <vert> [<depth>]:\n");
1222     (void) printf("\t\tExpand float data via pixel replication to ");
1223     (void) printf("produce the\n");
1224     (void) printf("\t\timage(s).  \"horiz\" and \"vert\" give the ");
1225     (void) printf("horizontal and\n");
1226     (void) printf("\t\tvertical resolution of the image(s) to be ");
1227     (void) printf("produced; and\n");
1228     (void) printf("\t\toptionally, \"depth\" gives the number of ");
1229     (void) printf("images or depth\n");
1230     (void) printf("\t\tplanes (for 3D input data).\n\n");
1231     (void) printf("\t-i[nterp] <horiz> <vert> [<depth>]:\n");
1232     (void) printf("\t\tApply bilinear, or trilinear, interpolation to ");
1233     (void) printf("the float\n");
1234     (void) printf("\t\tdata to produce the image(s).  \"horiz\", ");
1235     (void) printf("\"vert\", and \"depth\"\n");
1236     (void) printf("\t\tmust be greater than or equal to the dimensions ");
1237     (void) printf("of the\n");
1238     (void) printf("\t\toriginal dataset.\n\n");
1239     (void) printf("\t-p[alfile] <palfile>:\n");
1240     (void) printf("\t\tStore the palette with the image.  Get the ");
1241     (void) printf("palette from\n");
1242     (void) printf("\t\t\"palfile\"; which may be an HDF file containing ");
1243     (void) printf("a palette,\n");
1244     (void) printf("\t\tor a file containing a raw palette.\n\n");
1245     (void) printf("\t-m[ean] <mean>:\n");
1246     (void) printf("\t\tIf a floating point mean value is given, the ");
1247     (void) printf("image will be\n");
1248     (void) printf("\t\tscaled about the mean.  The new extremes ");
1249     (void) printf("(newmax and newmin),\n");
1250     (void) printf("\t\tas given by:\n\n");
1251     (void) printf("\t\t   newmax = mean + max(abs(max-mean), ");
1252     (void) printf("abs(mean-min))\n");
1253     (void) printf("\t\t   newmin = mean - max(abs(max-mean), ");
1254     (void) printf("abs(mean-min))\n\n");
1255     (void) printf("\t\twill be equidistant from the mean value.  If ");
1256     (void) printf("no mean value\n");
1257     (void) printf("\t\tis given, then the mean will be:  0.5 * (max ");
1258     (void) printf("+ min)\n\n");
1259     (void) printf("Notes:\n");
1260     (void) printf("\tIf the input file format is ASCII text or native ");
1261     (void) printf("floating point, it\n");
1262     (void) printf("\tmust have the following input fields:\n\n");
1263     (void) printf("\t\tformat\n");
1264     (void) printf("\t\tnplanes\n");
1265     (void) printf("\t\tnrows\n");
1266     (void) printf("\t\tncols\n");
1267     (void) printf("\t\tmax_value\n");
1268     (void) printf("\t\tmin_value\n");
1269     (void) printf("\t\t[plane1 plane2 plane3 ...]\n");
1270     (void) printf("\t\trow1 row2 row3 ...\n");
1271     (void) printf("\t\tcol1 col2 col3 ...\n");
1272     (void) printf("\t\tdata1 data2 data3 ...\n");
1273     (void) printf("\t\t...\n\n");
1274     (void) printf("\tWhere:\n");
1275     (void) printf("\t\tformat:\n");
1276     (void) printf("\t\t\tFormat designator (\"TEXT\", \"FP32\" or ");
1277     (void) printf("\"FP64\").\n");
1278     (void) printf("\t\tnplanes:\n");
1279     (void) printf("\t\t\tDimension of the depth axis (\"1\" for 2D ");
1280     (void) printf("input).\n");
1281     (void) printf("\t\tnrows:\n");
1282     (void) printf("\t\t\tDimension of the vertical axis.\n");
1283     (void) printf("\t\tncols:\n");
1284     (void) printf("\t\t\tDimension of the horizontal axis.\n");
1285     (void) printf("\t\tmax_value:\n");
1286     (void) printf("\t\t\tMaximum data value.\n");
1287     (void) printf("\t\tmin_value:\n");
1288     (void) printf("\t\t\tMinimum data value.\n");
1289     (void) printf("\t\tplane1, plane2, plane3, ...:\n");
1290     (void) printf("\t\t\tScales for depth axis.\n");
1291     (void) printf("\t\trow1, row2, row3, ...:\n");
1292     (void) printf("\t\t\tScales for the vertical axis.\n");
1293     (void) printf("\t\tcol1, col2, col3, ...:\n");
1294     (void) printf("\t\t\tScales for the horizontal axis.\n");
1295     (void) printf("\t\tdata1, data2, data3, ...:\n");
1296     (void) printf("\t\t\tThe data ordered by rows, left to right and ");
1297     (void) printf("top\n");
1298     (void) printf("\t\t\tto bottom; then optionally, ordered by planes,\n");
1299     (void) printf("\t\t\tfront to back.\n\n");
1300     (void) printf("\tFor FP32 and FP64 input format, \"format\", ");
1301     (void) printf("\"nplanes\", \"nrows\", \"ncols\",\n");
1302     (void) printf("\tand \"nplanes\" are native integers; where ");
1303     (void) printf("\"format\" is the integer\n");
1304     (void) printf("\trepresentation of the appropriate 4-character ");
1305     (void) printf("string (0x46503332 for\n");
1306     (void) printf("\t\"FP32\" and 0x46503634 for \"FP64\").  The ");
1307     (void) printf("remaining input fields are\n");
1308     (void) printf("\tcomposed of native 32-bit floating point values for ");
1309     (void) printf("FP32 input format,\n");
1310     (void) printf("\tor native 64-bit floating point values for FP64 ");
1311     (void) printf("input format.\n\n");
1312     (void) printf("Examples:\n");
1313     (void) printf("\tConvert floating point data in \"f1.txt\" to SDS ");
1314     (void) printf("format, and store it\n");
1315     (void) printf("\tas an SDS in HDF file \"o1\":\n\n");
1316     (void) printf("\t\t%s f1.txt -o o1\n\n", name);
1317     (void) printf("\tConvert floating point data in \"f2.hdf\" to ");
1318     (void) printf("8-bit raster format, and\n");
1319     (void) printf("\tstore it as an RIS8 in HDF file \"o2\":\n\n");
1320     (void) printf("\t\t%s f2.hdf -o o2 -r\n\n", name);
1321     (void) printf("\tConvert floating point data in \"f3.bin\" to ");
1322     (void) printf("8-bit raster format and\n");
1323     (void) printf("\tSDS format, and store both the RIS8 and the SDS ");
1324     (void) printf("in HDF file \"o3\":\n\n");
1325     (void) printf("\t\t%s f3.bin -o o3 -r -f\n\n", name);
1326     (void) printf("\tConvert floating point data in \"f4\" to a ");
1327     (void) printf("500x600 raster image, and\n");
1328     (void) printf("\tstore the RIS8 in HDF file \"o4\".  Also store a ");
1329     (void) printf("palette from \"palfile\"\n");
1330     (void) printf("\twith the image:\n\n");
1331     (void) printf("\t\t%s f4 -o o4 -r -e 500 600 -p palfile\n\n", name);
1332     (void) printf("\tConvert floating point data in \"f5\" to 200 ");
1333     (void) printf("planes of 500x600 raster\n");
1334     (void) printf("\timages, and store the RIS8 in HDF file \"o5\".  ");
1335     (void) printf("Also scale the image\n");
1336     (void) printf("\tdata so that it is centered about a mean value ");
1337     (void) printf("of 10.0:\n\n");
1338     (void) printf("\t\t%s f5 -o o5 -r -i 500 600 200 -m 10.0\n", name);
1339 
1340     return;
1341 }
1342 
1343 /*
1344  * Name:
1345  *      indexes
1346  *
1347  * Purpose:
1348  *      For each pixel location along an axis, determine the nearest
1349  *      scale value neighbor.  Return a list of indexes into the scale
1350  *      array.
1351  */
1352 static int
indexes(float32 * scale,int dim,int * idx,int res)1353 indexes(float32 *scale, int dim, int *idx, int res)
1354 {
1355     int         i, j;
1356     float32    *midpt;
1357     float32     loc;
1358     float32     delta;
1359 
1360     const char *err1 = "Unable to allocate dynamic memory.\n";
1361 
1362     /*
1363      * determine the midpoints between scale values
1364      */
1365     if ((midpt = (float32 *) HDmalloc((size_t) dim * sizeof(float32))) == NULL)
1366       {
1367           (void) fprintf(stderr, "%s", err1);
1368           goto err;
1369       }
1370     for (i = 0; i < dim - 1; i++)
1371         midpt[i] = (scale[i] + scale[i + 1]) * (float32)0.5;
1372     midpt[dim - 1] = scale[dim - 1] + (scale[dim - 1] - midpt[dim - 2]);
1373 
1374     /*
1375      * determine the distance between pixel locations
1376      */
1377     delta = (scale[dim - 1] - scale[0]) / (float32)(res - 1);
1378 
1379     /*
1380      * compute indexes, keeping the index the same until the location
1381      * extends beyond the midpoint
1382      */
1383     for (i = 1, j = 0, idx[0] = 0, loc = scale[0]; i < res; i++)
1384       {
1385           loc += delta;
1386           idx[i] = idx[i - 1];
1387           while (loc >= midpt[j])
1388             {
1389                 idx[i] += 1;
1390                 j += 1;
1391             }
1392       }
1393 
1394     /*
1395      * free dynamically allocated memory
1396      */
1397     HDfree((char *) midpt);
1398 
1399     return (0);
1400 
1401   err:
1402     return (1);
1403 }
1404 
1405 /*
1406  * Name:
1407  *      interp
1408  *
1409  * Purpose:
1410  *      Use a bilinear, or trilinear, interpolation scheme to construct
1411  *      the raster image(s).
1412  *
1413  *  Bug revision:  the line that previously read:
1414  *
1415  *      hratio[i] = ((hrange > 0) ? 1.0 : -1.0) * (in->hscale[j+1] -
1416  *                    loc) / (in->hscale[j+1] - in->hscale[j]);
1417  *    has been changed to read:
1418  *      hratio[i] = (in->hscale[j+1] - loc) / (in->hscale[j+1] - in->hscale[j]);
1419  *
1420  *    Similar changes were made to the corresponding lines for
1421  *    computing vratio and dratio.
1422  *
1423  *  Bug revision: If values occur that are outside the ranges of the
1424  *    max and min values provided, these values are now "clipped" to
1425  *    be the same as the max and min, respectively.
1426  */
1427 
1428 static int
interp(struct Input * in,struct Raster * im)1429 interp(struct Input *in, struct Raster *im)
1430 {
1431     int         i, j, k, m;
1432     int        *hinc, *voff, *doff = NULL;
1433     float32     pix;
1434     float32     loc;
1435     float32     range;
1436     float32     ratio;
1437     float32     hrange, vrange, drange = (float32)0.0;
1438     float32     hdelta, vdelta, ddelta = (float32)0.0;
1439     float32     t1, t2, t3, t4, t5, t6;
1440     float32    *hratio, *vratio, *dratio = NULL;
1441     float32    *pt[8];
1442     unsigned char *ip = im->image;
1443 
1444     const char *err1 = "Unable to allocate dynamic memory.\n";
1445 
1446     /*
1447      * determine the range of pixel locations
1448      */
1449     range = in->max - in->min;
1450     ratio = (float32)237.9 / range;
1451     hrange = in->hscale[in->dims[0] - 1] - in->hscale[0];
1452     vrange = in->vscale[in->dims[1] - 1] - in->vscale[0];
1453     if (in->rank == 3)
1454         drange = in->dscale[in->dims[2] - 1] - in->dscale[0];
1455 
1456     /*
1457      * determine the distance between pixel locations
1458      */
1459     hdelta = hrange / (float32)(im->hres - 1);
1460     vdelta = vrange / (float32)(im->vres - 1);
1461     if (in->rank == 3)
1462         ddelta = drange / (float32)(im->dres - 1);
1463 
1464     /*
1465      * allocate dynamic memory for the interpolation ratio buffers
1466      */
1467     if ((hratio = (float32 *) HDmalloc((size_t) im->hres * sizeof(float32))) == NULL)
1468       {
1469           (void) fprintf(stderr, "%s", err1);
1470           goto err;
1471       }
1472     if ((vratio = (float32 *) HDmalloc((unsigned int) im->vres *
1473                                          sizeof(float32))) == NULL)
1474       {
1475           (void) fprintf(stderr, "%s", err1);
1476           goto err;
1477       }
1478     if (in->rank == 3)
1479       {
1480           if ((dratio = (float32 *) HDmalloc((unsigned int) im->dres *
1481                                                sizeof(float32))) == NULL)
1482             {
1483                 (void) fprintf(stderr, "%s", err1);
1484                 goto err;
1485             }
1486       }
1487 
1488     /*
1489      * allocate dynamic memory for the pixel location offset/increment
1490      * buffers
1491      */
1492     if ((hinc = (int *) HDmalloc((unsigned int) im->hres *
1493                                    sizeof(int))) == NULL)
1494       {
1495           (void) fprintf(stderr, "%s", err1);
1496           goto err;
1497       }
1498     if ((voff = (int *) HDmalloc((unsigned int) (im->vres + 1) *
1499                                    sizeof(int))) == NULL)
1500       {
1501           (void) fprintf(stderr, "%s", err1);
1502           goto err;
1503       }
1504     if (in->rank == 3)
1505       {
1506           if ((doff = (int *) HDmalloc((unsigned int) (im->dres + 1) *
1507                                          sizeof(int))) == NULL)
1508             {
1509                 (void) fprintf(stderr, "%s", err1);
1510                 goto err;
1511             }
1512       }
1513 
1514     /*
1515      * compute the interpolation ratios and pixel location
1516      * offsets/increments for each axis
1517      */
1518     for (i = 0, j = 0; i < im->hres; i++)
1519       {
1520           loc = hdelta * (float) i + in->hscale[0];
1521           hinc[i] = 0;
1522           while ((j < (in->dims[0] - 2)) && ((hrange > (float32)0.0) ?
1523                      (in->hscale[j + 1] < loc) : (in->hscale[j + 1] > loc)))
1524             {
1525                 hinc[i] += 1;
1526                 j += 1;
1527             }
1528           hratio[i] = (in->hscale[j + 1] - loc) / (in->hscale[j + 1] - in->hscale[j]);
1529       }
1530     for (i = 0, j = 0, voff[0] = 0; i < im->vres; i++)
1531       {
1532           loc = vdelta * (float) i + in->vscale[0];
1533           while ((j < (in->dims[1] - 2)) && ((vrange > (float32)0.0) ?
1534                      (in->vscale[j + 1] < loc) : (in->vscale[j + 1] > loc)))
1535             {
1536                 voff[i] += 1;
1537                 j += 1;
1538             }
1539           vratio[i] = (in->vscale[j + 1] - loc) / (in->vscale[j + 1] - in->vscale[j]);
1540           voff[i + 1] = voff[i];
1541       }
1542     if (in->rank == 3)
1543       {
1544           for (i = 0, j = 0, doff[0] = 0; i < im->dres; i++)
1545             {
1546                 loc = ddelta * (float) i + in->dscale[0];
1547                 while ((j < (in->dims[2] - 2)) && ((drange > (float32)0.0) ?
1548                      (in->dscale[j + 1] < loc) : (in->dscale[j + 1] > loc)))
1549                   {
1550                       doff[i] += 1;
1551                       j += 1;
1552                   }
1553                 dratio[i] = (in->dscale[j + 1] - loc) /
1554                     (in->dscale[j + 1] - in->dscale[j]);
1555                 doff[i + 1] = doff[i];
1556             }
1557       }
1558 
1559     /*
1560      * do the interpolation for each point in the target image, taking
1561      * advantage of the fact that the target is evenly spaced along each
1562      * axis
1563      */
1564     if (in->rank == 2)
1565       {
1566           for (i = 0; i < im->vres; i++)
1567             {
1568                 pt[0] = (float32 *) in->data + (in->dims[0] * voff[i]);
1569                 pt[1] = pt[0] + 1;
1570                 pt[2] = pt[0] + in->dims[0];
1571                 pt[3] = pt[2] + 1;
1572                 for (j = 0; j < im->hres; j++)
1573                   {
1574                       for (m = 0; m < 4; m++)
1575                           pt[m] += hinc[j];
1576                       t1 = *pt[2] - ((*pt[2] - *pt[0]) * vratio[i]);
1577                       t2 = *pt[3] - ((*pt[3] - *pt[1]) * vratio[i]);
1578                       pix = t2 - ((t2 - t1) * hratio[j]);
1579                       if (pix > in->max)
1580                           pix = in->max;    /* clip (bug fix) */
1581                       if (pix < in->min)
1582                           pix = in->min;    /* ditto */
1583                       *ip++ = (unsigned char)((ratio * (pix - in->min)) + (float32)1.5);
1584                   }
1585             }
1586       }
1587     else
1588       {     /* rank == 3 */
1589           for (i = 0; i < im->dres; i++)
1590             {
1591                 for (j = 0; j < im->vres; j++)
1592                   {
1593                       pt[0] = (float32 *) in->data + (in->dims[0] * voff[j]) +
1594                           (in->dims[0] * in->dims[1] * doff[i]);
1595                       pt[1] = pt[0] + 1;
1596                       pt[2] = pt[0] + in->dims[0];
1597                       pt[3] = pt[2] + 1;
1598                       pt[4] = pt[0] + (in->dims[0] * in->dims[1]);
1599                       pt[5] = pt[4] + 1;
1600                       pt[6] = pt[4] + in->dims[0];
1601                       pt[7] = pt[6] + 1;
1602                       for (k = 0; k < im->hres; k++)
1603                         {
1604                             for (m = 0; m < 8; m++)
1605                                 pt[m] += hinc[k];
1606                             t1 = *pt[4] - ((*pt[4] - *pt[0]) *
1607                                            dratio[i]);
1608                             t2 = *pt[6] - ((*pt[6] - *pt[2]) *
1609                                            dratio[i]);
1610                             t3 = *pt[5] - ((*pt[5] - *pt[1]) *
1611                                            dratio[i]);
1612                             t4 = *pt[7] - ((*pt[7] - *pt[3]) *
1613                                            dratio[i]);
1614                             t5 = t2 - ((t2 - t1) * vratio[j]);
1615                             t6 = t4 - ((t4 - t3) * vratio[j]);
1616                             pix = t6 - ((t6 - t5) * hratio[k]);
1617                             if (pix > in->max)
1618                                 pix = in->max;  /* clip (bug fix) */
1619                             if (pix < in->min)
1620                                 pix = in->min;  /* ditto */
1621                             *ip++ = (unsigned char)((ratio * (pix - in->min)) + (float32)1.5);
1622                         }
1623                   }
1624             }
1625       }
1626 
1627     /*
1628      * free dynamically allocated memory
1629      */
1630     HDfree((char *) hratio);
1631     HDfree((char *) vratio);
1632     if (in->rank == 3)
1633         HDfree((char *) dratio);
1634     HDfree((char *) hinc);
1635     HDfree((char *) voff);
1636     if (in->rank == 3)
1637         HDfree((char *) doff);
1638 
1639     return (0);
1640 
1641   err:
1642     return (1);
1643 }
1644 
1645 /*
1646  * Name:
1647  *      isnum
1648  *
1649  * Purpose:
1650  *      Determine whether or not the string is representative of an
1651  *      integer or floating point number.  If it is, a non-zero value
1652  *      is returned.  A leading (-) to denote sign is acceptable.
1653  */
1654 static int
isnum(char * s)1655 isnum(char *s)
1656 {
1657     char       *cp;
1658     int         rval = FALSE;
1659 
1660     /*
1661      * check to see if its a floating point number
1662      */
1663     cp = s;
1664     (void) strtod(s, &cp);
1665     if ((*cp == '\0') && (cp != s))
1666         rval = TRUE;
1667 
1668     /*
1669      * check to see if its an integer number (radix 8, 10, or 16)
1670      */
1671     else
1672       {
1673           cp = s;
1674           (void) strtol(s, &cp, 0);
1675           if ((*cp == '\0') && (cp != s))
1676               rval = TRUE;
1677       }
1678 
1679     return (rval);
1680 }
1681 
1682 /*
1683  * Name:
1684  *      mean
1685  *
1686  * Purpose:
1687  *      Reset the maximum and minimum data values to be symmetric about
1688  *      the user-specified mean value.
1689  */
1690 void
mean(struct Input * in,struct Options * opt)1691 mean(struct Input *in,struct Options * opt)
1692 {
1693     float32     delta, delta_max, delta_min;
1694 
1695     delta_max = (float32)fabs((double)(in->max - opt->meanval));
1696     delta_min = (float32)fabs((double)(opt->meanval - in->min));
1697     delta = (delta_max > delta_min) ? delta_max : delta_min;
1698 
1699     in->max = opt->meanval + delta;
1700     in->min = opt->meanval - delta;
1701 
1702     return;
1703 }
1704 
1705 /*
1706  * Name:
1707  *      palette
1708  *
1709  * Purpose:
1710  *      Process the (user specified) palette input file.
1711  */
1712 static int
palette(char * palfile)1713 palette(char *palfile)
1714 {
1715     unsigned char *color;
1716     unsigned char pal[1024], red[256], green[256], blue[256];
1717     FILE       *strm;
1718     int         i;
1719 
1720     const char *err1 = "Unable to get palette from file: %s.\n";
1721     const char *err2 = "Unable to open palette file: %s.\n";
1722     const char *err3 = "Unable to set default palette.\n";
1723 
1724     /*
1725      * extract a palette from an HDF file
1726      */
1727     if (Hishdf(palfile))
1728       {
1729           if (DFPgetpal(palfile, pal))
1730             {
1731                 (void) fprintf(stderr, err1, palfile);
1732                 goto err;
1733             }
1734 
1735           /*
1736            * read in a raw palette file
1737            */
1738       }
1739     else
1740       {
1741           if ((strm = fopen(palfile, "r")) == NULL)
1742             {
1743                 (void) fprintf(stderr, err2, palfile);
1744                 goto err;
1745             }
1746           if (fread((char *) red, 1, 256, strm) != 256)
1747             {
1748                 (void) fprintf(stderr, err1, palfile);
1749                 goto err;
1750             }
1751           else if (fread((char *) green, 1, 256, strm) != 256)
1752             {
1753                 (void) fprintf(stderr, err1, palfile);
1754                 goto err;
1755             }
1756           else if (fread((char *) blue, 1, 256, strm) != 256)
1757             {
1758                 (void) fprintf(stderr, err1, palfile);
1759                 goto err;
1760             }
1761           (void) fclose(strm);
1762 
1763           /*
1764            * interleave the R,G,B values
1765            */
1766           color = pal;
1767           for (i = 0; i < 256; i++)
1768             {
1769                 *color++ = red[i];
1770                 *color++ = green[i];
1771                 *color++ = blue[i];
1772             }
1773       }
1774 
1775     /*
1776      * set up the palette as the default for subsequent images
1777      */
1778     if (DFR8setpalette(pal))
1779       {
1780           (void) fprintf(stderr, "%s", err3);
1781           goto err;
1782       }
1783 
1784     return (0);
1785 
1786   err:
1787     return (1);
1788 }
1789 
1790 /*
1791  * Name:
1792  *      pixrep
1793  *
1794  * Purpose:
1795  *      Expand the image(s) to the desired resolution using pixel
1796  *      replication.
1797  */
1798 static int
pixrep(struct Input * in,struct Raster * im)1799 pixrep(struct Input *in, struct Raster *im)
1800 {
1801     int        *hidx, *vidx, *didx;
1802     int         ovidx, odidx;
1803     int         dummy;
1804     int32       i, j, k;
1805     float32    *dp;
1806     float32     range;
1807     float32     ratio;
1808     unsigned char *ip, *plane, *row, *pix;
1809 
1810     const char *err1 = "Unable to dynamically allocate memory.\n";
1811 
1812     dp = (float32 *) in->data;
1813     ip = im->image;
1814     range = in->max - in->min;
1815     ratio = (float32)237.9 / range;
1816 
1817     /*
1818      * determine the scale indexes of the horizontal pixel locations
1819      */
1820     if ((hidx = (int *) HDmalloc((unsigned int) (im->hres + 1) * sizeof(int))) == NULL)
1821       {
1822           (void) fprintf(stderr, "%s", err1);
1823           goto err;
1824       }
1825 
1826     if (indexes(in->hscale, in->dims[0], hidx, im->hres))
1827         goto err;
1828 
1829     /*
1830      * determine the scale indexes of the vertical pixel locations
1831      */
1832     if ((vidx = (int *) HDmalloc((unsigned int) (im->vres + 1) *
1833                                    sizeof(int))) == NULL)
1834       {
1835           (void) fprintf(stderr, "%s", err1);
1836           goto err;
1837       }
1838 
1839     if (indexes(in->vscale, in->dims[1], vidx, im->vres))
1840         goto err;
1841 
1842     /*
1843      * determine the scale indexes of the depth plane locations
1844      */
1845     dummy = 0;
1846     didx = &dummy;
1847     if (in->rank == 3)
1848       {
1849           if ((didx = (int *) HDmalloc((unsigned int) (im->dres + 1) *
1850                                          sizeof(int))) == NULL)
1851             {
1852                 (void) fprintf(stderr, "%s", err1);
1853                 goto err;
1854             }
1855 
1856           if (indexes(in->dscale, in->dims[2], didx, im->dres))
1857               goto err;
1858       }
1859 
1860     /*
1861      * compute the expanded image
1862      */
1863     if ((pix = (unsigned char *) HDmalloc((unsigned int) (in->dims[0] + 1))) ==
1864         NULL)
1865       {
1866           (void) fprintf(stderr, "%s", err1);
1867           goto err;
1868       }
1869     for (k = 0, odidx = didx[0] - 1; k < im->dres; k++)
1870       {
1871           /*
1872            * construct a new depth plane
1873            */
1874           if (didx[k] > odidx)
1875             {
1876                 for (j = 0, ovidx = vidx[0] - 1; j < im->vres; j++)
1877                   {
1878                       /*
1879                        * construct a new row
1880                        */
1881                       if (vidx[j] > ovidx)
1882                         {
1883                             for (i = 0; i < in->dims[0]; i++)
1884                                 pix[i] = (unsigned char )((ratio * (*dp++ - in->min)) + (float32)1.5);
1885                             for (i = 0; i < im->hres; i++)
1886                                 *ip++ = pix[hidx[i]];
1887                             /*
1888                              * repeat the previous row
1889                              */
1890                         }
1891                       else
1892                         {
1893                             row = ip - im->hres;
1894                             for (i = 0; i < im->hres; i++)
1895                                 *ip++ = *row++;
1896                         }
1897                       ovidx = vidx[j];
1898                   }
1899                 /*
1900                  * repeat the previous depth plane
1901                  */
1902             }
1903           else
1904             {
1905                 plane = ip - (im->hres * im->vres);
1906                 for (j = 0; j < im->vres; j++)
1907                     for (i = 0; i < im->hres; i++)
1908                         *ip++ = plane[(j * im->hres) + i];
1909             }
1910           odidx = didx[k];
1911       }
1912 
1913     /*
1914      * free dynamically allocated space
1915      */
1916     HDfree((char *) hidx);
1917     HDfree((char *) vidx);
1918     if (in->rank == 3)
1919         HDfree((char *) didx);
1920     HDfree((char *) pix);
1921 
1922     return (0);
1923 
1924   err:
1925     return (1);
1926 }
1927 
1928 /*
1929  * Name:
1930  *      process
1931  *
1932  * Purpose:
1933  *      Process each input file.
1934  */
1935 static int
process(struct Options * opt)1936 process(struct Options *opt)
1937 {
1938     struct Input in;
1939     struct Raster im;
1940     unsigned char *ip;
1941     int         i, j;
1942     int         is_maxmin;
1943     int         is_scale;
1944     int32       hdfdims[3];     /* order: ZYX or YX */
1945     int32       len;
1946     FILE       *strm;
1947     int32       hdf;
1948 #ifdef  DEBUG
1949     int         h, v, d;
1950 #endif /* DEBUG */
1951 
1952     const char *err1 = "Error creating HDF output file: %s.\n";
1953     const char *err2 = "Unable to dynamically allocate memory.\n";
1954     const char *err3a = "Warning: cannot make image smaller using -e ";
1955     const char *err3b = "option.\n\t %s resolution will be made the ";
1956     const char *err3c = "same as %s dimension of the\n\t dataset, ";
1957     const char *err3d = "which is: %d.\n\n";
1958     const char *err4 = "Unable to write an RIS8 to the HDF output file\n";
1959     const char *err5 = "Unable to write an SDS to the HDF output file\n";
1960 
1961     /*
1962      * process the palette file (if one was specified)
1963      */
1964     if (opt->pal == TRUE)
1965         if (palette(opt->palfile))
1966             goto err;
1967 
1968     /*
1969      * create the HDF output file
1970      */
1971     if ((hdf = Hopen(opt->outfile, DFACC_CREATE, 0)) == FAIL)
1972       {
1973           (void) fprintf(stderr, err1, opt->outfile);
1974           goto err;
1975       }
1976     (void) Hclose(hdf);
1977 
1978     /*
1979      * main loop: process input files, one per pass
1980      */
1981     for (i = 0; i < opt->fcount; i++)
1982       {
1983           /*
1984            * initialize key parameters
1985            */
1986           in.is_hdf = FALSE;
1987           in.is_text = FALSE;
1988           in.is_fp32 = FALSE;
1989           in.is_fp64 = FALSE;
1990           is_maxmin = FALSE;
1991           is_scale = FALSE;
1992 
1993           /*
1994            * get the file type, input data dimensions, and input data
1995            * max/min values
1996            */
1997           if (gtype(opt->infiles[i], &in, &strm))
1998               goto err;
1999           if (gdimen(opt->infiles[i], &in, strm))
2000               goto err;
2001           if (gmaxmin(opt->infiles[i], &in, strm, &is_maxmin))
2002               goto err;
2003 
2004           /*
2005            * get the scale for each axis
2006            */
2007           if ((in.hscale = (float32 *) HDmalloc((size_t)
2008                              (in.dims[0] + 1) * sizeof(float32))) == NULL)
2009             {
2010                 (void) fprintf(stderr, "%s", err2);
2011                 goto err;
2012             }
2013           if ((in.vscale = (float32 *) HDmalloc((size_t)
2014                              (in.dims[1] + 1) * sizeof(float32))) == NULL)
2015             {
2016                 (void) fprintf(stderr, "%s", err2);
2017                 goto err;
2018             }
2019           if (in.rank == 3)
2020             {
2021                 if ((in.dscale = (float32 *) HDmalloc((size_t)
2022                              (in.dims[2] + 1) * sizeof(float32))) == NULL)
2023                   {
2024                       (void) fprintf(stderr, "%s", err2);
2025                       goto err;
2026                   }
2027             }
2028           if (gscale(opt->infiles[i], &in, strm, &is_scale))
2029               goto err;
2030 
2031           /*
2032            * get the input data
2033            */
2034           len = in.dims[0] * in.dims[1] * in.dims[2];
2035           if ((in.data = (VOIDP) HDmalloc((size_t) len *
2036                                                  sizeof(float32))) == NULL)
2037             {
2038                 (void) fprintf(stderr, "%s", err2);
2039                 goto err;
2040             }
2041           if (gdata(opt->infiles[i], &in, strm, &is_maxmin))
2042               goto err;
2043 
2044           /*
2045            * put the input data in the HDF output file, in SDS format
2046            */
2047           if (opt->to_float == TRUE)
2048             {
2049                 /*
2050                  * hdfdims is ordered: ZYX or YX
2051                  * in.dims is ordered: XYZ
2052                  */
2053                 if (in.rank == 2)
2054                   {
2055                       hdfdims[0] = in.dims[1];
2056                       hdfdims[1] = in.dims[0];
2057                   }
2058                 else
2059                   {
2060                       hdfdims[0] = in.dims[2];
2061                       hdfdims[1] = in.dims[1];
2062                       hdfdims[2] = in.dims[0];
2063                   }
2064 
2065                 if (DFSDsetNT(DFNT_FLOAT32))
2066                   {
2067                       (void) fprintf(stderr, "%s", err5);
2068                       goto err;
2069                   }
2070                 if (is_scale == TRUE)
2071                   {
2072                       if (DFSDsetdims(in.rank, hdfdims))
2073                         {
2074                             (void) fprintf(stderr, "%s", err5);
2075                             goto err;
2076                         }
2077                       if (DFSDsetrange(&in.max, &in.min))
2078                         {
2079                             (void) fprintf(stderr, "%s", err5);
2080                             goto err;
2081                         }
2082                       if (in.rank == 2)
2083                         {
2084                             if (DFSDsetdimscale(1, hdfdims[0],
2085                                                 in.vscale))
2086                               {
2087                                   (void) fprintf(stderr, "%s", err5);
2088                                   goto err;
2089                               }
2090                             if (DFSDsetdimscale(2, hdfdims[1],
2091                                                 in.hscale))
2092                               {
2093                                   (void) fprintf(stderr, "%s", err5);
2094                                   goto err;
2095                               }
2096                         }
2097                       else
2098                         {
2099                             if (DFSDsetdimscale(1, hdfdims[0],
2100                                                 in.dscale))
2101                               {
2102                                   (void) fprintf(stderr, "%s", err5);
2103                                   goto err;
2104                               }
2105                             if (DFSDsetdimscale(2, hdfdims[1],
2106                                                 in.vscale))
2107                               {
2108                                   (void) fprintf(stderr, "%s", err5);
2109                                   goto err;
2110                               }
2111                             if (DFSDsetdimscale(3, hdfdims[2],
2112                                                 in.hscale))
2113                               {
2114                                   (void) fprintf(stderr, "%s", err5);
2115                                   goto err;
2116                               }
2117                         }
2118                   }
2119                 if (DFSDadddata(opt->outfile, in.rank, hdfdims, in.data))
2120                   {
2121                       (void) fprintf(stderr, "%s", err5);
2122                       goto err;
2123                   }
2124             }
2125 
2126           /*
2127            * put the input data in the HDF output file, in RIS8 format
2128            */
2129           if (opt->to_image == TRUE)
2130             {
2131                 /*
2132                  * allocate a buffer for the output image
2133                  */
2134                 im.hres = (opt->hres == 0) ? in.dims[0] : opt->hres;
2135                 if ((im.hres < in.dims[0]) && (opt->ctm == EXPAND))
2136                   {
2137                       (void) fprintf(stderr, "%s", err3a);
2138                       (void) fprintf(stderr, err3b, "Horiz.");
2139                       (void) fprintf(stderr, err3c, "horiz.");
2140                       (void) fprintf(stderr, err3d, in.dims[0]);
2141                       im.hres = in.dims[0];
2142                       opt->hres = in.dims[0];
2143                   }
2144                 im.vres = (opt->vres == 0) ? in.dims[1] : opt->vres;
2145                 if ((im.vres < in.dims[1]) && (opt->ctm == EXPAND))
2146                   {
2147                       (void) fprintf(stderr, "%s", err3a);
2148                       (void) fprintf(stderr, err3b, "Vert.");
2149                       (void) fprintf(stderr, err3c, "vert.");
2150                       (void) fprintf(stderr, err3d, in.dims[1]);
2151                       im.vres = in.dims[1];
2152                       opt->vres = in.dims[1];
2153                   }
2154                 im.dres = 1;
2155                 if (in.rank == 3)
2156                   {
2157                       im.dres = (opt->dres == 0) ? in.dims[2] :
2158                           opt->dres;
2159                       if ((im.dres < in.dims[2]) &&
2160                           (opt->ctm == EXPAND))
2161                         {
2162                             (void) fprintf(stderr, "%s", err3a);
2163                             (void) fprintf(stderr, err3b, "Depth");
2164                             (void) fprintf(stderr, err3c, "depth");
2165                             (void) fprintf(stderr, err3d,
2166                                            in.dims[2]);
2167                             im.dres = in.dims[2];
2168                             opt->dres = in.dims[2];
2169                         }
2170                   }
2171                 len = im.hres * im.vres * im.dres;
2172                 if ((im.image = (unsigned char *) HDmalloc((unsigned
2173                                                          int) len)) == NULL)
2174                   {
2175                       (void) fprintf(stderr, "%s", err2);
2176                       goto err;
2177                   }
2178 
2179                 /*
2180                  * reset max/min symmetrically about the mean value
2181                  */
2182                 if (opt->mean == TRUE)
2183                     mean(&in, opt);
2184 
2185                 /*
2186                  * perform pixel replication or interpolation
2187                  */
2188                 if (opt->ctm == EXPAND)
2189                   {
2190                       if (pixrep(&in, &im))
2191                           goto err;
2192                   }
2193                 else
2194                   {     /* INTERP */
2195                       if (interp(&in, &im))
2196                           goto err;
2197                   }
2198 
2199                 len = im.hres * im.vres;
2200                 for (j = 0, ip = im.image; j < im.dres; j++, ip += len)
2201                   {
2202                       if (DFR8addimage(opt->outfile, ip, im.hres,
2203                                        im.vres, DFTAG_RLE))
2204                         {
2205                             (void) fprintf(stderr, "%s", err4);
2206                             goto err;
2207                         }
2208                   }
2209 
2210 #ifdef  DEBUG
2211                 (void) printf("Output Raster Information ...\n\n");
2212                 (void) printf("\tresolution (horiz,vert,[depth]):\n\n");
2213                 if (in.rank == 2)
2214                     (void) printf("\t%d %d\n\n", im.hres, im.vres);
2215                 else
2216                     (void) printf("\t%d %d %d\n\n", im.hres,
2217                                   im.vres, im.dres);
2218                 if (opt->mean == TRUE)
2219                   {
2220                       (void) printf("\tadjusted max/min values:\n\n");
2221                       (void) printf("\t%f %f\n\n", in.max, in.min);
2222                   }
2223                 (void) printf("\tcolor index values:");
2224                 for (d = 0, ip = im.image; d < im.dres; d++)
2225                   {
2226                       (void) printf("\n");
2227                       for (v = 0; v < im.vres; v++)
2228                         {
2229                             (void) printf("\n");
2230                             for (h = 0; h < im.hres; h++, ip++)
2231                                 (void) printf("\t%d", *ip);
2232                         }
2233                   }
2234                 (void) printf("\n");
2235 #endif /* DEBUG */
2236             }
2237 
2238           /*
2239            * free dynamically allocated space
2240            */
2241           HDfree((char *) in.hscale);
2242           HDfree((char *) in.vscale);
2243           if (in.rank == 3)
2244               HDfree((char *) in.dscale);
2245           HDfree((char *) in.data);
2246           if (opt->to_image == TRUE)
2247               HDfree((char *) im.image);
2248       }
2249 
2250     return (0);
2251 
2252   err:
2253     return (1);
2254 }
2255 
2256 /*
2257  * Name:
2258  *      usage
2259  *
2260  * Purpose:
2261  *      Print a summary of command usage.
2262  */
2263 void
usage(char * name)2264 usage(char *name)
2265 {
2266     (void) fprintf(stderr, "\nUsage:\t%s -h[elp], OR\n", name);
2267     (void) fprintf(stderr, "\t%s <infile> [<infile>...] ", name);
2268     (void) fprintf(stderr, "-o[utfile] <outfile> [options...]\n\n");
2269     (void) fprintf(stderr, "\toptions...\n");
2270     (void) fprintf(stderr, "\t    -r[aster]:\n");
2271     (void) fprintf(stderr, "\t        produce an image.  Could be ");
2272     (void) fprintf(stderr, "followed by:\n");
2273     (void) fprintf(stderr, "\t        -e[xpand] <horiz> <vert> ");
2274     (void) fprintf(stderr, "[<depth>]:\n");
2275     (void) fprintf(stderr, "\t            resolution with pixel ");
2276     (void) fprintf(stderr, "replication\n");
2277     (void) fprintf(stderr, "\t        -i[nterp] <horiz> <vert> ");
2278     (void) fprintf(stderr, "[<depth>]:\n");
2279     (void) fprintf(stderr, "\t            resolution with interpolation\n");
2280     (void) fprintf(stderr, "\t        -p[alfile] <palfile>:\n");
2281     (void) fprintf(stderr, "\t            include palette from palfile\n");
2282     (void) fprintf(stderr, "\t        -m[ean] <meanval>:\n");
2283     (void) fprintf(stderr, "\t            mean value to scale image ");
2284     (void) fprintf(stderr, "around\n");
2285     (void) fprintf(stderr, "\t    -f[loat]:\n");
2286     (void) fprintf(stderr, "\t        produce floating point data\n\n");
2287 
2288     return;
2289 }
2290