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