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 HDF5.  The full HDF5 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/HDF5/releases.  *
10  * If you do not have access to either file, you may request a copy from     *
11  * help@hdfgroup.org.                                                        *
12 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
13 
14 #include "H5IMprivate.h"
15 #include "H5LTprivate.h"
16 #include <string.h>
17 #include <stdlib.h>
18 
19 /*-------------------------------------------------------------------------
20 * Function: H5IMmake_image_8bit
21 *
22 * Purpose: Creates and writes an image an 8 bit image
23 *
24 * Return: Success: 0, Failure: -1
25 *
26 * Programmer: Pedro Vicente Nunes, pvn@ncsa.uiuc.edu
27 *
28 * Date: June 13, 2001
29 *
30 * Comments:
31 *  based on HDF5 Image and Palette Specification
32 *
33 * Modifications:
34 *
35 *-------------------------------------------------------------------------
36 */
37 
H5IMmake_image_8bit(hid_t loc_id,const char * dset_name,hsize_t width,hsize_t height,const unsigned char * buf)38 herr_t H5IMmake_image_8bit( hid_t loc_id,
39                            const char *dset_name,
40                            hsize_t width,
41                            hsize_t height,
42                            const unsigned char *buf )
43 {
44     hsize_t  dims[IMAGE8_RANK];
45 
46     /* check the arguments */
47     if (dset_name == NULL)
48         return -1;
49 
50     /* Initialize the image dimensions */
51     dims[0] = height;
52     dims[1] = width;
53 
54     /* Make the dataset */
55     if ( H5LTmake_dataset( loc_id, dset_name, IMAGE8_RANK, dims, H5T_NATIVE_UCHAR, buf ) < 0)
56         return -1;
57 
58     /* Attach the CLASS attribute */
59     if ( H5LTset_attribute_string( loc_id, dset_name, "CLASS", IMAGE_CLASS ) < 0)
60         return -1;
61 
62     /* Attach the VERSION attribute */
63     if ( H5LTset_attribute_string( loc_id, dset_name, "IMAGE_VERSION", IMAGE_VERSION ) < 0)
64         return -1;
65 
66     /* Attach the IMAGE_SUBCLASS attribute */
67     if ( H5LTset_attribute_string( loc_id, dset_name, "IMAGE_SUBCLASS", "IMAGE_INDEXED" ) < 0)
68         return -1;
69 
70     return 0;
71 }
72 
73 /*-------------------------------------------------------------------------
74 * Function: H5IMmake_image_24bit
75 *
76 * Purpose:
77 *
78 * Return: Success: 0, Failure: -1
79 *
80 * Programmer: Pedro Vicente Nunes, pvn@ncsa.uiuc.edu
81 *
82 * Date: June 13, 2001
83 *
84 * Comments:
85 *  based on HDF5 Image and Palette Specification
86 *
87 * Interlace Mode Dimensions in the Dataspace
88 * INTERLACE_PIXEL [height][width][pixel components]
89 * INTERLACE_PLANE [pixel components][height][width]
90 *
91 *
92 * Modifications:
93 *
94 *-------------------------------------------------------------------------
95 */
96 
H5IMmake_image_24bit(hid_t loc_id,const char * dset_name,hsize_t width,hsize_t height,const char * interlace,const unsigned char * buf)97 herr_t H5IMmake_image_24bit( hid_t loc_id,
98                             const char *dset_name,
99                             hsize_t width,
100                             hsize_t height,
101                             const char *interlace,
102                             const unsigned char *buf )
103 {
104     hsize_t  dims[IMAGE24_RANK];
105 
106     /* check the arguments */
107     if (interlace == NULL)
108         return -1;
109     if (dset_name == NULL)
110         return -1;
111 
112 
113     /* Initialize the image dimensions */
114 
115     if ( HDstrncmp( interlace, "INTERLACE_PIXEL",15 ) == 0 )
116     {
117         /* Number of color planes is defined as the third dimension */
118         dims[0] = height;
119         dims[1] = width;
120         dims[2] = IMAGE24_RANK;
121     }
122     else
123       if ( HDstrncmp( interlace, "INTERLACE_PLANE",15 ) == 0 )
124         {
125             /* Number of color planes is defined as the first dimension */
126             dims[0] = IMAGE24_RANK;
127             dims[1] = height;
128             dims[2] = width;
129         }
130         else return -1;
131 
132         /* Make the dataset */
133         if ( H5LTmake_dataset( loc_id, dset_name, IMAGE24_RANK, dims, H5T_NATIVE_UCHAR, buf ) < 0)
134             return -1;
135 
136         /* Attach the CLASS attribute */
137         if ( H5LTset_attribute_string( loc_id, dset_name, "CLASS", IMAGE_CLASS ) < 0)
138             return -1;
139 
140         /* Attach the VERSION attribute */
141         if ( H5LTset_attribute_string( loc_id, dset_name, "IMAGE_VERSION", IMAGE_VERSION ) < 0)
142             return -1;
143 
144         /* Attach the IMAGE_SUBCLASS attribute */
145         if ( H5LTset_attribute_string( loc_id, dset_name, "IMAGE_SUBCLASS", "IMAGE_TRUECOLOR" ) < 0)
146             return -1;
147 
148         /* Attach the INTERLACE_MODE attribute. This attributes is only for true color images */
149         if ( H5LTset_attribute_string( loc_id, dset_name, "INTERLACE_MODE", interlace ) < 0)
150             return -1;
151 
152         return 0;
153 
154 }
155 
156 
157 
158 /*-------------------------------------------------------------------------
159 * Function: find_palette
160 *
161 * Purpose: operator function used by H5LT_find_palette
162 *
163 * Return:
164 *
165 * Programmer: Pedro Vicente Nunes, pvn@ncsa.uiuc.edu
166 *
167 * Date: May 28, 2001
168 *
169 * Comments:
170 *
171 * Modifications:
172 *
173 *-------------------------------------------------------------------------
174 */
find_palette(hid_t loc_id,const char * name,const H5A_info_t * ainfo,void * op_data)175 static herr_t find_palette(hid_t loc_id,
176                            const char *name,
177                            const H5A_info_t *ainfo,
178                            void *op_data)
179 {
180     int ret = H5_ITER_CONT;
181 
182     /* check the arguments */
183     if (name == NULL)
184         return -1;
185 
186     /* Shut compiler up */
187     loc_id = loc_id; ainfo = ainfo; op_data = op_data;
188 
189     /* Define a positive value for return value if the attribute was found. This will
190     * cause the iterator to immediately return that positive value,
191     * indicating short-circuit success
192     */
193     if(HDstrncmp(name, "PALETTE",7) == 0)
194         ret = H5_ITER_STOP;
195 
196     return ret;
197 }
198 
199 
200 /*-------------------------------------------------------------------------
201 * Function: H5IM_find_palette
202 *
203 * Purpose: Private function. Find the attribute "PALETTE" in the image dataset
204 *
205 * Return: Success: 1, Failure: 0
206 *
207 * Programmer: Pedro Vicente Nunes, pvn@ncsa.uiuc.edu
208 *
209 * Date: May 11, 2001
210 *
211 * Comments:
212 *  The function uses H5Aiterate2 with the operator function find_palette
213 *
214 * Modifications:
215 *
216 *-------------------------------------------------------------------------
217 */
218 
H5IM_find_palette(hid_t loc_id)219 herr_t H5IM_find_palette( hid_t loc_id )
220 {
221     return H5Aiterate2(loc_id, H5_INDEX_NAME, H5_ITER_INC, NULL, find_palette, NULL);
222 }
223 
224 
225 /*-------------------------------------------------------------------------
226 * Function: H5IMget_image_info
227 *
228 * Purpose: Gets information about an image dataset (dimensions, interlace mode
229 *          and number of associated palettes).
230 *
231 * Return: Success: 0, Failure: -1
232 *
233 * Programmer: Pedro Vicente Nunes, pvn@ncsa.uiuc.edu
234 *
235 * Date: July 25, 2001
236 *
237 * Comments:
238 *  based on HDF5 Image and Palette Specification
239 *
240 * Modifications:
241 *
242 *-------------------------------------------------------------------------
243 */
244 
H5IMget_image_info(hid_t loc_id,const char * dset_name,hsize_t * width,hsize_t * height,hsize_t * planes,char * interlace,hssize_t * npals)245 herr_t H5IMget_image_info( hid_t loc_id,
246                           const char *dset_name,
247                           hsize_t *width,
248                           hsize_t *height,
249                           hsize_t *planes,
250                           char *interlace,
251                           hssize_t *npals )
252 {
253     hid_t       did                     = -1;
254     hid_t       sid                     = -1;
255     hsize_t     dims[IMAGE24_RANK];
256     hid_t       aid                     = -1;
257     hid_t       asid                    = -1;
258     hid_t       atid                    = -1;
259     H5T_class_t aclass;
260     int         has_pal;
261     int         has_attr;
262 
263     /* check the arguments */
264     if (dset_name == NULL)
265       return -1;
266     if (interlace == NULL)
267       return -1;
268 
269     /*assume initially we have no palettes attached*/
270     *npals = 0;
271 
272     /* Open the dataset. */
273     if((did = H5Dopen2(loc_id, dset_name, H5P_DEFAULT)) < 0)
274         return -1;
275 
276     /* Try to find the attribute "INTERLACE_MODE" on the >>image<< dataset */
277     has_attr = H5LT_find_attribute(did, "INTERLACE_MODE");
278 
279     /* It exists, get it */
280     if(has_attr == 1)
281     {
282 
283         if((aid = H5Aopen(did, "INTERLACE_MODE", H5P_DEFAULT)) < 0)
284             goto out;
285 
286         if((atid = H5Aget_type(aid)) < 0)
287             goto out;
288 
289         if(H5Aread(aid, atid, interlace) < 0)
290             goto out;
291 
292         if(H5Tclose(atid) < 0)
293             goto out;
294 
295         if(H5Aclose(aid) < 0)
296             goto out;
297     }
298 
299     /* Get the dataspace handle */
300     if ( (sid = H5Dget_space( did )) < 0)
301         goto out;
302 
303     /* Get dimensions */
304     if ( H5Sget_simple_extent_dims( sid, dims, NULL) < 0)
305         goto out;
306 
307     /* Initialize the image dimensions */
308 
309     if ( has_attr == 1 )
310         /* This is a 24 bit image */
311     {
312 
313       if ( HDstrncmp( interlace, "INTERLACE_PIXEL", 15 ) == 0 )
314         {
315             /* Number of color planes is defined as the third dimension */
316             *height = dims[0];
317             *width  = dims[1];
318             *planes = dims[2];
319         }
320         else
321 	  if ( HDstrncmp( interlace, "INTERLACE_PLANE", 15 ) == 0 )
322             {
323                 /* Number of color planes is defined as the first dimension */
324                 *planes = dims[0];
325                 *height = dims[1];
326                 *width  = dims[2];
327             }
328 	  else return -1;
329     }
330     else
331         /* This is a 8 bit image */
332     {
333         *height = dims[0];
334         *width  = dims[1];
335         *planes = 1;
336     }
337 
338     /* Close */
339     if ( H5Sclose( sid ) < 0)
340         goto out;
341 
342 
343     /* Get number of palettes */
344 
345 
346     /* Try to find the attribute "PALETTE" on the >>image<< dataset */
347     has_pal = H5IM_find_palette(did);
348 
349     if(has_pal ==  1)
350     {
351 
352         if((aid = H5Aopen(did, "PALETTE", H5P_DEFAULT)) < 0)
353             goto out;
354 
355         if((atid = H5Aget_type(aid)) < 0)
356             goto out;
357 
358         if((aclass = H5Tget_class(atid)) < 0)
359             goto out;
360 
361         /* Check if it is really a reference */
362 
363         if(aclass == H5T_REFERENCE)
364         {
365 
366             /* Get the reference(s) */
367 
368             if ( (asid = H5Aget_space( aid )) < 0)
369                 goto out;
370 
371             *npals = H5Sget_simple_extent_npoints( asid );
372 
373             if ( H5Sclose( asid ) < 0)
374                 goto out;
375 
376         } /* H5T_REFERENCE */
377 
378         if ( H5Tclose( atid ) < 0)
379             goto out;
380 
381         /* Close the attribute. */
382         if ( H5Aclose( aid ) < 0)
383             goto out;
384 
385     }
386 
387     /* End access to the dataset and release resources used by it. */
388     if ( H5Dclose( did ) < 0)
389         goto out;
390 
391     return 0;
392 
393 out:
394     if(did > 0)
395         H5Dclose( did );
396     if(aid > 0)
397         H5Aclose( aid );
398     if(asid > 0)
399         H5Sclose( asid );
400     if(atid > 0)
401         H5Tclose( atid );
402     return -1;
403 
404 }
405 
406 
407 /*-------------------------------------------------------------------------
408 * Function: H5IMread_image
409 *
410 * Purpose: Reads image data from disk.
411 *
412 * Return: Success: 0, Failure: -1
413 *
414 * Programmer: Pedro Vicente Nunes, pvn@ncsa.uiuc.edu
415 *
416 * Date: June 13, 2001
417 *
418 * Comments:
419 *  based on HDF5 Image and Palette Specification
420 *
421 * Modifications:
422 *
423 *-------------------------------------------------------------------------
424 */
425 
H5IMread_image(hid_t loc_id,const char * dset_name,unsigned char * buf)426 herr_t H5IMread_image( hid_t loc_id,
427                        const char *dset_name,
428                        unsigned char *buf )
429 {
430     hid_t   did;
431 
432     /* check the arguments */
433     if (dset_name == NULL)
434       return -1;
435 
436     /* Open the dataset. */
437     if((did = H5Dopen2(loc_id, dset_name, H5P_DEFAULT)) < 0)
438         return -1;
439 
440     /* Read */
441     if ( H5Dread( did, H5T_NATIVE_UCHAR, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf ) < 0)
442         goto out;
443 
444     /* End access to the dataset and release resources used by it. */
445     if ( H5Dclose( did ) )
446         return -1;
447 
448     return 0;
449 
450 out:
451     H5Dclose( did );
452     return -1;
453 
454 }
455 
456 
457 /*-------------------------------------------------------------------------
458 * Function: H5IMmake_palette
459 *
460 * Purpose: Creates and writes a palette.
461 *
462 * Return: Success: 0, Failure: -1
463 *
464 * Programmer: Pedro Vicente Nunes, pvn@ncsa.uiuc.edu
465 *
466 * Date: May 01, 2001
467 *
468 * Comments:
469 *  based on HDF5 Image and Palette Specification
470 *
471 * Modifications:
472 *
473 *-------------------------------------------------------------------------
474 */
475 
H5IMmake_palette(hid_t loc_id,const char * pal_name,const hsize_t * pal_dims,const unsigned char * pal_data)476 herr_t H5IMmake_palette( hid_t loc_id,
477                         const char *pal_name,
478                         const hsize_t *pal_dims,
479                         const unsigned char *pal_data )
480 
481 {
482 
483     int has_pal;
484 
485     /* check the arguments */
486     if (pal_name == NULL)
487       return -1;
488 
489     /* Check if the dataset already exists */
490     has_pal = H5LTfind_dataset( loc_id, pal_name );
491 
492     /* It exists. Return */
493     if ( has_pal == 1 )
494         return 0;
495 
496     /* Make the palette dataset. */
497     if ( H5LTmake_dataset( loc_id, pal_name, 2, pal_dims, H5T_NATIVE_UCHAR, pal_data ) <  0 )
498         return -1;
499 
500     /* Attach the attribute "CLASS" to the >>palette<< dataset*/
501     if ( H5LTset_attribute_string( loc_id, pal_name, "CLASS", PALETTE_CLASS ) < 0)
502         return -1;
503 
504     /* Attach the attribute "PAL_VERSION" to the >>palette<< dataset*/
505     if ( H5LTset_attribute_string( loc_id, pal_name, "PAL_VERSION", "1.2" ) < 0)
506         return -1;
507 
508     return 0;
509 
510 }
511 
512 
513 /*-------------------------------------------------------------------------
514 * Function: H5IMlink_palette
515 *
516 * Purpose: This function attaches a palette to an existing image dataset
517 *
518 * Return: Success: 0, Failure: -1
519 *
520 * Programmer: Pedro Vicente Nunes, pvn@ncsa.uiuc.edu
521 *
522 * Date: May 01, 2001
523 *
524 * Comments:
525 *  based on HDF5 Image and Palette Specification
526 *
527 *  An image (dataset) within an HDF5 file may optionally specify an array of
528 *  palettes to be viewed with. The dataset will have an attribute
529 *  which contains an array of object reference pointers which refer to palettes in the file.
530 *
531 * Modifications:
532 *
533 *-------------------------------------------------------------------------
534 */
535 
H5IMlink_palette(hid_t loc_id,const char * image_name,const char * pal_name)536 herr_t H5IMlink_palette( hid_t loc_id,
537                         const char *image_name,
538                         const char *pal_name )
539 
540 {
541     hid_t       did;
542     hid_t       atid=-1;
543     hid_t       aid=-1;
544     hid_t       asid=-1;
545     hobj_ref_t  ref;         /* write a new reference */
546     hobj_ref_t  *refbuf;     /* buffer to read references */
547     hssize_t    n_refs;
548     hsize_t     dim_ref;
549     int         ok_pal;
550 
551 
552     /* check the arguments */
553     if (image_name == NULL)
554       return -1;
555     if (pal_name == NULL)
556       return -1;
557 
558     /* The image dataset may or may not have the attribute "PALETTE"
559     * First we try to open to see if it is already there; if not, it is created.
560     * If it exists, the array of references is extended to hold the reference
561     * to the new palette
562     */
563 
564     /* First we get the image id */
565     if((did = H5Dopen2(loc_id, image_name, H5P_DEFAULT)) < 0)
566         return -1;
567 
568     /* Try to find the attribute "PALETTE" on the >>image<< dataset */
569     ok_pal = H5LT_find_attribute( did, "PALETTE" );
570 
571     /*-------------------------------------------------------------------------
572     * It does not exist. We create the attribute and one reference
573     *-------------------------------------------------------------------------
574     */
575     if(ok_pal == 0 )
576     {
577         if((asid = H5Screate(H5S_SCALAR)) < 0)
578             goto out;
579 
580         /* Create the attribute type for the reference */
581         if((atid = H5Tcopy(H5T_STD_REF_OBJ)) < 0)
582             goto out;
583 
584         /* Create the attribute "PALETTE" to be attached to the image*/
585         if((aid = H5Acreate2(did, "PALETTE", atid, asid, H5P_DEFAULT, H5P_DEFAULT)) < 0)
586             goto out;
587 
588         /* Create a reference. The reference is created on the local id.  */
589         if(H5Rcreate(&ref, loc_id, pal_name, H5R_OBJECT, (hid_t)-1) < 0)
590             goto out;
591 
592         /* Write the attribute with the reference */
593         if(H5Awrite(aid, atid, &ref) < 0)
594             goto out;
595 
596         /* close */
597         if(H5Sclose(asid) < 0)
598             goto out;
599         if(H5Tclose(atid) < 0)
600             goto out;
601         if(H5Aclose(aid) < 0)
602             goto out;
603 
604     }
605 
606     /*-------------------------------------------------------------------------
607     * The attribute already exists, open it
608     *-------------------------------------------------------------------------
609     */
610     else if(ok_pal ==  1)
611     {
612         if((aid = H5Aopen(did, "PALETTE", H5P_DEFAULT)) < 0)
613             goto out;
614 
615         if((atid = H5Aget_type(aid)) < 0)
616             goto out;
617 
618         if(H5Tget_class(atid) < 0)
619             goto out;
620 
621         /* Get and save the old reference(s) */
622         if((asid = H5Aget_space(aid)) < 0)
623             goto out;
624 
625         n_refs = H5Sget_simple_extent_npoints(asid);
626 
627         dim_ref = (hsize_t)n_refs + 1;
628 
629         refbuf = (hobj_ref_t*)HDmalloc( sizeof(hobj_ref_t) * (size_t)dim_ref );
630 
631         if ( H5Aread( aid, atid, refbuf ) < 0)
632             goto out;
633 
634         /* The attribute must be deleted, in order to the new one can reflect the changes*/
635         if(H5Adelete(did, "PALETTE") < 0)
636             goto out;
637 
638         /* Create a new reference for this palette. */
639         if ( H5Rcreate( &ref, loc_id, pal_name, H5R_OBJECT, (hid_t)-1 ) < 0)
640             goto out;
641 
642         refbuf[n_refs] = ref;
643 
644         /* Create the data space for the new references */
645         if(H5Sclose(asid) < 0)
646             goto out;
647 
648         if((asid = H5Screate_simple(1, &dim_ref, NULL)) < 0)
649             goto out;
650 
651         /* Create the attribute again with the changes of space */
652         if(H5Aclose(aid) < 0)
653             goto out;
654 
655         if((aid = H5Acreate2(did, "PALETTE", atid, asid, H5P_DEFAULT, H5P_DEFAULT)) < 0)
656             goto out;
657 
658         /* Write the attribute with the new references */
659         if(H5Awrite(aid, atid, refbuf) < 0)
660             goto out;
661 
662         /* close */
663         if(H5Sclose(asid) < 0)
664             goto out;
665         if(H5Tclose(atid) < 0)
666             goto out;
667         if(H5Aclose(aid) < 0)
668             goto out;
669 
670         HDfree( refbuf );
671 
672     } /* ok_pal ==  1 */
673 
674     /* Close the image dataset. */
675     if ( H5Dclose( did ) < 0)
676         return -1;
677 
678     return 0;
679 
680 out:
681     H5Dclose( did );
682     H5Sclose( asid );
683     H5Tclose( atid );
684     H5Aclose( aid );
685     return -1;
686 }
687 
688 
689 
690 /*-------------------------------------------------------------------------
691 * Function: H5IMunlink_palette
692 *
693 * Purpose: This function dettaches a palette from an existing image dataset
694 *
695 * Return: Success: 0, Failure: -1
696 *
697 * Programmer: Pedro Vicente Nunes, pvn@ncsa.uiuc.edu
698 *
699 * Date: September 10, 2001
700 *
701 * Comments:
702 *  based on HDF5 Image and Palette Specification
703 *
704 * Modifications:
705 *
706 *-------------------------------------------------------------------------
707 */
708 
H5IMunlink_palette(hid_t loc_id,const char * image_name,const char * pal_name)709 herr_t H5IMunlink_palette( hid_t loc_id,
710                           const char *image_name,
711                           const char *pal_name )
712 {
713     hid_t       did;
714     hid_t       atid;
715     hid_t       aid;
716     H5T_class_t aclass;
717     int         ok_pal, has_pal;
718 
719     /* check the arguments */
720     if(image_name == NULL)
721       return -1;
722     if(pal_name == NULL)
723       return -1;
724 
725     /* Try to find the palette dataset */
726     has_pal = H5LTfind_dataset( loc_id, pal_name );
727 
728     /* It does not exist. Return */
729     if ( has_pal == 0 )
730         return -1;
731 
732     /* The image dataset may or not have the attribute "PALETTE"
733     * First we try to open to see if it is already there; if not, it is created.
734     * If it exists, the array of references is extended to hold the reference
735     * to the new palette
736     */
737 
738     /* First we get the image id */
739     if((did = H5Dopen2(loc_id, image_name, H5P_DEFAULT)) < 0)
740         return -1;
741 
742     /* Try to find the attribute "PALETTE" on the >>image<< dataset */
743     ok_pal = H5LT_find_attribute(did, "PALETTE");
744 
745     /* It does not exist. Nothing to do */
746     if(ok_pal == 0)
747         return -1;
748 
749     /* The attribute exists, open it */
750     else if(ok_pal ==  1)
751     {
752         if((aid = H5Aopen(did, "PALETTE", H5P_DEFAULT)) < 0)
753             goto out;
754 
755         if((atid = H5Aget_type(aid)) < 0)
756             goto out;
757 
758         if((aclass = H5Tget_class(atid)) < 0)
759             goto out;
760 
761         /* Check if it is really a reference */
762         if(aclass == H5T_REFERENCE)
763         {
764             /* Delete the attribute */
765             if(H5Adelete(did, "PALETTE") < 0)
766                 goto out;
767 
768         }  /* H5T_REFERENCE */
769 
770         if(H5Tclose(atid) < 0)
771             goto out;
772 
773         /* Close the attribute. */
774         if(H5Aclose(aid) < 0)
775             goto out;
776 
777     } /* ok_pal */
778 
779     /* Close the image dataset. */
780     if(H5Dclose(did) < 0)
781         return -1;
782 
783     return 0;
784 
785 out:
786     H5Dclose( did );
787     return -1;
788 }
789 
790 
791 /*-------------------------------------------------------------------------
792 * Function: H5IMget_npalettes
793 *
794 * Purpose: Gets the number of palettes associated to an image
795 *
796 * Return: Success: 0, Failure: -1
797 *
798 * Programmer: Pedro Vicente Nunes, pvn@ncsa.uiuc.edu
799 *
800 * Date: July 22, 2001
801 *
802 * Comments:
803 *
804 * Modifications:
805 *
806 *-------------------------------------------------------------------------
807 */
808 
H5IMget_npalettes(hid_t loc_id,const char * image_name,hssize_t * npals)809 herr_t H5IMget_npalettes( hid_t loc_id,
810                          const char *image_name,
811                          hssize_t *npals )
812 {
813     hid_t       did;
814     hid_t       atid;
815     hid_t       aid;
816     hid_t       asid;
817     H5T_class_t aclass;
818     int         has_pal;
819 
820     /* check the arguments */
821     if(image_name == NULL)
822       return -1;
823 
824     /*assume initially we have no palettes attached*/
825     *npals = 0;
826 
827     /* Open the dataset. */
828     if((did = H5Dopen2(loc_id, image_name, H5P_DEFAULT)) < 0)
829         return -1;
830 
831     /* Try to find the attribute "PALETTE" on the >>image<< dataset */
832     has_pal = H5IM_find_palette(did);
833 
834     if(has_pal ==  1 )
835     {
836 
837         if((aid = H5Aopen(did, "PALETTE", H5P_DEFAULT)) < 0)
838             goto out;
839 
840         if((atid = H5Aget_type(aid)) < 0)
841             goto out;
842 
843         if((aclass = H5Tget_class(atid)) < 0)
844             goto out;
845 
846         /* Check if it is really a reference */
847 
848         if(aclass == H5T_REFERENCE)
849         {
850             if((asid = H5Aget_space(aid)) < 0)
851                 goto out;
852 
853             *npals = H5Sget_simple_extent_npoints( asid );
854 
855             if ( H5Sclose( asid ) < 0)
856                 goto out;
857 
858         } /* H5T_REFERENCE */
859 
860         if ( H5Tclose( atid ) < 0)
861             goto out;
862 
863         /* Close the attribute. */
864         if ( H5Aclose( aid ) < 0)
865             goto out;
866 
867     }
868 
869     /* Close the image dataset. */
870     if ( H5Dclose( did ) < 0)
871         return -1;
872 
873     return 0;
874 
875 out:
876     H5Dclose( did );
877     return -1;
878 
879 }
880 
881 
882 /*-------------------------------------------------------------------------
883 * Function: H5IMget_palette_info
884 *
885 * Purpose: Get palette information
886 *
887 * Return: Success: 0, Failure: -1
888 *
889 * Programmer: Pedro Vicente Nunes, pvn@ncsa.uiuc.edu
890 *
891 * Date: July 22, 2001
892 *
893 * Comments:
894 *  based on HDF5 Image and Palette Specification
895 *
896 * Modifications:
897 *
898 *-------------------------------------------------------------------------
899 */
900 
H5IMget_palette_info(hid_t loc_id,const char * image_name,int pal_number,hsize_t * pal_dims)901 herr_t H5IMget_palette_info( hid_t loc_id,
902                             const char *image_name,
903                             int pal_number,
904                             hsize_t *pal_dims )
905 {
906     hid_t      did;
907     int        has_pal;
908     hid_t      atid=-1;
909     hid_t      aid;
910     hid_t      asid=-1;
911     hssize_t   n_refs;
912     hsize_t    dim_ref;
913     hobj_ref_t *refbuf;     /* buffer to read references */
914     hid_t      pal_id;
915     hid_t      pal_space_id;
916     hsize_t    pal_maxdims[2];
917 
918     /* check the arguments */
919     if (image_name == NULL)
920       return -1;
921 
922     /* Open the dataset. */
923     if((did = H5Dopen2(loc_id, image_name, H5P_DEFAULT)) < 0)
924         return -1;
925 
926     /* Try to find the attribute "PALETTE" on the >>image<< dataset */
927     has_pal = H5IM_find_palette(did);
928 
929     if(has_pal ==  1)
930     {
931         if((aid = H5Aopen(did, "PALETTE", H5P_DEFAULT)) < 0)
932             goto out;
933 
934         if((atid = H5Aget_type(aid)) < 0)
935             goto out;
936 
937         if(H5Tget_class(atid) < 0)
938             goto out;
939 
940         /* Get the reference(s) */
941         if((asid = H5Aget_space(aid)) < 0)
942             goto out;
943 
944         n_refs = H5Sget_simple_extent_npoints(asid);
945 
946         dim_ref = (hsize_t)n_refs;
947 
948         refbuf = (hobj_ref_t*)HDmalloc( sizeof(hobj_ref_t) * (size_t)dim_ref );
949 
950         if ( H5Aread( aid, atid, refbuf ) < 0)
951             goto out;
952 
953         /* Get the actual palette */
954         if ( (pal_id = H5Rdereference2(did, H5P_DEFAULT, H5R_OBJECT, &refbuf[pal_number])) < 0)
955             goto out;
956 
957         if ( (pal_space_id = H5Dget_space( pal_id )) < 0)
958             goto out;
959 
960         if ( H5Sget_simple_extent_ndims( pal_space_id ) < 0)
961             goto out;
962 
963         if ( H5Sget_simple_extent_dims( pal_space_id, pal_dims, pal_maxdims ) < 0)
964             goto out;
965 
966         /* close */
967         if (H5Dclose(pal_id)<0)
968             goto out;
969         if ( H5Sclose( pal_space_id ) < 0)
970             goto out;
971         if ( H5Sclose( asid ) < 0)
972             goto out;
973         if ( H5Tclose( atid ) < 0)
974             goto out;
975         if ( H5Aclose( aid ) < 0)
976             goto out;
977         HDfree( refbuf );
978 
979 
980     }
981 
982     /* Close the image dataset. */
983     if ( H5Dclose( did ) < 0)
984         return -1;
985 
986     return 0;
987 
988 out:
989     H5Dclose( did );
990     H5Sclose( asid );
991     H5Tclose( atid );
992     H5Aclose( aid );
993     return -1;
994 
995 }
996 
997 
998 /*-------------------------------------------------------------------------
999 * Function: H5IMget_palette
1000 *
1001 * Purpose: Read palette
1002 *
1003 * Return: Success: 0, Failure: -1
1004 *
1005 * Programmer: Pedro Vicente Nunes, pvn@ncsa.uiuc.edu
1006 *
1007 * Date: August 30, 2001
1008 *
1009 * Comments:
1010 *  based on HDF5 Image and Palette Specification
1011 *
1012 * Modifications:
1013 *
1014 *-------------------------------------------------------------------------
1015 */
1016 
H5IMget_palette(hid_t loc_id,const char * image_name,int pal_number,unsigned char * pal_data)1017 herr_t H5IMget_palette( hid_t loc_id,
1018                        const char *image_name,
1019                        int pal_number,
1020                        unsigned char *pal_data )
1021 {
1022     hid_t      did;
1023     int        has_pal;
1024     hid_t      atid=-1;
1025     hid_t      aid;
1026     hid_t      asid=-1;
1027     hssize_t   n_refs;
1028     hsize_t    dim_ref;
1029     hobj_ref_t *refbuf;     /* buffer to read references */
1030     hid_t      pal_id;
1031 
1032     /* check the arguments */
1033     if (image_name == NULL)
1034       return -1;
1035     if (pal_data == NULL)
1036       return -1;
1037 
1038 
1039     /* Open the dataset. */
1040     if((did = H5Dopen2(loc_id, image_name, H5P_DEFAULT)) < 0)
1041         return -1;
1042 
1043     /* Try to find the attribute "PALETTE" on the >>image<< dataset */
1044     has_pal = H5IM_find_palette(did);
1045 
1046     if(has_pal ==  1 )
1047     {
1048         if((aid = H5Aopen(did, "PALETTE", H5P_DEFAULT)) < 0)
1049             goto out;
1050 
1051         if((atid = H5Aget_type(aid)) < 0)
1052             goto out;
1053 
1054         if(H5Tget_class(atid) < 0)
1055             goto out;
1056 
1057         /* Get the reference(s) */
1058         if((asid = H5Aget_space(aid)) < 0)
1059             goto out;
1060 
1061         n_refs = H5Sget_simple_extent_npoints(asid);
1062 
1063         dim_ref = (hsize_t)n_refs;
1064 
1065         refbuf = (hobj_ref_t*)HDmalloc( sizeof(hobj_ref_t) * (size_t)dim_ref );
1066 
1067         if ( H5Aread( aid, atid, refbuf ) < 0)
1068             goto out;
1069 
1070         /* Get the palette id */
1071         if ( (pal_id = H5Rdereference2(did, H5P_DEFAULT, H5R_OBJECT, &refbuf[pal_number])) < 0)
1072             goto out;
1073 
1074         /* Read the palette dataset */
1075         if ( H5Dread( pal_id, H5Dget_type(pal_id), H5S_ALL, H5S_ALL, H5P_DEFAULT, pal_data ) < 0)
1076             goto out;
1077 
1078         /* close */
1079         if (H5Dclose(pal_id)<0)
1080             goto out;
1081         if ( H5Sclose( asid ) < 0)
1082             goto out;
1083         if ( H5Tclose( atid ) < 0)
1084             goto out;
1085         if ( H5Aclose( aid ) < 0)
1086             goto out;
1087         HDfree( refbuf );
1088     }
1089 
1090     /* Close the image dataset. */
1091     if ( H5Dclose( did ) < 0)
1092         return -1;
1093 
1094     return 0;
1095 
1096 out:
1097     H5Dclose( did );
1098     H5Sclose( asid );
1099     H5Tclose( atid );
1100     H5Aclose( aid );
1101     return -1;
1102 
1103 }
1104 
1105 /*-------------------------------------------------------------------------
1106 * Function: H5IMis_image
1107 *
1108 * Purpose:
1109 *
1110 * Return: true, false, fail
1111 *
1112 * Programmer: Pedro Vicente Nunes, pvn@ncsa.uiuc.edu
1113 *
1114 * Date: August 30, 2001
1115 *
1116 * Comments:
1117 *  based on HDF5 Image and Palette Specification
1118 *
1119 * Modifications:
1120 *
1121 *-------------------------------------------------------------------------
1122 */
1123 
H5IMis_image(hid_t loc_id,const char * dset_name)1124 herr_t H5IMis_image( hid_t loc_id,
1125                     const char *dset_name )
1126 {
1127     hid_t      did;
1128     int        has_class;
1129     hid_t      atid;
1130     hid_t      aid = -1;
1131     char*      attr_data;    /* Name of attribute */
1132     hsize_t    storage_size; /* Size of storage for attribute */
1133     herr_t     ret;
1134 
1135     /* check the arguments */
1136     if (dset_name == NULL)
1137       return -1;
1138 
1139     /* Assume initially fail condition */
1140     ret = -1;
1141 
1142     /* Open the dataset. */
1143     if((did = H5Dopen2(loc_id, dset_name, H5P_DEFAULT)) < 0)
1144         return -1;
1145 
1146     /* Try to find the attribute "CLASS" on the dataset */
1147     has_class = H5LT_find_attribute(did, "CLASS");
1148 
1149     if(has_class == 0)
1150     {
1151         H5Dclose(did);
1152         return 0;
1153     }
1154     else if(has_class ==  1)
1155     {
1156 
1157         if((aid = H5Aopen(did, "CLASS", H5P_DEFAULT)) < 0)
1158             goto out;
1159 
1160         if((atid = H5Aget_type(aid)) < 0)
1161             goto out;
1162 
1163 	/* check to make sure attribute is a string */
1164 	if(H5T_STRING != H5Tget_class(atid))
1165 	    goto out;
1166 
1167 	/* check to make sure string is null-terminated */
1168 	if(H5T_STR_NULLTERM != H5Tget_strpad(atid))
1169 	    goto out;
1170 
1171 	/* allocate buffer large enough to hold string */
1172 	if((storage_size = H5Aget_storage_size(aid)) == 0)
1173 	    goto out;
1174 
1175 	attr_data = (char*)HDmalloc( (size_t)storage_size * sizeof(char) + 1);
1176 	if(attr_data == NULL)
1177 	    goto out;
1178 
1179         if(H5Aread(aid, atid, attr_data) < 0)
1180             goto out;
1181 
1182         if(HDstrncmp(attr_data, IMAGE_CLASS, MIN(HDstrlen(IMAGE_CLASS),HDstrlen(attr_data))) == 0)
1183             ret = 1;
1184         else
1185             ret = 0;
1186 
1187 	HDfree(attr_data);
1188 
1189         if ( H5Tclose( atid ) < 0)
1190             goto out;
1191 
1192         if ( H5Aclose( aid ) < 0)
1193             goto out;
1194 
1195     }
1196 
1197     /* Close the dataset. */
1198     if ( H5Dclose( did ) < 0)
1199         return -1;
1200 
1201     return ret;
1202 
1203 out:
1204     H5Dclose( did );
1205     return -1;
1206 
1207 }
1208 
1209 /*-------------------------------------------------------------------------
1210 * Function: H5IMis_palette
1211 *
1212 * Purpose:
1213 *
1214 * Return: true, false, fail
1215 *
1216 * Programmer: Pedro Vicente Nunes, pvn@ncsa.uiuc.edu
1217 *
1218 * Date: August 30, 2001
1219 *
1220 * Comments:
1221 *  based on HDF5 Image and Palette Specification
1222 *
1223 * Modifications:
1224 *
1225 *-------------------------------------------------------------------------
1226 */
1227 
H5IMis_palette(hid_t loc_id,const char * dset_name)1228 herr_t H5IMis_palette( hid_t loc_id,
1229                       const char *dset_name )
1230 {
1231     hid_t      did;
1232     int        has_class;
1233     hid_t      atid;
1234     hid_t      aid = -1;
1235     char*      attr_data;    /* Name of attribute */
1236     hsize_t    storage_size; /* Size of storage for attribute */
1237     herr_t     ret;
1238 
1239     /* check the arguments */
1240     if (dset_name == NULL)
1241       return -1;
1242 
1243     /* Assume initially fail condition */
1244     ret = -1;
1245 
1246     /* Open the dataset. */
1247     if((did = H5Dopen2(loc_id, dset_name, H5P_DEFAULT)) < 0)
1248         return -1;
1249 
1250     /* Try to find the attribute "CLASS" on the dataset */
1251     has_class = H5LT_find_attribute(did, "CLASS");
1252 
1253     if(has_class ==  0)
1254     {
1255         H5Dclose( did );
1256         return 0;
1257     }
1258     else if(has_class ==  1)
1259     {
1260 
1261         if((aid = H5Aopen(did, "CLASS", H5P_DEFAULT)) < 0)
1262             goto out;
1263 
1264         if((atid = H5Aget_type(aid)) < 0)
1265             goto out;
1266 
1267 	/* check to make sure attribute is a string */
1268 	if(H5T_STRING != H5Tget_class(atid))
1269 	    goto out;
1270 
1271 	/* check to make sure string is null-terminated */
1272 	if(H5T_STR_NULLTERM != H5Tget_strpad(atid))
1273 	    goto out;
1274 
1275 	/* allocate buffer large enough to hold string */
1276 	if((storage_size = H5Aget_storage_size(aid)) == 0)
1277 	    goto out;
1278 
1279 	attr_data = (char*)HDmalloc( (size_t)storage_size * sizeof(char) + 1);
1280 	if(attr_data == NULL)
1281 	    goto out;
1282 
1283         if(H5Aread(aid, atid, attr_data) < 0)
1284             goto out;
1285 
1286         if(HDstrncmp(attr_data, PALETTE_CLASS, MIN(HDstrlen(PALETTE_CLASS),HDstrlen(attr_data))) == 0)
1287             ret = 1;
1288         else
1289             ret = 0;
1290 
1291 	HDfree(attr_data);
1292 
1293         if ( H5Tclose( atid ) < 0)
1294             goto out;
1295 
1296         if ( H5Aclose( aid ) < 0)
1297             goto out;
1298 
1299     }
1300 
1301     /* Close the dataset. */
1302     if ( H5Dclose( did ) < 0)
1303         return -1;
1304 
1305     return ret;
1306 
1307 out:
1308     H5Dclose( did );
1309     return -1;
1310 
1311 }
1312 
1313