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