1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2  * Copyright by The HDF Group.                                               *
3  * All rights reserved.                                                      *
4  *                                                                           *
5  * This file is part of HDF.  The full HDF copyright notice, including       *
6  * terms governing use, modification, and redistribution, is contained in    *
7  * the COPYING file, which can be found at the root of the source code       *
8  * distribution tree, or in https://support.hdfgroup.org/ftp/HDF/releases/.  *
9  * If you do not have access to either file, you may request a copy from     *
10  * help@hdfgroup.org.                                                        *
11  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
12 
13 /****************************************************************************
14  * tdatainfo.c - tests the functions VSgetdatainfo, ANgetdatainfo,
15  *			GRgetdatainfo, and Hgetntinfo
16  * Structure of the file:
17  *    test_datainfo - test driver
18  *	test_simple_vs   - test VSgetdatainfo with data stored in one
19  *			   contiguous block
20  *	test_append_vs   - test VSgetdatainfo with data stored in linked blocks
21  *	test_annotation  - test ANgetdatainfo
22  *	test_oneblock_ri - test GRgetdatainfo with images stored in one
23  *			   contiguous block, with and without compression
24  *	test_dfr8_24     - test GRgetdatainfo with RI8 and RI24
25  *	test_getntinfo   - test Hgetntinfo
26  ****************************************************************************/
27 
28 #ifndef MFAN_TESTER
29 #define MFAN_TESTER	/* to use MFAN API */
30 #endif
31 
32 #include "hdf.h"
33 #include "tdatainfo.h"
34 #include "tproto.h"
35 
36 static void test_simple_vs();
37 static void test_append_vs();
38 static void test_annotation();
39 static void test_oneblock_ri();
40 static void test_dfr8_24();
41 static void test_getntinfo();
42 static void test_getpalinfo();
43 
44 /***********************************************************************
45   NOTE: At this time, some of the offsets in these tests are verified
46 	by hard-coding.  When adding new data to the files in exiting
47 	tests, please either add data at the bottom of the files or
48 	change the hard-coded offsets appropriately, using the values
49 	from the error messages.  However, you'll need to verify the
50 	correctness of these values first using the command 'od' on
51 	the hdf file.
52 *************************************************************************/
53 
54 /* Structure to hold annotation datainfo temporarily */
55 typedef struct
56   {
57 	char anntext[100]; /* values of the annotation */
58 	int32 offset; /* offset of data block */
59 	int32 length; /* length of data block */
60   } t_ann_info_t;
61 
62 /* Functions to access t_hdfdatainfo_t, defined in ./tdatainfo.h */
63 
64 /* alloc_info is a utility function that allocates t_hdf_datainfo_t's members*/
alloc_info(t_hdf_datainfo_t * info,uintn info_count)65 intn alloc_info(t_hdf_datainfo_t *info, uintn info_count)
66 {
67     info->offsets = (int32 *) HDmalloc(info_count * sizeof(int32));
68     if (info->offsets == NULL)
69         return -1;
70     info->lengths = (int32 *) HDmalloc(info_count * sizeof(int32));
71     if (info->lengths == NULL)
72         return -1;
73     return 0;
74 }
75 
free_info(t_hdf_datainfo_t * info)76 void free_info(t_hdf_datainfo_t *info)
77 {
78     if (info != NULL) {
79         if (info->offsets != NULL)
80             HDfree(info->offsets);
81         if (info->lengths != NULL)
82             HDfree(info->lengths);
83     }
84 }
85 
86 /****************************************************************************
87    Name: test_simple_vs() - tests non-special Vdatas
88 
89    Description:
90 	This routine creates and writes contiguous data to vdatas and verifies
91         some data and data information with VSgetdatainfo.  The tests include
92         the following vdatas:
93 	- a single field vdata with int32 values
94 	- a multiple field/multiple order vdata with all int32 values
95 	- a single field vdata with character values
96 	Only the character vdata's values are verified against the original
97 	buffer.  The other two were verified by examining the hdf file using
98 	od. (Todo 1)
99    BMR - Jul 2010
100  ****************************************************************************/
101 #define SIMPLE_FILE	"tdatainfo_simple.hdf"   /* data file */
102 #define NONSPECIAL_VS	"Non-Special Vdata"
103 #define CONTCLASS_NAME	"Contiguous Vdata"
104 #define LINKED_BLOCK	"Linked-block Vdata"
105 #define FIELD1_NAME	"Field1"	/* contains three integers */
106 #define FIELD2_NAME	"Field2"	/* contains one integer */
107 #define FIELD3_NAME	"Field3"	/* contains two integers */
108 #define	FIELD_NAME_LIST	"Field1,Field2,Field3"
109 #define ORDER_1 	3	/* order of first field of 1st vdata */
110 #define ORDER_2 	1	/* order of second field of 1st vdata */
111 #define ORDER_3 	2	/* order of third field of 1st vdata */
112 #define	BLOCK_SIZE	80	/* arbitrary number for block size */
113 #define	NUM_BLOCKS	8	/* arbitrary number for number of blocks */
114 #define N_VALS_PER_REC_1   1    /* # of values per record in single vdata */
115 #define N_VALS_PER_REC_2 (ORDER_1+ORDER_2+ORDER_3) /* # of vals/rec. in multiple vdata */
116 #define N_RECORDS	5	/* number of records to be written to the
117 				   vdatas at every write */
118 static void
test_simple_vs()119 test_simple_vs()
120 {
121     int32 fid,		/* File ID */
122 	  vsid,		/* Vdata ID */
123 	  vs_ref,	/* Vdata ref# */
124 	  n_records,	/* number of records actually written to vdata */
125 	  data_buf0[N_RECORDS][N_VALS_PER_REC_1], /* for single vdata's data */
126 	  data_buf1[N_RECORDS][N_VALS_PER_REC_2]; /* for multiple vdata's data*/
127     char  data_buf2[N_RECORDS] = {'H', '4', 'M', 'A', 'P'};
128     int16 rec_num;	/* current record number */
129     int32 offset, length; /* offset/length buffers for single block of data */
130     intn  n_blocks;	/* number of blocks a vdata has */
131 #ifdef NOTUSED
132     t_hdf_datainfo_t vs_info; /* data structure to hold offset/length arrays and
133 	some other information about the data */
134 #endif
135     int32 status;	/* Status values from routines */
136     intn status_n;	/* Status values from routines */
137 
138     /* Open the HDF file and initialize the interface. */
139     fid = Hopen(SIMPLE_FILE, DFACC_CREATE, 0);
140     CHECK_VOID(fid,FAIL,"Hopen");
141     status = Vstart(fid);
142     CHECK_VOID(status,FAIL,"Vstart");
143 
144     /* Create and write to the first vdata using high-level func VHstoredata */
145     for (rec_num = 0; rec_num < N_RECORDS; rec_num++)
146 	data_buf0[rec_num][0] = 5 + rec_num;
147 
148     vs_ref = VHstoredata(fid, "Only field", (const uint8 *)data_buf0, N_RECORDS, DFNT_INT32, "One Field One Order", CONTCLASS_NAME);
149 
150     /*
151      * Get access to the vdata just created then get and verify offset/length
152      * of its data
153      */
154 
155     vsid = VSattach (fid, vs_ref, "w");
156     CHECK_VOID(vsid, FAIL, "VSattach");
157 
158     /* Get the number of data blocks first, should be 1 */
159     n_blocks = VSgetdatainfo(vsid, 0, 0, NULL, NULL);
160     CHECK_VOID(n_blocks, FAIL, "VSgetdatainfo");
161     VERIFY_VOID(n_blocks, 1, "VSgetdatainfo");
162 
163     /* Get the offset/length of the data, should be 294/20 */
164     n_blocks = VSgetdatainfo(vsid, 0, n_blocks, &offset, &length);
165     CHECK_VOID(n_blocks, FAIL, "VSgetdatainfo");
166 
167     /* Verify offset/length */
168     VERIFY_VOID(offset, 294, "VSgetdatainfo offset from 'One Field One Order'");
169     VERIFY_VOID(length, 20, "VSgetdatainfo length from 'One Field One Order'");
170 
171     status = VSdetach (vsid);
172     CHECK_VOID(status, FAIL, "VSdetach");
173 
174     /*
175      * Create a multi-field/multi-order vdata, named NONSPECIAL_VS, in class
176      * CONTCLASS_NAME, write data to it, then get and verify its data's
177      * offsets/lengths
178      */
179     vsid = VSattach (fid, -1, "w");
180     CHECK_VOID(vsid, FAIL, "VSattach");
181 
182     /* Set name and class name of the vdata. */
183     status = VSsetname (vsid, NONSPECIAL_VS);
184     CHECK_VOID(status, FAIL, "VSsetname");
185     status = VSsetclass (vsid, CONTCLASS_NAME);
186     CHECK_VOID(status, FAIL, "VSsetclass");
187 
188     /* Record its reference number for later access before detaching it */
189     vs_ref = VSQueryref(vsid);
190     CHECK_VOID(vs_ref, FAIL, "VSQueryref");
191     status = VSdetach (vsid);
192     CHECK_VOID(status, FAIL, "VSdetach");
193 
194     /* Attach to vdata NONSPECIAL_VS to write data, but first verify that
195 	number of data blocks is 0 */
196     vsid = VSattach (fid, vs_ref, "w");
197     CHECK_VOID(vsid, FAIL, "VSattach");
198 
199     n_blocks = VSgetdatainfo(vsid, 0, 0, NULL, NULL);
200     CHECK_VOID(n_blocks, FAIL, "VSgetdatainfo");
201     VERIFY_VOID(n_blocks, 0, "VSgetdatainfo");
202 
203     /* Define the fields in the vdata */
204     status_n = VSfdefine (vsid, FIELD1_NAME, DFNT_INT32, ORDER_1);
205     CHECK_VOID(status_n, FAIL, "VSfdefine");
206     status_n = VSfdefine (vsid, FIELD2_NAME, DFNT_INT32, ORDER_2);
207     CHECK_VOID(status_n, FAIL, "VSfdefine");
208     status_n = VSfdefine (vsid, FIELD3_NAME, DFNT_INT32, ORDER_3);
209     CHECK_VOID(status_n, FAIL, "VSfdefine");
210     status_n = VSsetfields (vsid, FIELD_NAME_LIST);
211     CHECK_VOID(status_n, FAIL, "VSsetfields");
212 
213     /*
214      * Buffer the data by the record for fully interlaced mode.  Note that the
215      * first three elements contain the three values of the first field, the
216      * fourth element contains the value of the second field, and the last two
217      * elements contain the two values of the third field.
218      */
219     for (rec_num = 0; rec_num < N_RECORDS; rec_num++)
220     {
221         data_buf1[rec_num][0] = 2; /* easier to inspect the binary file using */
222         data_buf1[rec_num][1] = 2; /* a simple value */
223         data_buf1[rec_num][2] = 2;
224         data_buf1[rec_num][3] = 2;
225         data_buf1[rec_num][4] = 2;
226         data_buf1[rec_num][5] = 2;
227         /*  data_buf1[rec_num][0] = 1 + rec_num;
228         data_buf1[rec_num][1] = 2 + rec_num;
229         data_buf1[rec_num][2] = 3 + rec_num;
230         data_buf1[rec_num][3] = 10 + rec_num;
231         data_buf1[rec_num][4] = 10;
232         data_buf1[rec_num][5] = 65;
233  */
234     }
235 
236     /* Set the block size and the number of blocks */
237     status_n = VSsetblocksize(vsid, BLOCK_SIZE);
238     CHECK_VOID(status_n, FAIL, "VSsetblocksize");
239     status_n = VSsetnumblocks(vsid, NUM_BLOCKS);
240     CHECK_VOID(status_n, FAIL, "VSsetnumblocks");
241 
242     /* Write the data from data_buf1 to the non special vdata */
243     n_records = VSwrite(vsid, (uint8 *)data_buf1, N_RECORDS, FULL_INTERLACE);
244     VERIFY_VOID(n_records, N_RECORDS, "VSwrite");
245 
246     n_blocks = VSgetdatainfo(vsid, 0, 0, NULL, NULL);
247     CHECK_VOID(n_blocks, FAIL, "VSgetdatainfo");
248     VERIFY_VOID(n_blocks, 1, "VSgetdatainfo");
249 
250     n_blocks = VSgetdatainfo(vsid, 0, n_blocks, &offset, &length);
251     CHECK_VOID(n_blocks, FAIL, "VSgetdatainfo");
252 
253     /* Verify offset/length */
254     VERIFY_VOID(offset, 456, "VSgetdatainfo offset from NONSPECIAL_VS");
255     VERIFY_VOID(length, 120, "VSgetdatainfo length from NONSPECIAL_VS");
256 
257     status_n = VSdetach(vsid);
258     CHECK_VOID(status_n, FAIL, "VSdetach");
259 
260     /* Create and write to another simple vdata, named 'Characters Only', in
261 	class CONTCLASS_NAME */
262     vs_ref = VHstoredata(fid, "Only field", (const uint8 *)data_buf2,
263 		 N_RECORDS, DFNT_CHAR, "Characters Only", CONTCLASS_NAME);
264     CHECK_VOID(vs_ref, FAIL, "VHstoredata");
265 
266 
267     /* Attach to vdata 'Characters Only' and get offset and length of its data */
268     vsid = VSattach(fid, vs_ref, "r");
269 
270     n_blocks = VSgetdatainfo(vsid, 0, 0, NULL, NULL);
271     CHECK_VOID(n_blocks, FAIL, "VSgetdatainfo");
272     VERIFY_VOID(n_blocks, 1, "VSgetdatainfo NONSPECIAL_VS");
273 
274 #ifdef NOTUSED
275     /* Allocate space to record the vdata's data info */
276     if (alloc_info(&vs_info, n_blocks) == -1)
277         exit(1);
278 
279     /* Record various info */
280     vs_info.n_values = 5;
281     vs_info.numtype = DFNT_CHAR;
282 #endif
283 
284     /* Get offset/length */
285     n_blocks = VSgetdatainfo(vsid, 0, n_blocks, &offset, &length);
286     CHECK_VOID(n_blocks, FAIL, "VSgetdatainfo");
287 
288     /* Close everything */
289     status = VSdetach (vsid);
290     CHECK_VOID(status, FAIL, "VSdetach");
291 
292     status_n = Vend(fid);
293     CHECK_VOID(status_n,FAIL, "Vend");
294 
295     status_n = Hclose(fid);
296     CHECK_VOID(status_n,FAIL, "Hclose");
297 
298     /* Open the file with fopen, read data at the offset obtained and verify
299        the values */
300     status_n = readnoHDF_char(SIMPLE_FILE, offset, length, data_buf2);
301     if (status_n == FAIL)
302 	fprintf(stderr, "Attempt reading data without HDF4 library failed at line %d\n", __LINE__);
303 } /* test_simple_vs() */
304 
305 
306 /****************************************************************************
307    Name: test_append_vs() - tests Vdatas with linked-blocks
308 
309    Description:
310 	This routine creates and writes data to an appendable vdata and
311 	verifies its data information with VSgetdatainfo.  The tests include
312         the following:
313 	- create and write to an appendable vdata
314 	- create and write to a simple vdata
315 	- add data to the appendable vdata
316 	- use VSgetdatainfo to get offsets/lengths of the linked-blocks of data
317    BMR - Jul 2010
318  ****************************************************************************/
319 #define APPEND_FILE	"tdatainfo_linkblock.hdf"   /* data file */
320 #define APPENDABLE_VD	"Appendable Vdata"
321 static void
test_append_vs()322 test_append_vs()
323 {
324     int32 fid;       /* file ID */
325     int32 apvsid;    /* vdata IDs */
326     int32 vs1_ref,   /* vdata ref# */
327    	 n_records,  /* number of records written to vdata */
328          data_buf0[N_RECORDS][N_VALS_PER_REC_1], /* for "Very Simple Vdata" */
329          data_buf1[N_RECORDS][N_VALS_PER_REC_2]; /* for first vdata's data */
330     int16 rec_num;      /* current record number */
331     intn n_blocks;
332     t_hdf_datainfo_t vs_info;
333     int32 status;       /* Status values from routines */
334     intn status_n;       /* Status values from routines */
335 
336     /* Open the HDF file. */
337     fid = Hopen(APPEND_FILE, DFACC_CREATE, 0);
338     CHECK_VOID(fid,FAIL, "Hopen");
339 
340     /* Initialize HDF for subsequent vgroup/vdata access. */
341     status_n = Vstart(fid);
342     CHECK_VOID(status_n, FAIL, "Vstart");
343 
344     /* Create the first vdata */
345     apvsid = VSattach (fid, -1, "w");
346     CHECK_VOID(apvsid, FAIL, "VSattach");
347 
348     vs1_ref = VSQueryref(apvsid);
349     CHECK_VOID(vs1_ref, FAIL, "VSQueryref:apvsid");
350 
351     status = VSdetach (apvsid);
352     CHECK_VOID(status, FAIL, "VSdetach");
353 
354     apvsid = VSattach (fid, vs1_ref, "w");
355     CHECK_VOID(apvsid, FAIL, "VSattach");
356 
357     /* Set name and class name of the vdata. */
358     status = VSsetname (apvsid, APPENDABLE_VD);
359     CHECK_VOID(status, FAIL, "VSsetname");
360     status = VSsetclass (apvsid, LINKED_BLOCK);
361     CHECK_VOID(status, FAIL, "VSsetclass");
362 
363     n_blocks = VSgetdatainfo(apvsid, 0, 0, NULL, NULL);
364     CHECK_VOID(n_blocks, FAIL, "VSgetdatainfo");
365     VERIFY_VOID(n_blocks, 0, "VSgetdatainfo");
366 
367     /* Introduce each field's name, data type, and order.  This is the first
368       part in defining a field.  */
369     status_n = VSfdefine (apvsid, FIELD1_NAME, DFNT_INT32, ORDER_1);
370     CHECK_VOID(status_n, FAIL, "VSfdefine");
371     status_n = VSfdefine (apvsid, FIELD2_NAME, DFNT_INT32, ORDER_2);
372     CHECK_VOID(status_n, FAIL, "VSfdefine");
373     status_n = VSfdefine (apvsid, FIELD3_NAME, DFNT_INT32, ORDER_3);
374     CHECK_VOID(status_n, FAIL, "VSfdefine");
375 
376     /* Finalize the definition of the fields. */
377     status_n = VSsetfields (apvsid, FIELD_NAME_LIST);
378     CHECK_VOID(status_n, FAIL, "VSsetfields");
379 
380     /*
381      * Buffer the data by the record for fully interlaced mode.  Note that the
382      * first three elements contain the three values of the first field, the
383      * fourth element contains the value of the second field, and the last two
384      * elements contain the two values of the third field.
385      */
386     for (rec_num = 0; rec_num < N_RECORDS; rec_num++)
387     {
388         data_buf1[rec_num][0] = 5;	/* easier to inspect the bin file */
389         data_buf1[rec_num][1] = 5;
390         data_buf1[rec_num][2] = 5;
391         data_buf1[rec_num][3] = 5;
392         data_buf1[rec_num][4] = 5;
393         data_buf1[rec_num][5] = 5;
394 
395 	 /* data_buf1[rec_num][0] = 1 + rec_num;
396         data_buf1[rec_num][1] = 2 + rec_num;
397         data_buf1[rec_num][2] = 3 + rec_num;
398         data_buf1[rec_num][3] = 10 + rec_num;
399         data_buf1[rec_num][4] = 10;
400         data_buf1[rec_num][5] = 65;
401  */
402     }
403 
404     /* Set the block size and the number of blocks the first vdata */
405     status_n = VSsetblocksize(apvsid, BLOCK_SIZE);
406     CHECK_VOID(status_n, FAIL, "VSsetblocksize");
407     status_n = VSsetnumblocks(apvsid, NUM_BLOCKS);
408     CHECK_VOID(status_n, FAIL, "VSsetnumblocks");
409 
410     /* Write the data from data_buf1 to vdata APPENDABLE_VD the first time */
411     n_records = VSwrite(apvsid, (uint8 *)data_buf1, N_RECORDS, FULL_INTERLACE);
412     VERIFY_VOID(n_records, N_RECORDS, "VSwrite");
413 
414     n_blocks = VSgetdatainfo(apvsid, 0, 0, NULL, NULL);
415     CHECK_VOID(n_blocks, FAIL, "VSgetdatainfo");
416 
417     /* Allocate space to record the vdata's data info */
418     if (alloc_info(&vs_info, n_blocks) == -1)
419         exit(1);
420 
421     /* Get offset and lengths of the data */
422     n_blocks = VSgetdatainfo(apvsid, 0, n_blocks, vs_info.offsets, vs_info.lengths);
423     CHECK_VOID(n_blocks, FAIL, "VSgetdatainfo");
424     free_info(&vs_info);
425 
426     /* Get the reference number of this vdata for later use */
427     vs1_ref = VSQueryref(apvsid);
428     CHECK_VOID(vs1_ref, FAIL, "VSQueryref");
429 
430     /* Make another simple vdata to cause linked-blocks */
431     {
432 	int32 vd2_ref;
433 
434 	for (rec_num = 0; rec_num < N_RECORDS; rec_num++)
435 	    data_buf0[rec_num][0] = 10 + rec_num;
436 
437 	/* Create and write to another very simple vdata */
438 	vd2_ref = VHstoredata(fid, "Field 1", (const uint8 *)data_buf0, N_RECORDS, DFNT_INT32, "Another One Field One Order", "Very Simple Vdata");
439     }
440 
441     /* Make up the second batch of data for the appendable vdata */
442     for (rec_num = 0; rec_num < N_RECORDS; rec_num++)
443     {
444         data_buf1[rec_num][0] = 100 + rec_num;
445         data_buf1[rec_num][1] = 200 + rec_num;
446         data_buf1[rec_num][2] = 300 + rec_num;
447         data_buf1[rec_num][3] = 1000 + rec_num;
448         data_buf1[rec_num][4] = 1000;
449         data_buf1[rec_num][5] = 6500;
450     }
451     /* Write the data to vdata APPENDABLE_VD the second time */
452     n_records = VSwrite(apvsid, (uint8 *)data_buf1, N_RECORDS, FULL_INTERLACE);
453     VERIFY_VOID(n_records, N_RECORDS, "VSwrite");
454 
455     /* Detach this vdata and attach to it again, just to make sure meta-data
456        is recorded; it may not be necessary but it doesn't hurt */
457     status = VSdetach (apvsid);
458     CHECK_VOID(status, FAIL, "VSdetach");
459     apvsid = VSattach (fid, vs1_ref, "w");
460     CHECK_VOID(apvsid, FAIL, "VSattach");
461 
462     /* Get the number of data blocks the vdata currently has */
463     n_blocks = VSgetdatainfo(apvsid, 0, 0, NULL, NULL);
464     CHECK_VOID(n_blocks, FAIL, "VSgetdatainfo");
465     VERIFY_VOID(n_blocks, 3, "VSgetdatainfo");
466 
467     /* Allocate space to record the vdata's data info */
468     if (alloc_info(&vs_info, n_blocks) == -1)
469         exit(1);
470 
471     /* Record various info to be used in verifying data later */
472     vs_info.n_values = 30;
473     vs_info.numtype = DFNT_INT32;
474 
475     /* Get and verify offsets and lengths of data */
476     n_blocks = VSgetdatainfo(apvsid, 0, n_blocks, vs_info.offsets, vs_info.lengths);
477     CHECK_VOID(n_blocks, FAIL, "VSgetdatainfo");
478 
479     {
480 	int ii;
481 	int32 check_offsets[] = {294, 556, 636};
482 	int32 check_lengths[] = {120, 80, 40}; /* last chunk is not completely filled */
483 	for (ii = 0; ii < n_blocks; ii++)
484 	{
485 	    VERIFY_VOID(vs_info.offsets[ii], check_offsets[ii], "VSgetdatainfo offset");
486 	    VERIFY_VOID(vs_info.lengths[ii], check_lengths[ii], "VSgetdatainfo length");
487 	}
488     }
489     /* Verifying data read without HDF4 library */
490     /* NOT YET */
491 
492     /* Release memory */
493     free_info(&vs_info);
494 
495     /* Close everything */
496     status = VSdetach (apvsid);
497     CHECK_VOID(status, FAIL, "Vdetach");
498     status = Vend(fid);
499     CHECK_VOID(status, FAIL, "Vend");
500     status = Hclose(fid);
501     CHECK_VOID(status, FAIL, "Hclose");
502 } /* test_append_vs */
503 
504 
505 /*******************************************************************
506   Name: readnoHDF_char - utility routine to read and verify character
507 			data without HDF4 library
508 
509   Description:
510 	readnoHDF_char opens the file and reads in data at the specified
511 	offset.  The read data is compared against the original data passed
512 	by caller.  If any mis-match occurs, an error message will be
513 	displayed but the process will continue.
514 
515   Parameters:
516 	char *filename	IN: name of the file
517 	int32 offset	IN: where to start read data
518 	int32 length	IN: how long to read the data
519 
520   Return value:
521 	SUCCEED/FAIL
522   BMR - Jul 2010
523 ********************************************************************/
readnoHDF_char(const char * filename,const int32 offset,const int32 length,const char * orig_buf)524 intn readnoHDF_char(const char *filename, const int32 offset, const int32 length, const char *orig_buf)
525 {
526     FILE  *fd;		/* file descriptor */
527     size_t readlen=0;	/* number of bytes actually read */
528     char *readcbuf;
529     intn ret_value = SUCCEED;
530 
531     /* Open the file for reading without SD API */
532     fd = fopen(filename, "r");
533     if (fd == NULL)
534     {
535 	fprintf(stderr, "readnoHDF_char: unable to open file %s", filename);
536         ret_value = FAIL;
537     }
538 
539     /* Forward to the position of the first block of data */
540     if (fseek(fd, (off_t)offset, SEEK_SET) == -1)
541     {
542         fprintf(stderr, "readnoHDF_char: unable to seek offset %d\n",
543                 (int)offset);
544         ret_value = FAIL;
545     }
546 
547     /* Allocate buffers for SDS' data */
548     readcbuf = (char *) HDmalloc(length * sizeof(char));
549     if (readcbuf == NULL)
550     {
551 	fprintf(stderr, "readnoHDF_char: allocation readcbuf failed\n");
552         ret_value = FAIL;
553     }
554 
555     /* Read in this block of data */
556     readlen = fread((void*)readcbuf, 1, length, fd);
557     if (readlen > 0)
558     {
559         /* Compare data read without HDF4 lib against the original buffer */
560 	if (HDstrncmp(readcbuf, orig_buf, readlen) != 0)
561 	    fprintf(stderr, "Failure: non-HDF reading got different values than written values\n   >>> written = %s\n   >>> read = %s\n", orig_buf, readcbuf);
562     }
563     HDfree(readcbuf);
564     /* Close the file */
565     if (fclose(fd) == -1)
566     {
567 	fprintf(stderr, "readnoHDF_char: unable to close file %s", filename);
568         ret_value = FAIL;
569     }
570     return ret_value;
571 }
572 
573 /*******************************************************************
574   Name: get_annot_datainfo - utility routine to get datainfo of
575 	an annotation
576 
577   Description:
578 	get_annot_datainfo gets access to each annotation, then attempts to
579 	get the offset/length of its data.  If successful, increment the
580 	data info count and eventually returns that number to caller.  If
581 	failure occurs, simply return FAIL and all the previous data info
582 	will be discarded by the caller.
583 
584   Parameters:
585 	int32 an_id		IN: annotation ID
586 	ann_type annot_type	IN: type of the annotations
587 	int32 num_anns		IN: number of annotations of the specified type,
588 				    currently only 1, but will be adjusted after
589 				    the last parameter become arrays of strings
590 	t_ann_info_t *ann_info	OUT: structure that holds ann data info
591 	intn ann_info_num	IN: indicates where in ann_info to start
592 				    storing info
593 	char* ann_text		IN: text of the annotation (this will be changed
594 				    to array of strings when time permits)
595 
596   Return value:
597 	The number of annotations whose data info is successfully retrieved
598 	and stored in ann_info or FAIL if failure occurs.
599 ********************************************************************/
get_annot_datainfo(int32 an_id,ann_type annot_type,int32 num_anns,t_ann_info_t * ann_info,intn ann_info_num,char * ann_text)600 intn get_annot_datainfo(int32 an_id, ann_type annot_type, int32 num_anns, t_ann_info_t *ann_info, intn ann_info_num, char* ann_text)
601 {
602     int32 ann_id, ann_index;
603     intn status_n, ret_value = 0;
604 
605     /* Get the annotation. */
606     for (ann_index = 0; ann_index < num_anns; ann_index++)
607     {
608 	/* Get the identifier of the current annotation. */
609 	ann_id = ANselect (an_id, ann_index, annot_type);
610 	CHECK(ann_id, FAIL, "ANselect");
611 
612 	/* Get annotation's data info. */
613 	status_n = ANgetdatainfo(ann_id, &ann_info[ann_info_num].offset, &ann_info[ann_info_num].length);
614 	CHECK(status_n, FAIL, "ANgetdatainfo");
615 
616 	/* Store annotation text for later checking against data read from
617 	   the file without HDF4 library */
618 	HDstrcpy(ann_info[ann_info_num].anntext, ann_text);
619 
620 	/* Terminate access to the current annotation. */
621 	status_n = ANendaccess (ann_id);
622 	CHECK(status_n, FAIL, "ANendaccess");
623 
624 	/* Number of annotations whose datainfo is retrieved */
625 	ret_value++;
626     }
627     return(ret_value);
628 } /* get_annot_datainfo */
629 
630 
631 /****************************************************************************
632    Name: test_annotation() - tests getting data info of annotations
633 
634    Description:
635 	This routine tests getting data info of file label and description,
636 	and data label and description.
637 	- add a file label and a file description
638 	- create a vgroup then add a data label and a data description to it
639 	- use the utility routine get_annot_datainfo to record the offset,
640 	  length, and annotation text
641 	- use utility routine readnoHDF_char to read the annotation text
642 	  without the use of the HDF4 library and verify the correctness of
643 	  the read data
644 
645 	Todo 2: Should add more annotations so there will be multiple annots
646 	for an object or file.  get_annot_datainfo needs to be fixed to
647 	accommodate this.
648    BMR - Aug 2010
649    NOTE:
650 	It is near the end of H4 Mapping project and Ruth had said there were
651 	no annotation for Vgroup and Vdata, so the continuation of these tests
652 	is not that critical anymore.  For SDS, SDgetanndatainfo handles
653 	annotations already.  BMR - Jan 2011
654  ****************************************************************************/
655 #define ANNOT_FILE	"tdatainfo_annot.hdf"   /* data file */
656 #define	VG_NAME		"AN Vgroup"
657 #define	FILE_LABEL_TXT	"General HDF objects"
658 #define	FILE_DESC_TXT	"This is an HDF file that contains general HDF objects"
659 #define	DATA_LABEL_TXT	"Common AN Vgroup"
660 #define	DATA_DESC_TXT	"This is a vgroup that is used to test data annotations"
661 static void
test_annotation()662 test_annotation()
663 {
664     int32 fid,		/* file ID */
665 	  an_id, 	/* AN interface ID */
666 	  file_label_id, 	/* file label ID */
667 	  file_desc_id, 	/* file description ID */
668 	  data_label_id, 	/* data label ID */
669 	  data_desc_id, 	/* data description ID */
670 	  vgroup_id;	/* vgroup ID */
671     uint16 vgroup_tag, vgroup_ref; /* vgroup tag/ref */
672     t_ann_info_t ann_info[4];	/* temporary storage of annotation info */
673     intn  status_n;	/* returned status for functions returning an intn  */
674     int32 status;	/* returned status for functions returning an int32 */
675 
676     /* Create the HDF file. */
677     fid = Hopen (ANNOT_FILE, DFACC_CREATE, 0);
678     CHECK_VOID(fid, FAIL, "Hopen");
679 
680     /* Initialize the AN interface. */
681     an_id = ANstart(fid);
682     CHECK_VOID(an_id, FAIL, "ANstart");
683 
684     /* Create and write a file label. */
685     file_label_id = ANcreatef(an_id, AN_FILE_LABEL);
686     CHECK_VOID(file_label_id, FAIL, "ANcreatef");
687     status = ANwriteann(file_label_id, FILE_LABEL_TXT, strlen (FILE_LABEL_TXT));
688     CHECK_VOID(status, FAIL, "ANwriteann");
689 
690     /* Create and write a file description. */
691     file_desc_id = ANcreatef(an_id, AN_FILE_DESC);
692     CHECK_VOID(file_desc_id, FAIL, "ANcreatef");
693     status = ANwriteann(file_desc_id, FILE_DESC_TXT, strlen (FILE_DESC_TXT));
694     CHECK_VOID(status, FAIL, "ANwriteann");
695 
696     /* Create a vgroup to add annotation to it. */
697     status_n = Vstart(fid);
698     CHECK_VOID(status_n, FAIL, "Vstart");
699     vgroup_id = Vattach(fid, -1, "w");
700     CHECK_VOID(vgroup_id, FAIL, "Vattach");
701     status = Vsetname (vgroup_id, VG_NAME);
702     CHECK_VOID(status, FAIL, "Vsetname");
703 
704     /* Get the tag and ref number of the vgroup for ANcreate. */
705     vgroup_tag = (uint16) VQuerytag (vgroup_id);
706     CHECK_VOID(vgroup_tag, 0, "VQuerytag");
707     vgroup_ref = (uint16) VQueryref (vgroup_id);
708     CHECK_VOID(vgroup_ref, 0, "VQueryref");
709 
710     /* Add a data label to the vgroup. */
711     data_label_id = ANcreate(an_id, vgroup_tag, vgroup_ref, AN_DATA_LABEL);
712     CHECK_VOID(data_label_id, FAIL, "ANcreate");
713     status = ANwriteann(data_label_id, DATA_LABEL_TXT, strlen(DATA_LABEL_TXT));
714     CHECK_VOID(status, FAIL, "ANwriteann");
715 
716     /* Add a data description to the vgroup. */
717     data_desc_id = ANcreate(an_id, vgroup_tag, vgroup_ref, AN_DATA_DESC);
718     CHECK_VOID(data_desc_id, FAIL, "ANcreate");
719     status = ANwriteann(data_desc_id, DATA_DESC_TXT, strlen(DATA_DESC_TXT));
720     CHECK_VOID(status, FAIL, "ANwriteann");
721 
722     /* Terminate access to each annotation. */
723     status_n = ANendaccess(file_label_id);
724     CHECK_VOID(status_n, FAIL, "ANendaccess");
725     status_n = ANendaccess(file_desc_id);
726     CHECK_VOID(status_n, FAIL, "ANendaccess");
727     status_n = ANendaccess(data_label_id);
728     CHECK_VOID(status_n, FAIL, "ANendaccess");
729     status_n = ANendaccess(data_desc_id);
730     CHECK_VOID(status_n, FAIL, "ANendaccess");
731 
732     /* Teminate access to the vgroup and to the V interface. */
733     status = Vdetach(vgroup_id);
734     status_n = Vend(fid);
735 
736     /* Terminate access to the AN interface and close the HDF file. */
737     status = ANend(an_id);
738     CHECK_VOID(status, FAIL, "ANend");
739     status_n = Hclose (fid);
740     CHECK_VOID(status_n, FAIL, "Hclose");
741 
742     /* Open the file and read in location/size of all annotations */
743 
744     {
745 	int32 ann_index,	/* annotation index */
746 	      n_file_labels,	/* numbers of file labels */
747 	      n_file_descs,	/* numbers of file descs */
748 	      n_data_labels,	/* numbers of data labels */
749 	      n_data_descs;	/* numbers of data descs */
750 	intn  num_anns = 0, ann_info_num = 0;
751 
752 	/* Open the file. */
753 	fid = Hopen (ANNOT_FILE, DFACC_RDONLY, 0);
754 	CHECK_VOID(fid, FAIL, "Hopen");
755 
756 	/* Initialize the AN interface. */
757 	an_id = ANstart(fid);
758 	CHECK_VOID(an_id, FAIL, "ANstart");
759 
760 	/* Get the number of data/file labels/descriptions */
761 	status_n = ANfileinfo (an_id, &n_file_labels, &n_file_descs,
762                         &n_data_labels, &n_data_descs);
763 	CHECK_VOID(status_n, FAIL, "ANfileinfo");
764 	VERIFY_VOID(n_file_labels, 1, "ANfileinfo");
765 	VERIFY_VOID(n_file_descs, 1, "ANfileinfo");
766 	VERIFY_VOID(n_data_labels, 1, "ANfileinfo");
767 	VERIFY_VOID(n_data_descs, 1, "ANfileinfo");
768 
769 	/* Get access to each annotation then call ANgetdatainfo to retrieve
770 	   the offset/length of the annotation data */
771 
772 	/* Explanation of some parameters to get_annot_datainfo:
773 	   3rd parameter - number of annotations of the specified type,
774 	   currently only 1, but will adjust the last parameter to have arrays
775 	   of character strings when have time.
776 	   4th parameter - ann_info_num indicates where in ann_info to start
777 	   storing info */
778 
779 	/* AN_DATA_LABEL */
780 	num_anns = get_annot_datainfo(an_id, AN_DATA_LABEL, 1, ann_info, ann_info_num, DATA_LABEL_TXT);
781 	CHECK_VOID(num_anns, FAIL, "get_annot_datainfo");
782 	VERIFY_VOID(num_anns, 1, "get_annot_datainfo");
783 	ann_info_num = ann_info_num + num_anns;
784 
785 	/* AN_DATA_DESC */
786 	num_anns = get_annot_datainfo(an_id, AN_DATA_DESC, 1, ann_info, ann_info_num, DATA_DESC_TXT);
787 	CHECK_VOID(num_anns, FAIL, "get_annot_datainfo");
788 	VERIFY_VOID(num_anns, 1, "get_annot_datainfo");
789 	ann_info_num = ann_info_num + num_anns;
790 
791 	/* AN_FILE_LABEL */
792 	num_anns = get_annot_datainfo(an_id, AN_FILE_LABEL, 1, ann_info, ann_info_num, FILE_LABEL_TXT);
793 	CHECK_VOID(num_anns, FAIL, "get_annot_datainfo");
794 	VERIFY_VOID(num_anns, 1, "get_annot_datainfo");
795 	ann_info_num = ann_info_num + num_anns;
796 
797 	/* AN_FILE_DESC */
798 	num_anns = get_annot_datainfo(an_id, AN_FILE_DESC, 1, ann_info, ann_info_num, FILE_DESC_TXT);
799 	CHECK_VOID(num_anns, FAIL, "get_annot_datainfo");
800 	VERIFY_VOID(num_anns, 1, "get_annot_datainfo");
801 	ann_info_num = ann_info_num + num_anns;
802 
803 	/* Terminate access to the AN interface and close the HDF file. */
804 	status = ANend(an_id);
805 	CHECK_VOID(status, FAIL, "ANend");
806 	status_n = Hclose (fid);
807 	CHECK_VOID(status_n, FAIL, "Hclose");
808 
809 	/* calling readnoHDF_char to verify data without the use of HDF lib */
810 
811 	for (ann_index = 0; ann_index < ann_info_num; ann_index++)
812 	{
813 	    /* Open the file with fopen, read data at the offset obtained and
814 	       verify the values */
815 	    status_n = readnoHDF_char(ANNOT_FILE, ann_info[ann_index].offset,
816 		    ann_info[ann_index].length, ann_info[ann_index].anntext);
817 	    if (status_n == FAIL)
818 		fprintf(stderr, "Attempt reading data without HDF4 library failed at line %d\n", __LINE__);
819 	}
820     }
821 } /* test_annotation */
822 
823 /****************************************************************************
824    Name: test_oneblock_ri() - tests non-linked-block images
825 
826    Description:
827 	This routine creates and writes data to images and verifies
828         some data and data information with GRgetdatainfo.  The tests include
829         the following images:
830 	- a simple, non-compressed image
831 	- three images with RLE, Skipping-Huffman, and Deflate compression
832 	Only the non-compressed image's values are verified against the original
833 	buffer.  The other three were verified by debugging, additional
834 	decompression code needed for further verification (Todo 2)
835 
836    Note: Incomplete, waiting for schema design
837    BMR - Aug 2010
838  ****************************************************************************/
839 #define IMAGE_FILE	"tdatainfo_images.hdf"   /* data file */
840 #define	NONCOMP_IMAGE	"Image with No Compression"
841 #define	RLE_IMAGE	"Image with RLE Compression"
842 #define	DEFLATE_IMAGE	"Image with Deflate Compression"
843 #define	SKPHUFF_IMAGE	"Image with Skphuff Compression"
844 #define	JPEG_IMAGE	"Image with JPEG Compression"
845 #define	SKPHUFF_SKIPSIZE	28
846 #define	DEFLATE_LEVEL	7
847 #define WIDTH		5
848 #define LENGTH		5
849 #define N_IMAGES	4
850 
851 /* Convenient function to create and write to an image, used by
852    test_oneblock_ri */
make_comp_image(int32 grid,char * img_name,char start_char,int32 comp_type,comp_info * cinfo)853 static intn make_comp_image(
854 	int32 grid,
855 	char* img_name,
856 	char start_char,  /* first value in the image, for variety of data */
857 	int32 comp_type,  /* compression method */
858 	comp_info* cinfo) /* compression parameters */
859 {
860     int32 riid;         /* raster image ID */
861     int32 dims[2]={WIDTH,LENGTH};	/* dimensions for the image */
862     char image0[WIDTH][LENGTH];		/* image data */
863     int32 start[2];	/* start of image data to grab */
864     int32 stride[2];	/* stride of image data to grab */
865     intn ii, jj;	/* indices */
866     intn status;        /* generic return value */
867     intn ret_value=SUCCEED;
868 
869     /* Initialize data we are going to write out, each image created by this
870        convenient function will use the same data pattern with the first value
871        given by the caller  */
872     for (ii = 0; ii < WIDTH; ii++)
873         for (jj = 0; jj < LENGTH; jj++)
874             image0[ii][jj] = start_char + jj;
875 
876     /* Create the image with 1 component, type char, pixel interlace, and
877        dimension WIDTHxLENGTH */
878     riid = GRcreate(grid, img_name, 1, DFNT_CHAR, MFGR_INTERLACE_PIXEL, dims);
879     CHECK(riid, FAIL, "GRcreate");
880 
881     /* Set compression as instructed */
882     if (comp_type != COMP_CODE_NONE)
883     {
884 	status = GRsetcompress(riid, comp_type, cinfo);
885 	CHECK(status, FAIL, "GRsetcompress");
886     }
887 
888     /* Write the entire image data out */
889     start[0] = start[1] = 0;
890     stride[0] = stride[1] = 1;
891     status = GRwriteimage(riid, start, stride, dims, image0);
892     CHECK(status, FAIL, "GRreadimage");
893 
894     /* Close the first image */
895     status = GRendaccess(riid);
896     CHECK(status, FAIL, "GRendaccess");
897 
898     return ret_value;
899 }
900 
901 static void
test_oneblock_ri()902 test_oneblock_ri()
903 {
904     int32 fid, grid,	/* file ID and GR interface ID */
905 	  riid;		/* raster image ID */
906     int32 offset, length; /* offset/length buffers for single block of data */
907     intn  status;	/* status returned from routines */
908     intn ii;		/* indices */
909     int32 n_images, n_fattrs;
910     comp_info cinfo;    /* Compression parameters - union */
911     /* offsets/lengths to be used to verify offsets/lengths returned by
912        GRgetdatainfo - confirmed by the command "od" on the hdf file */
913     static int32 image_data_offsets[N_IMAGES] = {309, 363, 426, 486};
914     static int32 image_data_lengths[N_IMAGES] = {25, 26, 29, 16};
915 
916     /****************************************************************
917       Create a file in GR interface then create and write several
918       images with and without compression.
919     ****************************************************************/
920 
921     /* Create the HDF file and initialize the interface. */
922     fid = Hopen(IMAGE_FILE, DFACC_CREATE, 0);
923     CHECK_VOID(fid, FAIL, "Hopen");
924 
925     grid = GRstart(fid);
926     CHECK_VOID(grid, FAIL, "GRstart");
927 
928     /* Create and write the non-compressed image to this file */
929     status = make_comp_image(grid, NONCOMP_IMAGE, 'n', COMP_CODE_NONE, &cinfo);
930 
931     /* Create and write 3 more images: RLE, Deflate, and Skipping Huffman */
932 
933     /* No compression info for the RLE image */
934     HDmemset(&cinfo, 0, sizeof(cinfo)) ;
935 
936     /* Create and write the RLE compressed image to this file, starting the
937        data values with the letter 'r' */
938     status = make_comp_image(grid, RLE_IMAGE, 'r', COMP_CODE_RLE, &cinfo);
939 
940     /* Set the compression info for the image with Skipping Huffman method */
941     HDmemset(&cinfo, 0, sizeof(cinfo)) ;
942     cinfo.skphuff.skp_size = SKPHUFF_SKIPSIZE;
943 
944     /* Create and write the Skipping Huffman compressed image to this file,
945        starting the data values with the letter 's' */
946     status = make_comp_image(grid, SKPHUFF_IMAGE, 's', COMP_CODE_SKPHUFF, &cinfo);
947 
948     /* Set the compression info for the image with Deflate method */
949     HDmemset(&cinfo, 0, sizeof(cinfo)) ;
950     cinfo.deflate.level = DEFLATE_LEVEL;
951 
952     /* Create and write the Deflate compressed image to this file, starting the
953        data values with the letter 'd' */
954     status = make_comp_image(grid, DEFLATE_IMAGE, 'd', COMP_CODE_DEFLATE, &cinfo);
955 
956     /* Set the compression method for the image with JPEG method */
957     HDmemset(&cinfo, 0, sizeof(cinfo)) ;
958     cinfo.jpeg.quality = 100;
959     cinfo.jpeg.force_baseline = 1;
960 
961     /* Create and write the JPEG compressed image to this file, starting the
962        data values with the letter 'j' - more work to be done for JPEG */
963      /* status = make_comp_image(grid, JPEG_IMAGE, 'j', COMP_CODE_JPEG, &cinfo);
964  */
965 
966     /* Terminate access to the GR interface and close the file */
967     status = GRend(grid);
968     CHECK_VOID(status, FAIL, "GRend");
969     status = Hclose(fid);
970     CHECK_VOID(status, FAIL, "Hclose");
971 
972     /****************************************************************
973       Re-open the file to read the images and their data information
974     ****************************************************************/
975 
976    /* Re-open the file and initialize the GR interface */
977     fid = Hopen (IMAGE_FILE, DFACC_RDONLY, 0);
978     CHECK_VOID(fid, FAIL, "Hopen");
979     grid = GRstart (fid);
980     CHECK_VOID(grid, FAIL, "GRstart");
981 
982     /* Get the number of images in the file */
983     status = GRfileinfo(grid, &n_images, &n_fattrs);
984     CHECK_VOID(status, FAIL, "GRfileinfo");
985     VERIFY_VOID(n_images, N_IMAGES, "GRfileinfo");
986 
987     /* Open each image then get and verify its data information.  Note that
988 	currently, the offsets and lengths are obtained from debugging
989 	and the command od on the file */
990     for (ii = 0; ii < n_images; ii++)
991     {
992 	riid = GRselect(grid, ii);
993 	CHECK_VOID(riid, FAIL, "GRselect");
994 
995 	status = GRgetdatainfo(riid, 0, 1, &offset, &length);
996 	CHECK_VOID(status, FAIL, "GRgetdatainfo");
997 	VERIFY_VOID(offset, image_data_offsets[ii], "GRgetdatainfo");
998 	VERIFY_VOID(length, image_data_lengths[ii], "GRgetdatainfo");
999 
1000 	/* Only verify data of the first image, which has non-compressed data. */
1001 	if (ii == 0)
1002 	{
1003 	    intn jj, kk;
1004 	    char buffer[WIDTH][LENGTH], check_image[WIDTH*LENGTH];
1005 	    for (kk = 0; kk < WIDTH; kk++)
1006 		for (jj = 0; jj < LENGTH; jj++)
1007 		    buffer[kk][jj] = 'n' + jj;
1008 
1009 	    /* Work around to pass check_image into readnoHDF_char w/o warning*/
1010 	    HDmemcpy(check_image, buffer, WIDTH*LENGTH);
1011 
1012 	    /* Open the file with fopen, read data at the offset obtained and verify
1013 	       the values */
1014 	    status = readnoHDF_char(IMAGE_FILE, offset, length, check_image);
1015 	    if (status == FAIL)
1016 		fprintf(stderr, "Attempt reading data without HDF4 library failed at line %d\n", __LINE__);
1017 	}
1018 
1019 	/* Close the image */
1020 	status = GRendaccess(riid);
1021 	CHECK_VOID(status, FAIL, "GRendaccess");
1022     } /* for n_images */
1023 
1024     /* Terminate access to the GR interface and close the file */
1025     status = GRend(grid);
1026     CHECK_VOID(status, FAIL, "GRend");
1027     status = Hclose(fid);
1028     CHECK_VOID(status, FAIL, "Hclose");
1029 } /* end test_oneblock_ri */
1030 
1031 #define IMAGE_DF_FILE	"tdatainfo_dfri.hdf"	/* data file for DFR APIs */
1032 #define N_DF_IMAGES	2	/* number of DF images in the file, 1 RI8 &
1033 				   1 RI24 */
1034 static void
test_dfr8_24()1035 test_dfr8_24()
1036 {
1037     int32 fid, grid,	/* file ID and GR interface ID */
1038 	  riid;		/* raster image ID */
1039     int32 offset, length; /* offset/length buffers for single block of data */
1040     intn  status;	/* status returned from routines */
1041     intn ii, jj;	/* indices */
1042     int32 n_images, n_fattrs;
1043     char  buf[WIDTH][LENGTH][3];
1044 
1045     /* offsets/lengths to be used to verify offsets/lengths returned by
1046        GRgetdatainfo - confirmed by the command "od" on the hdf file */
1047     static int32 image_data_offsets[N_IMAGES] = {294, 1132};
1048     static int32 image_data_lengths[N_IMAGES] = {30, 75};
1049 
1050     /* Initialize the 8-bit image array */
1051     static uint8 raster_data[WIDTH][LENGTH] =
1052 	{{1, 2, 3, 4, 5},
1053 	 {5, 4, 3, 2, 1},
1054 	 {1, 2, 3, 4, 5},
1055 	 {5, 4, 3, 2, 1},
1056 	 {6, 4, 2, 0, 2}};
1057 
1058    /* Write the 8-bit raster image to file */
1059    status = DFR8putimage(IMAGE_DF_FILE, raster_data, WIDTH, LENGTH, COMP_RLE);
1060 
1061     /* Initialize the 24-bit image array */
1062     for (ii = 0; ii < WIDTH; ii++)
1063 	for (jj = 0; jj < LENGTH; jj++)
1064 	{
1065 	    buf[ii][jj][0] = buf[ii][jj][1] = buf[ii][jj][2] = (char)(ii + jj);
1066 	}
1067 
1068     /* Set interlace for the 24-bit RI */
1069     status = DF24setil(DFIL_PIXEL);
1070 
1071     /* Make sure that no compression is being used - the variable Grcompr is
1072        global in dfgr.c so its value is inherited from other tests in the lib
1073        and causes this image to be compressed with JPEG unintentionally.  We
1074        want to be able to see the data to verify it with "od" */
1075     status = DF24setcompress(COMP_NONE, NULL);
1076 
1077     /* Write the 24-bit raster image to file */
1078     status = DF24addimage(IMAGE_DF_FILE, &(buf[0][0][0]), WIDTH, LENGTH);
1079 
1080 
1081     /****************************************************************
1082       Re-open the file to read the images and their data information
1083      ****************************************************************/
1084     /* Re-open the file and initialize the GR interface */
1085     fid = Hopen (IMAGE_DF_FILE, DFACC_RDONLY, 0);
1086     CHECK_VOID(fid, FAIL, "Hopen");
1087     grid = GRstart (fid);
1088     CHECK_VOID(grid, FAIL, "GRstart");
1089 
1090     /* Get the number of images in the file */
1091     status = GRfileinfo(grid, &n_images, &n_fattrs);
1092     CHECK_VOID(status, FAIL, "GRfileinfo");
1093     VERIFY_VOID(n_images, N_DF_IMAGES, "GRfileinfo");
1094 
1095     /* Open each image then get and verify its data information.  Note that
1096 	currently, the offsets and lengths are obtained from debugging
1097 	and the command od on the file */
1098     for (ii = 0; ii < n_images; ii++)
1099     {
1100 	uintn info_count = 0;
1101 
1102 	riid = GRselect(grid, ii);
1103 	CHECK_VOID(riid, FAIL, "GRselect");
1104 
1105 	/* Get the number of data blocks and verify; should be 1 */
1106 	info_count = GRgetdatainfo(riid, 0, 0, NULL, NULL);
1107 	CHECK_VOID(info_count, FAIL, "GRgetdatainfo");
1108 	VERIFY_VOID(info_count, 1, "GRgetdatainfo");
1109 
1110 	/* Get offset/length of the image and verify with pre-determined
1111 	   values */
1112 	info_count = GRgetdatainfo(riid, 0, info_count, &offset, &length);
1113 	CHECK_VOID(info_count, FAIL, "GRgetdatainfo");
1114 	VERIFY_VOID(offset, image_data_offsets[ii], "GRgetdatainfo");
1115 	VERIFY_VOID(length, image_data_lengths[ii], "GRgetdatainfo");
1116 
1117 	/* Close the image */
1118 	status = GRendaccess(riid);
1119 	CHECK_VOID(status, FAIL, "GRendaccess");
1120     } /* for n_images */
1121 
1122     /* Terminate access to the GR interface and close the file */
1123     status = GRend(grid);
1124     CHECK_VOID(status, FAIL, "GRend");
1125     status = Hclose(fid);
1126     CHECK_VOID(status, FAIL, "Hclose");
1127 }  /* test_dfr8_24 */
1128 
1129 #if 0
1130 /* clang does not like CHECK_VOID which does not return any value. */
1131 /* So, coding is wrong but this function is not used at all.*/
1132 /* So, screen it out for now. -AKC 2013/01/18 */
1133  /* intn check_dds(char *fname, char *msg)
1134  */
1135 intn check_dds(int32 grid, char *msg)
1136 {
1137     intn n_pals = 0;
1138     hdf_ddinfo_t *palinfo_array = NULL;
1139     uint8 *inbuf;
1140     intn  status;       /* status returned from routines */
1141     intn ii, jj;        /* indices */
1142 
1143     n_pals = 0;
1144     n_pals = GRgetpalinfo(grid, 0, NULL);
1145     CHECK_VOID(n_pals, FAIL, "GRgetpalinfo");
1146 
1147     palinfo_array = (hdf_ddinfo_t *) HDmalloc(n_pals * sizeof(hdf_ddinfo_t));
1148     CHECK_ALLOC(palinfo_array, "palinfo_array", "test_getpalinfo");
1149 
1150     n_pals = GRgetpalinfo(grid, n_pals, palinfo_array);
1151     CHECK_VOID(n_pals, FAIL, "GRgetpalinfo");
1152 
1153     fprintf(stderr, "GRgetpalinfo return pal count = %d\n", n_pals);
1154     fprintf(stderr, "tag    ref    offset  length \n");
1155     for (ii = 0; ii < n_pals; ii++)
1156        fprintf(stderr, "%d    %d      %d       %d\n", palinfo_array[ii].tag,
1157     palinfo_array[ii].ref, palinfo_array[ii].offset, palinfo_array[ii].length);
1158 
1159     return 0;
1160 }
1161 #endif
1162 
1163 
1164 /*************************************************************************
1165  test_getpalinfo() - tests GRgetpalinfo
1166  Need documentation
1167 **************************************************************************/
1168 #define  IMAGE_DFPAL_FILE  "tdatainfo_pal.hdf"
1169 #define  IMAGE_WITH_PAL    "GR Image with Palette"
1170 #define  IMAGE2_WITH_PAL   "Second GR Image w/pal"
1171 #define  ANO_IMAGE_NAME    "ANO_IMAGE_NAME"
1172 #define  LASTIMAGE_NOPAL   "Last GR Image: no pal"
1173 #define  N_COMPS_IMG       2       /* number of image components */
1174 #define  N_ENTRIES         256     /* number of entries in the palette */
1175 #define  N_COMPS_PAL       3       /* number of palette's components */
1176 
1177 static void
test_getpalinfo()1178 test_getpalinfo()
1179 {
1180     int32 fid, grid,	/* file ID and GR interface ID */
1181 	      riid, palid,  /* raster image ID and palette ID */
1182           interlace_mode,
1183           start[2],     /* where to start to write for each dimension  */
1184           edges[2],     /* specifies how long to write for each dimension */
1185           dim_sizes[2];  /* sizes of the two dimensions of the image array */
1186     uint8 image_buf[WIDTH][LENGTH][N_COMPS_IMG]; /* data of raster image */
1187     uint8 palette_buf1[N_ENTRIES][N_COMPS_PAL];  /* for LUT mostly */
1188     uint8 palette_buf2[N_ENTRIES][N_COMPS_PAL];
1189     uint8 paletteA[N_ENTRIES*N_COMPS_PAL],  /* for IP8 mostly */
1190 	      paletteB[N_ENTRIES*N_COMPS_PAL],
1191 	      paletteD[N_ENTRIES*N_COMPS_PAL];
1192     intn  n_pals = 0; /* number of palettes, returned by DFPnpals and GRgetpalinfo */
1193     hdf_ddinfo_t *palinfo_array = NULL; /* list of palette DDs */
1194     uint8 *inbuf;	/* palette data read back in */
1195     intn  ii, jj;	/* indices */
1196     intn  status;	/* status returned from routines */
1197 
1198     /* Initialize the 8-bit image array */
1199     static uint8 raster_data[WIDTH][LENGTH] =
1200 	{ 1, 2, 3, 4, 5,
1201 	  5, 4, 3, 2, 1,
1202 	  1, 2, 3, 4, 5,
1203 	  5, 4, 3, 2, 1,
1204 	  6, 4, 2, 0, 2 };
1205 
1206     /* Palettes are added in the following means and order:
1207 	paletteA (DFPputpal)
1208 	paletteB (DFPputpal)
1209 	paletteA (DFR8setpalette/DFR8addimage)
1210 	palette_buf1 (GRwritelut) for image named IMAGE_WITH_PAL
1211 	palette_buf2 (GRwritelut) for image named IMAGE2_WITH_PAL
1212 	paletteB (DFR8setpalette/DFR8addimage)
1213 	paletteD (DFPputpal)
1214 	paletteB (DFPputpal)
1215 	paletteD (DFPputpal)
1216 	palette_buf2 (GRwritelut) for image named IMAGE2_WITH_PAL
1217 	paletteD (DFPputpal)
1218     */
1219     /* Add two palettes with DFP API. */
1220     status = DFPputpal(IMAGE_DFPAL_FILE, paletteA, 0, "w");
1221     CHECK_VOID(status, FAIL, "DFPputpal");
1222 
1223     status = DFPputpal(IMAGE_DFPAL_FILE, paletteB, 0, "a");
1224     CHECK_VOID(status, FAIL, "DFPputpal");
1225 
1226     n_pals = DFPnpals(IMAGE_DFPAL_FILE);
1227     CHECK_VOID(n_pals, FAIL, "DFPnpals");
1228     VERIFY_VOID(n_pals, 2, "DFPputpal");  /* 2 palettes from 2 DFPputpal's */
1229 
1230     /* Specify palette to be used with subsequent 8-bit images */
1231     status = DFR8setpalette(paletteA);
1232     CHECK_VOID(status, FAIL, "DFR8setpalette");
1233 
1234     /* Write an 8-bit raster image to the file */
1235     status = DFR8addimage(IMAGE_DFPAL_FILE, raster_data, WIDTH, LENGTH, COMP_RLE);
1236     CHECK_VOID(status, FAIL, "DFR8addimage");
1237 
1238     /* Get the number of palettes using DFP API */
1239     n_pals = DFPnpals(IMAGE_DFPAL_FILE);
1240     CHECK_VOID(n_pals, FAIL, "DFPnpals");
1241     VERIFY_VOID(n_pals, 3, "DFPputpal");
1242     /* 3 palettes: 2 DFPputpal's + DFR8setpalette/DFR8addimage combo */
1243 
1244     /* Write another 8-bit raster image to file, without calling another
1245        DFR8setpalette, that means this image is using the same palette as the
1246        previous image.  This is when only 201 is created */
1247     status = DFR8addimage(IMAGE_DFPAL_FILE, raster_data, WIDTH, LENGTH, COMP_RLE);
1248     CHECK_VOID(status, FAIL, "DFR8addimage");
1249 
1250     /* Thus, the number of palettes returned by DFPnpals should be the same as
1251        from the last call to DFPnpals */
1252     n_pals = DFPnpals(IMAGE_DFPAL_FILE);
1253     CHECK_VOID(n_pals, FAIL, "DFPnpals");
1254     VERIFY_VOID(n_pals, 3, "DFPputpal");
1255 
1256     /****************************************************************
1257 	Re-open the file in GR interface, add a few images with
1258 	palettes, then test GRgetpalinfo on the palettes
1259      ****************************************************************/
1260 
1261     /* Re-open the file and initialize the GR interface */
1262     fid = Hopen (IMAGE_DFPAL_FILE, DFACC_RDWR, 0);
1263     CHECK_VOID(fid, FAIL, "Hopen");
1264     grid = GRstart (fid);
1265     CHECK_VOID(grid, FAIL, "GRstart");
1266 
1267     /* Define the dimensions and interlace mode of the image */
1268     dim_sizes[0] = LENGTH;
1269     dim_sizes[1] = WIDTH;
1270     interlace_mode = MFGR_INTERLACE_PIXEL;
1271 
1272     /* Create an image named IMAGE_WITH_PAL */
1273     riid = GRcreate (grid, IMAGE_WITH_PAL, N_COMPS_IMG, DFNT_UINT8,
1274                      interlace_mode, dim_sizes);
1275 
1276     /* Fill the image data buffer with values */
1277     for (ii = 0; ii < WIDTH; ii++)
1278     {
1279        for (jj = 0; jj < LENGTH; jj++)
1280        {
1281           image_buf[ii][jj][0] = (ii + jj) + 1;
1282           image_buf[ii][jj][1] = (ii + jj) + 2;
1283        }
1284      }
1285 
1286     /* Define the size of the data to be written */
1287     start[0] = start[1] = 0;
1288     edges[0] = WIDTH;
1289     edges[1] = LENGTH;
1290 
1291     /* Write the data in the buffer into the image array */
1292     status = GRwriteimage (riid, start, NULL, edges, (VOIDP)image_buf);
1293 
1294     /* Initialize the palette data */
1295     for (ii = 0; ii < N_ENTRIES; ii++) {
1296         palette_buf1[ii][0] = ii;
1297         palette_buf1[ii][1] = 0;
1298         palette_buf1[ii][2] = 8;
1299     }
1300 
1301     /* Get the identifier of the palette attached to the image IMAGE_WITH_PAL */
1302     palid = GRgetlutid (riid, 0);
1303 
1304     /* Write data to the palette. */
1305     status = GRwritelut (palid, N_COMPS_PAL, DFNT_UINT8, interlace_mode,
1306                          N_ENTRIES, (VOIDP)palette_buf1);
1307 
1308     /* DFPnpals now sees another palette */
1309     n_pals = DFPnpals(IMAGE_DFPAL_FILE);
1310     CHECK_VOID(n_pals, FAIL, "DFPnpals");
1311     VERIFY_VOID(n_pals, 4, "DFPputpal");
1312 
1313     /* Terminate access to the first image */
1314     status = GRendaccess (riid);
1315 
1316     /* Create another image named IMAGE2_WITH_PAL */
1317     riid = GRcreate (grid, IMAGE2_WITH_PAL, N_COMPS_IMG, DFNT_UINT8,
1318                      interlace_mode, dim_sizes);
1319 
1320     /* Write the data in the buffer into the image array */
1321     status = GRwriteimage (riid, start, NULL, edges, (VOIDP)image_buf);
1322 
1323     /* Get the id of the palette attached to the image IMAGE2_WITH_PAL */
1324     palid = GRgetlutid (riid, 0);
1325 
1326     /* Initialize the palette for second image */
1327     for (ii = 0; ii < N_ENTRIES; ii++) {
1328 	palette_buf2[ii][0] = 2;
1329 	palette_buf2[ii][1] = 4;
1330 	palette_buf2[ii][2] = 8;
1331     }
1332 
1333     /* Write data to the palette */
1334     status = GRwritelut (palid, N_COMPS_PAL, DFNT_UINT8, interlace_mode,
1335                          N_ENTRIES, (VOIDP)palette_buf2);
1336 
1337     /* DFPnpals now sees another palette */
1338     n_pals = DFPnpals(IMAGE_DFPAL_FILE);
1339     CHECK_VOID(n_pals, FAIL, "DFPnpals");
1340     VERIFY_VOID(n_pals, 5, "DFPputpal");
1341 
1342     /* Terminate access to this image */
1343     status = GRendaccess (riid);
1344     CHECK_VOID(status, FAIL, "GRendaccess");
1345 
1346     /* Create another image named LASTIMAGE_NOPAL */
1347     riid = GRcreate (grid, LASTIMAGE_NOPAL, N_COMPS_IMG, DFNT_UINT8,
1348                      interlace_mode, dim_sizes);
1349     CHECK_VOID(riid, FAIL, "GRcreate");
1350 
1351     /* Write the data in the buffer into the image array */
1352     status = GRwriteimage (riid, start, NULL, edges, (VOIDP)image_buf);
1353     CHECK_VOID(status, FAIL, "GRwriteimage");
1354 
1355     /* Terminate access to the image */
1356     status = GRendaccess (riid);
1357     CHECK_VOID(status, FAIL, "GRendaccess");
1358 
1359     status = DFR8setpalette(paletteB);
1360     CHECK_VOID(status, FAIL, "DFR8setpalette");
1361 
1362     /* Write another 8-bit raster image to file */
1363     status = DFR8addimage(IMAGE_DFPAL_FILE, raster_data, WIDTH, LENGTH, COMP_RLE);
1364     CHECK_VOID(status, FAIL, "DFR8addimage");
1365 
1366     /* DFR8setpalette/DFR8addimage just added another palette, so DFPnpals now
1367        returns 6 */
1368     n_pals = DFPnpals(IMAGE_DFPAL_FILE);
1369     CHECK_VOID(n_pals, FAIL, "DFPnpals");
1370     VERIFY_VOID(n_pals, 6, "DFPputpal");
1371 
1372     status = DFPputpal(IMAGE_DFPAL_FILE, paletteD, 0, "a");
1373     CHECK_VOID(status, FAIL, "DFPputpal");
1374 
1375     n_pals = DFPnpals(IMAGE_DFPAL_FILE);
1376     CHECK_VOID(n_pals, FAIL, "DFPnpals");
1377     VERIFY_VOID(n_pals, 7, "DFPnpals");
1378 
1379     status = DFPputpal(IMAGE_DFPAL_FILE, paletteB, 0, "a");
1380     CHECK_VOID(status, FAIL, "DFPputpal");
1381 
1382     status = DFPputpal(IMAGE_DFPAL_FILE, paletteD, 0, "a");
1383     CHECK_VOID(status, FAIL, "DFPputpal");
1384 
1385     n_pals = DFPnpals(IMAGE_DFPAL_FILE);
1386     CHECK_VOID(n_pals, FAIL, "DFPnpals");
1387     VERIFY_VOID(n_pals, 9, "DFPputpal");
1388 
1389     /* Create another image named ANO_IMAGE_NAME. */
1390     riid = GRcreate (grid, ANO_IMAGE_NAME, N_COMPS_IMG, DFNT_UINT8,
1391                       interlace_mode, dim_sizes);
1392     CHECK_VOID(riid, FAIL, "GRcreate");
1393 
1394     /* Write the data in the buffer into the image array. */
1395     status = GRwriteimage (riid, start, NULL, edges, (VOIDP)image_buf);
1396     CHECK_VOID(status, FAIL, "GRwriteimage");
1397 
1398     /* Get the identifier of the palette attached to the image ANO_IMAGE_NAME */
1399     palid = GRgetlutid (riid, 0);
1400     CHECK_VOID(palid, FAIL, "GRgetlutid");
1401 
1402     /* Write data to the palette. */
1403     status = GRwritelut (palid, N_COMPS_PAL, DFNT_UINT8, interlace_mode,
1404                          N_ENTRIES, (VOIDP)palette_buf2);
1405 
1406     n_pals = DFPnpals(IMAGE_DFPAL_FILE);
1407     CHECK_VOID(n_pals, FAIL, "DFPnpals");
1408     VERIFY_VOID(n_pals, 10, "DFPputpal");
1409 
1410    status = GRendaccess (riid);
1411 
1412     status = DFPputpal(IMAGE_DFPAL_FILE, paletteD, 0, "a");
1413     CHECK_VOID(status, FAIL, "DFPputpal");
1414 
1415     n_pals = DFPnpals(IMAGE_DFPAL_FILE);
1416     CHECK_VOID(n_pals, FAIL, "DFPnpals");
1417     VERIFY_VOID(n_pals, 11, "DFPputpal");
1418 
1419     /* Assuming that this file has been written exactly in this manner, this
1420        is what the palette DDs would look like at this point:
1421 	tag    ref    offset  length
1422 	201    1      294       768
1423 	301    1      294       768
1424 	201    2      1062      768
1425 	301    2      1062      768
1426 	301    3      1860      768
1427 	201    3      1860      768
1428 	201    4      1860      768
1429 	301    4      2973      768 <- cannot be read by DFPgetpal
1430 	301    5      3806      768 <- cannot be read by DFPgetpal
1431 	301    8      4669      768
1432 	201    8      4669      768
1433 	201    5      5449      768
1434 	201    6      6217      768
1435 	301    6      6217      768
1436 	201    7      7183      768
1437 	301    7      7183      768
1438 	301    9      8016      768 <- cannot be read by DFPgetpal
1439 	201    9      8784      768
1440  */
1441 
1442     /* Read some palettes */
1443     {
1444 
1445     /* Call GRgetpalinfo the first time, passing in NULL for the palette array,
1446        to get the number of palettes in the file */
1447     n_pals = 0;
1448     n_pals = GRgetpalinfo(grid, 0, NULL);
1449     CHECK_VOID(n_pals, FAIL, "GRgetpalinfo");
1450 
1451     palinfo_array = (hdf_ddinfo_t *) HDmalloc(n_pals * sizeof(hdf_ddinfo_t));
1452     CHECK_ALLOC(palinfo_array, "palinfo_array", "test_getpalinfo");
1453 
1454     n_pals = GRgetpalinfo(grid, n_pals, palinfo_array);
1455     CHECK_VOID(n_pals, FAIL, "GRgetpalinfo");
1456 
1457     /* Read and verify data of the first palette which is pointed to by both
1458        data identifiers 201/ref and 301/ref */
1459      /* inbuf = (uint8 *) HDmalloc(palinfo_array[0].length * sizeof(uint8));
1460  */
1461     inbuf = (uint8 *) HDmalloc(palinfo_array[0].length);
1462     CHECK_ALLOC(inbuf, "inbuf", "test_getpalinfo");
1463     status = Hgetelement(fid, palinfo_array[0].tag, palinfo_array[0].ref, inbuf);
1464     CHECK_VOID(status, FAIL, "Hgetelement");
1465 
1466     if (HDmemcmp(inbuf, paletteA, palinfo_array[0].length)!=0)
1467 	fprintf(stderr, "palette data pointed by tag/ref = %d/%d at offset/length = %d/%d differs from written\n", palinfo_array[0].tag, palinfo_array[0].ref, palinfo_array[0].offset, palinfo_array[0].length);
1468 
1469     /* Read and verify data of the palette pointed to by 301/4.  This is the
1470        data element that was not revealed by DFPgetpal because the tag/ref pair
1471        201/4 is associated with a different offset */
1472 
1473      /* inbuf = (uint8 *) HDmalloc(palinfo_array[7].length * sizeof(uint8));
1474  */
1475     inbuf = (uint8 *) HDmalloc(palinfo_array[7].length);
1476     CHECK_ALLOC(inbuf, "inbuf", "test_getpalinfo");
1477     status = Hgetelement(fid, palinfo_array[7].tag, palinfo_array[7].ref, inbuf);
1478     CHECK_VOID(status, FAIL, "Hgetelement");
1479 
1480     if (HDmemcmp(inbuf, palette_buf1, palinfo_array[7].length)!=0)
1481 	fprintf(stderr, "palette data pointed by tag/ref = %d/%d at offset/length = %d/%d differs from written\n", palinfo_array[7].tag, palinfo_array[7].ref, palinfo_array[7].offset, palinfo_array[7].length);
1482     }
1483 
1484     /* Terminate access to the GR interface and close the file */
1485     status = GRend(grid);
1486     CHECK_VOID(status, FAIL, "GRend");
1487     status = Hclose(fid);
1488     CHECK_VOID(status, FAIL, "Hclose");
1489 
1490 }  /* test_getpalinfo */
1491 
1492 
1493 /****************************************************************************
1494    Name: test_getntinfo() - tests getting number type's information
1495 
1496    Description:
1497 	This routine simply calls Hgetntinfo with various types and verifies
1498 	the information retrieved.
1499    BMR - Aug 2010
1500  ****************************************************************************/
1501 static void
test_getntinfo()1502 test_getntinfo()
1503 {
1504     hdf_ntinfo_t nt_info;
1505     intn status = SUCCEED;
1506 
1507     status = Hgetntinfo(DFNT_UINT8, &nt_info);
1508     CHECK_VOID(status, FAIL, "Hgetntinfo DFNT_UINT8");
1509     VERIFY_CHAR_VOID(nt_info.type_name, "uint8", "Hgetntinfo DFNT_UINT8");
1510     VERIFY_CHAR_VOID(nt_info.byte_order, "bigEndian", "Hgetntinfo DFNT_UINT8");
1511 
1512     status = Hgetntinfo(DFNT_CHAR16, &nt_info);
1513     CHECK_VOID(status, FAIL, "Hgetntinfo DFNT_CHAR16");
1514     VERIFY_CHAR_VOID(nt_info.type_name, "char16", "Hgetntinfo DFNT_CHAR16");
1515     VERIFY_CHAR_VOID(nt_info.byte_order, "bigEndian", "Hgetntinfo DFNT_CHAR16");
1516 
1517     /* Native */
1518     status = Hgetntinfo(DFNT_NFLOAT32, &nt_info);
1519     CHECK_VOID(status, FAIL, "Hgetntinfo DFNT_NFLOAT32");
1520     VERIFY_CHAR_VOID(nt_info.type_name, "float32", "Hgetntinfo DFNT_NFLOAT32");
1521     VERIFY_CHAR_VOID(nt_info.byte_order, "bigEndian", "Hgetntinfo DFNT_NFLOAT32");
1522 
1523     /* Little endian */
1524     status = Hgetntinfo(DFNT_LFLOAT32, &nt_info);
1525     CHECK_VOID(status, FAIL, "Hgetntinfo DFNT_LFLOAT32");
1526     VERIFY_CHAR_VOID(nt_info.type_name, "float32", "Hgetntinfo DFNT_LFLOAT32");
1527     VERIFY_CHAR_VOID(nt_info.byte_order, "littleEndian", "Hgetntinfo DFNT_LFLOAT32");
1528 
1529     /* Little endian backward compatible */
1530     status = Hgetntinfo(DFNT_LCHAR, &nt_info);
1531     CHECK_VOID(status, FAIL, "Hgetntinfo DFNT_LCHAR");
1532     VERIFY_CHAR_VOID(nt_info.type_name, "char8", "Hgetntinfo DFNT_LCHAR");
1533     VERIFY_CHAR_VOID(nt_info.byte_order, "littleEndian", "Hgetntinfo DFNT_LCHAR");
1534 
1535     /* Backward compatible */
1536     status = Hgetntinfo(DFNT_DOUBLE, &nt_info);
1537     CHECK_VOID(status, FAIL, "Hgetntinfo DFNT_DOUBLE");
1538     VERIFY_CHAR_VOID(nt_info.type_name, "float64", "Hgetntinfo DFNT_DOUBLE");
1539     VERIFY_CHAR_VOID(nt_info.byte_order, "bigEndian", "Hgetntinfo DFNT_DOUBLE");
1540 
1541     /* Native backward compatible */
1542     status = Hgetntinfo(DFNT_NUCHAR, &nt_info);
1543     CHECK_VOID(status, FAIL, "Hgetntinfo DFNT_NUCHAR");
1544     VERIFY_CHAR_VOID(nt_info.type_name, "uchar8", "Hgetntinfo DFNT_NUCHAR");
1545     VERIFY_CHAR_VOID(nt_info.byte_order, "bigEndian", "Hgetntinfo DFNT_NUCHAR");
1546 } /* test_getntinfo */
1547 
1548 /* Test driver for testing the public functions VSgetdatainfo, ANgetdatainfo,
1549    GRgetdatainfo, and Hgetntinfo. */
1550 void
test_datainfo()1551 test_datainfo()
1552 {
1553     /* Test VSgetdatainfo with data stored in one contiguous block */
1554     test_simple_vs();
1555 
1556     /* Test VSgetdatainfo with data might be stored in linked blocks */
1557     test_append_vs();
1558 
1559     /* Test ANgetdatainfo */
1560     test_annotation();
1561 
1562     /* Test GRgetdatainfo with images stored in one contiguous block, with
1563        and without compression */
1564     test_oneblock_ri();
1565 
1566     /* Test GRgetdatainfo with RI8 and RI24 */
1567     test_dfr8_24();
1568 
1569     /* Test GRgetpalinfo with RI8 and GR */
1570     test_getpalinfo();
1571 
1572     /* Test Hgetntinfo */
1573     test_getntinfo();
1574 }
1575