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 /* $Id$ */
15
16 /*-----------------------------------------------------------------------------
17 * File: dfr8.c
18 * Purpose: read and write 8-bit Raster Image Groups
19 * Invokes: df.c, dfcomp.c, dfgroup.c, dfrig.h
20 * Contents:
21 * DFR8setpalette : specify palette to be used with subsequent 8-bit images
22 * DFR8setcompress : Set the compression for next image written
23 * DFR8putimage : write 8-bit image into an HDF file
24 * DFR8addimage : append another 8-bit image to an HDF file
25 * DFR8getdims : retrieve information about 8-bit image dimensions
26 * DFR8getimage : retrieve 8-bit image and associated palette
27 * DFR8putrig : write out a raster image group for 8-bit images
28 * DFR8getrig : read in a raster image group for 8-bit images
29 * DFR8nimages : number of images in HDF file
30 * DFR8readref : get image with this reference number next
31 * DFR8writeref : put image with this reference number next
32 * DFR8lastref : return reference number of last element read or written
33 * DFR8restart : forget info about last file accessed, restart from
34 * beginning
35 * Private:
36 * DFR8Iopen: open/reopen file
37 * DFR8Iriginfo: obtain info about next RIG/RI8 to get
38 * DFR8Iputimage : internal routine that write 8-bit images to files
39 * Remarks: A RIG specifies attributes associated with an image - palette,
40 * dimension, compression, color compensation etc.
41 * The palette for an 8-bit image is assumed to always be 768 bytes
42 * The palette is arranged as RGBRGB...
43 *---------------------------------------------------------------------------*/
44
45 #include "hdf.h"
46 #include "dfrig.h"
47
48 /* Private Variables */
49 PRIVATE uint8 *paletteBuf = NULL;
50 PRIVATE uint16 Refset = 0; /* Ref of image to get next */
51 PRIVATE uint16 Lastref = 0; /* Last ref read/written */
52 PRIVATE uint16 Writeref = 0; /* ref of next image to put in this file */
53 PRIVATE intn foundRig = -1; /* -1: don't know if HDF file has RIGs
54 0: No RIGs, try for RI8s etc.
55 1: RIGs used, ignore RI8s etc. */
56 PRIVATE intn Newdata = 0; /* does Readrig contain fresh data? */
57 PRIVATE intn Newpalette = -1; /* -1 = no palette is associated
58 0 = palette already written out
59 1 = new palette, not yet written out */
60
61 PRIVATE intn CompressSet = FALSE; /* Whether the compression parameters have
62 been set for the next image */
63 PRIVATE int32 CompType = COMP_NONE; /* What compression to use for the next
64 image */
65 PRIVATE comp_info CompInfo; /* Params for compression to perform */
66 PRIVATE char Lastfile[DF_MAXFNLEN]; /* last file opened */
67 PRIVATE DFRrig Readrig =
68 { /* information about RIG being read */
69 NULL, 0, 0, (float32) 0.0, (float32) 0.0,
70 {(float32) 0.0, (float32) 0.0, (float32) 0.0},
71 {(float32) 0.0, (float32) 0.0, (float32) 0.0},
72 {(float32) 0.0, (float32) 0.0, (float32) 0.0},
73 {(float32) 0.0, (float32) 0.0, (float32) 0.0},
74 {0, 0},
75 {0, 0, 0, 0,
76 {0, 0},
77 {0, 0}},
78 {0, 0},
79 {0, 0, 0, 0,
80 {0, 0},
81 {0, 0}},
82 {0, 0},
83 {0, 0, 0, 0,
84 {0, 0},
85 {0, 0}},
86 };
87 PRIVATE DFRrig Writerig =
88 { /* information about RIG being written */
89 NULL, 0, 0, (float32) 0.0, (float32) 0.0,
90 {(float32) 0.0, (float32) 0.0, (float32) 0.0},
91 {(float32) 0.0, (float32) 0.0, (float32) 0.0},
92 {(float32) 0.0, (float32) 0.0, (float32) 0.0},
93 {(float32) 0.0, (float32) 0.0, (float32) 0.0},
94 {0, 0},
95 {0, 0, 0, 0,
96 {0, 0},
97 {0, 0}},
98 {0, 0},
99 {0, 0, 0, 0,
100 {0, 0},
101 {0, 0}},
102 {0, 0},
103 {0, 0, 0, 0,
104 {0, 0},
105 {0, 0}},
106 };
107 PRIVATE DFRrig Zrig =
108 { /* empty RIG for initialization */
109 NULL,
110 0, 0, (float32) 0.0, (float32) 0.0,
111 {(float32) 0.0, (float32) 0.0, (float32) 0.0},
112 {(float32) 0.0, (float32) 0.0, (float32) 0.0},
113 {(float32) 0.0, (float32) 0.0, (float32) 0.0},
114 {(float32) 0.0, (float32) 0.0, (float32) 0.0},
115 {0, 0},
116 {0, 0, 0, 0,
117 {0, 0},
118 {0, 0}},
119 {0, 0},
120 {0, 0, 0, 0,
121 {0, 0},
122 {0, 0}},
123 {0, 0},
124 {0, 0, 0, 0,
125 {0, 0},
126 {0, 0}},
127 };
128
129 /* Whether we've installed the library termination function yet for this interface */
130 PRIVATE intn library_terminate = FALSE;
131
132 /* private functions */
133 PRIVATE intn DFR8Iputimage
134 (const char *filename, const void * image, int32 xdim, int32 ydim, uint16 compress,
135 intn append);
136
137 PRIVATE int32 DFR8Iopen
138 (const char *filename, intn acc_mode);
139
140 PRIVATE intn DFR8Iriginfo
141 (int32 file_id);
142
143 PRIVATE intn DFR8getrig
144 (int32 file_id, uint16 ref, DFRrig * rig);
145
146 PRIVATE intn DFR8putrig
147 (int32 file_id, uint16 ref, DFRrig * rig, intn wdim);
148
149 PRIVATE intn DFR8Istart(void);
150
151 /*--------------------------------------------------------------------------
152 NAME
153 DFR8setcompress -- set compression scheme for 8-bit image
154 USAGE
155 intn DFR8setcompress(type,cinfo)
156 int32 type; IN: the type of compression to perform on the
157 next image
158 comp_info *cinfo; IN: ptr to compression information structure
159 RETURNS
160 SUCCEED on success, FAIL on failure.
161 DESCRIPTION
162 Sets the scheme used to compress the next 8-bit raster image written out
163 with the DFR8 interface.
164
165 Valid compression types available for this interface are listed in
166 hcomp.h as COMP_nnnn.
167 GLOBAL VARIABLES
168 Uses the CompressSet, CompType and CompInfo global variables to store
169 the information about the compression scheme.
170 COMMENTS, BUGS, ASSUMPTIONS
171 Only the JPEG compression type currently uses the cinfo structure.
172 EXAMPLES
173 REVISION LOG
174 --------------------------------------------------------------------------*/
175 intn
DFR8setcompress(int32 type,comp_info * cinfo)176 DFR8setcompress(int32 type, comp_info * cinfo)
177 {
178 CONSTR(FUNC, "DFR8setcompress");
179 intn ret_value = SUCCEED;
180
181 /* Perform global, one-time initialization */
182 if (library_terminate == FALSE)
183 if(DFR8Istart()==FAIL)
184 HGOTO_ERROR(DFE_CANTINIT, FAIL);
185
186 if (type == COMP_NONE)
187 { /* quick check for no compression */
188 CompType = 0;
189 HGOTO_DONE(SUCCEED);
190 } /* end if */
191
192 if (type < 0 || type > COMP_MAX_COMP || compress_map[type] == 0)
193 HGOTO_ERROR(DFE_BADSCHEME, FAIL);
194
195 CompressSet = TRUE;
196
197 /* map JPEG compression into correct type of JPEG compression */
198 if (type == COMP_JPEG)
199 CompType = DFTAG_GREYJPEG5;
200 else /* otherwise, just use mapped tag */
201 CompType = (int32)compress_map[type];
202 CompInfo = (*cinfo);
203
204 done:
205 if(ret_value == FAIL)
206 { /* Error condition cleanup */
207
208 } /* end if */
209
210 /* Normal function cleanup */
211 return ret_value;
212 } /* end DFR8setcompress() */
213
214 /*--------------------------------------------------------------------------
215 NAME
216 DFR8getdims -- get dimensions of next image from RIG, also if there is a
217 palette
218 USAGE
219 intn DFR8getdims(filename,pxdim,pydim,pispal)
220 char *filename; IN: name of HDF file
221 int32 *pxdim, *pydim; OUT: ptr to locations for returning X & Y dims
222 intn *pispal; OUT: ptr to location for returning if there is
223 a palette
224 RETURNS
225 SUCCEED on success, FAIL on failure.
226 DESCRIPTION
227 Moves to the next 8-bit raster image in a file and returns the
228 dimensions and whether there is a palette associated with it.
229
230 Will also handle file with just raster-8 tags: RI8, CI8, ID8, IP8
231 GLOBAL VARIABLES
232 COMMENTS, BUGS, ASSUMPTIONS
233 EXAMPLES
234 REVISION LOG
235 --------------------------------------------------------------------------*/
236 intn
DFR8getdims(const char * filename,int32 * pxdim,int32 * pydim,intn * pispal)237 DFR8getdims(const char *filename, int32 *pxdim, int32 *pydim, intn *pispal)
238 {
239 CONSTR(FUNC, "DFR8getdims");
240 int32 file_id=(-1);
241 intn ret_value = SUCCEED;
242
243 HEclear();
244
245 if (!filename || !*filename || !pxdim || !pydim)
246 HGOTO_ERROR(DFE_ARGS, FAIL);
247
248 /* Perform global, one-time initialization */
249 if (library_terminate == FALSE)
250 if(DFR8Istart()==FAIL)
251 HGOTO_ERROR(DFE_CANTINIT, FAIL);
252
253 if ((file_id = DFR8Iopen(filename, DFACC_READ)) == FAIL)
254 HGOTO_ERROR(DFE_BADOPEN, FAIL);
255
256 if (DFR8Iriginfo(file_id) == FAIL) /* reads next RIG or RI8 from file */
257 HGOTO_ERROR(DFE_INTERNAL,FAIL);
258
259 Newdata = 1;
260 *pxdim = Readrig.descimage.xdim;
261 *pydim = Readrig.descimage.ydim;
262 if (pispal)
263 *pispal = Readrig.lut.tag ? 1 : 0; /* is there a palette */
264
265 done:
266 if(ret_value == FAIL)
267 { /* Error condition cleanup */
268
269 } /* end if */
270
271 /* Normal function cleanup */
272 if(file_id!=(-1))
273 Hclose(file_id);
274
275 return ret_value;
276 } /* end DFR8getdims() */
277
278 /*--------------------------------------------------------------------------
279 NAME
280 DFR8getimage -- get next image from a RIG, get palette also if desired
281 USAGE
282 intn DFR8getimage(filename,image,xdim,ydim,pal)
283 char *filename; IN: name of HDF file
284 uint8 *image; OUT: ptr to buffer to store image in
285 int32 xdim,ydim; IN: dims of space allocated by user for image
286 uint8 *pal; OUT: 768-byte space for palette, NULL if palette
287 not wanted
288 RETURNS
289 SUCCEED on success, FAIL on failure.
290 DESCRIPTION
291 Reads the next 8-bit raster image from the file specified into the image
292 buffer and it's associated palette into the palette buffer if the pal
293 ptr is not NULL.
294
295 Will also get RI8s and CI8s if no RIGs in file.
296
297 Normally,DFR8getdims is called first and it finds next image to get.
298 But if that is not called, DFR8getimage will itself find next image.
299
300 Automatically decompresses images.
301 GLOBAL VARIABLES
302 COMMENTS, BUGS, ASSUMPTIONS
303 EXAMPLES
304 REVISION LOG
305 --------------------------------------------------------------------------*/
306 intn
DFR8getimage(const char * filename,uint8 * image,int32 xdim,int32 ydim,uint8 * pal)307 DFR8getimage(const char *filename, uint8 *image, int32 xdim, int32 ydim, uint8 *pal)
308 {
309 CONSTR(FUNC, "DFR8getimage");
310 int32 file_id=(-1);
311 intn ret_value = SUCCEED;
312
313 HEclear();
314
315 if (!filename || !*filename || !image || (xdim <= 0) || (ydim <= 0))
316 HGOTO_ERROR(DFE_ARGS, FAIL);
317
318 /* Perform global, one-time initialization */
319 if (library_terminate == FALSE)
320 if(DFR8Istart()==FAIL)
321 HGOTO_ERROR(DFE_CANTINIT, FAIL);
322
323 if ((file_id = DFR8Iopen(filename, DFACC_READ)) == FAIL)
324 HGOTO_ERROR(DFE_BADOPEN, FAIL);
325
326 if (!Newdata)
327 { /* if Readrig not fresh */
328 if (DFR8Iriginfo(file_id) == FAIL) /*reads next RIG or RI8 from file */
329 HGOTO_ERROR(DFE_INTERNAL,FAIL);
330 } /* end if */
331 Newdata = 0; /* read new RIG next time */
332
333 if ((Readrig.descimage.xdim > xdim) || (Readrig.descimage.ydim > ydim))
334 HGOTO_ERROR(DFE_ARGS, FAIL);
335
336 /* read image */
337 if (Readrig.descimage.compr.tag)
338 { /* compressed image */
339 if (DFgetcomp(file_id, Readrig.image.tag, Readrig.image.ref, image,
340 Readrig.descimage.xdim, Readrig.descimage.ydim,
341 Readrig.descimage.compr.tag) == FAIL)
342 HGOTO_ERROR(DFE_INTERNAL,FAIL);
343 } /* end if */
344 else
345 { /* non-compressed raster image */
346 if (Hgetelement(file_id, Readrig.image.tag, Readrig.image.ref, image) == FAIL)
347 HGOTO_ERROR(DFE_GETELEM,FAIL);
348 } /* end else */
349
350 if (xdim > Readrig.descimage.xdim)
351 {
352 int32 off1, off2;
353 int32 x, y;
354
355 off1 = (Readrig.descimage.ydim - 1) * xdim;
356 off2 = (Readrig.descimage.ydim - 1) * Readrig.descimage.xdim;
357 for (y = Readrig.descimage.ydim - 1; y > 0; y--)
358 {
359 for (x = Readrig.descimage.xdim - 1; x >= 0; x--)
360 image[off1 + x] = image[off2 + x];
361 off1 -= xdim;
362 off2 -= Readrig.descimage.xdim;
363 } /* end for */
364 } /* end for */
365
366 if (pal && Readrig.lut.tag)
367 { /* read palette */
368 if (Hgetelement(file_id, Readrig.lut.tag, Readrig.lut.ref, pal) == FAIL)
369 HGOTO_ERROR(DFE_GETELEM,FAIL);
370 } /* end if */
371
372 if((ret_value = Hclose(file_id))==FAIL)
373 HGOTO_ERROR(DFE_CANTCLOSE, FAIL);
374
375 done:
376 if(ret_value == FAIL)
377 { /* Error condition cleanup */
378 if(file_id!=(-1))
379 Hclose(file_id);
380
381 } /* end if */
382
383 /* Normal function cleanup */
384
385 return ret_value;
386 } /* end DFR8getimage() */
387
388 /*--------------------------------------------------------------------------
389 NAME
390 DFR8setpalette -- set palette for subsequent images
391 USAGE
392 intn DFR8setpalette(pal)
393 uint8 *pal; IN: 768-byte buffer for palette to use for next
394 image
395 RETURNS
396 SUCCEED on success, FAIL on failure.
397 DESCRIPTION
398 Stores a palette for use with further 8-bit raster images written
399 through this interface.
400
401 If pal is NULL, no palette is associated with subsequent images.
402 GLOBAL VARIABLES
403 paletteBuf, Writerig, Newpalette
404 COMMENTS, BUGS, ASSUMPTIONS
405 EXAMPLES
406 REVISION LOG
407 --------------------------------------------------------------------------*/
408 intn
DFR8setpalette(uint8 * pal)409 DFR8setpalette(uint8 *pal)
410 {
411 CONSTR(FUNC, "DFR8setpalette");
412 intn ret_value = SUCCEED;
413
414 /* Perform global, one-time initialization */
415 if (library_terminate == FALSE)
416 if(DFR8Istart()==FAIL)
417 HGOTO_ERROR(DFE_CANTINIT, FAIL);
418
419 /* Check if paletteBuf buffer has been allocated */
420 if (paletteBuf == NULL)
421 {
422 paletteBuf = (uint8 *) HDmalloc(768 * sizeof(uint8));
423 if (paletteBuf == NULL)
424 HGOTO_ERROR(DFE_NOSPACE, FAIL);
425 } /* end if */
426
427 if (!pal)
428 {
429 Newpalette = -1; /* no palette */
430 Writerig.lut.tag = 0;
431 Writerig.lut.ref = 0; /* forget tag/ref of previous palette */
432 Writerig.desclut.xdim = 0;
433 Writerig.desclut.ncomponents = 0;
434 } /* end if */
435 else
436 { /* store palette */
437 HDmemcpy(paletteBuf, pal, 768);
438 Newpalette = 1;
439 } /* end else */
440
441 done:
442 if(ret_value == FAIL)
443 { /* Error condition cleanup */
444
445 } /* end if */
446
447 /* Normal function cleanup */
448 return ret_value;
449 } /* end DFR8setpalette() */
450
451 /*--------------------------------------------------------------------------
452 NAME
453 DFR8Iputimage -- Internal routine to write RIG to file
454 USAGE
455 intn DFR8Iputimage(filename, image, xdim, ydim, compress, append)
456 char *filename; IN: name of HDF file
457 const void * image; IN: ptr to buffer image is stored in
458 int32 xdim,ydim; IN: dims of space allocated by user for image
459 uint16 compress; IN: type of compression to store image with
460 intn append; IN: whether to (0) overwrite existing file, or
461 (1) append image to file.
462 RETURNS
463 SUCCEED on success, FAIL on failure.
464 DESCRIPTION
465 Stores an image in an HDF file. If a palette has been specified to use
466 with 8-bit rasters, then it will be written to the file too and associated
467 with the image.
468 GLOBAL VARIABLES
469 paletteBuf, Newpalette, Writeref, CompressSet, CompType, CompInfo, Lastref,
470 Writerig
471 COMMENTS, BUGS, ASSUMPTIONS
472 Palette will be associated with image is isPalette is 1
473 Palette will be written to file if not written before (Palref=0)
474 Creates both RIG and RI8/CI8 tags, to accomodate older programs
475 EXAMPLES
476 REVISION LOG
477 --------------------------------------------------------------------------*/
478 PRIVATE intn
DFR8Iputimage(const char * filename,const void * image,int32 xdim,int32 ydim,uint16 compress,intn append)479 DFR8Iputimage(const char *filename, const void * image, int32 xdim, int32 ydim,
480 uint16 compress, intn append)
481 {
482 CONSTR(FUNC, "DFR8Iputimage");
483 intn acc_mode; /* create if op 0, write if op 1 */
484 int32 file_id=(-1);
485 uint16 r8tag; /* RIG and raster tags of image being written */
486 uint8 *pal; /* pointer to palette to be written */
487 uint8 newpal[768]; /* Imcomp creates new palette to be associated */
488 intn wdim; /* have dimensions already been written out? */
489 intn ret_value = SUCCEED;
490
491 HEclear();
492
493 if (!filename || !*filename || !image || (xdim <= 0) || (ydim <= 0))
494 HGOTO_ERROR(DFE_ARGS, FAIL);
495
496 /* Perform global, one-time initialization */
497 if (library_terminate == FALSE)
498 if(DFR8Istart()==FAIL)
499 HGOTO_ERROR(DFE_CANTINIT, FAIL);
500
501 /* Check if Palette buffer has been allocated */
502 if (paletteBuf == NULL)
503 {
504 paletteBuf = (uint8 *) HDmalloc(768 * sizeof(uint8));
505 if (paletteBuf == NULL)
506 HGOTO_ERROR(DFE_NOSPACE, FAIL);
507 } /* end if */
508
509 pal = (Newpalette >= 0) ? paletteBuf : NULL;
510 acc_mode = append ? DFACC_WRITE : DFACC_CREATE;
511
512 if ((file_id = DFR8Iopen(filename, acc_mode)) == FAIL)
513 HGOTO_ERROR(DFE_BADOPEN, FAIL);
514
515 /* write out image */
516 if (compress || CompressSet)
517 {
518 /* if a compression type has been set, check if it's the same */
519 if (CompressSet == FALSE || (compress > (uint16)1 && (int32)compress != CompType &&
520 !(compress == (uint16)COMP_JPEG && CompType == (int32)DFTAG_GREYJPEG5)))
521 {
522 if ((int32)compress > COMP_MAX_COMP || compress_map[compress] == 0)
523 HGOTO_ERROR(DFE_BADSCHEME, FAIL);
524 /* map JPEG compression into correct type of JPEG compression */
525 if (compress == COMP_JPEG)
526 {
527 CompType = DFTAG_GREYJPEG5;
528 /* set up some sane JPEG params */
529 CompInfo.jpeg.quality = 75;
530 CompInfo.jpeg.force_baseline = TRUE;
531 } /* end if */
532 else /* otherwise, just use mapped tag */
533 CompType = (int32)compress_map[compress];
534 } /* end if */
535 if (!Writeref)
536 if ((Writeref = Hnewref(file_id)) == 0)
537 HGOTO_ERROR(DFE_NOREF, FAIL);
538
539 if (DFputcomp(file_id, DFTAG_CI, Writeref, image, xdim, ydim,
540 pal, newpal, (int16) CompType, &CompInfo) == FAIL)
541 HGOTO_ERROR(DFE_WRITEERROR, FAIL);
542 Writerig.image.tag = DFTAG_CI;
543 if (CompType == DFTAG_IMC)
544 {
545 pal = newpal; /* Imcomp creates new pal */
546 Newpalette = 1; /* write out palette */
547 } /* end if */
548 } /* end if */
549 else
550 { /* image need not be compressed */
551 if (!Writeref)
552 if ((Writeref = Hnewref(file_id)) == 0)
553 HGOTO_ERROR(DFE_NOREF, FAIL);
554
555 if (Hputelement(file_id, DFTAG_RI, Writeref, image, xdim * ydim) == FAIL)
556 HGOTO_ERROR(DFE_PUTELEM, FAIL);
557 Writerig.image.tag = DFTAG_RI;
558 } /* end else */
559 Writerig.image.ref = Writeref;
560 Writerig.descimage.ncomponents = 1;
561 Writerig.aspectratio = (float32) 1.0;
562
563 /* Write out Raster-8 tags for those who want it */
564 if (CompType != DFTAG_GREYJPEG5)
565 {
566 r8tag = (uint16) (CompType ?
567 ((CompType == DFTAG_RLE) ? DFTAG_CI8 : DFTAG_II8) : DFTAG_RI8);
568 if (Hdupdd(file_id, r8tag, Writeref, Writerig.image.tag, Writeref) == FAIL)
569 HGOTO_ERROR(DFE_NOFREEDD, FAIL);
570 } /* end if */
571
572 /* Write out palette */
573 if (pal)
574 { /* if there is a palette */
575 if (Newpalette == 1)
576 { /* write palette */
577 if (Hputelement(file_id, DFTAG_LUT, Writeref, pal, (int32) 768) == FAIL)
578 HGOTO_ERROR(DFE_PUTELEM, FAIL);
579 Writerig.lut.tag = DFTAG_LUT;
580 Writerig.lut.ref = Writeref;
581 Writerig.desclut.xdim = 768;
582 Writerig.desclut.ncomponents = 1;
583 } /* end if */
584 if (CompType != DFTAG_IMC)
585 Newpalette = 0;
586 /* if IMCOMP, original palette not written out */
587
588 /* put in Raster-8 stuff also, for those who want it */
589 Hdeldd(file_id, DFTAG_IP8, Writeref);
590 if (Hdupdd(file_id, DFTAG_IP8, Writeref, Writerig.lut.tag,
591 Writerig.lut.ref) == FAIL)
592 HGOTO_ERROR(DFE_NOFREEDD, FAIL);
593 } /* end if */
594
595 /* Write out RIG */
596 if ((Writerig.descimage.xdim == xdim) && (Writerig.descimage.ydim == ydim) &&
597 (Writerig.descimage.compr.tag == (uint16) CompType))
598 wdim = 0;
599 else
600 {
601 wdim = 1;
602 Writerig.descimage.xdim = xdim;
603 Writerig.descimage.ydim = ydim;
604 Writerig.descimage.compr.tag = (uint16) CompType;
605 Writerig.descimage.compr.ref = Writeref;
606 } /* end else */
607
608 /* write ID, NT */
609 if (DFR8putrig(file_id, Writeref, &Writerig, wdim) == FAIL)
610 HGOTO_ERROR(DFE_WRITEERROR, FAIL);
611
612 Lastref = Writeref; /* remember ref written */
613
614 Writeref = 0; /* don't know ref to write next */
615 CompressSet = FALSE; /* Reset Compression flag and type */
616 CompType = COMP_NONE;
617
618 ret_value = Hclose(file_id);
619
620 done:
621 if(ret_value == FAIL)
622 { /* Error condition cleanup */
623 if(file_id!=(-1))
624 Hclose(file_id);
625
626 } /* end if */
627
628 /* Normal function cleanup */
629
630 return ret_value;
631 } /* end DFR8Iputimage() */
632
633 /*--------------------------------------------------------------------------
634 NAME
635 DFR8putimage -- Write 8-bit raster image to HDF file
636 USAGE
637 intn DFR8putimage(filename, image, xdim, ydim, compress)
638 char *filename; IN: name of HDF file
639 const void * image; IN: ptr to buffer to store image in
640 int32 xdim,ydim; IN: dims of space allocated by user for image
641 uint16 compress; IN: type of compression to store image with
642 RETURNS
643 SUCCEED on success, FAIL on failure.
644 DESCRIPTION
645 Stores an image in an HDF file. If a palette has been specified to use
646 with 8-bit rasters, then it will be written to the file too and associated
647 with the image.
648
649 This function overwrites existing HDF files.
650 GLOBAL VARIABLES
651 COMMENTS, BUGS, ASSUMPTIONS
652 EXAMPLES
653 REVISION LOG
654 --------------------------------------------------------------------------*/
655 intn
DFR8putimage(const char * filename,const void * image,int32 xdim,int32 ydim,uint16 compress)656 DFR8putimage(const char *filename, const void * image, int32 xdim, int32 ydim,
657 uint16 compress)
658 {
659 CONSTR(FUNC, "DFR8putimage"); /* for HERROR */
660 intn ret_value;
661
662 /* Perform global, one-time initialization */
663 if (library_terminate == FALSE)
664 if(DFR8Istart()==FAIL)
665 HGOTO_ERROR(DFE_CANTINIT, FAIL);
666
667 ret_value = (DFR8Iputimage(filename, image, xdim, ydim, compress, 0));
668
669 done:
670 if(ret_value == FAIL)
671 { /* Error condition cleanup */
672
673 } /* end if */
674
675 /* Normal function cleanup */
676
677 return ret_value;
678 } /* end DFR8putimage() */
679
680 /*--------------------------------------------------------------------------
681 NAME
682 DFR8addimage -- Append 8-bit raster image to HDF file
683 USAGE
684 intn DFR8putimage(filename, image, xdim, ydim, compress)
685 char *filename; IN: name of HDF file
686 const void * image; IN: ptr to buffer to store image in
687 int32 xdim,ydim; IN: dims of space allocated by user for image
688 uint16 compress; IN: type of compression to store image with
689 RETURNS
690 SUCCEED on success, FAIL on failure.
691 DESCRIPTION
692 Stores an image in an HDF file. If a palette has been specified to use
693 with 8-bit rasters, then it will be written to the file too and associated
694 with the image.
695
696 This function does not overwrite existing HDF files, just appends the
697 to the file. It will create the file if necessary.
698 GLOBAL VARIABLES
699 COMMENTS, BUGS, ASSUMPTIONS
700 EXAMPLES
701 REVISION LOG
702 --------------------------------------------------------------------------*/
703 intn
DFR8addimage(const char * filename,const void * image,int32 xdim,int32 ydim,uint16 compress)704 DFR8addimage(const char *filename, const void * image, int32 xdim, int32 ydim,
705 uint16 compress)
706 {
707 CONSTR(FUNC, "DFR8addimage"); /* for HERROR */
708 intn ret_value;
709
710 /* Perform global, one-time initialization */
711 if (library_terminate == FALSE)
712 if(DFR8Istart()==FAIL)
713 HGOTO_ERROR(DFE_CANTINIT, FAIL);
714
715 ret_value = (DFR8Iputimage(filename, image, xdim, ydim, compress, 1));
716
717 done:
718 if(ret_value == FAIL)
719 { /* Error condition cleanup */
720
721 } /* end if */
722
723 /* Normal function cleanup */
724
725 return ret_value;
726 } /* end DFR8addimage() */
727
728 /*****************************************************************************/
729 /* This is the next lower layer - procedures to get and put a RIG. */
730 /* These are specific to 8-bit */
731 /*****************************************************************************/
732
733 /*--------------------------------------------------------------------------
734 NAME
735 DFR8getrig -- Read a RIG into memory
736 USAGE
737 intn DFR8getrig(file_id,ref,rig)
738 int32 file_id; IN: HDF file ID of file to retrieve RIG from
739 uint16 ref; IN: ref # of RIG to get
740 DFRrig *rig; OUT: ptr to RIG structure to place info in
741 RETURNS
742 SUCCEED on success, FAIL on failure.
743 DESCRIPTION
744 Retrieves a specific RIG from an HDF file.
745 GLOBAL VARIABLES
746 COMMENTS, BUGS, ASSUMPTIONS
747 This function seems to be a low level routine, but could be exported.
748 EXAMPLES
749 REVISION LOG
750 --------------------------------------------------------------------------*/
751 PRIVATE intn
DFR8getrig(int32 file_id,uint16 ref,DFRrig * rig)752 DFR8getrig(int32 file_id, uint16 ref, DFRrig * rig)
753 {
754 CONSTR(FUNC, "DFR8getrig");
755 uint16 elt_tag;
756 uint16 elt_ref;
757 uint8 ntstring[4];
758 int32 GroupID;
759 uint8 R8tbuf[64];
760 intn ret_value = SUCCEED;
761
762 HEclear();
763
764 if (!HDvalidfid(file_id) || !ref || !rig)
765 HGOTO_ERROR(DFE_ARGS, FAIL);
766
767 /* Perform global, one-time initialization */
768 if (library_terminate == FALSE)
769 if(DFR8Istart()==FAIL)
770 HGOTO_ERROR(DFE_CANTINIT, FAIL);
771
772 /* read RIG into memory */
773 if ((GroupID = DFdiread(file_id, DFTAG_RIG, ref)) == FAIL)
774 HGOTO_ERROR(DFE_BADGROUP, FAIL);
775
776 *rig = Zrig; /* fill rig with zeroes */
777 while (DFdiget(GroupID, &elt_tag, &elt_ref) != FAIL)
778 {
779 /*get next tag/ref from RIG */
780 switch (elt_tag)
781 { /* process tag/ref */
782 case DFTAG_CI:
783 case DFTAG_RI:
784 rig->image.tag = elt_tag; /* put tag/ref in struct */
785 rig->image.ref = elt_ref;
786 break;
787
788 case DFTAG_LUT:
789 rig->lut.tag = elt_tag;
790 rig->lut.ref = elt_ref;
791 break;
792
793 case DFTAG_ID: /* read description info */
794 if (Hgetelement(file_id, elt_tag, elt_ref, R8tbuf) != FAIL)
795 {
796 uint8 *p;
797
798 p = R8tbuf;
799 INT32DECODE(p, rig->descimage.xdim);
800 INT32DECODE(p, rig->descimage.ydim);
801 UINT16DECODE(p, rig->descimage.nt.tag);
802 UINT16DECODE(p, rig->descimage.nt.ref);
803 INT16DECODE(p, rig->descimage.ncomponents);
804 INT16DECODE(p, rig->descimage.interlace);
805 UINT16DECODE(p, rig->descimage.compr.tag);
806 UINT16DECODE(p, rig->descimage.compr.ref);
807 } /* end if */
808 else
809 {
810 DFdifree(GroupID);
811 ret_value = FAIL;
812 goto done;
813 }
814 if (rig->descimage.ncomponents != 1)
815 {
816 DFdifree(GroupID);
817 HGOTO_ERROR(DFE_BADCALL, FAIL);
818 }
819 if (rig->descimage.nt.tag == 0)
820 break; /* old RIGs */
821
822 /* read NT */
823 if (Hgetelement(file_id, rig->descimage.nt.tag,
824 rig->descimage.nt.ref, ntstring) == FAIL)
825 {
826 DFdifree(GroupID);
827 HGOTO_ERROR(DFE_GETELEM, FAIL);
828 }
829 if ((ntstring[2] != 8) || (ntstring[1] != DFNT_UCHAR))
830 {
831 DFdifree(GroupID);
832 HGOTO_ERROR(DFE_BADCALL, FAIL);
833 }
834 break;
835
836 default: /* ignore unknown tags */
837 break;
838 } /* end switch */
839 } /* end while */
840
841 done:
842 if(ret_value == FAIL)
843 { /* Error condition cleanup */
844
845 } /* end if */
846
847 /* Normal function cleanup */
848
849 return ret_value;
850 } /* end DFR8getrig() */
851
852 /*--------------------------------------------------------------------------
853 NAME
854 DFR8putrig -- Write RIG struct out to HDF file
855 USAGE
856 intn DFR8putrig(file_id,ref,rig,wdim)
857 int32 file_id; IN: HDF file ID of file to put RIG into
858 uint16 ref; IN: ref # of RIG to put
859 DFRrig *rig; IN: ptr to RIG structure to write to file
860 intn wdim; IN: if (1) write new descr. records, (0)
861 if records already written
862 RETURNS
863 SUCCEED on success, FAIL on failure.
864 DESCRIPTION
865 Writes a specific RIG to an HDF file. If wdim is 1, then the ID & ID8
866 records will be written also
867 GLOBAL VARIABLES
868 COMMENTS, BUGS, ASSUMPTIONS
869 This function seems to be a low level routine, but could be exported.
870 EXAMPLES
871 REVISION LOG
872 --------------------------------------------------------------------------*/
873 PRIVATE intn
DFR8putrig(int32 file_id,uint16 ref,DFRrig * rig,intn wdim)874 DFR8putrig(int32 file_id, uint16 ref, DFRrig * rig, intn wdim)
875 {
876 CONSTR(FUNC, "DFR8putrig");
877 static uint16 prevdimref = 0; /*ref of previous dimension record, to reuse */
878 R8dim im8dim;
879 uint8 ntstring[4];
880 int32 GroupID;
881 uint8 R8tbuf[64];
882 intn ret_value = SUCCEED;
883
884 HEclear();
885
886 if (!HDvalidfid(file_id) || !ref)
887 HGOTO_ERROR(DFE_ARGS, FAIL);
888
889 /* Perform global, one-time initialization */
890 if (library_terminate == FALSE)
891 if(DFR8Istart()==FAIL)
892 HGOTO_ERROR(DFE_CANTINIT, FAIL);
893
894 if (!rig->descimage.nt.tag)
895 { /* construct and write out NT */
896 ntstring[0] = DFNT_VERSION; /* version */
897 ntstring[1] = DFNT_UCHAR; /* type */
898 ntstring[2] = 8; /* width: RIG data is 8-bit chars */
899 ntstring[3] = DFNTC_BYTE; /* class: data are numeric values */
900 if (Hputelement(file_id, DFTAG_NT, ref, ntstring, (int32) 4) == FAIL)
901 HGOTO_ERROR(DFE_PUTELEM, FAIL);
902 rig->descimage.nt.tag = DFTAG_NT;
903 rig->descimage.nt.ref = ref;
904 } /* end if */
905
906 im8dim.xd = (uint16) rig->descimage.xdim;
907 im8dim.yd = (uint16) rig->descimage.ydim;
908 if (wdim)
909 {
910 uint8 *p;
911
912 p = R8tbuf;
913 INT32ENCODE(p, rig->descimage.xdim);
914 INT32ENCODE(p, rig->descimage.ydim);
915 UINT16ENCODE(p, rig->descimage.nt.tag);
916 UINT16ENCODE(p, rig->descimage.nt.ref);
917 INT16ENCODE(p, rig->descimage.ncomponents);
918 INT16ENCODE(p, rig->descimage.interlace);
919 UINT16ENCODE(p, rig->descimage.compr.tag);
920 UINT16ENCODE(p, rig->descimage.compr.ref);
921 if (Hputelement(file_id, DFTAG_ID, ref, R8tbuf, (int32) (p - R8tbuf)) == FAIL)
922 HGOTO_ERROR(DFE_PUTELEM, FAIL);
923
924 /* write out ID8 */
925 p = R8tbuf;
926 UINT16ENCODE(p, im8dim.xd);
927 UINT16ENCODE(p, im8dim.yd);
928 if (Hputelement(file_id, DFTAG_ID8, ref, R8tbuf, (int32) 4) == FAIL)
929 HGOTO_ERROR(DFE_PUTELEM, FAIL);
930 prevdimref = ref;
931 } /* end if */
932 if (!prevdimref)
933 HGOTO_ERROR(DFE_ARGS, FAIL);
934
935 /* prepare to start writing rig */
936 /* ### NOTE: the second parameter to this call may go away */
937 if ((GroupID = DFdisetup(10)) == FAIL)
938 HGOTO_ERROR(DFE_GROUPSETUP, FAIL); /* max 10 tag/refs in set */
939
940 /* add tag/ref to RIG - image description, image and palette */
941 if (DFdiput(GroupID, DFTAG_ID, prevdimref) == FAIL)
942 HGOTO_ERROR(DFE_PUTGROUP, FAIL);
943
944 if (DFdiput(GroupID, rig->image.tag, rig->image.ref) == FAIL)
945 HGOTO_ERROR(DFE_PUTGROUP, FAIL);
946
947 if (rig->lut.ref && DFdiput(GroupID, rig->lut.tag, rig->lut.ref) == FAIL)
948 HGOTO_ERROR(DFE_PUTGROUP, FAIL);
949
950 /* write out RIG */
951 if((ret_value = DFdiwrite(file_id, GroupID, DFTAG_RIG, ref))==FAIL)
952 HGOTO_ERROR(DFE_GROUPWRITE, FAIL);
953
954 done:
955 if(ret_value == FAIL)
956 { /* Error condition cleanup */
957
958 } /* end if */
959
960 /* Normal function cleanup */
961
962 return ret_value;
963 } /* end DFR8putrig() */
964
965 /*--------------------------------------------------------------------------
966 NAME
967 DFR8nimages -- Determines the number of 8-bit raster images in a file
968 USAGE
969 intn DFR8nimages(filename)
970 char *filename; IN: filename to check # of images
971 RETURNS
972 number of images on success, -1 on failure.
973 DESCRIPTION
974 Determines the number of unique 8-bit images in the file. Only counts
975 RIGs and RI8s which point to the same image once.
976 GLOBAL VARIABLES
977 COMMENTS, BUGS, ASSUMPTIONS
978 Does not count 8-bit SDS datasets. (Should not either!)
979 EXAMPLES
980 REVISION LOG
981 --------------------------------------------------------------------------*/
982 intn
DFR8nimages(const char * filename)983 DFR8nimages(const char *filename)
984 {
985 CONSTR(FUNC, "DFR8nimages");
986 int32 file_id;
987 int32 group_id; /* group ID for looking at RIG's */
988 uint16 elt_tag, elt_ref; /* tag/ref of items in a RIG */
989 intn curr_image; /* current image gathering information about */
990 intn nimages; /* total number of potential images */
991 int32 nrig, nri8, nci8; /* number of RIGs, RI8s, and CI8s */
992 int32 *img_off; /* storage for an array of image offsets */
993 uint16 rig_tag, rig_ref; /* storage for tag/ref pairs of RIGs */
994 intn found_8bit; /* indicates whether a RIG is an 8-bit RIG */
995 uint16 find_tag, find_ref; /* storage for tag/ref pairs found */
996 int32 find_off, find_len; /* storage for offset/lengths of tag/refs found */
997 uint8 GRtbuf[64]; /* local buffer to read the ID element into */
998 intn i, j; /* local counting variable */
999 intn ret_value = SUCCEED;
1000
1001 HEclear();
1002
1003 /* Perform global, one-time initialization */
1004 if (library_terminate == FALSE)
1005 if(DFR8Istart()==FAIL)
1006 HGOTO_ERROR(DFE_CANTINIT, FAIL);
1007
1008 /* should use reopen if same file as last time - more efficient */
1009 file_id = DFR8Iopen(filename, DFACC_READ);
1010 if (file_id == FAIL)
1011 HGOTO_ERROR(DFE_BADOPEN, FAIL);
1012
1013 /* In a completely psychotic file, there could be RIGs with no corresponding
1014 RI8s and also RI8s with no corresponding RIGs, so assume the worst
1015 case and then run through them all to eliminate matched pairs */
1016 nrig = Hnumber(file_id, DFTAG_RIG); /* count the number of RIGS */
1017 if (nrig == FAIL)
1018 HGOTO_ERROR(DFE_INTERNAL, FAIL);
1019 nri8 = Hnumber(file_id, DFTAG_RI8); /* add the number of RI8 and CI8s */
1020 if (nri8 == FAIL)
1021 HGOTO_ERROR(DFE_INTERNAL, FAIL);
1022 nci8 = Hnumber(file_id, DFTAG_CI8);
1023 if (nci8 == FAIL)
1024 HGOTO_ERROR(DFE_INTERNAL, FAIL);
1025 nimages = (intn) (nrig + nri8 + nci8);
1026
1027 /* if there are no images just close the file and get out */
1028 if (nimages == 0)
1029 {
1030 if (Hclose(file_id) == FAIL)
1031 ret_value = FAIL;
1032 else
1033 ret_value = nimages;
1034
1035 goto done; /* we are done */
1036 }
1037
1038 /* Get space to store the image offsets */
1039 if ((img_off = (int32 *) HDmalloc(nimages * sizeof(int32))) == NULL)
1040 HGOTO_ERROR(DFE_NOSPACE, FAIL);
1041
1042 /* go through the RIGs looking for 8-bit images */
1043 curr_image = 0;
1044 find_tag = find_ref = 0;
1045 while (Hfind(file_id, DFTAG_RIG, DFREF_WILDCARD, &find_tag, &find_ref, &find_off, &find_len, DF_FORWARD) == SUCCEED)
1046 {
1047 /* read RIG into memory */
1048 if ((group_id = DFdiread(file_id, DFTAG_RIG, find_ref)) == FAIL)
1049 HGOTO_ERROR(DFE_INTERNAL, FAIL);
1050 found_8bit = FALSE; /* initialize to no 8-bit image found */
1051 rig_tag = rig_ref = 0; /* initialize bogus tag/ref */
1052 while (!DFdiget(group_id, &elt_tag, &elt_ref))
1053 { /* get next tag/ref */
1054 if (elt_tag == DFTAG_ID)
1055 { /* just look for ID tags to get the number of components */
1056 if (Hgetelement(file_id, elt_tag, elt_ref, GRtbuf) != FAIL)
1057 {
1058 uint16 temp16; /* temporary holding variable */
1059 int32 temp; /* temporary holding variable */
1060 int16 ncomponents; /* number of image components */
1061 uint8 *p;
1062
1063 p = GRtbuf;
1064 INT32DECODE(p, temp);
1065 INT32DECODE(p, temp);
1066 UINT16DECODE(p, temp16);
1067 UINT16DECODE(p, temp16);
1068 INT16DECODE(p, ncomponents);
1069 if (ncomponents == 1) /* whew, all that work and we finally found an 8-bit image */
1070 found_8bit = TRUE;
1071 } /* end if */
1072 else
1073 {
1074 DFdifree(group_id);
1075 HGOTO_ERROR(DFE_GETELEM, FAIL);
1076 }
1077 } /* end if */
1078 else
1079 /* check for the image tag/ref */ if (elt_tag == DFTAG_CI || elt_tag == DFTAG_RI)
1080 { /* keep for later */
1081 rig_tag = elt_tag;
1082 rig_ref = elt_ref;
1083 } /* end if */
1084 } /* end while */
1085 if (found_8bit)
1086 { /* check for finding an 8-bit RIG */
1087 if ((uintn)rig_tag > (uintn)0 && (uintn)rig_ref > (uintn)0)
1088 { /* make certain we found an image */
1089 img_off[curr_image] = Hoffset(file_id, rig_tag, rig_ref); /* store offset */
1090 curr_image++;
1091 } /* end if */
1092 } /* end if */
1093 } /* end while */
1094
1095 /* go through the RI8s */
1096 find_tag = find_ref = 0;
1097 while (Hfind(file_id, DFTAG_RI8, DFREF_WILDCARD, &find_tag, &find_ref, &find_off, &find_len, DF_FORWARD) == SUCCEED)
1098 {
1099 img_off[curr_image] = find_off; /* store offset */
1100 curr_image++;
1101 } /* end while */
1102
1103 /* go through the CI8s */
1104 find_tag = find_ref = 0;
1105 while (Hfind(file_id, DFTAG_CI8, DFREF_WILDCARD, &find_tag, &find_ref, &find_off, &find_len, DF_FORWARD) == SUCCEED)
1106 {
1107 img_off[curr_image] = find_off; /* store offset */
1108 curr_image++;
1109 } /* end while */
1110
1111 nimages = curr_image; /* reset the number of images we really have */
1112 for (i = 1; i < curr_image; i++)
1113 { /* go through the images looking for duplicates */
1114 for (j = 0; j < i; j++)
1115 {
1116 if (img_off[i] == img_off[j])
1117 {
1118 nimages--; /* if duplicate found, decrement the number of images */
1119 img_off[j]=(-1); /* mark as used, so we don't count it too... */
1120 } /* end if */
1121 } /* end for */
1122 } /* end for */
1123
1124 HDfree(img_off); /* free offsets */
1125 if (Hclose(file_id) == FAIL)
1126 HGOTO_ERROR(DFE_CANTCLOSE, FAIL);
1127
1128 ret_value = nimages;
1129
1130 done:
1131 if(ret_value == FAIL)
1132 { /* Error condition cleanup */
1133
1134 } /* end if */
1135
1136 /* Normal function cleanup */
1137 return ret_value;
1138 } /* end DFR8nimages() */
1139
1140 /*--------------------------------------------------------------------------
1141 NAME
1142 DFR8readref -- Set ref of image to get next
1143 USAGE
1144 intn DFR8readref(char *filename, uint16 ref)
1145 char *filename; IN: filename to set read ref #
1146 uint16 ref; IN: ref# of next image to read
1147 RETURNS
1148 SUCCEED on success, FAIL on failure.
1149 DESCRIPTION
1150 Sets the reference # of the RIG to read from next.
1151 GLOBAL VARIABLES
1152 Refset, Newdata
1153 COMMENTS, BUGS, ASSUMPTIONS
1154 Checks if image with this ref exists.
1155 EXAMPLES
1156 REVISION LOG
1157 --------------------------------------------------------------------------*/
1158 intn
DFR8readref(const char * filename,uint16 ref)1159 DFR8readref(const char *filename, uint16 ref)
1160 {
1161 CONSTR(FUNC, "DFR8readref");
1162 int32 file_id=(-1);
1163 int32 aid;
1164 intn ret_value = SUCCEED;
1165
1166 HEclear();
1167
1168 /* Perform global, one-time initialization */
1169 if (library_terminate == FALSE)
1170 if(DFR8Istart()==FAIL)
1171 HGOTO_ERROR(DFE_CANTINIT, FAIL);
1172
1173 if ((file_id = DFR8Iopen(filename, DFACC_READ)) == FAIL)
1174 HGOTO_ERROR(DFE_BADOPEN, FAIL);
1175
1176 if ((aid = Hstartread(file_id, DFTAG_RIG, ref)) == FAIL
1177 && (aid = Hstartread(file_id, DFTAG_RI8, ref)) == FAIL
1178 && (aid = Hstartread(file_id, DFTAG_CI8, ref)) == FAIL)
1179 HGOTO_ERROR(DFE_NOMATCH, FAIL);
1180
1181 Refset = ref;
1182 Newdata = 0;
1183 Hendaccess(aid);
1184 ret_value = Hclose(file_id);
1185
1186 done:
1187 if(ret_value == FAIL)
1188 { /* Error condition cleanup */
1189 if(file_id!=(-1))
1190 Hclose(file_id);
1191
1192 } /* end if */
1193
1194 /* Normal function cleanup */
1195 return ret_value;
1196 } /* end DFR8readref() */
1197
1198 /*--------------------------------------------------------------------------
1199 NAME
1200 DFR8writeref -- Set ref of image to put next
1201 USAGE
1202 intn DFR8writeref(char *filename, uint16 ref)
1203 char *filename; IN: filename to set write ref #
1204 uint16 ref; IN: ref# of next image to write
1205 RETURNS
1206 SUCCEED on success, FAIL on failure.
1207 DESCRIPTION
1208 Sets the reference # of the RIG to write to next.
1209 GLOBAL VARIABLES
1210 Writeref
1211 COMMENTS, BUGS, ASSUMPTIONS
1212 EXAMPLES
1213 REVISION LOG
1214 --------------------------------------------------------------------------*/
1215 intn
DFR8writeref(const char * filename,uint16 ref)1216 DFR8writeref(const char *filename, uint16 ref)
1217 {
1218 CONSTR(FUNC, "DFR8writeref"); /* for HERROR */
1219 intn ret_value = SUCCEED;
1220
1221 HEclear();
1222
1223 /* Perform global, one-time initialization */
1224 if (library_terminate == FALSE)
1225 if(DFR8Istart()==FAIL)
1226 HGOTO_ERROR(DFE_CANTINIT, FAIL);
1227
1228 /* shut compiler up */
1229 filename = filename;
1230 Writeref = ref;
1231
1232 done:
1233 if(ret_value == FAIL)
1234 { /* Error condition cleanup */
1235
1236 } /* end if */
1237
1238 /* Normal function cleanup */
1239
1240 return ret_value;
1241 } /* end DFR8writeref() */
1242
1243 /*--------------------------------------------------------------------------
1244 NAME
1245 DFR8restart -- Restart reading/writing from beginning of file
1246 USAGE
1247 intn DFR8restart(void)
1248 RETURNS
1249 SUCCEED on success, FAIL on failure.
1250 DESCRIPTION
1251 Restarts reading and writing of RIGs from file from the beginning.
1252 GLOBAL VARIABLES
1253 Lastfile
1254 COMMENTS, BUGS, ASSUMPTIONS
1255 EXAMPLES
1256 REVISION LOG
1257 --------------------------------------------------------------------------*/
1258 intn
DFR8restart(void)1259 DFR8restart(void)
1260 {
1261 CONSTR(FUNC, "DFR8restart"); /* for HERROR */
1262 intn ret_value = SUCCEED;
1263
1264 /* Perform global, one-time initialization */
1265 if (library_terminate == FALSE)
1266 if(DFR8Istart()==FAIL)
1267 HGOTO_ERROR(DFE_CANTINIT, FAIL);
1268
1269 Lastfile[0] = '\0';
1270
1271 done:
1272 if(ret_value == FAIL)
1273 { /* Error condition cleanup */
1274
1275 } /* end if */
1276
1277 /* Normal function cleanup */
1278
1279 return ret_value;
1280 } /* end DFR8restart() */
1281
1282 /*--------------------------------------------------------------------------
1283 NAME
1284 DFR8lastref -- Return last ref # written or read
1285 USAGE
1286 uint16 DFR8lastref(void)
1287 RETURNS
1288 Ref # on success, 0 on failure.
1289 DESCRIPTION
1290 Returns the last ref # written to or read from.
1291 GLOBAL VARIABLES
1292 Lastref
1293 COMMENTS, BUGS, ASSUMPTIONS
1294 EXAMPLES
1295 REVISION LOG
1296 --------------------------------------------------------------------------*/
1297 uint16
DFR8lastref(void)1298 DFR8lastref(void)
1299 {
1300 CONSTR(FUNC, "DFR8lastref"); /* for HERROR */
1301 uint16 ret_value;
1302
1303 /* Perform global, one-time initialization */
1304 if (library_terminate == FALSE)
1305 if(DFR8Istart()==FAIL)
1306 HGOTO_ERROR(DFE_CANTINIT, 0);
1307
1308 ret_value = Lastref;
1309
1310 done:
1311 if(ret_value == 0) /* 0 is invalid ref */
1312 { /* Error condition cleanup */
1313
1314 } /* end if */
1315
1316 /* Normal function cleanup */
1317
1318 return ret_value;
1319 } /* end DFR8lastref() */
1320
1321 /*--------------------------------------------------------------------------
1322 * NAME
1323 * DFR8getpalref - get the reference number of the palette
1324 * DESCRIPTION
1325 * Convience function to get reference number of the palette of
1326 * last image. Must come after DFR8getdims() since it relies on
1327 * this call to fill the Readrig structure
1328 * RETURNS
1329 * SUCCEED.
1330 --------------------------------------------------------------------------*/
1331 intn
DFR8getpalref(uint16 * pal_ref)1332 DFR8getpalref(uint16 *pal_ref)
1333 {
1334 CONSTR(FUNC, "DFR8getpalref");
1335 intn ret_value = SUCCEED;
1336
1337 HEclear();
1338
1339 /* Perform global, one-time initialization */
1340 if (library_terminate == FALSE)
1341 if(DFR8Istart()==FAIL)
1342 HGOTO_ERROR(DFE_CANTINIT, FAIL);
1343
1344 *pal_ref = Readrig.lut.ref; /* ref of palette */
1345
1346 done:
1347 if(ret_value == FAIL)
1348 { /* Error condition cleanup */
1349
1350 } /* end if */
1351
1352 /* Normal function cleanup */
1353
1354 return ret_value;
1355 } /* end DFR8getpalref() */
1356
1357 /*************************************************************************/
1358 /*----------------------- Internal routines -----------------------------*/
1359 /*************************************************************************/
1360
1361 /*--------------------------------------------------------------------------
1362 NAME
1363 DFR8Iopen -- open or reopen a file
1364 USAGE
1365 int32 DFR8Iopen(filename, acc_mode)
1366 char *filename; IN: name of file to open
1367 intn acc_mode; IN: access mode to open file with
1368 RETURNS
1369 HDF file ID on success, FAIL on failure
1370 DESCRIPTION
1371 Used to open/reopen a file for the DFR8 interface.
1372 GLOBAL VARIABLES
1373 Lastfile, foundRig, Refset, Newdata, Readrig, Writerig, Newpalette
1374 COMMENTS, BUGS, ASSUMPTIONS
1375 This is a hook for someday providing more efficient ways to
1376 reopen a file, to avoid re-reading all the headers.
1377 EXAMPLES
1378 REVISION LOG
1379 --------------------------------------------------------------------------*/
1380 PRIVATE int32
DFR8Iopen(const char * filename,intn acc_mode)1381 DFR8Iopen(const char *filename, intn acc_mode)
1382 {
1383 CONSTR(FUNC, "DFR8Iopen");
1384 int32 file_id;
1385 int32 ret_value = SUCCEED;
1386
1387 /* use reopen if same file as last time - more efficient */
1388 if (HDstrncmp(Lastfile, filename, DF_MAXFNLEN) || (acc_mode == DFACC_CREATE))
1389 {
1390 /* treat create as different file */
1391 if ((file_id = Hopen(filename, acc_mode, 0)) == FAIL)
1392 HGOTO_ERROR(DFE_BADOPEN, FAIL);
1393 foundRig = -1; /* don't know if any RIGs in file */
1394 Refset = 0; /* no ref to get set for this file */
1395 Newdata = 0;
1396 Readrig = Zrig; /* blank out read/write RIGs */
1397 Writerig = Zrig;
1398 if (Newpalette != (-1))
1399 Newpalette = 1; /* need to write out palette */
1400 } /* end if */
1401 else
1402 {
1403 if ((file_id = Hopen(filename, acc_mode, 0)) == FAIL)
1404 HGOTO_ERROR(DFE_BADOPEN, FAIL);
1405 } /* end else */
1406
1407 /* remember filename, so reopen may be used next time if same file */
1408 HDstrncpy(Lastfile, filename, DF_MAXFNLEN);
1409
1410 ret_value = file_id;
1411
1412 done:
1413 if(ret_value == FAIL)
1414 { /* Error condition cleanup */
1415
1416 } /* end if */
1417
1418 /* Normal function cleanup */
1419
1420 return ret_value;
1421 } /* end DFR8Iopen() */
1422
1423 /*--------------------------------------------------------------------------
1424 NAME
1425 DFR8Iriginfo -- Get information about next RIG or RI8 in file
1426 USAGE
1427 intn DFR8Iriginfo(file_id)
1428 int32 file_id; IN: HDF file ID to read from
1429 RETURNS
1430 SUCCEED on success, FAIL on failure
1431 DESCRIPTION
1432 Reads in a RIGs structure into internal data structures, or if no RIGs
1433 are found, patches things together from RI8 information.
1434
1435 GLOBAL VARIABLES
1436
1437 COMMENTS, BUGS, ASSUMPTIONS
1438 if Refset is set, gets image with that ref, if any.
1439 EXAMPLES
1440 REVISION LOG
1441 --------------------------------------------------------------------------*/
1442 PRIVATE intn
DFR8Iriginfo(int32 file_id)1443 DFR8Iriginfo(int32 file_id)
1444 {
1445 CONSTR(FUNC, "DFR8Iriginfo");
1446 uint16 riref = 0, ciref = 0;
1447 int32 aid = FAIL;
1448 uint16 ref;
1449 uint8 R8tbuf[64];
1450 intn ret_value = SUCCEED;
1451
1452 HEclear();
1453 /* find next rig */
1454 if (foundRig)
1455 { /* either RIGs present or don't know */
1456 if (!Refset && Readrig.image.ref)
1457 aid = Hstartread(file_id, DFTAG_RIG, Readrig.image.ref);
1458 do
1459 {
1460 if (Refset)
1461 aid = Hstartread(file_id, DFTAG_RIG, Refset);
1462 else
1463 {
1464 if (!Readrig.image.ref)
1465 aid = Hstartread(file_id, DFTAG_RIG, DFREF_WILDCARD);
1466 else
1467 {
1468 if (aid != FAIL && Hnextread(aid, DFTAG_RIG, DFREF_WILDCARD,
1469 DF_CURRENT) == FAIL)
1470 {
1471 if(Hendaccess(aid)==FAIL)
1472 HGOTO_ERROR(DFE_CANTENDACCESS, FAIL);
1473 aid = FAIL;
1474 } /* end if */
1475 } /* end else */
1476 } /* end else */
1477 if (aid == FAIL)
1478 {
1479 if (foundRig == 1) /*RIGs present, but no more to return */
1480 HGOTO_ERROR(DFE_NOMATCH, FAIL);
1481 foundRig = 0; /* No RIGs present in file */
1482 } /* end if */
1483
1484 /* RIG found */
1485 if (aid != FAIL)
1486 {
1487 Hinquire(aid, (int32 *) NULL, (uint16 *) NULL, &ref,
1488 (int32 *) NULL, (int32 *) NULL, (int32 *) NULL,
1489 (int16 *) NULL, (int16 *) NULL);
1490 if (DFR8getrig(file_id, ref, &Readrig) == FAIL)
1491 {
1492 if (Refset || (HEvalue(1) != DFE_BADCALL))
1493 {
1494 Refset = 0;
1495 if(Hendaccess(aid)==FAIL)
1496 HGOTO_ERROR(DFE_CANTENDACCESS, FAIL);
1497 HGOTO_ERROR(DFE_BADRIG, FAIL);
1498 } /* end if */
1499 Readrig.image.ref = ref;
1500 } /* end if */
1501 else
1502 {
1503 foundRig = 1;
1504 Refset = 0;
1505 } /* end else */
1506 } /* end if */
1507 } while ((aid != FAIL) && (HEvalue(1) == DFE_BADCALL));
1508 if (aid != FAIL)
1509 if(Hendaccess(aid)==FAIL)
1510 HGOTO_ERROR(DFE_CANTENDACCESS, FAIL);
1511 } /* end if */
1512 if (Refset || !foundRig)
1513 { /* No RIGs present, look for RI8 and CI8 */
1514 /* look for Refset if DFR8ref called, else look for next ref */
1515 if (Refset)
1516 aid = Hstartread(file_id, DFTAG_RI8, Refset);
1517 else
1518 {
1519 if (Readrig.image.ref)
1520 {
1521 aid = Hstartread(file_id, DFTAG_RI8, Readrig.image.ref);
1522 if (aid != FAIL && Hnextread(aid, DFTAG_RI8, DFREF_WILDCARD,
1523 DF_CURRENT) == FAIL)
1524 {
1525 Hendaccess(aid);
1526 aid = FAIL;
1527 } /* end if */
1528 } /* end if */
1529 else
1530 aid = Hstartread(file_id, DFTAG_RI8, DFREF_WILDCARD);
1531 } /* end else */
1532 if (aid != FAIL)
1533 {
1534 Hinquire(aid, (int32 *) NULL, (uint16 *) NULL, &riref,
1535 (int32 *) NULL, (int32 *) NULL, (int32 *) NULL,
1536 (int16 *) NULL, (int16 *) NULL);
1537 if(Hendaccess(aid)==FAIL)
1538 HGOTO_ERROR(DFE_CANTENDACCESS, FAIL);
1539 } /* end if */
1540
1541 if (Refset)
1542 aid = Hstartread(file_id, DFTAG_CI8, Refset);
1543 else
1544 {
1545 if (Readrig.image.ref)
1546 {
1547 aid = Hstartread(file_id, DFTAG_CI8, Readrig.image.ref);
1548 if (aid != FAIL && Hnextread(aid, DFTAG_CI8, DFREF_WILDCARD,
1549 DF_CURRENT) == FAIL)
1550 {
1551 if(Hendaccess(aid)==FAIL)
1552 HGOTO_ERROR(DFE_CANTENDACCESS, FAIL);
1553 aid = FAIL;
1554 } /* end if */
1555 } /* end if */
1556 else
1557 aid = Hstartread(file_id, DFTAG_CI8, DFREF_WILDCARD);
1558 } /* end else */
1559 if (aid != FAIL)
1560 {
1561 Hinquire(aid, (int32 *) NULL, (uint16 *) NULL, &ciref,
1562 (int32 *) NULL, (int32 *) NULL, (int32 *) NULL,
1563 (int16 *) NULL, (int16 *) NULL);
1564 if(Hendaccess(aid)==FAIL)
1565 HGOTO_ERROR(DFE_CANTENDACCESS, FAIL);
1566 } /* end if */
1567
1568 Refset = 0;
1569 if (!riref && !ciref)
1570 HGOTO_ERROR(DFE_NOMATCH, FAIL);
1571 if ((!ciref) || (riref && (riref < ciref)))
1572 { /* next image is RI8 */
1573 Readrig.image.ref = riref;
1574 Readrig.image.tag = DFTAG_RI8;
1575 } /* end if */
1576 else
1577 { /* next image is CI8 */
1578 Readrig.image.ref = ciref;
1579 Readrig.image.tag = DFTAG_CI8;
1580 Readrig.descimage.compr.tag = DFTAG_RLE;
1581 } /* end else */
1582
1583 if (Hgetelement(file_id, DFTAG_ID8, Readrig.image.ref, R8tbuf) != FAIL)
1584 {
1585 uint8 *p;
1586 uint16 uint16var;
1587
1588 p = R8tbuf;
1589 UINT16DECODE(p, uint16var);
1590 Readrig.descimage.xdim=(int32)uint16var;
1591 UINT16DECODE(p, uint16var);
1592 Readrig.descimage.ydim=(int32)uint16var;
1593 } /* end if */
1594 else
1595 HGOTO_ERROR(DFE_GETELEM, FAIL);
1596
1597 if (Hexist(file_id, DFTAG_IP8, Readrig.image.ref) != FAIL)
1598 {
1599 Readrig.lut.tag = DFTAG_IP8;
1600 Readrig.lut.ref = Readrig.image.ref;
1601 } /* end if */
1602 } /* end if */
1603 Lastref = Readrig.image.ref; /* remember ref read */
1604
1605 done:
1606 if(ret_value == FAIL)
1607 { /* Error condition cleanup */
1608
1609 } /* end if */
1610
1611 /* Normal function cleanup */
1612
1613 return ret_value;
1614 } /* end DFR8Iriginfo() */
1615
1616 /*--------------------------------------------------------------------------
1617 NAME
1618 DFR8Istart
1619 PURPOSE
1620 DFR8-level initialization routine
1621 USAGE
1622 intn DFR8Istart()
1623 RETURNS
1624 Returns SUCCEED/FAIL
1625 DESCRIPTION
1626 Register the shut-down routine (DFR8Pshutdown) for call with atexit
1627 GLOBAL VARIABLES
1628 COMMENTS, BUGS, ASSUMPTIONS
1629 EXAMPLES
1630 REVISION LOG
1631 --------------------------------------------------------------------------*/
DFR8Istart(void)1632 PRIVATE intn DFR8Istart(void)
1633 {
1634 CONSTR(FUNC, "DFR8Istart"); /* for HERROR */
1635 intn ret_value = SUCCEED;
1636
1637 /* Don't call this routine again... */
1638 library_terminate = TRUE;
1639
1640 /* Install atexit() library cleanup routine */
1641 if (HPregister_term_func(&DFR8Pshutdown) != 0)
1642 HGOTO_ERROR(DFE_CANTINIT, FAIL);
1643
1644 done:
1645 if(ret_value == FAIL)
1646 { /* Error condition cleanup */
1647
1648 } /* end if */
1649
1650 /* Normal function cleanup */
1651 return(ret_value);
1652 } /* end DFR8Istart() */
1653
1654 /*--------------------------------------------------------------------------
1655 NAME
1656 DFR8Pshutdown
1657 PURPOSE
1658 Terminate various static buffers.
1659 USAGE
1660 intn DFR8shutdown()
1661 RETURNS
1662 Returns SUCCEED/FAIL
1663 DESCRIPTION
1664 Free various buffers allocated in the DFR8 routines.
1665 GLOBAL VARIABLES
1666 COMMENTS, BUGS, ASSUMPTIONS
1667 Should only ever be called by the "atexit" function HDFend
1668 EXAMPLES
1669 REVISION LOG
1670 --------------------------------------------------------------------------*/
DFR8Pshutdown(void)1671 intn DFR8Pshutdown(void)
1672 {
1673 if(paletteBuf!=NULL)
1674 {
1675 HDfree(paletteBuf);
1676 paletteBuf=NULL;
1677 } /* end if */
1678 return(SUCCEED);
1679 } /* end DFR8Pshutdown() */
1680
1681
1682