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 #include "hdf.h"
15 #include "mfhdf.h"
16 #include "hcomp.h"
17 #include "pal_rgb.h"
18 
19 #if defined (H4_HAVE_LIBSZ)
20 #include "szlib.h"
21 #endif
22 
23 #define HREPACK_FILE1         "hrepacktst1.hdf"
24 #define HREPACK_FILE1_OUT     "hrepacktst1_out.hdf"
25 #define HREPACK_FILE2         "hrepacktst2.hdf"
26 #define HREPACK_FILE2_OUT     "hrepacktst2_out.hdf"
27 #define HREPACK_FILE3         "hrepacktst3.hdf"
28 #define HREPACK_FILE3_OUT     "hrepacktst3_out.hdf"
29 #define DATA_FILE1            "image8.txt"
30 #define DATA_FILE2            "image24pixel.txt"
31 #define DATA_FILE3            "image24plane.txt"
32 #define TAG_GRP_IMAGE DFTAG_RIG
33 #define TAG_GRP_DSET  DFTAG_NDG
34 
35 #define TESTING(WHAT) {printf("%-70s", "Testing " WHAT); fflush(stdout); }
36 #define PASSED() {puts(" PASSED");fflush(stdout);}
37 #define SKIPPED() {puts(" SKIPPED");fflush(stdout);}
38 #define H4_FAILED() {puts("*FAILED*");fflush(stdout);}
39 
40 /* AN labels */
41 #define  FILE_LABEL_TXT "This is a file label"
42 #define  FILE_DESC_TXT  "This is a file description"
43 #define  DATA_LABEL_TXT "This is a data label"
44 #define  DATA_DESC_TXT  "This is a data annotation"
45 /* dimensions of image */
46 #define X_DIM_GR   60
47 #define Y_DIM_GR   400
48 /* dimensions of dataset */
49 #define X_DIM      20
50 #define Y_DIM      800
51 #define Z_DIM      2
52 /* dimensions */
53 #define XD1        60
54 #define YD1        40
55 /* dimensions for hyperslab sds */
56 #define DIM0       10
57 #define DIM1       10
58 #define ADD_ROWS ( 1024 * 1024 - 10 ) / 10
59 /* Vdata */
60 #define  N_RECORDS        3         /* number of records the vdata contains */
61 #define  ORDER_1          3         /* order of first field */
62 #define  ORDER_2          1         /* order of second field */
63 #define  ORDER_3          2         /* order of third field */
64 #define  CLASS_NAME       "Particle"
65 #define  FIELD1_NAME      "Position"      /* contains x, y, z values */
66 #define  FIELD2_NAME      "Mass"          /* contains weight values */
67 #define  FIELD3_NAME      "Temperature"   /* contains min and max values */
68 #define  FIELDNAME_LIST   "Position,Mass,Temperature" /* No spaces b/w names */
69 #define  N_VALS_PER_REC   (ORDER_1 + ORDER_2 + ORDER_3)  /* number of values per record */
70 
71 /*-------------------------------------------------------------------------
72  * global variables for read image data, used in gr, r8 and r24 add
73  *-------------------------------------------------------------------------
74  */
75 
76 static int            g_lenght_x;
77 static int            g_lenght_y;
78 static int            g_ncomps;
79 static unsigned char *g_image_data = NULL;
80 
81 
82 /*-------------------------------------------------------------------------
83  * read_data
84  * utility function to read ASCII image data
85  * the files have a header of the type
86  *
87  *   components
88  *   n
89  *   height
90  *   n
91  *   width
92  *   n
93  *
94  * followed by the image data
95  *
96  *-------------------------------------------------------------------------
97  */
98 
99 static
read_data(const char * fname)100 int read_data(const char* fname)
101 {
102     int    i, n;
103     int    color_planes;
104     char   str[20];
105     FILE   *f;
106     int    w, h;
107 
108     f = fopen( fname, "r");
109 
110     if ( f == NULL )
111     {
112         printf( "Could not open file <%s>\n", fname );
113         return -1;
114     }
115 
116     fscanf( f, "%s", str );
117     fscanf( f, "%d", &color_planes );
118     fscanf( f, "%s", str );
119     fscanf( f, "%d", &h);
120     fscanf( f, "%s", str );
121     fscanf( f, "%d", &w);
122 
123     /* globals */
124     g_ncomps=color_planes;
125     g_lenght_y=h;
126     g_lenght_x=w;
127 
128     if ( g_image_data != NULL )
129     {
130         HDfree( g_image_data );
131         g_image_data=NULL;
132     }
133 
134     g_image_data = (unsigned char*)HDmalloc(w*h*color_planes*sizeof(unsigned char));
135 
136     for (i = 0; i < h*w*color_planes ; i++)
137     {
138         fscanf( f, "%d",&n );
139         g_image_data[i] = (unsigned char)n;
140     }
141     fclose(f);
142 
143     return 1;
144 
145 }
146 
147 /*-------------------------------------------------------------------------
148  * Function: vg_getngrpdep
149  *
150  * Purpose: utility function to get number of vgroups dependencies in
151  *  file HFILEID f
152  *
153  * Return: number of vgroups dependencies in file
154  *
155  * Programmer: Pedro Vicente, pvn@hdfgroup.org
156  *
157  * Date: September 10, 2007
158  *
159  *-------------------------------------------------------------------------
160  */
161 
162 static
vg_getngrpdep(HFILEID f)163 int vg_getngrpdep( HFILEID f)
164 {
165     int32       vg, vgt;
166     int32       vgotag, vgoref;
167     int32       vgid = -1;
168     int32       vsid = -1;
169     int32       vsno = 0;
170     int32       vstag;
171     int32       i, nvg, n, ne, nlnk;
172     uint16      name_len;
173     char        *vgname;
174 
175     Vstart(f);
176 
177     nvg = 0;
178     nlnk = 0;
179     while ((vgid = Vgetid(f, vgid)) != -1)
180     {
181         vg = Vattach(f, vgid, "r");
182         if (vg == FAIL)
183         {
184             printf("cannot open vg id=%d\n", (int) vgid);
185         }
186         /* Get vgroup's name */
187         if (Vgetnamelen(vg, &name_len)==FAIL)
188         {
189             printf("Error: Could not get name length for group with ref <%ld>\n", vgid);
190             continue;
191         }
192         vgname = (char *) HDmalloc(sizeof(char) * (name_len+1));
193 
194         Vinquire(vg, &n, vgname);
195         vgotag = VQuerytag(vg);
196         vgoref = VQueryref(vg);
197 
198         for (i = 0; i < Vntagrefs(vg); i++)
199         {
200             Vgettagref(vg, i, &vstag, &vsid);
201 
202             if (vstag == DFTAG_VG)
203             {
204                 vgt = Vattach(f, vsid, "r");
205 
206                 if (vgt == FAIL)
207                 {
208                     printf("cannot open vg id=%d\n", (int) vsid);
209                     continue;
210                 }
211 
212                 Vinquire(vgt, &ne, vgname);
213 
214                 vgotag = VQuerytag(vgt);
215                 vgoref = VQueryref(vgt);
216 
217                 Vdetach(vgt);
218 
219                 nlnk++;
220 
221             } /* if */
222 
223         }   /* for */
224 
225         Vdetach(vg);
226         nvg++;
227 
228     }  /* while */
229 
230 
231     Vend(f);
232 
233     return nlnk;
234 
235 }
236 
237 /*-------------------------------------------------------------------------
238  * Function: vg_verifygrpdep
239  *
240  * Purpose: utility function to verify number of vgroups dependencies in
241  *  2 files NAME1 and NAME2
242  *
243  * Return: 0, group dependencies are the same in both files
244  *         1, they are not the same
245  *        -1, error
246  *
247  * Programmer: Pedro Vicente, pvn@hdfgroup.org
248  *
249  * Date: September 10, 2007
250  *
251  *-------------------------------------------------------------------------
252  */
253 static
vg_verifygrpdep(char * name1,char * name2)254 int vg_verifygrpdep( char* name1, char* name2 )
255 {
256     HFILEID f1;
257     HFILEID f2;
258     int32   nlnk1;
259     int32   nlnk2;
260 
261 
262     if ((f1 = Hopen(name1, DFACC_READ, 0)) == FAIL)
263     {
264         printf("\nFile (%s) failed to open.\n", name1);
265         return -1;
266     }
267     if ((f2 = Hopen(name2, DFACC_READ, 0)) == FAIL)
268     {
269         printf("\nFile (%s) failed to open.\n", name2);
270         return -1;
271     }
272 
273     nlnk1 = vg_getngrpdep( f1 );
274     nlnk2 = vg_getngrpdep( f2 );
275 
276     Hclose(f1);
277     Hclose(f2);
278 
279     return (nlnk1 == nlnk2) ? 0: 1;
280 
281 }
282 
283 
284 /*-------------------------------------------------------------------------
285  * Function: set_chunk_def
286  *
287  * Purpose: set chunk parameters. used by GR and SDS
288  *
289  * Return: void
290  *
291  * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu
292  *
293  * Date: September 15, 2003
294  *
295  *-------------------------------------------------------------------------
296  */
297 
298 static
set_chunk_def(comp_coder_t comp_type,int32 * dim,int32 ncomps,int32 bits_per_pixel,HDF_CHUNK_DEF * chunk_def)299 void set_chunk_def( comp_coder_t comp_type,
300                     int32 *dim,
301                     int32 ncomps,
302                     int32 bits_per_pixel, /* for szip */
303                     HDF_CHUNK_DEF *chunk_def )
304 {
305 
306     /* Define chunk's dimensions */
307     chunk_def->chunk_lengths[0] = dim[0]/2;
308     chunk_def->chunk_lengths[1] = dim[1]/2;
309     /* To use chunking with RLE, Skipping Huffman, GZIP, SZIP compression */
310     chunk_def->comp.chunk_lengths[0] = dim[0]/2;
311     chunk_def->comp.chunk_lengths[1] = dim[1]/2;
312 
313     /*define some compression specific parameters */
314     switch(comp_type)
315     {
316     default:
317         break;
318     case COMP_CODE_RLE:
319         chunk_def->comp.comp_type = COMP_CODE_RLE;
320         break;
321 
322     case COMP_CODE_SKPHUFF:
323         chunk_def->comp.comp_type = COMP_CODE_SKPHUFF;
324         chunk_def->comp.cinfo.skphuff.skp_size = 1;
325         break;
326 
327     case COMP_CODE_DEFLATE:
328         /* GZIP compression, set compression type, flag and deflate level*/
329         chunk_def->comp.comp_type = COMP_CODE_DEFLATE;
330         chunk_def->comp.cinfo.deflate.level = 6;
331         break;
332 
333     case COMP_CODE_SZIP:
334 #ifdef H4_HAVE_LIBSZ
335         if (SZ_encoder_enabled()) {
336             chunk_def->comp.cinfo.szip.pixels_per_block = 2;
337             chunk_def->comp.cinfo.szip.options_mask = SZ_EC_OPTION_MASK;
338             chunk_def->comp.cinfo.szip.options_mask |= SZ_RAW_OPTION_MASK;
339             chunk_def->comp.cinfo.szip.pixels = 0;
340             chunk_def->comp.cinfo.szip.pixels_per_scanline = 0;
341             chunk_def->comp.cinfo.szip.bits_per_pixel = 0;
342         } else {
343             printf("Warning: SZIP encoding not available\n");
344         }
345 #else
346         printf("Warning: SZIP compression not available\n");
347 #endif
348         break;
349     }
350 
351 }
352 
353 
354 /*-------------------------------------------------------------------------
355  * verify functions
356  *-------------------------------------------------------------------------
357  */
358 
359 /*-------------------------------------------------------------------------
360  * Function: cmp_gr
361  *
362  * Purpose: compare 2 GR images
363  *
364  * Return: same as memcmp
365  *
366  * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu
367  *
368  * Date: September 03, 2003
369  *
370  *-------------------------------------------------------------------------
371  */
372 
373 static
cmp_gr(int32 ri1_id,int32 ri2_id)374 int cmp_gr(int32 ri1_id, int32 ri2_id)
375 {
376     int32         dimsizes[2],   /* dimensions of an image */
377         n_comps,       /* number of components an image contains */
378         interlace_mode1,/* interlace mode of an image */
379         dtype,         /* number type of an image */
380         n_attrs;       /* number of attributes belong to an image */
381     int32         interlace_mode2;
382     char          gr_name[H4_MAX_GR_NAME];
383     int           j, rank=2;
384     int32         start[2],       /* read start */
385         edges[2],       /* read edges */
386         numtype,        /* number type */
387         eltsz,          /* element size */
388         nelms,          /* number of elements */
389         data_size;
390     VOIDP         buf1=NULL, buf2=NULL;
391     int           cmp=-1;
392 
393     GRgetiminfo(ri1_id,gr_name,&n_comps,&dtype,&interlace_mode1,dimsizes,&n_attrs);
394     GRgetiminfo(ri2_id,gr_name,&n_comps,&dtype,&interlace_mode2,dimsizes,&n_attrs);
395 
396     printf( "Comparing GR <%s>: ", gr_name);
397 
398 
399     /*-------------------------------------------------------------------------
400     * match interlace
401     * NOTE: GR images are always stored as pixel_interlace (0) on disk
402     *       that does not happen with images saved with the
403     *       DF24 - Single-file 24-Bit Raster Image Interface,
404     *       where the interlace mode on disk can be 0, 1 or 2
405     *-------------------------------------------------------------------------
406     */
407     if ( interlace_mode1 != interlace_mode2 )
408     {
409         printf("Warning: different interlace mode: <%ld> and <%ld>",
410             interlace_mode1,interlace_mode2);
411         interlace_mode1=interlace_mode2;
412     }
413 
414     /*-------------------------------------------------------------------------
415     * check for data size before printing
416     *-------------------------------------------------------------------------
417     */
418 
419     /* compute the number of the bytes for each value. */
420     numtype = dtype & DFNT_MASK;
421     eltsz = DFKNTsize(numtype | DFNT_NATIVE);
422 
423     /* set edges of GR */
424     nelms=1;
425     for (j = 0; j < rank; j++) {
426         nelms   *= dimsizes[j];
427         edges[j] = dimsizes[j];
428         start[j] = 0;
429     }
430 
431     data_size = dimsizes[0]*dimsizes[1]*n_comps*eltsz;
432 
433     /*-------------------------------------------------------------------------
434     * read gr 1
435     *-------------------------------------------------------------------------
436     */
437 
438     /* alloc */
439     if ((buf1 = (VOIDP) HDmalloc(data_size)) == NULL) {
440         printf( "Failed to allocate %ld elements of size %ld\n", nelms, eltsz);
441         goto out;
442     }
443 
444 
445     /* read data */
446     if (GRreadimage (ri1_id, start, NULL, edges, buf1) == FAIL) {
447         printf( "Could not read GR\n");
448         goto out;
449     }
450 
451     /*-------------------------------------------------------------------------
452     * read gr 2
453     *-------------------------------------------------------------------------
454     */
455 
456     /* alloc */
457     if ((buf2 = (VOIDP) HDmalloc(data_size)) == NULL) {
458         printf( "Failed to allocate %ld elements of size %ld\n", nelms, eltsz);
459         goto out;
460     }
461 
462     /* read data */
463     if (GRreadimage (ri2_id, start, NULL, edges, buf2) == FAIL) {
464         printf( "Could not read GR\n");
465         goto out;
466     }
467 
468     cmp = HDmemcmp(buf1,buf2,data_size);
469     if (cmp!=0)
470         printf("Differences found\n");
471     else
472         printf("\n");
473 
474 out:
475     /* terminate access to the GRs */
476     GRendaccess(ri1_id);
477     GRendaccess(ri2_id);
478     if (buf1)
479         HDfree(buf1);
480     if (buf2)
481         HDfree(buf2);
482     return cmp;
483 
484 }
485 
486 /*-------------------------------------------------------------------------
487  * Function: sds_verifiy_comp
488  *
489  * Purpose: utility function to verify compression for SDS_NAME
490  *
491  * Return: 0, -1 on error
492  *
493  * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu
494  *
495  * Date: August 3, 2003
496  *
497  *-------------------------------------------------------------------------
498  */
499 static
sds_verifiy_comp(const char * sds_name,int32 in_comp_type,int32 in_comp_info)500 int sds_verifiy_comp(const char *sds_name,
501                      int32 in_comp_type,
502                      int32 in_comp_info)
503 {
504     comp_coder_t  comp_type;    /* to retrieve compression type into */
505     comp_info     comp_info;    /* compression structure */
506     int32         sd_id,
507                   sds_id,
508                   sds_index;
509 
510     /* get chunk and comp */
511     sd_id     = SDstart (HREPACK_FILE1_OUT, DFACC_RDONLY);
512     sds_index = SDnametoindex(sd_id, sds_name);
513     if ((sds_id = SDselect(sd_id, sds_index))==FAIL) {
514         printf("Error: Cannot open sds <%s>", sds_name);
515         SDend (sd_id);
516         return -1;
517     }
518 
519     /*-------------------------------------------------------------------------
520     * retrieve and verify the compression info
521     *-------------------------------------------------------------------------
522     */
523 
524     comp_type = COMP_CODE_NONE;  /* reset variables before retrieving info */
525     HDmemset(&comp_info, 0, sizeof(comp_info)) ;
526     SDgetcompinfo(sds_id, &comp_type, &comp_info);
527     if ( comp_type != in_comp_type )
528     {
529         printf("Error: Compression type does not match ");
530         SDendaccess (sds_id);
531         SDend (sd_id);
532         return -1;
533     }
534     if (in_comp_info) {
535         if ( comp_info.skphuff.skp_size != in_comp_info )
536         {
537             printf("Error: compresion information does not match ");
538             SDendaccess (sds_id);
539             SDend (sd_id);
540             return -1;
541         }
542     }
543 
544     /* terminate access to the sds */
545     SDendaccess (sds_id);
546 
547     /* terminate access to the sd interface */
548     SDend (sd_id);
549 
550     return 0;
551 
552 }
553 
554 /*-------------------------------------------------------------------------
555  * Function: sds_verifiy_comp_all
556  *
557  * Purpose: utility function to verify compression for all SDSs
558  *
559  * Return: 0, -1 on error
560  *
561  * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu
562  *
563  * Date: August 3, 2003
564  *
565  *-------------------------------------------------------------------------
566  */
567 static
sds_verifiy_comp_all(comp_coder_t in_comp_type,int in_comp_info)568 int sds_verifiy_comp_all(comp_coder_t in_comp_type,
569                          int in_comp_info)
570 {
571     comp_coder_t  comp_type;    /* to retrieve compression type into */
572     comp_info     comp_info;    /* compression structure */
573     int32         sd_id,
574         sds_id,
575         sds_index,
576         n_datasets,   /* number of datasets in the file */
577         n_file_attrs, /* number of file attributes */
578         data_type,              /* number type  */
579         rrank,                  /* read rank */
580         n_attrs,                /* number of attributes */
581         dim_sizes[H4_MAX_VAR_DIMS];/* dimensions of an image */
582     char          name[H4_MAX_GR_NAME];      /* name of dataset */
583     int           info;
584     intn          empty_sds;
585     int           is_record = 0;
586 
587     /* initialize the sd interface */
588     sd_id  = SDstart (HREPACK_FILE1_OUT, DFACC_READ);
589 
590     /* determine the number of data sets in the file */
591     if (SDfileinfo (sd_id, &n_datasets, &n_file_attrs)==FAIL)
592     {
593         printf("Error: Cannot get file information");
594         SDend (sd_id);
595         return -1;
596     }
597 
598     for (sds_index = 0; sds_index < n_datasets; sds_index++)
599     {
600         sds_id   = SDselect (sd_id, sds_index);
601 
602         /* skip dimension scales */
603         if ( SDiscoordvar(sds_id) )
604         {
605             SDendaccess(sds_id);
606             continue;
607         }
608 
609         name[0] = '\0';
610         if ( SDgetinfo(sds_id, name, &rrank, dim_sizes, &data_type, &n_attrs) == FAIL )
611         {
612             printf("Error: can't read info for SDS <%s>",name);
613             SDendaccess (sds_id);
614             SDend (sd_id);
615             return -1;
616         }
617 
618         /*-------------------------------------------------------------------------
619         * check if the input SDS is empty
620         *-------------------------------------------------------------------------
621         */
622         if (SDcheckempty( sds_id, &empty_sds ) == FAIL)
623         {
624             printf( "Failed to check empty SDS <%s>\n", name);
625             SDendaccess (sds_id);
626             SDend (sd_id);
627             return -1;
628         }
629 
630         /*-------------------------------------------------------------------------
631         * retrieve and verify the compression info
632         *-------------------------------------------------------------------------
633         */
634 
635         if (empty_sds==0 )
636         {
637 
638             comp_type = COMP_CODE_NONE;  /* reset variables before retrieving info */
639             HDmemset(&comp_info, 0, sizeof(comp_info)) ;
640 
641             if (SDisrecord(sds_id))
642                 is_record = 1;
643 
644             /* unlimited dimensions don't work with compression */
645             if ( ! is_record )
646             {
647 
648 
649                 if ( SDgetcompinfo(sds_id, &comp_type, &comp_info) == FAIL )
650                 {
651                     printf("Warning: can't read compression for SDS <%s>",name);
652                 }
653                 else
654                 {
655                     if ( comp_type != in_comp_type )
656                     {
657                         printf("Error: compression type does not match <%s>",name);
658                         SDendaccess (sds_id);
659                         SDend (sd_id);
660                         return -1;
661                     }
662                     if (in_comp_type)
663                     {
664                         switch (in_comp_type)
665                         {
666                         case COMP_CODE_NONE:
667                             break;
668                         case COMP_CODE_RLE:
669                             break;
670                         case COMP_CODE_SZIP:
671                             break;
672                         case COMP_CODE_SKPHUFF:
673                             info  = comp_info.skphuff.skp_size;
674                             break;
675                         case COMP_CODE_DEFLATE:
676                             info  = comp_info.deflate.level;
677                             break;
678                         default:
679                             printf("Error: Unrecognized compression code %d\n",in_comp_type);
680                             info = -1;
681                             break;
682                         };
683 
684                         if ( info != in_comp_info )
685                         {
686                             printf("Error: compresion information does not match for <%s>",name);
687                             SDendaccess (sds_id);
688                             SDend (sd_id);
689                             return -1;
690                         }
691                     }
692                 }
693 
694             } /* is_record */
695 
696         } /* empty_sds */
697 
698         /* terminate access to the current dataset */
699         SDendaccess (sds_id);
700     }
701 
702     /* terminate access to the sd interface */
703     SDend (sd_id);
704 
705     return 0;
706 }
707 
708 /*-------------------------------------------------------------------------
709  * Function: sds_verifiy_chunk
710  *
711  * Purpose: utility function to verify chunking for  SDS_NAME
712  *
713  * Return: 0, -1 on error
714  *
715  * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu
716  *
717  * Date: August 3, 2003
718  *
719  *-------------------------------------------------------------------------
720  */
721 static
sds_verifiy_chunk(const char * sds_name,int32 in_chunk_flags,int rank,int32 * in_chunk_lengths)722 int sds_verifiy_chunk(const char *sds_name,
723                       int32 in_chunk_flags,
724                       int rank,
725                       int32 *in_chunk_lengths)
726 {
727     HDF_CHUNK_DEF chunk_def;    /* chunk defintion read */
728     int32         chunk_flags;  /* chunking flag */
729     int32         sd_id,
730         sds_id,
731         sds_index;
732     int           i;
733 
734     /* get chunk and comp */
735     sd_id     = SDstart (HREPACK_FILE1_OUT, DFACC_RDONLY);
736     sds_index = SDnametoindex(sd_id, sds_name);
737     if ((sds_id = SDselect(sd_id, sds_index))==FAIL) {
738         printf("Error: cannot open sds <%s>", sds_name);
739         SDend (sd_id);
740         return -1;
741     }
742     SDgetchunkinfo (sds_id, &chunk_def, &chunk_flags);
743 
744     /*-------------------------------------------------------------------------
745     * retrieve and verify the chunk info
746     *-------------------------------------------------------------------------
747     */
748     if ( chunk_flags != (in_chunk_flags) )
749     {
750         printf("Error: chunk flags do not match");
751         SDendaccess (sds_id);
752         SDend (sd_id);
753         return -1;
754     }
755     for (i = 0; i < rank; i++)
756     {
757         if (chunk_def.chunk_lengths[i] != in_chunk_lengths[i] )
758         {
759             printf("Error: chunk lengths do not match ");
760             SDendaccess (sds_id);
761             SDend (sd_id);
762             return -1;
763         }
764     }
765 
766     /* terminate access to the sds */
767     SDendaccess (sds_id);
768 
769     /* terminate access to the sd interface */
770     SDend (sd_id);
771 
772     return 0;
773 
774 }
775 
776 /*-------------------------------------------------------------------------
777  * Function: sds_verifiy_chunk_all
778  *
779  * Purpose: utility function to verify chunking for all SDSs
780  *
781  * Return: 0, -1 on error
782  *
783  * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu
784  *
785  * Date: August 3, 2003
786  *
787  *-------------------------------------------------------------------------
788  */
789 static
sds_verifiy_chunk_all(int32 in_chunk_flags,int rank,int32 * in_chunk_lengths,const char * sds_exclude)790 int sds_verifiy_chunk_all(int32 in_chunk_flags,
791                           int rank,
792                           int32 *in_chunk_lengths,
793                           const char *sds_exclude)
794 {
795     HDF_CHUNK_DEF chunk_def;    /* chunk defintion read */
796     int32         chunk_flags;  /* chunking flag */
797     int32         sd_id,
798         sds_id,
799         sds_index,
800         n_datasets,   /* number of datasets in the file */
801         n_file_attrs, /* number of file attributes */
802         data_type,              /* number type  */
803         rrank,                  /* read rank */
804         n_attrs,                /* number of attributes */
805         dim_sizes[H4_MAX_VAR_DIMS];/* dimensions of an image */
806     char          name[H4_MAX_GR_NAME];      /* name of dataset */
807     int           i;
808 
809     /* initialize the sd interface */
810     sd_id  = SDstart (HREPACK_FILE1_OUT, DFACC_READ);
811 
812     /* determine the number of data sets in the file */
813     if (SDfileinfo (sd_id, &n_datasets, &n_file_attrs)==FAIL) {
814         printf("Error: cannot get file information");
815         SDend (sd_id);
816         return -1;
817     }
818 
819     for (sds_index = 0; sds_index < n_datasets; sds_index++)
820     {
821         sds_id   = SDselect (sd_id, sds_index);
822 
823         /* skip dimension scales */
824         if ( SDiscoordvar(sds_id) ) {
825             SDendaccess(sds_id);
826             continue;
827         }
828 
829         SDgetinfo(sds_id, name, &rrank, dim_sizes, &data_type, &n_attrs);
830         SDgetchunkinfo (sds_id, &chunk_def, &chunk_flags);
831 
832         /* do not compare this one */
833         if (strcmp(name,sds_exclude)==0)
834         {
835             SDendaccess(sds_id);
836             SDend (sd_id);
837             return 0;
838         }
839 
840         /*-------------------------------------------------------------------------
841         * retrieve and verify the chunk info
842         *-------------------------------------------------------------------------
843         */
844         if ( chunk_flags != (in_chunk_flags) )
845         {
846             printf("Error: chunk flags do not match");
847             SDendaccess (sds_id);
848             SDend (sd_id);
849             return -1;
850         }
851         for (i = 0; i < rank; i++)
852         {
853             if (chunk_def.chunk_lengths[i] != in_chunk_lengths[i] )
854             {
855                 printf("Error: chunk lengths do not match ");
856                 SDendaccess (sds_id);
857                 SDend (sd_id);
858                 return -1;
859             }
860         }
861 
862         /* terminate access to the current dataset */
863         SDendaccess (sds_id);
864     }
865 
866     /* terminate access to the sd interface */
867     SDend (sd_id);
868 
869     return 0;
870 
871 }
872 
873 
874 
875 /*-------------------------------------------------------------------------
876  * add functions
877  *-------------------------------------------------------------------------
878  */
879 
880 /*-------------------------------------------------------------------------
881  * Function: add_an
882  *
883  * Purpose: utility function to write a AN
884  *
885  * Return: SUCCEED, FAIL
886  *
887  * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu
888  *
889  * Date: August 19, 2003
890  *
891  *-------------------------------------------------------------------------
892  */
893 
894 static
add_an(int32 file_id,int32 tag,int32 ref)895 int add_an(int32 file_id, int32 tag, int32 ref)
896 {
897     int32 an_id,        /* AN interface identifier */
898           data_label_id,  /* data label identifier */
899           data_desc_id;   /* data description identifier */
900 
901     /* Initialize the AN interface */
902     an_id = ANstart (file_id);
903 
904    /*-------------------------------------------------------------------------
905     * data labels and annotations
906     *-------------------------------------------------------------------------
907     */
908 
909     /* Create the data label for the object identified by its tag and ref number */
910     data_label_id = ANcreate (an_id, (uint16)tag, (uint16)ref, AN_DATA_LABEL);
911 
912     /* Write the annotation text to the data label */
913     if (ANwriteann (data_label_id, DATA_LABEL_TXT, strlen (DATA_LABEL_TXT))==FAIL){
914         printf("Error: writing data label in tag %ld ref %ld\n", tag, ref);
915         return FAIL;
916     }
917 
918     /* Create the data description for the object identified by its tag and ref number */
919     data_desc_id = ANcreate (an_id, (uint16)tag, (uint16)ref, AN_DATA_DESC);
920 
921     /* Write the annotation text to the data description */
922     if (ANwriteann (data_desc_id, DATA_DESC_TXT, strlen (DATA_DESC_TXT))==FAIL){
923         printf("Error: writing data label in tag %ld ref %ld\n", tag, ref);
924         return FAIL;
925     }
926 
927     /* Terminate access to each annotation explicitly */
928     if (ANendaccess (data_label_id)==FAIL||
929         ANendaccess (data_desc_id)==FAIL){
930         printf( "Failed to close AN\n");
931         return FAIL;
932     }
933 
934     /* Terminate access to the AN interface */
935     if (ANend (an_id)==FAIL){
936         printf( "Failed to close AN\n");
937         return FAIL;
938     }
939 
940     return SUCCEED;
941 }
942 
943 
944 
945 
946 
947 
948 /*-------------------------------------------------------------------------
949  * Function: add_gr_ffile
950  *
951  * Purpose: utility function to read an image data file and save the image with the
952  *  GR - Multifile General Raster Image Interface,
953  *  optionally inserting the image into the group VGROUP_ID
954  *
955  * Return: SUCCEED, FAIL
956  *
957  * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu
958  *
959  * Date: July 3, 2003
960  *
961  *-------------------------------------------------------------------------
962  */
963 static
add_gr_ffile(const char * name_file,int32 gr_id,const char * gr_name,int32 interlace_mode,int32 file_id,int32 vgroup_id)964 int add_gr_ffile(const char* name_file,
965                   int32 gr_id,
966                   const char* gr_name,
967                   int32 interlace_mode,
968                   int32 file_id,
969                   int32 vgroup_id)
970 {
971     int32  ri_id,          /* raster image identifier */
972            gr_ref,         /* reference number of the GR image */
973            start[2],       /* start position to write for each dimension */
974            edges[2],       /* number of elements to be written along each dimension */
975            dim_gr[2],      /* dimension sizes of the image array */
976            data_type;      /* data type of the image data */
977     char   *srcdir = getenv("srcdir"); /* the source directory */
978     char   data_file[512]="";          /* buffer to hold name of existing data file */
979     uint8  attr_values[2]={1,2};
980     int    n_values;
981 
982     /* compose the name of the file to open, using the srcdir, if appropriate */
983     if ( srcdir )
984     {
985         HDstrcpy(data_file, srcdir);
986         HDstrcat(data_file, "/");
987     }
988     HDstrcat( data_file, name_file);
989 
990     if ( read_data(data_file) > 0 )
991     {
992         /* set the data type, interlace mode, and dimensions of the image */
993         data_type = DFNT_UINT8;
994         dim_gr[0] = g_lenght_x;
995         dim_gr[1] = g_lenght_y;
996 
997         /* create the raster image array */
998         if ((ri_id = GRcreate (gr_id, gr_name, g_ncomps, data_type, interlace_mode, dim_gr))== FAIL)
999         {
1000             printf("Error: Could not create GR <%s>\n", gr_name);
1001             return FAIL;
1002         }
1003 
1004         /* define the size of the data to be written */
1005         start[0] = start[1] = 0;
1006         edges[0] = g_lenght_x;
1007         edges[1] = g_lenght_y;
1008 
1009 
1010         /* write the data in the buffer into the image array */
1011         if (GRwriteimage(ri_id, start, NULL, edges, (VOIDP)g_image_data)==FAIL)
1012         {
1013             printf("Error: Could not write GR <%s>\n", gr_name);
1014         }
1015 
1016         /* assign an attribute to the SDS */
1017         n_values = 2;
1018         if(GRsetattr(ri_id, "Myattr", DFNT_UINT8, n_values, (VOIDP)attr_values)==FAIL)
1019         {
1020             printf("Error: Could not write attributes for GR <%s>\n", gr_name);
1021             return FAIL;
1022         }
1023 
1024         /* obtain the reference number of the GR using its identifier */
1025         gr_ref = GRidtoref (ri_id);
1026 
1027         /* add the GR to the vgroup. the tag DFTAG_RIG is used */
1028         if (vgroup_id)
1029         {
1030             if (Vaddtagref (vgroup_id, TAG_GRP_IMAGE, gr_ref)==FAIL)
1031             {
1032                 printf("Error: Could not add GR <%s> to group\n", gr_name);
1033                 return FAIL;
1034             }
1035         }
1036 
1037         /* terminate access to the raster image */
1038         if (GRendaccess (ri_id)==FAIL)
1039         {
1040             printf("Error: Could not close GR <%s>\n", gr_name);
1041             return FAIL;
1042         }
1043 
1044         /* add an annotation and label to the object */
1045         if (add_an(file_id, DFTAG_RI, gr_ref)<0)
1046             return FAIL;
1047 
1048     }  /* read data */
1049 
1050     if ( g_image_data != NULL )
1051     {
1052         HDfree( g_image_data );
1053         g_image_data=NULL;
1054     }
1055 
1056     return SUCCEED;
1057 }
1058 
1059 
1060 /*-------------------------------------------------------------------------
1061  * Function: add_gr
1062  *
1063  * Purpose: utility function to write images with the
1064  *  GR - Multifile General Raster Image Interface,
1065  *  optionally inserting the image into the group VGROUP_ID
1066  *
1067  * Return: SUCCEED, FAIL
1068  *
1069  * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu
1070  *
1071  * Date: August 18, 2003
1072  *
1073  *-------------------------------------------------------------------------
1074  */
1075 
1076 static
add_gr(const char * gr_name,int32 file_id,int32 gr_id,int32 vgroup_id,int32 chunk_flags,comp_coder_t comp_type,comp_info * comp_info)1077 int add_gr(const char* gr_name,     /* gr name */
1078             int32 file_id,           /* file ID */
1079             int32 gr_id,             /* GR ID */
1080             int32 vgroup_id,         /* group ID */
1081             int32 chunk_flags,       /* chunk flags */
1082             comp_coder_t comp_type,  /* compression flag */
1083             comp_info *comp_info     /* compression structure */ )
1084 {
1085     int32  ri_id,          /* raster image identifier */
1086            gr_ref,         /* reference number of the GR image */
1087            start[2],       /* start position to write for each dimension */
1088            edges[2],       /* number of elements to be written along each dimension */
1089            dim_gr[2],      /* dimension sizes of the image array */
1090            interlace_mode, /* interlace mode of the image */
1091            data_type,      /* data type of the image data */
1092            data[Y_DIM_GR][X_DIM_GR];
1093     int    i, j, n=0, ncomps=1;
1094     HDF_CHUNK_DEF chunk_def;           /* Chunking definitions */
1095 
1096     /* set the data type, interlace mode, and dimensions of the image */
1097     data_type = DFNT_UINT32;
1098     interlace_mode = MFGR_INTERLACE_PIXEL;
1099     dim_gr[0] = Y_DIM_GR;
1100     dim_gr[1] = X_DIM_GR;
1101 
1102     /* data set data initialization */
1103     for (j = 0; j < Y_DIM_GR; j++) {
1104         for (i = 0; i < X_DIM_GR; i++)
1105             data[j][i] = n++;
1106     }
1107 
1108     /*define some compression specific parameters */
1109     switch(comp_type)
1110     {
1111     default:
1112         break;
1113     case COMP_CODE_RLE:
1114         break;
1115 
1116     case COMP_CODE_SKPHUFF:
1117         comp_info->skphuff.skp_size = 1;
1118         break;
1119 
1120     case COMP_CODE_DEFLATE:
1121         comp_info->deflate.level = 6;
1122         break;
1123 
1124     case COMP_CODE_SZIP:
1125 #ifdef H4_GR_SZIP
1126         /* not supported for GR */
1127 #ifdef H4_HAVE_LIBSZ
1128         if (SZ_encoder_enabled()) {
1129             comp_info->szip.pixels_per_block = 2;
1130             comp_info->szip.options_mask = SZ_EC_OPTION_MASK;
1131             comp_info->szip.options_mask |= SZ_RAW_OPTION_MASK;
1132             comp_info->szip.pixels = 0;
1133             comp_info->szip.pixels_per_scanline = 0;
1134             comp_info->szip.bits_per_pixel = 0;
1135         } else {
1136             printf("Warning: SZIP encoding not available\n");
1137         }
1138 #else
1139         printf("Warning: SZIP compression not available\n");
1140 #endif
1141 #endif
1142         printf("Warning: SZIP compression not available for GR\n");
1143         break;
1144     }
1145 
1146     /* create the raster image array */
1147     if ((ri_id = GRcreate (gr_id, gr_name, ncomps, data_type, interlace_mode, dim_gr))== FAIL)
1148     {
1149         printf("Error: Could not create GR <%s>\n", gr_name);
1150         return FAIL;
1151     }
1152 
1153     /* set chunk */
1154     if ( (chunk_flags == HDF_CHUNK) || (chunk_flags == (HDF_CHUNK | HDF_COMP)) )
1155     {
1156         /* Define chunk's dimensions */
1157         chunk_def.chunk_lengths[0] = Y_DIM_GR/2;
1158         chunk_def.chunk_lengths[1] = X_DIM_GR/2;
1159         /* To use chunking with RLE, Skipping Huffman, and GZIP compression */
1160         chunk_def.comp.chunk_lengths[0] = Y_DIM_GR/2;
1161         chunk_def.comp.chunk_lengths[1] = X_DIM_GR/2;
1162 
1163         /*define some compression specific parameters */
1164         switch(comp_type)
1165         {
1166         default:
1167             break;
1168         case COMP_CODE_RLE:
1169             chunk_def.comp.comp_type = COMP_CODE_RLE;
1170             break;
1171 
1172         case COMP_CODE_SKPHUFF:
1173             chunk_def.comp.comp_type = COMP_CODE_SKPHUFF;
1174             chunk_def.comp.cinfo.skphuff.skp_size = 1;
1175             break;
1176 
1177         case COMP_CODE_DEFLATE:
1178             /* GZIP compression, set compression type, flag and deflate level*/
1179             chunk_def.comp.comp_type = COMP_CODE_DEFLATE;
1180             chunk_def.comp.cinfo.deflate.level = 6;
1181             break;
1182 
1183         case COMP_CODE_SZIP:
1184 #ifdef H4_GR_SZIP
1185 #ifdef H4_HAVE_LIBSZ
1186             if (SZ_encoder_enabled()) {
1187                 chunk_def.comp.cinfo.szip.pixels_per_block = 2;
1188                 chunk_def.comp.cinfo.szip.options_mask = SZ_EC_OPTION_MASK;
1189                 chunk_def.comp.cinfo.szip.options_mask |= SZ_RAW_OPTION_MASK;
1190                 chunk_def.comp.cinfo.szip.pixels = 0;
1191                 chunk_def.comp.cinfo.szip.pixels_per_scanline = 0;
1192                 chunk_def.comp.cinfo.szip.bits_per_pixel = 0;
1193             } else {
1194                 printf("Warning: SZIP encoding not available\n");
1195             }
1196 #else
1197             printf("Warning: SZIP compression not available\n");
1198 #endif
1199 #endif
1200             printf("Warning: SZIP compression not available for GR\n");
1201             break;
1202         }
1203         if(GRsetchunk (ri_id, chunk_def, chunk_flags)==FAIL)
1204         {
1205             printf("Error: Could not set chunk for GR <%s>\n", gr_name);
1206             return FAIL;
1207         }
1208     }
1209 
1210     /* use compress without chunk-in */
1211     else if ( (chunk_flags==HDF_NONE || chunk_flags==HDF_CHUNK) &&
1212         comp_type>COMP_CODE_NONE && comp_type<COMP_CODE_INVALID)
1213     {
1214         if(GRsetcompress (ri_id, comp_type, comp_info)==FAIL)
1215         {
1216             printf("Error: Could not set compress for GR <%s>\n", gr_name);
1217             return FAIL;
1218         }
1219     }
1220 
1221 
1222     /* define the size of the data to be written */
1223     start[0] = start[1] = 0;
1224     edges[0] = Y_DIM_GR;
1225     edges[1] = X_DIM_GR;
1226 
1227     /* write the data in the buffer into the image array */
1228     if (GRwriteimage(ri_id, start, NULL, edges, (VOIDP)data)==FAIL)
1229     {
1230         printf("Error: Could not set write GR <%s>\n", gr_name);
1231         return FAIL;
1232     }
1233 
1234     /* obtain the reference number of the GR using its identifier */
1235     gr_ref = GRidtoref (ri_id);
1236 
1237     /* add the GR to the vgroup. the tag DFTAG_RIG is used */
1238     if (vgroup_id)
1239     {
1240         if (Vaddtagref (vgroup_id, TAG_GRP_IMAGE, gr_ref)==FAIL)
1241         {
1242             printf("Error: Could not add GR <%s> to group\n", gr_name);
1243             return FAIL;
1244         }
1245     }
1246 
1247     /* terminate access to the raster image */
1248     if (GRendaccess (ri_id)==FAIL)
1249     {
1250         printf("Error: Could not close GR <%s>\n", gr_name);
1251         return FAIL;
1252     }
1253 
1254     /* add an annotation and label to the object */
1255     if (add_an(file_id, DFTAG_RI, gr_ref)<0)
1256         return FAIL;
1257 
1258     return SUCCEED;
1259 
1260 }
1261 
1262 /*-------------------------------------------------------------------------
1263  * Function: add_glb_attrs
1264  *
1265  * Purpose: utility function to write global attributes
1266  *
1267  * Return: SUCCEED, FAIL
1268  *
1269  * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu
1270  *
1271  * Date: July 30, 2003
1272  *
1273  *-------------------------------------------------------------------------
1274  */
1275 static
add_glb_attrs(const char * fname,int32 file_id,int32 sd_id,int32 gr_id)1276 int add_glb_attrs(const char *fname,
1277                    int32 file_id,
1278                    int32 sd_id,
1279                    int32 gr_id)
1280 
1281 {
1282     uint8 attr_values[2]={1,2};
1283     int   n_values=2;
1284 
1285    /*-------------------------------------------------------------------------
1286     * make SDS global attributes
1287     *-------------------------------------------------------------------------
1288     */
1289     /* assign an attribute to the SD */
1290     if (SDsetattr(sd_id, "MySDgattr", DFNT_UINT8, n_values, (VOIDP)attr_values)==FAIL){
1291         printf("Could not set SDS attr\n");
1292         return FAIL;
1293     }
1294 
1295    /*-------------------------------------------------------------------------
1296     * make GR global attributes
1297     *-------------------------------------------------------------------------
1298     */
1299 
1300     /* assign an attribute to the GR */
1301     if (GRsetattr(gr_id, "MyGRgattr", DFNT_UINT8, n_values, (VOIDP)attr_values)==FAIL){
1302         printf("Could not set GR attr\n");
1303         return FAIL;
1304     }
1305 
1306     return SUCCEED;
1307 }
1308 
1309 
1310 /*-------------------------------------------------------------------------
1311  * Function: add_r8
1312  *
1313  * Purpose: utility function to read an image data file and save the image with the
1314  *  DFR8 - Single-file 8-Bit Raster Image Interface,
1315  *  optionally inserting the image into the group VGROUP_ID
1316  *
1317  * Return: SUCCEED, FAIL
1318  *
1319  * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu
1320  *
1321  * Date: July 3, 2003
1322  *
1323  *-------------------------------------------------------------------------
1324  */
1325 
1326 static
add_r8(const char * image_file,const char * fname,int32 file_id,int32 vgroup_id)1327 int add_r8(const char* image_file,
1328             const char *fname,
1329             int32 file_id,
1330             int32 vgroup_id)
1331 {
1332     int32  ri_ref;                     /* reference number of the GR image */
1333     char   *srcdir = getenv("srcdir"); /* the source directory */
1334     char   data_file[512]="";          /* buffer to hold name of existing data file */
1335 
1336     /* compose the name of the file to open, using the srcdir, if appropriate */
1337     if ( srcdir )
1338     {
1339         HDstrcpy(data_file, srcdir);
1340         HDstrcat(data_file, "/");
1341     }
1342     HDstrcat( data_file, image_file);
1343 
1344     if ( read_data(data_file) > 0 )
1345     {
1346         /* add a palette */
1347         if (DFR8setpalette(pal_rgb)==FAIL){
1348             printf( "Could not set palette for image\n");
1349             return FAIL;
1350         }
1351 
1352         /* write the image */
1353         if (DFR8addimage(fname, g_image_data, g_lenght_x, g_lenght_y, (uint16)0)==FAIL){
1354             printf( "Could not write palette for image\n");
1355             return FAIL;
1356         }
1357 
1358         /* obtain the reference number of the RIS8 */
1359         ri_ref = DFR8lastref();
1360 
1361         /* add the image to the vgroup. the tag DFTAG_RIG is used */
1362         if (vgroup_id)
1363         {
1364             if (Vaddtagref (vgroup_id, TAG_GRP_IMAGE, ri_ref)==FAIL){
1365                 printf( "Could not add image to group\n");
1366                 return FAIL;
1367             }
1368         }
1369 
1370         /* add an annotation and label to the object */
1371         if (add_an(file_id, TAG_GRP_IMAGE, ri_ref)<0)
1372             return FAIL;
1373     }
1374 
1375     if ( g_image_data != NULL )
1376     {
1377         HDfree( g_image_data );
1378         g_image_data=NULL;
1379     }
1380 
1381     return SUCCEED;
1382 }
1383 
1384 
1385 /*-------------------------------------------------------------------------
1386  * Function: add_r24
1387  *
1388  * Purpose: utility function to read an image data file and save the image with the
1389  *  DF24 - Single-file 24-Bit Raster Image Interface,
1390  *  optionally inserting the image into the group VGROUP_ID
1391  *
1392  * Return: SUCCEED, FAIL
1393  *
1394  * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu
1395  *
1396  * Date: July 3, 2003
1397  *
1398  *-------------------------------------------------------------------------
1399  */
1400 static
add_r24(const char * image_file,const char * fname,int32 file_id,intn il,int32 vgroup_id)1401 int add_r24(const char* image_file,
1402             const char *fname,
1403             int32 file_id,
1404             intn il,
1405             int32 vgroup_id)
1406 {
1407     int32  ri_ref;                      /* reference number of the GR image */
1408     char   *srcdir = getenv("srcdir");  /* the source directory */
1409     char   data_file[512]="";           /* buffer to hold name of existing data file */
1410 
1411     /* compose the name of the file to open, using the srcdir, if appropriate */
1412     if ( srcdir )
1413     {
1414         HDstrcpy(data_file, srcdir);
1415         HDstrcat(data_file, "/");
1416     }
1417     HDstrcat( data_file, image_file);
1418 
1419     if ( read_data(data_file) > 0 )
1420     {
1421         /* set interlace */
1422         if (DF24setil(il)==FAIL){
1423             printf( "Could not set interlace for image\n");
1424             return FAIL;
1425         }
1426 
1427         /* write the image */
1428         if (DF24addimage(fname, g_image_data, g_lenght_x, g_lenght_y)==FAIL){
1429             printf( "Could not write image\n");
1430             return FAIL;
1431         }
1432 
1433         /* obtain the reference number of the RIS24 */
1434         ri_ref = DF24lastref();
1435 
1436         /* add the image to the vgroup. the tag DFTAG_RIG is used */
1437         if (vgroup_id)
1438         {
1439             if (Vaddtagref (vgroup_id, TAG_GRP_IMAGE, ri_ref)==FAIL)
1440             {
1441                 printf( "Could not set group for image\n");
1442                 return FAIL;
1443             }
1444         }
1445 
1446         /* add an annotation and label to the object */
1447         if (add_an(file_id, TAG_GRP_IMAGE, ri_ref)<0)
1448             return FAIL;
1449 
1450     } /* read_data */
1451 
1452     if ( g_image_data != NULL )
1453     {
1454         HDfree( g_image_data );
1455         g_image_data=NULL;
1456     }
1457 
1458     return SUCCEED;
1459 }
1460 
1461 
1462 
1463 /*-------------------------------------------------------------------------
1464  * Function: add_sd
1465  *
1466  * Purpose: utility function to write with
1467  *  SD - Multifile Scientific Data Interface,
1468  *  optionally :
1469  *   1)inserting the SD into the group VGROUP_ID
1470  *   2)making the dataset chunked and/or compressed
1471  *
1472  * Return: SUCCEED, FAIL
1473  *
1474  * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu
1475  *
1476  * Date: July 3, 2003
1477  *
1478  *-------------------------------------------------------------------------
1479  */
1480 static
add_sd(const char * fname,int32 file_id,int32 sd_id,const char * sds_name,int32 vgroup_id,int32 chunk_flags,comp_coder_t comp_type,comp_info * comp_info)1481 int add_sd(const char *fname,       /* file name */
1482             int32 file_id,           /* file ID */
1483             int32 sd_id,             /* SD id */
1484             const char* sds_name,    /* sds name */
1485             int32 vgroup_id,         /* group ID */
1486             int32 chunk_flags,       /* chunk flags */
1487             comp_coder_t comp_type,  /* compression flag */
1488             comp_info *comp_info     /* compression structure */ )
1489 
1490 {
1491     int32  sds_id,       /* data set identifier */
1492            sds_ref,      /* reference number of the data set */
1493            dim_sds[2],   /* dimension of the data set */
1494            rank = 2,     /* rank of the data set array */
1495            n_values,     /* number of values of attribute */
1496            dim_index,    /* dimension index */
1497            dim_id,       /* dimension ID */
1498            start[2],     /* write start */
1499            edges[2],     /* write edges */
1500            fill_value=2, /* fill value */
1501            data[Y_DIM][X_DIM],
1502            bits_per_pixel=32;
1503     float32 sds_values[2] = {2., 10.}; /* values of the SDS attribute  */
1504     int16   data_X[X_DIM];             /* X dimension dimension scale */
1505     float64 data_Y[Y_DIM];             /* Y dimension dimension scale */
1506     int     i, j;
1507     HDF_CHUNK_DEF chunk_def;           /* Chunking definitions */
1508 
1509     /* set the size of the SDS's dimension */
1510     dim_sds[0] = Y_DIM;
1511     dim_sds[1] = X_DIM;
1512 
1513     /*define some compression specific parameters */
1514     switch(comp_type)
1515     {
1516     default:
1517         break;
1518     case COMP_CODE_RLE:
1519         break;
1520 
1521     case COMP_CODE_SKPHUFF:
1522         comp_info->skphuff.skp_size = 1;
1523         break;
1524 
1525     case COMP_CODE_DEFLATE:
1526         comp_info->deflate.level = 6;
1527         break;
1528 
1529     case COMP_CODE_SZIP:
1530 #ifdef H4_HAVE_LIBSZ
1531         if (SZ_encoder_enabled()) {
1532             comp_info->szip.pixels_per_block = 2;
1533             comp_info->szip.options_mask = SZ_EC_OPTION_MASK;
1534             comp_info->szip.options_mask |= SZ_RAW_OPTION_MASK;
1535             comp_info->szip.pixels = 0;
1536             comp_info->szip.pixels_per_scanline = 0;
1537             comp_info->szip.bits_per_pixel = 0;
1538         } else {
1539             printf("Warning: SZIP encoding not available\n");
1540         }
1541 #else
1542         printf("Warning: SZIP compression not available\n");
1543 #endif
1544         break;
1545     }
1546 
1547     /* data set data initialization */
1548     for (j = 0; j < Y_DIM; j++) {
1549         for (i = 0; i < X_DIM; i++)
1550             data[j][i] = (i + j) + 1;
1551     }
1552     /* initialize dimension scales */
1553     for (i=0; i < X_DIM; i++) data_X[i] = i;
1554     for (i=0; i < Y_DIM; i++) data_Y[i] = 0.1 * i;
1555 
1556     /* create the SDS */
1557     if ((sds_id = SDcreate (sd_id, sds_name, DFNT_INT32, rank, dim_sds))<0)
1558     {
1559         printf( "Could not create SDS <%s>\n",sds_name);
1560         return FAIL;
1561     }
1562 
1563     /* set chunk */
1564     if ( (chunk_flags == HDF_CHUNK) || (chunk_flags == (HDF_CHUNK | HDF_COMP)) )
1565     {
1566         set_chunk_def(comp_type,
1567             dim_sds,
1568             1,
1569             bits_per_pixel,
1570             &chunk_def);
1571         if (SDsetchunk (sds_id, chunk_def, chunk_flags)==FAIL)  {
1572             printf( "Failed to set chunk for SDS <%s>\n", sds_name);
1573             goto fail;
1574         }
1575     }
1576 
1577     /* use compress without chunk-in */
1578     else if ( chunk_flags==HDF_NONE &&
1579         comp_type>COMP_CODE_NONE && comp_type<COMP_CODE_INVALID)
1580     {
1581         if(SDsetcompress (sds_id, comp_type, comp_info)==FAIL){
1582             printf( "Failed to set compress for SDS <%s>\n", sds_name);
1583             goto fail;
1584         }
1585     }
1586 
1587     /* set a fill value */
1588     if (SDsetfillvalue (sds_id, (VOIDP)&fill_value)==FAIL){
1589         printf( "Failed to set fillvaclue for SDS <%s>\n", sds_name);
1590         goto fail;
1591     }
1592 
1593     /* define the location and size of the data to be written to the data set */
1594     start[0] = 0;
1595     start[1] = 0;
1596     edges[0] = Y_DIM;
1597     edges[1] = X_DIM;
1598 
1599     /* write the stored data to the data set */
1600     if (SDwritedata (sds_id, start, NULL, edges, (VOIDP)data)==FAIL){
1601         printf( "Failed to set write for SDS <%s>\n", sds_name);
1602         goto fail;
1603     }
1604 
1605     /* assign an attribute to the SDS */
1606     n_values = 2;
1607     if (SDsetattr(sds_id,"Valid_range",DFNT_FLOAT32,n_values,(VOIDP)sds_values)==FAIL){
1608         printf( "Failed to set attr for SDS <%s>\n", sds_name);
1609         goto fail;
1610     }
1611 
1612     /*  For each dimension of the data set specified in SDS_NAME,
1613     *  get its dimension identifier and set dimension name
1614     *  and dimension scale. Note that data type of dimension scale
1615     *  can be different between dimensions and can be different from
1616     *  SDS data type.
1617     */
1618     for (dim_index = 0; dim_index < rank; dim_index++)
1619     {
1620         /* select the dimension at position dim_index */
1621         dim_id = SDgetdimid (sds_id, dim_index);
1622 
1623         /* assign name and dimension scale to selected dimension */
1624         switch (dim_index)
1625         {
1626         case 0:
1627             n_values = Y_DIM;
1628 
1629             if (SDsetdimname (dim_id, "Y_Axis")==FAIL){
1630                 printf( "Failed to set dims for SDS <%s>\n", sds_name);
1631                 goto fail;
1632             }
1633             if (SDsetdimscale (dim_id,n_values,DFNT_FLOAT64,(VOIDP)data_Y)==FAIL){
1634                 printf( "Failed to set dims for SDS <%s>\n", sds_name);
1635                 goto fail;
1636             }
1637             if (SDsetattr (dim_id, "info", DFNT_CHAR8, 7,"meters")==FAIL){
1638                 printf( "Failed to set dims for SDS <%s>\n", sds_name);
1639                 goto fail;
1640             }
1641             break;
1642         case 1:
1643             n_values = X_DIM;
1644 
1645             if (SDsetdimname (dim_id, "X_Axis")==FAIL){
1646                 printf( "Failed to set dims for SDS <%s>\n", sds_name);
1647                 goto fail;
1648             }
1649             if (SDsetdimscale (dim_id,n_values,DFNT_INT16,(VOIDP)data_X)==FAIL){
1650                 printf( "Failed to set dims for SDS <%s>\n", sds_name);
1651                 goto fail;
1652             }
1653             if (SDsetattr (dim_id, "info", DFNT_CHAR8, 5,"feet")==FAIL){
1654                 printf( "Failed to set dims for SDS <%s>\n", sds_name);
1655                 goto fail;
1656             }
1657             break;
1658         default:
1659             break;
1660         }
1661     }
1662 
1663     /* obtain the reference number of the SDS using its identifier */
1664     sds_ref = SDidtoref (sds_id);
1665 
1666     /* add the SDS to the vgroup. the tag DFTAG_NDG is used */
1667     if (vgroup_id)
1668     {
1669         if (Vaddtagref (vgroup_id, TAG_GRP_DSET, sds_ref)==FAIL)
1670         {
1671             printf( "Failed to add ref for SDS <%s>\n", sds_name);
1672             goto fail;
1673         }
1674     }
1675 
1676     /* add an annotation and label to the object */
1677     add_an(file_id, TAG_GRP_DSET, sds_ref);
1678 
1679     /* terminate access to the SDS */
1680     if (SDendaccess (sds_id)==FAIL){
1681         printf( "Failed to end SDS <%s>\n", sds_name);
1682         goto fail;
1683     }
1684 
1685     return SUCCEED;
1686 
1687 fail:
1688     SDendaccess (sds_id);
1689     return FAIL;
1690 }
1691 
1692 
1693 /*-------------------------------------------------------------------------
1694  * Function: add_sd3d
1695  *
1696  * Purpose: utility function to write with
1697  *  SD - Multifile Scientific Data Interface,
1698  *  optionally :
1699  *   1)inserting the SD into the group VGROUP_ID
1700  *   2)making the dataset chunked and/or compressed
1701  *
1702  * Return: SUCCEED, FAIL
1703  *
1704  * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu
1705  *
1706  * Date: July 3, 2003
1707  *
1708  *-------------------------------------------------------------------------
1709  */
1710 
1711 static
add_sd3d(const char * fname,int32 file_id,int32 sd_id,const char * sds_name,int32 vgroup_id,int32 chunk_flags,comp_coder_t comp_type,comp_info * comp_info)1712 int add_sd3d(const char *fname,       /* file name */
1713               int32 file_id,           /* file ID */
1714               int32  sd_id,            /* SD interface identifier */
1715               const char* sds_name,    /* sds name */
1716               int32 vgroup_id,         /* group ID */
1717               int32 chunk_flags,       /* chunk flags */
1718               comp_coder_t comp_type,  /* compression flag */
1719               comp_info *comp_info     /* compression structure */ )
1720 
1721 {
1722     int32  sds_id,       /* data set identifier */
1723            sds_ref,      /* reference number of the data set */
1724            dim_sds[3],   /* dimension of the data set */
1725            rank = 3,     /* rank of the data set array */
1726            start[3],     /* write start */
1727            fill_value=2, /* fill value */
1728            data[Z_DIM][Y_DIM][X_DIM];
1729     int    i, j, k;
1730     HDF_CHUNK_DEF chunk_def;           /* Chunking definitions */
1731 
1732 
1733     /* Define chunk's dimensions */
1734     chunk_def.chunk_lengths[0] = Z_DIM/2;
1735     chunk_def.chunk_lengths[1] = Y_DIM/2;
1736     chunk_def.chunk_lengths[2] = X_DIM/2;
1737     /* To use chunking with RLE, Skipping Huffman, and GZIP compression */
1738     chunk_def.comp.chunk_lengths[0] = Y_DIM/2;
1739     chunk_def.comp.chunk_lengths[1] = Y_DIM/2;
1740     chunk_def.comp.chunk_lengths[2] = X_DIM/2;
1741 
1742     /* GZIP compression, set compression type, flag and deflate level*/
1743     chunk_def.comp.comp_type = COMP_CODE_DEFLATE;
1744     chunk_def.comp.cinfo.deflate.level = 6;
1745 
1746     /* data set data initialization */
1747     for (k = 0; k < Z_DIM; k++){
1748         for (j = 0; j < Y_DIM; j++)
1749             for (i = 0; i < X_DIM; i++)
1750                 data[k][j][i] = (i + j) + 1;
1751     }
1752 
1753     /* set the size of the SDS's dimension */
1754     dim_sds[0] = Z_DIM;
1755     dim_sds[1] = Y_DIM;
1756     dim_sds[2] = X_DIM;
1757 
1758     /* create the SDS */
1759     if ((sds_id = SDcreate (sd_id, sds_name, DFNT_INT32, rank, dim_sds))<0)
1760     {
1761         printf( "Could not create SDS <%s>\n",sds_name);
1762         return FAIL;
1763     }
1764 
1765     /* set chunk */
1766     if ( (chunk_flags == HDF_CHUNK) || (chunk_flags == (HDF_CHUNK | HDF_COMP)) )
1767     {
1768         if (SDsetchunk (sds_id, chunk_def, chunk_flags)==FAIL){
1769             printf( "Failed to set chunk for SDS <%s>\n", sds_name);
1770             goto fail;
1771         }
1772     }
1773 
1774     /* use compress without chunk-in */
1775     else if ( (chunk_flags==HDF_NONE) && comp_type>COMP_CODE_NONE && comp_type<COMP_CODE_INVALID)
1776     {
1777         if (SDsetcompress (sds_id, comp_type, comp_info)==FAIL){
1778             printf( "Failed to set compress for SDS <%s>\n", sds_name);
1779             goto fail;
1780         }
1781     }
1782 
1783     /* set a fill value */
1784     if (SDsetfillvalue (sds_id, (VOIDP)&fill_value)==FAIL)
1785     {
1786         printf( "Failed to set fill for SDS <%s>\n", sds_name);
1787         goto fail;
1788     }
1789 
1790     /* define the location and size of the data to be written to the data set */
1791     start[0] = 0;
1792     start[1] = 0;
1793     start[2] = 0;
1794 
1795     /* write the stored data to the data set */
1796     if (SDwritedata (sds_id, start, NULL, dim_sds, (VOIDP)data)==FAIL)
1797     {
1798         printf( "Failed to write SDS <%s>\n", sds_name);
1799         goto fail;
1800     }
1801 
1802     /* obtain the reference number of the SDS using its identifier */
1803     sds_ref = SDidtoref (sds_id);
1804 
1805     /* add the SDS to the vgroup. the tag DFTAG_NDG is used */
1806     if (vgroup_id)
1807     {
1808         if (Vaddtagref (vgroup_id, TAG_GRP_DSET, sds_ref)==FAIL)
1809         {
1810             printf( "Failed to set ref for SDS <%s>\n", sds_name);
1811             goto fail;
1812         }
1813     }
1814 
1815     /* add an annotation and label to the object */
1816     add_an(file_id, TAG_GRP_DSET, sds_ref);
1817 
1818     /* terminate access to the SDS */
1819     if (SDendaccess (sds_id)==FAIL)
1820     {
1821         printf( "Failed to end SDS <%s>\n", sds_name);
1822         goto fail;
1823     }
1824 
1825     return SUCCEED;
1826 
1827 fail:
1828     SDendaccess (sds_id);
1829     return FAIL;
1830 }
1831 
1832 
1833 
1834 /*-------------------------------------------------------------------------
1835  * Function: add_empty_sd
1836  *
1837  * Purpose: utility function to write an empty sds
1838  *
1839  *-------------------------------------------------------------------------
1840  */
1841 static
add_empty_sd(int32 sd_id,const char * sds_name)1842 int add_empty_sd(int32 sd_id,             /* SD id */
1843                  const char* sds_name     /* sds name */
1844                 )
1845 
1846 {
1847     int32  sds_id,       /* data set identifier */
1848            dim_sds[2],   /* dimension of the data set */
1849            rank = 2;     /* rank of the data set array */
1850 
1851     /* set the size of the SDS's dimension */
1852     dim_sds[0] = Y_DIM;
1853     dim_sds[1] = X_DIM;
1854 
1855     /* create the SDS */
1856     if ((sds_id = SDcreate (sd_id, sds_name, DFNT_INT32, rank, dim_sds))<0)
1857     {
1858         printf( "Could not create SDS <%s>\n",sds_name);
1859         return FAIL;
1860     }
1861 
1862     /* terminate access to the SDS */
1863     if (SDendaccess (sds_id)==FAIL)
1864     {
1865         printf( "Failed to end SDS <%s>\n", sds_name);
1866         return FAIL;
1867     }
1868 
1869     return SUCCEED;
1870 
1871 }
1872 
1873 /*-------------------------------------------------------------------------
1874  * Function: add_unl_sd
1875  *
1876  * Purpose: utility function to create a sds with unlimited dimension
1877  *
1878  *-------------------------------------------------------------------------
1879  */
1880 static
add_unl_sd(int32 sd_id,const char * sds_name,int do_write)1881 int add_unl_sd(int32 sd_id,             /* SD id */
1882                const char* sds_name,    /* sds name */
1883                int do_write
1884                 )
1885 
1886 {
1887     int32  sds_id,       /* data set identifier */
1888            dim_sds[2],   /* dimension of the data set */
1889            rank = 2;     /* rank of the data set array */
1890 
1891     /* set the size of the SDS's dimension */
1892     dim_sds[0] = SD_UNLIMITED;
1893     dim_sds[1] = X_DIM;
1894 
1895     /* create the SDS */
1896     if ((sds_id = SDcreate (sd_id, sds_name, DFNT_INT32, rank, dim_sds))<0)
1897     {
1898         printf( "Could not create SDS <%s>\n",sds_name);
1899         return FAIL;
1900     }
1901 
1902     if ( do_write )
1903     {
1904 
1905         int32 start[2],     /* write start */
1906             edges[2],       /* write edges */
1907             buf[Y_DIM][X_DIM];
1908         int i, j;
1909 
1910         /* data set data initialization */
1911         for (j = 0; j < Y_DIM; j++)
1912         {
1913             for (i = 0; i < X_DIM; i++)
1914             {
1915                 buf[j][i] = (i + j) + 1;
1916             }
1917         }
1918         /* define the location and size of the data to be written to the data set */
1919         start[0] = 0;
1920         start[1] = 0;
1921         edges[0] = Y_DIM;
1922         edges[1] = X_DIM;
1923 
1924         /* write the stored data to the data set */
1925         if (SDwritedata (sds_id, start, NULL, edges, (VOIDP)buf)==FAIL)
1926         {
1927             printf( "Failed to set write for SDS <%s>\n", sds_name);
1928             goto fail;
1929         }
1930 
1931     }
1932 
1933     /* terminate access to the SDS */
1934     if (SDendaccess (sds_id)==FAIL)
1935     {
1936         printf( "Failed to end SDS <%s>\n", sds_name);
1937         return FAIL;
1938     }
1939 
1940     return SUCCEED;
1941 
1942 fail:
1943 
1944     SDendaccess (sds_id);
1945     return FAIL;
1946 
1947 }
1948 
1949 
1950 /*-------------------------------------------------------------------------
1951  * Function: add_vs
1952  *
1953  * Purpose: utility function to write with
1954  *  VS - Vdata Interface,
1955  *  optionally inserting the VS into the group VGROUP_ID
1956  *
1957  * Return: SUCCEED, FAIL
1958  *
1959  * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu
1960  *
1961  * Date: July 3, 2003
1962  *
1963  *-------------------------------------------------------------------------
1964  */
1965 
1966 static
add_vs(const char * vs_name,int32 file_id,int32 vgroup_id)1967 int add_vs(const char* vs_name,
1968             int32 file_id,
1969             int32 vgroup_id)
1970 {
1971     int32   vdata_ref,      /* reference number of the vdata */
1972             vdata_tag,      /* tag number of the vdata */
1973             vdata_id;       /* vdata id */
1974     int32   attr_n_values   = 3; /* number of values in the vdata attribute */
1975     int32   field_n_values  = 4; /* number of values in the field attribute */
1976     char    vd_attr[3]      = {'A', 'B', 'C'};/* vdata attribute values*/
1977     int32   fld_attr[4]     = {2, 4, 6, 8};   /* field attribute values*/
1978     float32 data_buf[N_RECORDS][N_VALS_PER_REC]; /* buffer for vdata values */
1979     int     i;
1980 
1981     /* Initialize the VS interface */
1982     Vstart (file_id);
1983 
1984     /* Create a new vdata, set to -1 to create  */
1985     vdata_ref = -1,
1986     vdata_id = VSattach (file_id, vdata_ref, "w");
1987 
1988     /* Set name and class name of the vdata */
1989     if (VSsetname (vdata_id, vs_name)==FAIL){
1990         printf( "Could not set name for VS\n");
1991         return FAIL;
1992     }
1993     if (VSsetclass (vdata_id, CLASS_NAME)==FAIL){
1994         printf( "Could not set class for VS\n");
1995         return FAIL;
1996     }
1997 
1998     /* Introduce each field's name, data type, and order */
1999     VSfdefine (vdata_id, FIELD1_NAME, DFNT_FLOAT32, ORDER_1 );
2000     VSfdefine (vdata_id, FIELD2_NAME, DFNT_FLOAT32, ORDER_2 );
2001     VSfdefine (vdata_id, FIELD3_NAME, DFNT_FLOAT32, ORDER_3 );
2002 
2003     /* Finalize the definition of the fields */
2004     if (VSsetfields (vdata_id, FIELDNAME_LIST)==FAIL){
2005         printf( "Could not set fields for VS\n");
2006         return FAIL;
2007     }
2008 
2009     /*
2010     * Buffer the data by the record for fully interlaced mode.  Note that the
2011     * first three elements contain the three values of the first field, the
2012     * fourth element contains the value of the second field, and the last two
2013     * elements contain the two values of the third field.
2014     */
2015     for (i = 0; i < N_RECORDS; i++)
2016     {
2017         data_buf[i][0] = (float32)1.0 * i;
2018         data_buf[i][1] = (float32)2.0 * i;
2019         data_buf[i][2] = (float32)3.0 * i;
2020         data_buf[i][3] = (float32)0.1 + i;
2021         data_buf[i][4] = 0.0;
2022         data_buf[i][5] = 65.0;
2023     }
2024 
2025     /* Write the data from data_buf to the vdata with full interlacing mode */
2026     if (VSwrite (vdata_id, (uint8 *)data_buf, N_RECORDS,FULL_INTERLACE)==FAIL){
2027         printf( "Could not write VS\n");
2028         return FAIL;
2029     }
2030 
2031     /* Attach an attribute to the vdata, i.e., indicated by the second parameter */
2032     if (VSsetattr (vdata_id,_HDF_VDATA,"Myattr",DFNT_CHAR,
2033         attr_n_values, vd_attr)==FAIL){
2034         printf( "Could not set attr for VS\n");
2035         return FAIL;
2036     }
2037 
2038     /* Attach an attribute to the field 0 */
2039     if (VSsetattr (vdata_id, 0, "Myfattr", DFNT_INT32,
2040         field_n_values, fld_attr)==FAIL){
2041         printf( "Could not set attr for VS\n");
2042         return FAIL;
2043     }
2044 
2045     /* Obtain the tag and ref number of the vdata */
2046     vdata_tag = VSQuerytag (vdata_id);
2047     vdata_ref = VSQueryref (vdata_id);
2048 
2049     /* add the VS to the vgroup*/
2050     if (vgroup_id)
2051     {
2052         if (Vaddtagref (vgroup_id, vdata_tag, vdata_ref)==FAIL){
2053             printf( "Could not set group for VS\n");
2054             return FAIL;
2055         }
2056     }
2057 
2058     /* terminate access to the VSs */
2059     if (VSdetach (vdata_id)==FAIL){
2060         printf( "Could not detach VS\n");
2061         return FAIL;
2062     }
2063 
2064     /* Terminate access to the VS interface */
2065     if (Vend (file_id)==FAIL){
2066         printf( "Could not end VS\n");
2067         return FAIL;
2068     }
2069 
2070     /* add an annotation and label to the vdata */
2071     if (add_an(file_id, vdata_tag, vdata_ref)<0)
2072         return FAIL;
2073 
2074     return SUCCEED;
2075 }
2076 
2077 
2078 /*-------------------------------------------------------------------------
2079  * Function: add_file_an
2080  *
2081  * Purpose: utility function to write a file AN
2082  *
2083  * Return: SUCCEED, FAIL
2084  *
2085  * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu
2086  *
2087  * Date: July 30, 2003
2088  *
2089  *-------------------------------------------------------------------------
2090  */
2091 
2092 static
add_file_an(int32 file_id)2093 int add_file_an(int32 file_id)
2094 {
2095     int32 an_id,        /* AN interface identifier */
2096           file_label_id,/* file label identifier */
2097           file_desc_id, /* file description identifier */
2098           data_label_id,  /* data label identifier */
2099           data_desc_id,   /* data description identifier */
2100           vgroup_id;
2101     uint16 vgroup_tag, vgroup_ref;
2102 
2103     /* Initialize the AN interface */
2104     an_id = ANstart (file_id);
2105 
2106    /*-------------------------------------------------------------------------
2107     * file labels and annotations
2108     *-------------------------------------------------------------------------
2109     */
2110 
2111     /* Create the file label */
2112     file_label_id = ANcreatef (an_id, AN_FILE_LABEL);
2113 
2114     /* Write the annotations to the file label */
2115     if (ANwriteann (file_label_id,FILE_LABEL_TXT,strlen (FILE_LABEL_TXT))==FAIL)
2116     {
2117         printf( "Could not write AN\n");
2118         return FAIL;
2119     }
2120 
2121     /* Create file description */
2122     file_desc_id = ANcreatef (an_id, AN_FILE_DESC);
2123 
2124     /* Write the annotation to the file description */
2125     if (ANwriteann (file_desc_id, FILE_DESC_TXT, strlen (FILE_DESC_TXT))==FAIL)
2126     {
2127         printf( "Could not write AN\n");
2128         return FAIL;
2129     }
2130 
2131    /*-------------------------------------------------------------------------
2132     * data labels and annotations
2133     *-------------------------------------------------------------------------
2134     */
2135 
2136     /* Create a vgroup in the V interface*/
2137     Vstart (file_id);
2138     vgroup_id = Vattach (file_id, -1, "w");
2139     if (Vsetname (vgroup_id, "an_group")==FAIL)
2140     {
2141         printf( "Could not set name for VG\n");
2142         return FAIL;
2143     }
2144 
2145     /* Obtain the tag and ref number of the vgroup */
2146     vgroup_tag = (uint16) VQuerytag (vgroup_id);
2147     vgroup_ref = (uint16) VQueryref (vgroup_id);
2148 
2149     /* Create the data label for the vgroup identified by its tag and ref number */
2150     data_label_id = ANcreate (an_id, vgroup_tag, vgroup_ref, AN_DATA_LABEL);
2151 
2152     /* Write the annotation text to the data label */
2153     if (ANwriteann (data_label_id, DATA_LABEL_TXT, strlen (DATA_LABEL_TXT))==FAIL)
2154     {
2155         printf( "Could not write AN\n");
2156         return FAIL;
2157     }
2158 
2159     /* Create the data description for the vgroup identified by its tag and ref number */
2160     data_desc_id = ANcreate (an_id, (uint16)vgroup_tag, (uint16)vgroup_ref, AN_DATA_DESC);
2161 
2162     /* Write the annotation text to the data description */
2163     if (ANwriteann (data_desc_id, DATA_DESC_TXT, strlen (DATA_DESC_TXT))==FAIL)
2164     {
2165         printf( "Could not write AN\n");
2166         return FAIL;
2167     }
2168 
2169     /* Teminate access to the vgroup and to the V interface */
2170     if (Vdetach (vgroup_id)==FAIL)
2171     {
2172         printf( "Could not detach VG\n");
2173         return FAIL;
2174     }
2175     if (Vend (file_id)==FAIL){
2176         printf( "Could not end VG\n");
2177         return FAIL;
2178     }
2179 
2180     /* Terminate access to each annotation explicitly */
2181     if (ANendaccess (file_label_id)==FAIL||
2182         ANendaccess (file_desc_id)==FAIL||
2183         ANendaccess (data_label_id)==FAIL||
2184         ANendaccess (data_desc_id)==FAIL){
2185         printf( "Could not end AN\n");
2186         return FAIL;
2187     }
2188 
2189     /* Terminate access to the AN interface */
2190     if (ANend (an_id)==FAIL==FAIL){
2191         printf( "Could not end AN\n");
2192         return FAIL;
2193     }
2194 
2195     return SUCCEED;
2196 }
2197 
2198 
2199 /*-------------------------------------------------------------------------
2200  * Function: add_pal
2201  *
2202  * Purpose: utility function to write a palette
2203  *
2204  * Return: SUCCEED, FAIL
2205  *
2206  * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu
2207  *
2208  * Date: August 19, 2003
2209  *
2210  *-------------------------------------------------------------------------
2211  */
2212 
2213 static
add_pal(const char * fname)2214 int add_pal(const char* fname)
2215 {
2216     uint8  pal[256*3];
2217     int i, n;
2218 
2219    /*-------------------------------------------------------------------------
2220     * define a palette, blue to red tones
2221     *-------------------------------------------------------------------------
2222     */
2223     for ( i=0, n=0; i< 256*3; i+=3, n++)
2224     {
2225         pal[i]  =n;      /* red */
2226         pal[i+1]=0;      /* green */
2227         pal[i+2]=255-n;  /* blue */
2228     }
2229 
2230     if (DFPaddpal(fname,pal)==FAIL){
2231         printf( "Failed to write palette in <%s>\n", fname);
2232         return FAIL;
2233     }
2234 
2235     return SUCCEED;
2236 }
2237 
2238 
2239 /*-------------------------------------------------------------------------
2240  * Function: add_sd_szip
2241  *
2242  * Purpose: utility function to write with SZIPed SDSs
2243  *  SD - Multifile Scientific Data Interface,
2244  *
2245  * Return: SUCCEED, FAIL
2246  *
2247  * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu
2248  *
2249  * Date: September 15, 2003
2250  *
2251  *-------------------------------------------------------------------------
2252  */
2253 static
add_sd_szip(const char * fname,int32 file_id,int32 sd_id,const char * sds_name,int32 vgroup_id,int32 chunk_flags,int32 nt,int32 bits_per_pixel,int32 * dim,void * data)2254 int add_sd_szip(const char *fname,       /* file name */
2255                  int32 file_id,           /* file ID */
2256                  int32 sd_id,             /* SD interface identifier */
2257                  const char* sds_name,    /* sds name */
2258                  int32 vgroup_id,         /* group ID */
2259                  int32 chunk_flags,       /* chunk flags */
2260                  int32 nt,                /* number type */
2261                  int32 bits_per_pixel,    /* szip parameter */
2262                  int32 *dim,              /* dimension of the data set */
2263                  void *data
2264                  )
2265 
2266 {
2267     int32          sds_id,            /* data set identifier */
2268                    sds_ref,           /* reference number of the data set */
2269                    rank = 2;          /* rank of the data set array */
2270     comp_coder_t   comp_type  = COMP_CODE_NONE;    /* compression flag */
2271     comp_info      comp_info;         /* compression structure */
2272     HDF_CHUNK_DEF  chunk_def;         /* chunking definitions */
2273     int32          edges[2],          /* write edges */
2274                    start[2]={0,0};    /* write start */
2275 
2276     edges[0]=dim[0];
2277     edges[1]=dim[1];
2278 
2279 #ifdef H4_HAVE_LIBSZ
2280     if (SZ_encoder_enabled()) {
2281         comp_type = COMP_CODE_SZIP;
2282         comp_info.szip.pixels_per_block = 2;
2283         comp_info.szip.options_mask = SZ_EC_OPTION_MASK;
2284         comp_info.szip.options_mask |= SZ_RAW_OPTION_MASK;
2285         comp_info.szip.pixels = 0;
2286         comp_info.szip.pixels_per_scanline = 0;
2287         comp_info.szip.bits_per_pixel = 0;
2288     } else {
2289         printf("Warning: SZIP encoding not available\n");
2290     }
2291 #else
2292     printf("Warning: SZIP compression not available\n");
2293 #endif
2294 
2295     /* create the SDS */
2296     sds_id = SDcreate (sd_id, sds_name, nt, rank, dim);
2297     if (sds_id < 0) {
2298         printf( "SDcreate failed for file <%s>\n",sds_name);
2299         return FAIL;
2300     }
2301 
2302     /* set chunk */
2303     if ( (chunk_flags == HDF_CHUNK) || (chunk_flags == (HDF_CHUNK | HDF_COMP)) )
2304     {
2305         set_chunk_def(comp_type,
2306             dim,
2307             1,
2308             bits_per_pixel,
2309             &chunk_def);
2310         if (SDsetchunk (sds_id, chunk_def, chunk_flags)==FAIL) {
2311             printf( "Failed to set chunk for SDS <%s>\n",sds_name);
2312             goto fail;
2313         }
2314     }
2315 
2316     /* use compress without chunk-in */
2317     else if ( chunk_flags==HDF_NONE &&
2318         comp_type>COMP_CODE_NONE && comp_type<COMP_CODE_INVALID)
2319     {
2320         if (SDsetcompress (sds_id, comp_type, &comp_info)==FAIL) {
2321             printf( "Failed to set compress for SDS <%s>\n",sds_name);
2322             goto fail;
2323         }
2324     }
2325 
2326     /* write the stored data to the data set */
2327     if (SDwritedata (sds_id, start, NULL, edges, (VOIDP)data)==FAIL) {
2328         printf( "Failed to writer SDS <%s>\n",sds_name);
2329         goto fail;
2330     }
2331 
2332     /* obtain the reference number of the SDS using its identifier */
2333     sds_ref = SDidtoref (sds_id);
2334 
2335     /* add the SDS to the vgroup. the tag DFTAG_NDG is used */
2336     if (vgroup_id)
2337     {
2338         if (Vaddtagref (vgroup_id, TAG_GRP_DSET, sds_ref)==FAIL) {
2339             printf( "Failed to set ref for SDS <%s>\n",sds_name);
2340             goto fail;
2341         }
2342     }
2343 
2344     /* terminate access to the SDS */
2345     if (SDendaccess (sds_id)==FAIL) {
2346         printf( "Failed to end SDS <%s>\n",sds_name);
2347         goto fail;
2348     }
2349 
2350     return SUCCEED;
2351 
2352 fail:
2353     SDendaccess (sds_id);
2354     return FAIL;
2355 }
2356 
2357 
2358 
2359 
2360 /*-------------------------------------------------------------------------
2361  * Function: do_file_all
2362  *
2363  * Purpose: writes all types of HDF objects
2364  *
2365  * Return: SUCCEED, FAIL
2366  *
2367  *-------------------------------------------------------------------------
2368  */
2369 
2370 static
do_file_all(char * fname)2371 int do_file_all(char* fname)
2372 {
2373     int32         vgroup1_id,   /* vgroup identifier */
2374                   vgroup2_id,   /* vgroup identifier */
2375                   vgroup3_id,   /* vgroup identifier */
2376                   vgroup_img_id,/* vgroup identifier */
2377                   file_id,      /* HDF file identifier, same for V interface */
2378                   gr_id,        /* GR interface identifier */
2379                   sd_id;        /* SD interface identifier */
2380     int32         attr_n_values = 3;  /* number of values in the vg attribute */
2381     char          vg_attr[3]    = {'A', 'B', 'C'};/* vg attribute values*/
2382     comp_coder_t  comp_type;    /* to retrieve compression type into */
2383     int32         chunk_flags;  /* Chunking flag */
2384     comp_info     comp_info;    /* compression structure */
2385 
2386    /*-------------------------------------------------------------------------
2387     * create a file with SDSs, images , groups and vdatas
2388     *-------------------------------------------------------------------------
2389     */
2390 
2391     /* create a HDF file */
2392     if ((file_id = Hopen (fname, DFACC_CREATE, (int16)0))<0)
2393     {
2394         printf("Error: Could not create file <%s>\n",fname);
2395         return FAIL;
2396     }
2397 
2398     /* initialize the SD interface */
2399     if ((sd_id = SDstart (fname, DFACC_RDWR))== FAIL)
2400     {
2401         printf("Error: Could not start SD interface\n");
2402         return FAIL;
2403     }
2404 
2405     /* initialize the GR interface */
2406     if ((gr_id = GRstart (file_id))== FAIL)
2407     {
2408         printf("Error: Could not start GR interface\n");
2409         return FAIL;
2410     }
2411 
2412     /* initialize the V interface */
2413     if (Vstart (file_id)==FAIL)
2414     {
2415         printf( "Could not start VG\n");
2416         return FAIL;
2417     }
2418 
2419 
2420    /*-------------------------------------------------------------------------
2421     * create groups
2422     *-------------------------------------------------------------------------
2423     */
2424 
2425 
2426     vgroup1_id = Vattach (file_id, -1, "w");
2427     if (Vsetname (vgroup1_id, "g1")==FAIL)
2428     {
2429         printf( "Could not name group\n");
2430         goto out;
2431     }
2432 
2433     /* attach an attribute to the vgroup */
2434     if (Vsetattr (vgroup1_id,"Myattr",DFNT_CHAR,attr_n_values,vg_attr)==FAIL)
2435     {
2436         printf( "Could set group attributes\n");
2437         goto out;
2438     }
2439 
2440     /* create the second vgroup */
2441     vgroup2_id = Vattach (file_id, -1, "w");
2442     if (Vsetname (vgroup2_id, "g2")==FAIL)
2443     {
2444         printf( "Could not name group\n");
2445         goto out;
2446     }
2447 
2448     /* create the 3rd vgroup */
2449     vgroup3_id = Vattach (file_id, -1, "w");
2450     if (Vsetname (vgroup3_id, "g3")==FAIL)
2451     {
2452         printf( "Could not name group\n");
2453         goto out;
2454     }
2455 
2456     /* insert the second vgroup into the first vgroup using its identifier */
2457     if (Vinsert (vgroup1_id, vgroup2_id)==FAIL)
2458     {
2459         printf( "Could not insert VG\n");
2460         goto out;
2461     }
2462 
2463     /* insert the 3rd vgroup into the 2nd vgroup using its identifier */
2464     if (Vinsert (vgroup2_id, vgroup3_id)==FAIL)
2465     {
2466         printf( "Could not insert VG\n");
2467         goto out;
2468     }
2469 
2470     /* create the 4th vgroup, for images */
2471     vgroup_img_id = Vattach (file_id, -1, "w");
2472     if (Vsetname (vgroup_img_id, "images")==FAIL)
2473     {
2474         printf( "Could not name group\n");
2475         goto out;
2476     }
2477 
2478 
2479 
2480    /*-------------------------------------------------------------------------
2481     * add some SDSs to the file
2482     * duplicates are inserted in the groups "g1", "g2", "g3" and root
2483     *-------------------------------------------------------------------------
2484     */
2485 
2486 
2487     /* add non chunked, non compressed sds */
2488     chunk_flags = HDF_NONE;
2489     comp_type   = COMP_CODE_NONE;
2490     if (add_sd(fname,file_id,sd_id,"dset1",vgroup1_id,chunk_flags,comp_type,NULL)<0)
2491         goto out;
2492     if (add_sd(fname,file_id,sd_id,"dset2",vgroup2_id,chunk_flags,comp_type,NULL)<0)
2493         goto out;
2494     if (add_sd(fname,file_id,sd_id,"dset3",vgroup3_id,chunk_flags,comp_type,NULL)<0)
2495         goto out;
2496     if (add_sd(fname,file_id,sd_id,"dset4",0,chunk_flags,comp_type,NULL)<0)
2497         goto out;
2498     if (add_sd(fname,file_id,sd_id,"dset5",0,chunk_flags,comp_type,NULL)<0)
2499         goto out;
2500     if (add_sd(fname,file_id,sd_id,"dset6",0,chunk_flags,comp_type,NULL)<0)
2501         goto out;
2502     if (add_sd3d(fname,file_id,sd_id,"dset7",0,chunk_flags,comp_type,NULL)<0)
2503         goto out;
2504 
2505 
2506    /*-------------------------------------------------------------------------
2507     * add some chunked/compressd SDS to the file
2508     * Chunked                  -> flags = HDF_CHUNK
2509     * Chunked and compressed   -> flags = HDF_CHUNK | HDF_COMP
2510     * Non-chunked              -> flags = HDF_NONE
2511     *-------------------------------------------------------------------------
2512     */
2513 
2514     /* add a chunked, non compressed sds */
2515     chunk_flags = HDF_CHUNK;
2516     comp_type   = COMP_CODE_NONE;
2517     if (add_sd(fname,file_id,sd_id,"dset_chunk",0,chunk_flags,comp_type,NULL)<0)
2518         goto out;
2519 
2520     /* add a chunked-compressed sds with SDsetchunk */
2521     chunk_flags = HDF_CHUNK | HDF_COMP;
2522     comp_type   = COMP_CODE_DEFLATE;
2523     if (add_sd(fname,file_id,sd_id,"dset_chunk_comp",0,chunk_flags,comp_type,&comp_info)<0)
2524         goto out;
2525 
2526    /*-------------------------------------------------------------------------
2527     * GZIP
2528     *-------------------------------------------------------------------------
2529     */
2530 
2531     /* add some non chunked, compressed sds */
2532     chunk_flags = HDF_NONE;
2533     comp_type   = COMP_CODE_DEFLATE;
2534     if (add_sd(fname,file_id,sd_id,"dset_gzip",0,chunk_flags,comp_type,&comp_info)<0)
2535         goto out;
2536 
2537    /*-------------------------------------------------------------------------
2538     * add an empty sds
2539     *-------------------------------------------------------------------------
2540     */
2541     if (add_empty_sd(sd_id,"dset_empty")<0)
2542         goto out;
2543 
2544     /*-------------------------------------------------------------------------
2545     * add 2 SDSs with unlimited dimensions, one written
2546     *-------------------------------------------------------------------------
2547     */
2548     if (add_unl_sd(sd_id,"dset_unl", 0)<0)
2549         goto out;
2550     if (add_unl_sd(sd_id,"dset_unlw", 1)<0)
2551         goto out;
2552 
2553    /*-------------------------------------------------------------------------
2554     * RLE
2555     *-------------------------------------------------------------------------
2556     */
2557 
2558     /* add some non chunked, compressed sds */
2559     chunk_flags = HDF_NONE;
2560     comp_type   = COMP_CODE_RLE;
2561     if (add_sd(fname,file_id,sd_id,"dset_rle",0,chunk_flags,comp_type,&comp_info)<0)
2562         goto out;
2563 
2564    /*-------------------------------------------------------------------------
2565     * HUFF
2566     *-------------------------------------------------------------------------
2567     */
2568 
2569     /* add some non chunked, compressed sds */
2570     chunk_flags = HDF_NONE;
2571     comp_type   = COMP_CODE_SKPHUFF;
2572     if (add_sd(fname,file_id,sd_id,"dset_huff",0,chunk_flags,comp_type,&comp_info)<0)
2573         goto out;
2574 
2575 #if defined (H4_HAVE_LIBSZ)
2576    /*-------------------------------------------------------------------------
2577     * SZIP
2578     *-------------------------------------------------------------------------
2579     */
2580     if (SZ_encoder_enabled())
2581     {
2582         chunk_flags = HDF_NONE;
2583         comp_type   = COMP_CODE_SZIP;
2584         if (add_sd(fname,file_id,sd_id,"dset_szip",0,chunk_flags,comp_type,&comp_info)<0)
2585             goto out;
2586 
2587         {
2588 
2589             int i, j;
2590             {
2591                 int32 buf[YD1][XD1];
2592                 int32 dim[2]={YD1,XD1};
2593                 int32 bpp=32;
2594                 for (j = 0; j < YD1; j++) {
2595                     for (i = 0; i < XD1; i++)
2596                         buf[j][i] = (int32) (i + j) + 1;
2597                 }
2598                 if (add_sd_szip(fname,file_id,sd_id,"dset32szip",0,HDF_NONE,DFNT_INT32,bpp,dim,buf)<0)
2599                     return FAIL;
2600             }
2601 
2602         }
2603     }
2604 
2605 #endif
2606 
2607    /*-------------------------------------------------------------------------
2608     * add some RIS24 images to the file
2609     *-------------------------------------------------------------------------
2610     */
2611     /* Pixel Interlacing */
2612     if (add_r24(DATA_FILE2,fname,file_id,DFIL_PIXEL,vgroup_img_id)<0)
2613         goto out;
2614     /* Scan Plane Interlacing */
2615     if (add_r24(DATA_FILE3,fname,file_id,DFIL_PLANE,vgroup_img_id)<0)
2616         goto out;
2617 
2618 
2619    /*-------------------------------------------------------------------------
2620     * add some RIS8 images to the file
2621     *-------------------------------------------------------------------------
2622     */
2623     if (add_r8(DATA_FILE1,fname,file_id,vgroup_img_id)<0)
2624         goto out;
2625 
2626    /*-------------------------------------------------------------------------
2627     * add some GR images to the file with compression/chunking
2628     *-------------------------------------------------------------------------
2629     */
2630 
2631    /*-------------------------------------------------------------------------
2632     * no compression
2633     *-------------------------------------------------------------------------
2634     */
2635 
2636     chunk_flags = HDF_NONE;
2637     comp_type   = COMP_CODE_NONE;
2638     if (add_gr("gr_none",file_id,gr_id,0,chunk_flags,comp_type,&comp_info)<0)
2639         goto out;
2640 
2641 
2642    /*-------------------------------------------------------------------------
2643     * GZIP
2644     *-------------------------------------------------------------------------
2645     */
2646 
2647     chunk_flags = HDF_NONE;
2648     comp_type   = COMP_CODE_DEFLATE;
2649     if (add_gr("gr_gzip",file_id,gr_id,0,chunk_flags,comp_type,&comp_info)<0)
2650         goto out;
2651 
2652 #if defined (H4_GR_SZIP)
2653    /* not supported for GR */
2654    /*-------------------------------------------------------------------------
2655     * SZIP
2656     *-------------------------------------------------------------------------
2657     */
2658 
2659 #if defined (H4_HAVE_LIBSZ)
2660 
2661     if (SZ_encoder_enabled())
2662     {
2663         chunk_flags = HDF_NONE;
2664         comp_type   = COMP_CODE_SZIP;
2665         if (add_gr("gr_szip",file_id,gr_id,0,chunk_flags,comp_type,&comp_info)<0)
2666             goto out;
2667     }
2668 
2669 #endif
2670 #endif
2671 
2672    /*-------------------------------------------------------------------------
2673     * add some GR realistic images to the file
2674     * realistic data is read from ASCII files
2675     *-------------------------------------------------------------------------
2676     */
2677 
2678     if (add_gr_ffile(DATA_FILE1,gr_id,"gr_8bit",0,file_id,0)<0)
2679         goto out;
2680     if (add_gr_ffile(DATA_FILE2,gr_id,"gr_24bit",0,file_id,0)<0)
2681         goto out;
2682 
2683    /*-------------------------------------------------------------------------
2684     * add some VS to the file
2685     * duplicates are inserted in the groups "g1", "g2", "g3" and root
2686     *-------------------------------------------------------------------------
2687     */
2688 
2689     if (add_vs("vdata1",file_id,vgroup1_id)<0)
2690         goto out;
2691     if (add_vs("vdata2",file_id,vgroup2_id)<0)
2692         goto out;
2693     if (add_vs("vdata3",file_id,vgroup3_id)<0)
2694         goto out;
2695     if (add_vs("vdata4",file_id,0)<0)
2696         goto out;
2697 
2698    /*-------------------------------------------------------------------------
2699     * add some global attributes to the file
2700     *-------------------------------------------------------------------------
2701     */
2702     if (add_glb_attrs(fname,file_id,sd_id,gr_id)<0)
2703         goto out;
2704 
2705 
2706    /*-------------------------------------------------------------------------
2707     * add annotations to the file
2708     *-------------------------------------------------------------------------
2709     */
2710     if (add_file_an(file_id)<0)
2711         goto out;
2712 
2713    /*-------------------------------------------------------------------------
2714     * add a palette to the file
2715     *-------------------------------------------------------------------------
2716     */
2717 
2718 
2719     if (add_pal(fname)<0)
2720         goto out;
2721 
2722 
2723    /*-------------------------------------------------------------------------
2724     * close
2725     *-------------------------------------------------------------------------
2726     */
2727 
2728     /* terminate access to the vgroups */
2729     if (Vdetach (vgroup1_id)==FAIL ||
2730         Vdetach (vgroup2_id)==FAIL ||
2731         Vdetach (vgroup3_id)==FAIL ||
2732         Vdetach (vgroup_img_id)==FAIL)
2733     {
2734         printf( "Could not close group\n");
2735         goto out;
2736     }
2737 
2738     /* terminate access to the V interface */
2739     if (Vend (file_id)==FAIL)
2740     {
2741         printf( "Could not end VG\n");
2742         goto out;
2743     }
2744 
2745     /* terminate access to the GR interface */
2746     if (GRend (gr_id)==FAIL)
2747     {
2748         printf("Error: Could not close GR interface\n");
2749         goto out;
2750     }
2751     /* terminate access to the SD interface */
2752     if (SDend (sd_id)==FAIL)
2753     {
2754         printf("Error: Could not close SD interface\n");
2755         goto out;
2756     }
2757     /* close the HDF file */
2758     if (Hclose (file_id)==FAIL)
2759     {
2760         printf( "Could not close file\n");
2761         return FAIL;
2762     }
2763 
2764 
2765     return SUCCEED;
2766 
2767 out:
2768 
2769     /* close interfaces */
2770     Vend (file_id);
2771     GRend (gr_id);
2772     SDend (sd_id);
2773     Hclose (file_id);
2774     return FAIL;
2775  }
2776 
2777 /*-------------------------------------------------------------------------
2778  * write a big file for hyperslab reading
2779  *-------------------------------------------------------------------------
2780  */
2781 
2782 static
do_file_hyperslab(char * fname)2783 int do_file_hyperslab(char* fname)
2784 {
2785 
2786     int32 sd_id;         /* SD interface identifier */
2787     int32 sds_id;        /* SDS identifier */
2788     int32 dims[2];       /* sizes of the SDS dimensions */
2789     int32 start[2];      /* start location to write */
2790     int32 edges[2];      /* number of elements to write */
2791 
2792     int32 sds_idx;
2793     int32 rank;
2794 	uint8 array_data[DIM0][DIM1];
2795     uint8 append_data[DIM1];
2796 	intn  i, j, n;
2797 
2798 	/* Create a file and initiate the SD interface. */
2799     if ((sd_id = SDstart(fname, DFACC_CREATE))==FAIL)
2800         goto error;
2801 
2802 	/* Define the rank and dimensions of the data set to be created. */
2803 	rank = 2;
2804 	dims[0] = SD_UNLIMITED;
2805 	dims[1] = DIM1;
2806 
2807 	/* Create 2 data sets */
2808 	if ((sds_id = SDcreate(sd_id, "data1", DFNT_UINT8, rank, dims))==FAIL)
2809         goto error;
2810 
2811 	/* initial values */
2812     for (j = 0; j < DIM0; j++)
2813     {
2814         for (i = 0; i < DIM1; i++)
2815             array_data[j][i] = (i + j) + 1;
2816     }
2817 
2818 	/* define the location, pattern, and size of the data set */
2819     for (i = 0; i < rank; i++)
2820     {
2821         start[i] = 0;
2822     }
2823 	edges[0] = DIM0; /* 10 */
2824 	edges[1] = DIM1; /* 5 */
2825 
2826     if ( SDwritedata(sds_id, start, NULL, edges, (VOIDP)array_data)==FAIL)
2827         goto error;
2828 
2829 	/* terminate access to the datasets and SD interface */
2830     if ( SDendaccess(sds_id)==FAIL)
2831         goto error;
2832     if ( SDend(sd_id)==FAIL)
2833         goto error;
2834 
2835     /* append data */
2836 	if (( sd_id = SDstart(fname, DFACC_WRITE))==FAIL)
2837         goto error;
2838 
2839     if ((sds_idx = SDnametoindex (sd_id, "data1"))==FAIL)
2840         goto error;
2841     if ((sds_id = SDselect (sd_id, sds_idx))==FAIL)
2842         goto error;
2843 
2844     /* store array values to be appended */
2845     for (i = 0; i < DIM1; i++)
2846         append_data[i] = i + 1;
2847 
2848    	/* define the location of the append */
2849     for (n = 0; n < ADD_ROWS; n++)
2850     {
2851         start[0] = DIM0 + n;   /* 10 */
2852         start[1] = 0;
2853         edges[0] = 1;          /* 1 row at a time */
2854         edges[1] = DIM1;       /* 5 elements */
2855 
2856         /* append data to file */
2857         if ( SDwritedata (sds_id, start, NULL, edges, (VOIDP) append_data)==FAIL)
2858             goto error;
2859 
2860     }
2861 
2862 
2863     /* terminate access */
2864     if ( SDendaccess (sds_id)==FAIL)
2865         goto error;
2866     if ( SDend (sd_id)==FAIL)
2867         goto error;
2868 
2869     return SUCCEED;
2870 
2871 error:
2872 
2873     printf("Error...Exiting...\n");
2874 
2875     return FAIL;
2876 
2877 
2878 }
2879 
2880 /*-------------------------------------------------------------------------
2881  * write groups
2882  * a circular reference
2883  *
2884  *                g0 ----->   g1
2885  *                 |       |    ^
2886  *                 |       |    |
2887  *                 |       \/   |
2888  *                 |----->   g1.1
2889  *
2890  *-------------------------------------------------------------------------
2891  */
2892 
2893 static
do_file_groups(char * name)2894 int do_file_groups(char* name)
2895 {
2896 
2897      int32 vg0_id,    /* vgroup identifier */
2898            vg1_id,    /* vgroup identifier */
2899            vg2_id,    /* vgroup identifier */
2900            file1_id;  /* HDF file identifier */
2901 
2902      /* create a HDF file */
2903      if ((file1_id = Hopen (name, DFACC_CREATE, (int16)0))<0)
2904      {
2905          printf("Error: Could not create file <%s>\n",name);
2906          return FAIL;
2907      }
2908 
2909      /* initialize the V interface */
2910      if (Vstart (file1_id)==FAIL)
2911      {
2912          printf( "Could not start VG\n");
2913          return FAIL;
2914      }
2915 
2916      /* create a vgroup */
2917      vg0_id = Vattach (file1_id, -1, "w");
2918      if (Vsetname (vg0_id, "g0")==FAIL)
2919      {
2920          printf( "Could not name group\n");
2921          goto out;
2922      }
2923 
2924      /* create the second vgroup */
2925      vg1_id = Vattach (file1_id, -1, "w");
2926      if (Vsetname (vg1_id, "g1")==FAIL)
2927      {
2928          printf( "Could not name group\n");
2929          goto out;
2930      }
2931 
2932      /* create the third vgroup */
2933      vg2_id = Vattach (file1_id, -1, "w");
2934      if (Vsetname (vg2_id, "g1.1")==FAIL)
2935      {
2936          printf( "Could not name group\n");
2937          goto out;
2938      }
2939 
2940      if (Vinsert (vg0_id, vg1_id)==FAIL)
2941      {
2942          printf( "Could not insert VG\n");
2943          goto out;
2944      }
2945 
2946      if (Vinsert (vg0_id, vg2_id)==FAIL)
2947      {
2948          printf( "Could not insert VG\n");
2949          goto out;
2950      }
2951 
2952      if (Vinsert (vg1_id, vg2_id)==FAIL)
2953      {
2954          printf( "Could not insert VG\n");
2955          goto out;
2956      }
2957 
2958      if (Vinsert (vg2_id, vg1_id)==FAIL)
2959      {
2960          printf( "Could not insert VG\n");
2961          goto out;
2962      }
2963 
2964      /* terminate access to the vgroup */
2965      if (Vdetach (vg0_id)==FAIL)
2966      {
2967          printf( "Could not close group\n");
2968          goto out;
2969      }
2970 
2971      /* terminate access to the vgroup */
2972      if (Vdetach (vg1_id)==FAIL)
2973      {
2974          printf( "Could not close group\n");
2975          goto out;
2976      }
2977 
2978      /* terminate access to the vgroup */
2979      if (Vdetach (vg2_id)==FAIL)
2980      {
2981          printf( "Could not close group\n");
2982          goto out;
2983      }
2984 
2985      /* terminate access to the V interface */
2986      if (Vend (file1_id)==FAIL)
2987      {
2988          printf( "Could not end VG\n");
2989          goto out;
2990      }
2991 
2992      /* close the HDF file */
2993      if (Hclose (file1_id)==FAIL)
2994      {
2995          printf( "Could not close file\n");
2996          return FAIL;
2997      }
2998 
2999      return SUCCEED;
3000 
3001 out:
3002      printf("Error...Exiting...\n");
3003      return FAIL;
3004 
3005 }
3006 
3007 
3008 /*-------------------------------------------------------------------------
3009  * Function: generate_files
3010  *
3011  * Purpose: writes several HDF objects to the files
3012  *  HREPACK_FILE1
3013  *  HREPACK_FILE2
3014  *  HREPACK_FILE3
3015  *
3016  * Return: SUCCEED, FAIL
3017  *
3018  *-------------------------------------------------------------------------
3019  */
3020 
3021 static
generate_files(void)3022 int generate_files(void)
3023 {
3024     TESTING("generating files");
3025 
3026     if (do_file_all(HREPACK_FILE1)<0)
3027         return FAIL;
3028 
3029     if (do_file_hyperslab(HREPACK_FILE2)<0)
3030         return FAIL;
3031 
3032     if (do_file_groups(HREPACK_FILE3)<0)
3033         return FAIL;
3034 
3035     PASSED();
3036 
3037     return SUCCEED;
3038 
3039 }
3040 
3041 /*-------------------------------------------------------------------------
3042  * Function: main
3043  *
3044  * Purpose: test program for hrepack
3045  *
3046  * A)This program writes several HDF objects to the file HREPACK_FILE1
3047  *   The image data consists of realistic data read from the files DATA_FILE1
3048  *   (8bit image) , DATA_FILE2 (24bit image, pixel interlace) and
3049  *    DATA_FILE3 (24bit image, plane interlace)
3050  *  The objects written are
3051  *  1) groups
3052  *  2) images
3053  *  3) datasets
3054  *  4) vdatas with attributes and field attributes
3055  *  5) global and local attributes
3056  *  6) labels and annotations
3057  *
3058  * B) Then several calls are made to hrepack, in each call the HREPACK_FILE1_OUT is
3059  *  generated
3060  *
3061  * C) In each test the hdiff utility is called to compare the files
3062  *  HREPACK_FILE1 and HREPACK_FILE1_OUT
3063  *
3064  * D) In each test the verifiy_comp_chunk function is called to compare
3065  *  the input and output compression and chunking parameters
3066  *
3067  * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu
3068  *
3069  * Date: August 3, 2003
3070  *
3071  * Modifications:
3072  *  July 7, 2007. Add test for hyperslab repacking in HREPACK_FILE2
3073  *  September 12, 2007. Add test for duplicate vgroup insertions in HREPACK_FILE3
3074  *
3075  *-------------------------------------------------------------------------
3076  */
3077 
3078 
main(void)3079 int main(void)
3080 {
3081 
3082     if ( generate_files() < 0 )
3083         return 1;
3084 
3085     return 0;
3086 
3087 }
3088