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