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