1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2  * Copyright by The HDF Group.                                               *
3  * Copyright by the Board of Trustees of the University of Illinois.         *
4  * All rights reserved.                                                      *
5  *                                                                           *
6  * This file is part of HDF5.  The full HDF5 copyright notice, including     *
7  * terms governing use, modification, and redistribution, is contained in    *
8  * the COPYING file, which can be found at the root of the source code       *
9  * distribution tree, or in https://support.hdfgroup.org/ftp/HDF5/releases.  *
10  * If you do not have access to either file, you may request a copy from     *
11  * help@hdfgroup.org.                                                        *
12  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
13 
14 #include "h5test.h"
15 
16 #define ROWS    12
17 #define COLS    18
18 #define FLOAT_TOL 0.0001F
19 
20 static int init_test(hid_t file_id);
21 static int test_copy(const hid_t dxpl_id_c_to_f_copy, const hid_t dxpl_id_polynomial_copy);
22 static int test_trivial(const hid_t dxpl_id_simple);
23 static int test_poly(const hid_t dxpl_id_polynomial);
24 static int test_specials(hid_t file);
25 static int test_set(void);
26 static int test_getset(const hid_t dxpl_id_simple);
27 
28 /* These are needed for multiple tests, so are declared here globally and are init'ed in init_test */
29 hid_t dset_id_int = -1;
30 hid_t dset_id_float = -1;
31 hid_t dset_id_int_chunk = -1;
32 hid_t dset_id_float_chunk = -1;
33 
34 
35 const float windchillFfloat[ROWS][COLS] =
36     {   {36.0f, 31.0f, 25.0f, 19.0f, 13.0f,   7.0f,   1.0f,  -5.0f, -11.0f, -16.0f, -22.0f, -28.0f, -34.0f, -40.0f, -46.0f, -52.0f, -57.0f, -63.0f},
37 	{34.0f, 27.0f, 21.0f, 15.0f,  9.0f,   3.0f,  -4.0f, -10.0f, -16.0f, -22.0f, -28.0f, -35.0f, -41.0f, -47.0f, -53.0f, -59.0f, -66.0f, -72.0f} ,
38 	{32.0f, 25.0f, 19.0f, 13.0f,  6.0f,   0.0f,  -7.0f, -13.0f, -19.0f, -26.0f, -32.0f, -39.0f, -45.0f, -51.0f, -58.0f, -64.0f, -71.0f, -77.0f},
39 	{30.0f, 24.0f, 17.0f, 11.0f,  4.0f,  -2.0f,  -9.0f, -15.0f, -22.0f, -29.0f, -35.0f, -42.0f, -48.0f, -55.0f, -61.0f, -68.0f, -74.0f, -81.0f},
40 	{29.0f, 23.0f, 16.0f,  9.0f,  3.0f,  -4.0f, -11.0f, -17.0f, -24.0f, -31.0f, -37.0f, -44.0f, -51.0f, -58.0f, -64.0f, -71.0f, -78.0f, -84.0f},
41 	{28.0f, 22.0f, 15.0f,  8.0f,  1.0f,  -5.0f, -12.0f, -19.0f, -26.0f, -33.0f, -39.0f, -46.0f, -53.0f, -60.0f, -67.0f, -73.0f, -80.0f, -87.0f},
42 	{28.0f, 21.0f, 14.0f,  7.0f,  0.0f,  -7.0f, -14.0f, -21.0f, -27.0f, -34.0f, -41.0f, -48.0f, -55.0f, -62.0f, -69.0f, -76.0f, -82.0f, -89.0f},
43 	{27.0f, 20.0f, 13.0f,  6.0f, -1.0f,  -8.0f, -15.0f, -22.0f, -29.0f, -36.0f, -43.0f, -50.0f, -57.0f, -64.0f, -71.0f, -78.0f, -84.0f, -91.0f},
44 	{26.0f, 19.0f, 12.0f,  5.0f, -2.0f,  -9.0f, -16.0f, -23.0f, -30.0f, -37.0f, -44.0f, -51.0f, -58.0f, -65.0f, -72.0f, -79.0f, -86.0f, -93.0f},
45 	{26.0f, 19.0f, 12.0f,  4.0f, -3.0f, -10.0f, -17.0f, -24.0f, -31.0f, -38.0f, -45.0f, -52.0f, -60.0f, -67.0f, -74.0f, -81.0f, -88.0f, -95.0f},
46 	{25.0f, 18.0f, 11.0f,  4.0f, -3.0f, -11.0f, -18.0f, -25.0f, -32.0f, -39.0f, -46.0f, -54.0f, -61.0f, -68.0f, -75.0f, -82.0f, -89.0f, -97.0f},
47 	{25.0f, 17.0f, 10.0f,  3.0f, -4.0f, -11.0f, -19.0f, -26.0f, -33.0f, -40.0f, -48.0f, -55.0f, -62.0f, -69.0f, -76.0f, -84.0f, -91.0f, -98.0f}
48     };
49 
50 const int transformData[ROWS][COLS] =
51     {   {36, 31, 25, 19, 13, 7, 1, 5, 11, 16, 22, 28, 34, 40, 46, 52, 57, 63 },
52         {34, 27, 21, 15, 9, 3, 4, 10, 16, 22, 28, 35, 41, 47, 53, 59, 66, 1 } ,
53         {32, 25, 19, 13, 6, 2, 7, 13, 19, 26, 32, 39, 45, 51, 58, 64, 71, 5 },
54         {30, 24, 17, 11, 4, 2, 9, 15, 22, 29, 35, 42, 48, 55, 61, 68, 2, 9 },
55         {29, 23, 16, 9, 3, 4, 11, 17, 24, 31, 37, 44, 51, 58, 64, 71, 6, 12 },
56         {28, 22, 15, 8, 1, 5, 12, 19, 26, 33, 39, 46, 53, 60, 67, 1, 8, 15 },
57         {28, 21, 14, 7, 6, 7, 14, 21, 27, 34, 41, 48, 55, 62, 69, 4, 10, 17 },
58         {27, 20, 13, 6, 1, 8, 15, 22, 29, 36, 43, 50, 57, 64, 71, 6, 12, 19 },
59         {26, 19, 12, 5, 2, 9, 16, 23, 30, 37, 44, 51, 58, 65, 5, 7, 14, 21 },
60         {26, 19, 12, 4, 3, 10, 17, 24, 31, 38, 45, 52, 60, 67, 2, 9, 16, 23},
61         {25, 18, 11, 4, 3, 11, 18, 25, 32, 39, 46, 54, 61, 68, 3, 10, 17, 25},
62         {25, 17, 10, 3, 4, 11, 19, 26, 33, 40, 48, 55, 62, 69, 4, 12, 19, 26}
63     };
64 
65 #define UCOMPARE(TYPE,VAR1,VAR2,TOL)			\
66 {							\
67     size_t i,j;						\
68 							\
69     for(i=0; i<ROWS; i++)				\
70         for(j=0; j<COLS; j++)				\
71         {							\
72             if(!( (((VAR1)[i][j] >= (TYPE)((VAR2)[i][j])) && ( ((VAR1)[i][j] - TOL) < (TYPE)((VAR2)[i][j]))) || (  ((VAR1)[i][j] <= (TYPE)((VAR2)[i][j])) && ( ((VAR1)[i][j] + TOL) > (TYPE)((VAR2)[i][j])))))	\
73             {						\
74                 H5_FAILED();				\
75                 fprintf(stderr, "    ERROR: Conversion failed to match computed data\n");	\
76                 goto error;					\
77             }						\
78         }							\
79     PASSED();						\
80 }
81 
82 #define COMPARE(TYPE,VAR1,VAR2,TOL)			\
83 {							\
84     size_t i,j;						\
85 							\
86     for(i=0; i<ROWS; i++)				\
87         for(j=0; j<COLS; j++)				\
88         {							\
89             if( !(((VAR1)[i][j] <= ((TYPE)(VAR2)[i][j] + TOL)) && ((VAR1)[i][j] >= ((TYPE)(VAR2)[i][j] - TOL))) )	\
90             {						\
91                 H5_FAILED();				\
92                 fprintf(stderr, "    ERROR: Conversion failed to match computed data\n");	\
93                 goto error;					\
94             }						\
95         }							\
96     PASSED();						\
97 }
98 
99 #define COMPARE_INT(VAR1,VAR2)			        \
100 {							\
101     size_t i,j;						\
102 							\
103     for(i=0; i<ROWS; i++)				\
104         for(j=0; j<COLS; j++)				\
105         {						\
106             if( (VAR1)[i][j] != (VAR2)[i][j] )	        \
107             {						\
108                 H5_FAILED();				\
109                 fprintf(stderr, "    ERROR: data  failed to match computed data\n");	\
110                 goto error;				\
111             }						\
112         }						\
113 }
114 
115 #define TEST_TYPE_CONTIG(XFORM, TYPE, HDF_TYPE, TEST_STR, COMPARE_DATA, SIGNED)	\
116 {										\
117     TYPE array[ROWS][COLS];							\
118     const char* f_to_c = "(5/9.0)*(x-32)";					\
119     /* utrans is a transform for unsigned types: no negative numbers involved and results are < 255 to fit into uchar */ \
120     const char* utrans = "((x+100)/4)*3";					\
121 										\
122     hid_t dataspace, dxpl_id_f_to_c, dxpl_id_utrans, dset, dset_nn, dt_nn;	\
123     H5T_order_t order;                                                          \
124     hsize_t dim[2] = {ROWS, COLS};						\
125 										\
126     if((dataspace = H5Screate_simple(2, dim, NULL)) < 0) TEST_ERROR;		\
127     if((dset = H5Dcreate2(file_id, "/transformtest_"TEST_STR, HDF_TYPE, dataspace, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR; \
128                                                                                 \
129     if((dt_nn = H5Tcopy(HDF_TYPE)) < 0) TEST_ERROR                              \
130     if((order = H5Tget_order(dt_nn)) == H5T_ORDER_ERROR) TEST_ERROR             \
131     if(H5Tset_order(dt_nn, order == H5T_ORDER_LE ? H5T_ORDER_BE : H5T_ORDER_LE) < 0) TEST_ERROR \
132     if((dset_nn = H5Dcreate2(file_id, "/nonnative_transformtest_"TEST_STR, dt_nn, dataspace, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR	\
133     if(H5Tclose(dt_nn) < 0) TEST_ERROR                                          \
134 										\
135     if(SIGNED)									\
136     {										\
137 	if((dxpl_id_f_to_c = H5Pcreate(H5P_DATASET_XFER)) < 0) TEST_ERROR;	\
138 	if(H5Pset_data_transform(dxpl_id_f_to_c, f_to_c) < 0) TEST_ERROR;	\
139 	if(H5Dwrite(dset, H5T_NATIVE_FLOAT, H5S_ALL, H5S_ALL, dxpl_id_f_to_c, windchillFfloat) < 0) TEST_ERROR;	\
140 	if(H5Dwrite(dset_nn, H5T_NATIVE_FLOAT, H5S_ALL, H5S_ALL, dxpl_id_f_to_c, windchillFfloat) < 0) TEST_ERROR;	\
141 	if(H5Pclose(dxpl_id_f_to_c) < 0) TEST_ERROR;			\
142     }										\
143     else									\
144     {										\
145 	if((dxpl_id_utrans = H5Pcreate(H5P_DATASET_XFER)) < 0) TEST_ERROR;	\
146 	if(H5Pset_data_transform(dxpl_id_utrans, utrans) < 0) TEST_ERROR;	\
147 	if(H5Dwrite(dset, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, dxpl_id_utrans, transformData) < 0) TEST_ERROR;	\
148 	if(H5Dwrite(dset_nn, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, dxpl_id_utrans, transformData) < 0) TEST_ERROR;	\
149 	if(H5Pclose(dxpl_id_utrans) < 0) TEST_ERROR;			\
150     }										\
151 										\
152 										\
153     TESTING("contiguous, no data type conversion ("TEST_STR"->"TEST_STR")")	\
154 										\
155     if(H5Dread(dset, HDF_TYPE, H5S_ALL, H5S_ALL, XFORM, array) < 0) TEST_ERROR;	\
156     if(SIGNED)									\
157         COMPARE(TYPE, array, COMPARE_DATA, 2)					\
158     else									\
159         UCOMPARE(TYPE, array, COMPARE_DATA, 4)					\
160                                                                                 \
161     TESTING("contiguous, byte order conversion ("TEST_STR"->"TEST_STR")")	\
162 										\
163     if(H5Dread(dset_nn, HDF_TYPE, H5S_ALL, H5S_ALL, XFORM, array) < 0) TEST_ERROR;	\
164     if(SIGNED)									\
165         COMPARE(TYPE, array, COMPARE_DATA, 2)					\
166     else									\
167         UCOMPARE(TYPE, array, COMPARE_DATA, 4)					\
168 										\
169     if(SIGNED)									\
170     {    									\
171         TESTING("contiguous, with type conversion (float->"TEST_STR")")	\
172 										\
173 	if(H5Dread(dset_id_float, HDF_TYPE, H5S_ALL, H5S_ALL, XFORM, array) < 0) TEST_ERROR;	\
174 	COMPARE(TYPE, array, COMPARE_DATA, 2)				\
175     }										\
176 										\
177    if(H5Dclose(dset) < 0) TEST_ERROR;					\
178    if(H5Sclose(dataspace) < 0) TEST_ERROR;				\
179 }
180 
181 #define TEST_TYPE_CHUNK(XFORM, TYPE, HDF_TYPE, TEST_STR, COMPARE_DATA, SIGNED)	\
182 {										\
183     TYPE array[ROWS][COLS];							\
184     const char* f_to_c = "(5/9.0)*(x-32)";					\
185     /* utrans is a transform for unsigned types: no negative numbers involved and results are < 255 to fit into uchar */ \
186     const char* utrans = "((x+100)/4)*3";					\
187 										\
188     hid_t dataspace, dxpl_id_f_to_c, dxpl_id_utrans, cparms, memspace, dset_chunk, filespace;	\
189     hsize_t dim[2] = {ROWS, COLS};						\
190     hsize_t offset[2] = {0, 0};							\
191 										\
192 										\
193     if((dataspace = H5Screate_simple(2, dim, NULL)) < 0) TEST_ERROR;		\
194 										\
195     if((cparms = H5Pcreate(H5P_DATASET_CREATE)) < 0) TEST_ERROR;		\
196     if(H5Pset_chunk(cparms, 2, dim) < 0) TEST_ERROR;				\
197 										\
198     if((dset_chunk = H5Dcreate2(file_id, "/transformtest_chunk_"TEST_STR, HDF_TYPE, dataspace, H5P_DEFAULT, cparms, H5P_DEFAULT)) < 0) TEST_ERROR;	\
199     if((filespace = H5Dget_space(dset_chunk)) < 0) TEST_ERROR			\
200     if((memspace = H5Screate_simple(2, dim, NULL)) < 0) TEST_ERROR		\
201     if(H5Sselect_hyperslab(filespace, H5S_SELECT_SET, offset, NULL, dim, NULL) < 0) TEST_ERROR;			\
202     										\
203     if(SIGNED)									\
204     {										\
205 	if((dxpl_id_f_to_c = H5Pcreate(H5P_DATASET_XFER)) < 0) TEST_ERROR;	\
206 	if(H5Pset_data_transform(dxpl_id_f_to_c, f_to_c) < 0) TEST_ERROR;	\
207 	if(H5Dwrite(dset_chunk, H5T_NATIVE_FLOAT, dataspace, filespace, dxpl_id_f_to_c, windchillFfloat) < 0) TEST_ERROR;	\
208 	if(H5Pclose(dxpl_id_f_to_c) < 0) TEST_ERROR;				\
209     }										\
210     else									\
211     {										\
212 	if((dxpl_id_utrans = H5Pcreate(H5P_DATASET_XFER)) < 0) TEST_ERROR;	\
213 	if(H5Pset_data_transform(dxpl_id_utrans, utrans) < 0) TEST_ERROR;	\
214 	if(H5Dwrite(dset_chunk, H5T_NATIVE_INT, dataspace, filespace, dxpl_id_utrans, transformData) < 0) TEST_ERROR;	\
215 	if(H5Pclose(dxpl_id_utrans) < 0) TEST_ERROR;				\
216     }										\
217 										\
218 										\
219     TESTING("chunked, no data type conversion ("TEST_STR"->"TEST_STR")")	\
220 										\
221     if(H5Dread(dset_chunk, HDF_TYPE, memspace, filespace, XFORM, array) < 0) TEST_ERROR;	\
222     if(SIGNED)									\
223         COMPARE(TYPE, array, COMPARE_DATA, 2)					\
224     else									\
225         UCOMPARE(TYPE, array, COMPARE_DATA, 4)					\
226 										\
227     if(SIGNED)									\
228     {    									\
229         TESTING("chunked, with type conversion (float->"TEST_STR")")		\
230 										\
231 	if(H5Dread(dset_id_float_chunk, HDF_TYPE, memspace, filespace, XFORM, array) < 0) TEST_ERROR;	\
232 	COMPARE(TYPE, array, COMPARE_DATA, 2)					\
233     }										\
234 										\
235 										\
236    if(H5Pclose(cparms) < 0) TEST_ERROR;						\
237    if(H5Dclose(dset_chunk) < 0) TEST_ERROR;					\
238    if(H5Sclose(dataspace) < 0) TEST_ERROR;					\
239    if(H5Sclose(memspace) < 0) TEST_ERROR;					\
240 }
241 
242 #define INVALID_SET_TEST(TRANSFORM)			\
243 {							\
244     if(H5Pset_data_transform(dxpl_id, TRANSFORM) < 0)	\
245     {							\
246 	PASSED();					\
247     }							\
248     else						\
249     {							\
250 	H5_FAILED();					\
251 	fprintf(stderr, "    ERROR: Data transform allowed invalid TRANSFORM transform to be set\n");	\
252 	goto error;					\
253     }							\
254 }
255 
main(void)256 int main(void)
257 {
258     hid_t dxpl_id_c_to_f = -1;
259     hid_t dxpl_id_c_to_f_copy = 1;
260     hid_t dxpl_id_simple = -1;
261     hid_t dxpl_id_polynomial = -1;
262     hid_t dxpl_id_polynomial_copy = -1;
263     hid_t dxpl_id_utrans_inv = -1;
264     hid_t file_id = -1;
265 
266     const char* c_to_f = "(9/5.0)*x + 32";
267     const char* simple = "(4/2) * ( (2 + 4)/(5 - 2.5))"; /* this equals 4.8 */
268     const char* polynomial = "(2+x)* ((x-8)/2)";
269     /* inverses the utrans transform in init_test to get back original array */
270     const char* utrans_inv = "(x/3)*4 - 100";
271 
272     if((file_id = H5Fcreate("dtransform.h5", H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT)) < 0) TEST_ERROR;
273 
274     if((dxpl_id_c_to_f = H5Pcreate(H5P_DATASET_XFER)) < 0) TEST_ERROR;
275     if((dxpl_id_simple = H5Pcreate(H5P_DATASET_XFER)) < 0) TEST_ERROR;
276     if((dxpl_id_utrans_inv = H5Pcreate(H5P_DATASET_XFER)) < 0) TEST_ERROR;
277     if((dxpl_id_polynomial =  H5Pcreate(H5P_DATASET_XFER)) < 0) TEST_ERROR;
278     if(H5Pset_data_transform(dxpl_id_c_to_f, c_to_f) < 0) TEST_ERROR;
279     if(H5Pset_data_transform(dxpl_id_polynomial, polynomial) < 0) TEST_ERROR;
280     if(H5Pset_data_transform(dxpl_id_simple, simple) < 0) TEST_ERROR;
281     if(H5Pset_data_transform(dxpl_id_utrans_inv, utrans_inv) < 0) TEST_ERROR;
282     if((dxpl_id_polynomial_copy = H5Pcopy(dxpl_id_polynomial)) < 0) TEST_ERROR;
283     if((dxpl_id_c_to_f_copy = H5Pcopy(dxpl_id_c_to_f)) < 0) TEST_ERROR;
284 
285     /* Run all the tests */
286 
287     if(init_test(file_id) < 0) TEST_ERROR;
288     if(test_set() < 0) TEST_ERROR;
289     TEST_TYPE_CONTIG(dxpl_id_utrans_inv, char, H5T_NATIVE_CHAR, "char", transformData, 0);
290     TEST_TYPE_CONTIG(dxpl_id_utrans_inv, unsigned char, H5T_NATIVE_UCHAR, "uchar", transformData, 0);
291     TEST_TYPE_CONTIG(dxpl_id_c_to_f, signed char, H5T_NATIVE_SCHAR, "schar", windchillFfloat, 1);
292     TEST_TYPE_CONTIG(dxpl_id_c_to_f, short, H5T_NATIVE_SHORT, "short", windchillFfloat, 1);
293     TEST_TYPE_CONTIG(dxpl_id_utrans_inv, unsigned short, H5T_NATIVE_USHORT, "ushort", transformData, 0);
294     TEST_TYPE_CONTIG(dxpl_id_c_to_f, int, H5T_NATIVE_INT, "int", windchillFfloat, 1);
295     TEST_TYPE_CONTIG(dxpl_id_utrans_inv, unsigned int, H5T_NATIVE_UINT, "uint", transformData, 0);
296     TEST_TYPE_CONTIG(dxpl_id_c_to_f, long, H5T_NATIVE_LONG, "long", windchillFfloat, 1);
297     TEST_TYPE_CONTIG(dxpl_id_utrans_inv, unsigned long, H5T_NATIVE_ULONG, "ulong", transformData, 0);
298     TEST_TYPE_CONTIG(dxpl_id_c_to_f, long long, H5T_NATIVE_LLONG, "llong", windchillFfloat, 1);
299     TEST_TYPE_CONTIG(dxpl_id_utrans_inv, unsigned long long, H5T_NATIVE_ULLONG, "ullong", transformData, 0);
300     TEST_TYPE_CONTIG(dxpl_id_c_to_f, float, H5T_NATIVE_FLOAT, "float", windchillFfloat, 1);
301     TEST_TYPE_CONTIG(dxpl_id_c_to_f, double, H5T_NATIVE_DOUBLE, "double", windchillFfloat, 1);
302 #if H5_SIZEOF_LONG_DOUBLE!=0
303     TEST_TYPE_CONTIG(dxpl_id_c_to_f, long double, H5T_NATIVE_LDOUBLE, "ldouble", windchillFfloat, 1);
304 #endif
305 
306     TEST_TYPE_CHUNK(dxpl_id_utrans_inv, char, H5T_NATIVE_CHAR, "char", transformData, 0);
307     TEST_TYPE_CHUNK(dxpl_id_utrans_inv, unsigned char, H5T_NATIVE_UCHAR, "uchar", transformData, 0);
308     TEST_TYPE_CHUNK(dxpl_id_c_to_f, signed char, H5T_NATIVE_SCHAR, "schar", windchillFfloat, 1);
309     TEST_TYPE_CHUNK(dxpl_id_c_to_f, short, H5T_NATIVE_SHORT, "short", windchillFfloat, 1);
310     TEST_TYPE_CHUNK(dxpl_id_utrans_inv, unsigned short, H5T_NATIVE_USHORT, "ushort", transformData, 0);
311     TEST_TYPE_CHUNK(dxpl_id_c_to_f, int, H5T_NATIVE_INT, "int", windchillFfloat, 1);
312     TEST_TYPE_CHUNK(dxpl_id_utrans_inv, unsigned int, H5T_NATIVE_UINT, "uint", transformData, 0);
313     TEST_TYPE_CHUNK(dxpl_id_c_to_f, long, H5T_NATIVE_LONG, "long", windchillFfloat, 1);
314     TEST_TYPE_CHUNK(dxpl_id_utrans_inv, unsigned long, H5T_NATIVE_ULONG, "ulong", transformData, 0);
315     TEST_TYPE_CHUNK(dxpl_id_c_to_f, long long, H5T_NATIVE_LLONG, "llong", windchillFfloat, 1);
316     TEST_TYPE_CHUNK(dxpl_id_utrans_inv, unsigned long long, H5T_NATIVE_ULLONG, "ullong", transformData, 0);
317     TEST_TYPE_CHUNK(dxpl_id_c_to_f, float, H5T_NATIVE_FLOAT, "float", windchillFfloat, 1);
318     TEST_TYPE_CHUNK(dxpl_id_c_to_f, double, H5T_NATIVE_DOUBLE, "double", windchillFfloat, 1);
319 #if H5_SIZEOF_LONG_DOUBLE!=0
320     TEST_TYPE_CHUNK(dxpl_id_c_to_f, long double, H5T_NATIVE_LDOUBLE, "ldouble", windchillFfloat, 1);
321 #endif
322 
323     if(test_copy(dxpl_id_c_to_f_copy, dxpl_id_polynomial_copy) < 0) TEST_ERROR;
324     if(test_trivial(dxpl_id_simple) < 0) TEST_ERROR;
325     if(test_poly(dxpl_id_polynomial) < 0) TEST_ERROR;
326     if(test_getset(dxpl_id_c_to_f) < 0) TEST_ERROR;
327     if(test_specials(file_id) < 0) TEST_ERROR;
328 
329     /* Close the objects we opened/created */
330     if(H5Dclose(dset_id_int) < 0) TEST_ERROR;
331     if(H5Dclose(dset_id_int_chunk) < 0) TEST_ERROR;
332     if(H5Dclose(dset_id_float) < 0) TEST_ERROR;
333     if(H5Dclose(dset_id_float_chunk) < 0) TEST_ERROR;
334     if(H5Fclose(file_id) < 0) TEST_ERROR;
335     if(H5Pclose(dxpl_id_c_to_f) < 0) TEST_ERROR;
336     if(H5Pclose(dxpl_id_c_to_f_copy) < 0) TEST_ERROR;
337     if(H5Pclose(dxpl_id_polynomial) < 0) TEST_ERROR;
338     if(H5Pclose(dxpl_id_polynomial_copy) < 0) TEST_ERROR;
339     if(H5Pclose(dxpl_id_simple) < 0) TEST_ERROR;
340     if(H5Pclose(dxpl_id_utrans_inv) < 0) TEST_ERROR;
341 
342 
343    return 0;
344 
345 error:
346     H5E_BEGIN_TRY {
347         H5Dclose(dset_id_int);
348         H5Dclose(dset_id_int_chunk);
349         H5Dclose(dset_id_float);
350         H5Dclose(dset_id_float_chunk);
351         H5Fclose(file_id);
352         H5Pclose(dxpl_id_c_to_f);
353         H5Pclose(dxpl_id_c_to_f_copy);
354         H5Pclose(dxpl_id_polynomial);
355         H5Pclose(dxpl_id_polynomial_copy);
356         H5Pclose(dxpl_id_simple);
357         H5Pclose(dxpl_id_utrans_inv);
358     } H5E_END_TRY
359    return -1;
360 }
361 
362 static int
init_test(hid_t file_id)363 init_test(hid_t file_id)
364 {
365     const char* f_to_c = "(5/9.0)*(x-32)";
366     /* utrans is a transform for unsigned types: no negative numbers involved and results are < 255 to fit into uchar */
367     const char* utrans = "((x+100)/4)*3";
368 
369     hid_t   dataspace = -1;
370     hid_t   dxpl_id_f_to_c = -1;
371     hid_t   dxpl_id_utrans = -1;
372     hid_t   cparms = -1;
373     hid_t   filespace = -1;
374     hsize_t dim[2] = { ROWS, COLS };
375     hsize_t offset[2] = { 0, 0 };
376 
377     if((dxpl_id_f_to_c = H5Pcreate(H5P_DATASET_XFER)) < 0)
378         TEST_ERROR
379     if((dxpl_id_utrans = H5Pcreate(H5P_DATASET_XFER)) < 0)
380         TEST_ERROR
381 
382     if(H5Pset_data_transform(dxpl_id_f_to_c, f_to_c) < 0)
383         TEST_ERROR
384     if(H5Pset_data_transform(dxpl_id_utrans, utrans) < 0)
385         TEST_ERROR
386 
387     cparms = H5Pcreate(H5P_DATASET_CREATE);
388     if(H5Pset_chunk(cparms, 2, dim) < 0)
389         TEST_ERROR
390 
391     if((dataspace = H5Screate_simple(2, dim, NULL)) < 0)
392         TEST_ERROR
393 
394     TESTING("Intializing test...")
395 
396     if((dset_id_int = H5Dcreate2(file_id, "/default_int", H5T_NATIVE_INT,
397             dataspace, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0)
398         TEST_ERROR
399     if(H5Dwrite(dset_id_int, H5T_NATIVE_FLOAT, H5S_ALL, H5S_ALL,
400             dxpl_id_f_to_c, windchillFfloat) < 0)
401         TEST_ERROR
402 
403     if((dset_id_float = H5Dcreate2(file_id, "/default_float",
404             H5T_NATIVE_FLOAT, dataspace, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0)
405         TEST_ERROR
406     if(H5Dwrite(dset_id_float, H5T_NATIVE_FLOAT, H5S_ALL, H5S_ALL,
407             dxpl_id_f_to_c, windchillFfloat) < 0)
408         TEST_ERROR
409 
410     if((dset_id_int_chunk = H5Dcreate2(file_id, "/default_chunk_int",
411             H5T_NATIVE_INT, dataspace, H5P_DEFAULT, cparms, H5P_DEFAULT)) < 0)
412         TEST_ERROR
413 
414     if((filespace = H5Dget_space(dset_id_int_chunk)) < 0)
415         TEST_ERROR
416     if(H5Sselect_hyperslab(filespace, H5S_SELECT_SET, offset, NULL, dim, NULL) < 0)
417         TEST_ERROR
418     if(H5Dwrite(dset_id_int_chunk, H5T_NATIVE_FLOAT, dataspace, filespace,
419             dxpl_id_f_to_c, windchillFfloat) < 0)
420         TEST_ERROR
421 
422     if((dset_id_float_chunk = H5Dcreate2(file_id, "/default_chunk_float",
423             H5T_NATIVE_FLOAT, dataspace, H5P_DEFAULT, cparms, H5P_DEFAULT)) < 0)
424         TEST_ERROR
425     if(H5Dwrite(dset_id_float_chunk, H5T_NATIVE_FLOAT, dataspace, filespace,
426             dxpl_id_f_to_c, windchillFfloat) < 0)
427         TEST_ERROR
428 
429     if(H5Pclose(cparms) < 0)
430         TEST_ERROR
431     if(H5Pclose(dxpl_id_f_to_c) < 0)
432         TEST_ERROR
433     if(H5Pclose(dxpl_id_utrans) < 0)
434         TEST_ERROR
435     if(H5Sclose(dataspace) < 0)
436         TEST_ERROR
437     if(H5Sclose(filespace) < 0)
438         TEST_ERROR
439 
440     PASSED();
441 
442     return 0;
443 
444 error:
445     H5E_BEGIN_TRY {
446         H5Pclose(cparms);
447         H5Pclose(dxpl_id_f_to_c);
448         H5Pclose(dxpl_id_utrans);
449         H5Sclose(dataspace);
450         H5Sclose(filespace);
451     } H5E_END_TRY
452 
453     return -1;
454 }
455 
456 static int
test_poly(const hid_t dxpl_id_polynomial)457 test_poly(const hid_t dxpl_id_polynomial)
458 {
459     float polyflres[ROWS][COLS];
460     int polyintread[ROWS][COLS];
461     float polyflread[ROWS][COLS];
462     int windchillC;
463     int row, col;
464 
465     for(row = 0; row < ROWS; row++)
466         for(col = 0; col < COLS; col++) {
467             windchillC = (int) ((5.0f / 9.0f) * (windchillFfloat[row][col] - 32));
468             polyflres[row][col] = (float) ((2.0f + windchillC) * ((windchillC - 8.0f) / 2.0f));
469         }
470 
471     TESTING("data transform, polynomial transform (int->float)")
472     if(H5Dread(dset_id_int, H5T_NATIVE_FLOAT, H5S_ALL, H5S_ALL,
473             dxpl_id_polynomial, polyflread) < 0)
474         TEST_ERROR
475 
476     COMPARE(float, polyflread, polyflres, 2.0f)
477 
478     for(row = 0; row < ROWS; row++)
479         for(col = 0; col < COLS; col++) {
480             windchillC = (int) ((5.0f / 9.0f) * (windchillFfloat[row][col] - 32));
481             polyflres[row][col] = (float) ((2 + windchillC) * ((windchillC - 8) / 2));
482         }
483 
484     TESTING("data transform, polynomial transform (float->int)")
485     if(H5Dread(dset_id_float, H5T_NATIVE_INT, H5S_ALL, H5S_ALL,
486             dxpl_id_polynomial, polyintread) < 0)
487         TEST_ERROR
488 
489     COMPARE(int, polyintread, polyflres, 4)
490 
491     return 0;
492 
493 error:
494      return -1;
495 }
496 
497 static int
test_specials(hid_t file)498 test_specials(hid_t file)
499 {
500     hid_t dxpl_id, dset_id, dataspace;
501     hsize_t dim[2] = { ROWS, COLS };
502     int read_buf[ROWS][COLS];
503     int data_res[ROWS][COLS];
504     int row, col;
505     const char* special1 = "x*-100";
506     const char* special2 = "100-x";
507     const char* special3 = "1000/x";
508     const char* special4 = "-x";
509     const char* special5 = "+x";
510 
511     TESTING("data transform of some special cases")
512 
513     if((dataspace = H5Screate_simple(2, dim, NULL)) < 0)
514         TEST_ERROR
515 
516     if((dxpl_id = H5Pcreate(H5P_DATASET_XFER)) < 0) TEST_ERROR;
517 
518     /*-----------------------------
519      * Operation 1: x*-100
520      *----------------------------*/
521     if(H5Pset_data_transform(dxpl_id, special1) < 0) TEST_ERROR;
522 
523     for(row = 0; row < ROWS; row++)
524         for(col = 0; col < COLS; col++)
525             data_res[row][col] = transformData[row][col] * -100;
526 
527     if((dset_id = H5Dcreate2(file, "/special1", H5T_NATIVE_INT,
528             dataspace, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0)
529         TEST_ERROR
530     if(H5Dwrite(dset_id, H5T_NATIVE_INT, H5S_ALL, H5S_ALL,
531             dxpl_id, transformData) < 0)
532         TEST_ERROR
533     if(H5Dread(dset_id, H5T_NATIVE_INT, H5S_ALL, H5S_ALL,
534             H5P_DEFAULT, read_buf) < 0)
535         TEST_ERROR
536 
537     COMPARE_INT(read_buf, data_res)
538 
539     if(H5Dclose(dset_id) < 0)
540         TEST_ERROR
541 
542     /*-----------------------------
543      * Operation 2: 100-x
544      *----------------------------*/
545     if(H5Pset_data_transform(dxpl_id, special2) < 0) TEST_ERROR;
546 
547     for(row = 0; row < ROWS; row++)
548         for(col = 0; col < COLS; col++)
549             data_res[row][col] = 100 - transformData[row][col];
550 
551     if((dset_id = H5Dcreate2(file, "/special2", H5T_NATIVE_INT,
552             dataspace, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0)
553         TEST_ERROR
554     if(H5Dwrite(dset_id, H5T_NATIVE_INT, H5S_ALL, H5S_ALL,
555             dxpl_id, transformData) < 0)
556         TEST_ERROR
557     if(H5Dread(dset_id, H5T_NATIVE_INT, H5S_ALL, H5S_ALL,
558             H5P_DEFAULT, read_buf) < 0)
559         TEST_ERROR
560 
561     COMPARE_INT(read_buf, data_res)
562 
563     if(H5Dclose(dset_id) < 0)
564         TEST_ERROR
565 
566     /*-----------------------------
567      * Operation 3: 1000/x
568      *----------------------------*/
569     if(H5Pset_data_transform(dxpl_id, special3) < 0) TEST_ERROR;
570 
571     for(row = 0; row < ROWS; row++)
572         for(col = 0; col < COLS; col++)
573             data_res[row][col] = 1000 / transformData[row][col];
574 
575     if((dset_id = H5Dcreate2(file, "/special3", H5T_NATIVE_INT,
576             dataspace, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0)
577         TEST_ERROR
578     if(H5Dwrite(dset_id, H5T_NATIVE_INT, H5S_ALL, H5S_ALL,
579             dxpl_id, transformData) < 0)
580         TEST_ERROR
581     if(H5Dread(dset_id, H5T_NATIVE_INT, H5S_ALL, H5S_ALL,
582             H5P_DEFAULT, read_buf) < 0)
583         TEST_ERROR
584 
585     COMPARE_INT(read_buf, data_res)
586 
587     if(H5Dclose(dset_id) < 0)
588         TEST_ERROR
589 
590     /*-----------------------------
591      * Operation 4: -x
592      *----------------------------*/
593     if(H5Pset_data_transform(dxpl_id, special4) < 0) TEST_ERROR;
594 
595     for(row = 0; row < ROWS; row++)
596         for(col = 0; col < COLS; col++)
597             data_res[row][col] = -1 * transformData[row][col];
598 
599     if((dset_id = H5Dcreate2(file, "/special4", H5T_NATIVE_INT,
600             dataspace, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0)
601         TEST_ERROR
602     if(H5Dwrite(dset_id, H5T_NATIVE_INT, H5S_ALL, H5S_ALL,
603             dxpl_id, transformData) < 0)
604         TEST_ERROR
605     if(H5Dread(dset_id, H5T_NATIVE_INT, H5S_ALL, H5S_ALL,
606             H5P_DEFAULT, read_buf) < 0)
607         TEST_ERROR
608 
609     COMPARE_INT(read_buf, data_res)
610 
611     if(H5Dclose(dset_id) < 0)
612         TEST_ERROR
613 
614     /*-----------------------------
615      * Operation 5: +x
616      *----------------------------*/
617     if(H5Pset_data_transform(dxpl_id, special5) < 0) TEST_ERROR;
618 
619     for(row = 0; row < ROWS; row++)
620         for(col = 0; col < COLS; col++)
621             data_res[row][col] = transformData[row][col];
622 
623     if((dset_id = H5Dcreate2(file, "/special5", H5T_NATIVE_INT,
624             dataspace, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0)
625         TEST_ERROR
626     if(H5Dwrite(dset_id, H5T_NATIVE_INT, H5S_ALL, H5S_ALL,
627             dxpl_id, transformData) < 0)
628         TEST_ERROR
629     if(H5Dread(dset_id, H5T_NATIVE_INT, H5S_ALL, H5S_ALL,
630             H5P_DEFAULT, read_buf) < 0)
631         TEST_ERROR
632 
633     COMPARE_INT(read_buf, data_res)
634 
635     if(H5Dclose(dset_id) < 0)
636         TEST_ERROR
637 
638 
639     if(H5Pclose(dxpl_id) < 0)
640         TEST_ERROR
641     if(H5Sclose(dataspace) < 0)
642         TEST_ERROR
643 
644     PASSED();
645     return 0;
646 
647 error:
648      return -1;
649 }
650 
651 static int
test_copy(const hid_t dxpl_id_c_to_f_copy,const hid_t dxpl_id_polynomial_copy)652 test_copy(const hid_t dxpl_id_c_to_f_copy, const hid_t dxpl_id_polynomial_copy)
653 {
654     int windchillC;
655     float polyflres[ROWS][COLS];
656     int polyintread[ROWS][COLS];
657     int windchillFintread[ROWS][COLS];
658     int row, col;
659 
660     for(row = 0; row < ROWS; row++)
661         for(col = 0; col < COLS; col++) {
662             windchillC = (int) ((5.0f / 9.0f) * (windchillFfloat[row][col] - 32));
663             polyflres[row][col] = (float) ((2 + windchillC) * ((windchillC - 8) / 2));
664         }
665 
666     TESTING("data transform, linear transform w/ copied property")
667     if(H5Dread(dset_id_float, H5T_NATIVE_INT, H5S_ALL, H5S_ALL,
668             dxpl_id_c_to_f_copy, windchillFintread) < 0)
669         TEST_ERROR
670 
671     COMPARE(int, windchillFintread, windchillFfloat, 2)
672 
673     TESTING("data transform, polynomial transform w/ copied property")
674     if(H5Dread(dset_id_float, H5T_NATIVE_INT, H5S_ALL, H5S_ALL,
675             dxpl_id_polynomial_copy, polyintread) < 0)
676         TEST_ERROR
677 
678     COMPARE(int, polyintread, polyflres, 2)
679 
680     return 0;
681 
682 error:
683     return -1;
684 }
685 
686 static int
test_trivial(const hid_t dxpl_id_simple)687 test_trivial(const hid_t dxpl_id_simple)
688 {
689     float windchillFfloatread[ROWS][COLS];
690     int windchillFintread[ROWS][COLS];
691     int row, col;
692 
693     TESTING("data transform, trivial transform, without type conversion")
694     if(H5Dread(dset_id_float, H5T_NATIVE_FLOAT, H5S_ALL, H5S_ALL,
695             dxpl_id_simple, windchillFfloatread) < 0)
696         TEST_ERROR
697     for(row = 0; row < ROWS; row++)
698         for(col = 0; col < COLS; col++) {
699             if((windchillFfloatread[row][col] - 4.8f) > FLOAT_TOL)
700                 FAIL_PUTS_ERROR("    ERROR: Conversion failed to match computed data\n");
701         }
702 
703     PASSED()
704 
705     TESTING("data transform, trivial transform, with type conversion")
706     if(H5Dread(dset_id_float, H5T_NATIVE_INT, H5S_ALL, H5S_ALL,
707             dxpl_id_simple, windchillFintread) < 0)
708         TEST_ERROR
709     for(row = 0; row < ROWS; row++)
710         for(col = 0; col < COLS; col++) {
711             if(windchillFintread[row][col] != 4)
712                 FAIL_PUTS_ERROR("    ERROR: Conversion failed to match computed data\n")
713         }
714 
715     PASSED()
716 
717     return 0;
718 error:
719     return -1;
720 }
721 
722 static int
test_getset(const hid_t dxpl_id_c_to_f)723 test_getset(const hid_t dxpl_id_c_to_f)
724 {
725     int         row;
726     int         col;
727     float       windchillFfloatread[ROWS][COLS];
728     const char *simple = "(4/2) * ( (2 + 4)/(5 - 2.5))"; /* this equals 4.8 */
729     const char *c_to_f = "(9/5.0)*x + 32";
730     char       *ptrgetTest = NULL;
731 
732     TESTING("H5Pget_data_transform")
733 
734     if(NULL == (ptrgetTest = (char *)HDmalloc(HDstrlen(simple) + 1)))
735         TEST_ERROR
736 
737     if(H5Pget_data_transform(dxpl_id_c_to_f, ptrgetTest, HDstrlen(c_to_f) + 1) < 0)
738         TEST_ERROR
739     if(HDstrcmp(c_to_f, ptrgetTest) != 0)
740         FAIL_PUTS_ERROR("    ERROR: Data transform failed to match what was set\n")
741 
742     PASSED()
743 
744     HDfree(ptrgetTest);
745     ptrgetTest = NULL;
746 
747     TESTING("data transform, read after reseting of transform property")
748 
749     if(H5Pset_data_transform(dxpl_id_c_to_f, simple) < 0)
750         TEST_ERROR
751 
752     if(H5Dread(dset_id_float, H5T_NATIVE_FLOAT, H5S_ALL, H5S_ALL,
753                 dxpl_id_c_to_f, windchillFfloatread) < 0)
754         TEST_ERROR
755 
756     for(row = 0; row < ROWS; row++)
757         for(col = 0; col < COLS; col++) {
758             if((windchillFfloatread[row][col] - 4.8f) > FLOAT_TOL)
759                 FAIL_PUTS_ERROR("    ERROR: Conversion failed to match computed data\n")
760         }
761 
762     PASSED()
763 
764     TESTING("H5Pget_data_transform, after resetting transform property")
765 
766     if(NULL == (ptrgetTest = (char *)HDcalloc((size_t)1, HDstrlen(simple) + 1)))
767         TEST_ERROR
768     if(H5Pget_data_transform(dxpl_id_c_to_f, ptrgetTest, HDstrlen(simple) + 1) < 0)
769         TEST_ERROR
770     if(HDstrcmp(simple, ptrgetTest) != 0)
771         FAIL_PUTS_ERROR("    ERROR: Data transform failed to match what was set\n")
772 
773     PASSED()
774 
775     HDfree(ptrgetTest);
776     ptrgetTest = NULL;
777 
778     return 0;
779 
780 error:
781     if(ptrgetTest)
782         HDfree(ptrgetTest);
783 
784     return -1;
785 }
786 
787 static int
test_set(void)788 test_set(void)
789 {
790     hid_t dxpl_id = -1;
791     H5E_auto2_t func;
792     const char *str = "(9/5.0)*x + 32";
793     char *ptrgetTest = NULL;
794 
795     TESTING("H5Pget_data_transform (get before set)")
796 
797     if(NULL == (ptrgetTest = (char *)HDmalloc(HDstrlen(str) + 1)))
798         TEST_ERROR
799 
800     if((dxpl_id = H5Pcreate(H5P_DATASET_XFER)) < 0)
801         TEST_ERROR
802 
803     /* Test get before set */
804     H5Eget_auto2(H5E_DEFAULT, &func, NULL);
805 
806     H5Eset_auto2(H5E_DEFAULT, NULL, NULL);
807 
808     if(H5Pget_data_transform(dxpl_id, ptrgetTest, HDstrlen(str) + 1) < 0)
809         PASSED()
810     else
811         FAIL_PUTS_ERROR("    ERROR: Data transform get before set succeeded (it shouldn't have)\n");
812 
813     HDfree(ptrgetTest);
814     ptrgetTest = NULL;
815 
816     TESTING("H5Pset_data_transform (set with NULL transform)");
817     INVALID_SET_TEST(NULL);
818 
819     TESTING("H5Pset_data_transform (set with invalid transform 1)")
820     INVALID_SET_TEST("\0");
821 
822     TESTING("H5Pset_data_transform (set with invalid transform 2)")
823     INVALID_SET_TEST("     ");
824 
825     TESTING("H5Pset_data_transform (set with invalid transform 3)")
826     INVALID_SET_TEST("x+");
827 
828     TESTING("H5Pset_data_transform (set with invalid transform 4)")
829     INVALID_SET_TEST("(x+5");
830 
831     TESTING("H5Pset_data_transform (set with invalid transform 5)")
832     INVALID_SET_TEST("+");
833 
834     TESTING("H5Pset_data_transform (set with invalid transform 6)")
835     INVALID_SET_TEST("(9/5)*x + x**2");
836 
837     TESTING("H5Pset_data_transform (set with invalid transform 7)")
838     INVALID_SET_TEST("(9/5)x");
839 
840     TESTING("H5Pset_data_transform (set with invalid transform 8)")
841     INVALID_SET_TEST("(9/5)*x + x^2");
842 
843     H5Eset_auto2(H5E_DEFAULT, func, NULL);
844 
845     if(H5Pclose(dxpl_id) < 0)
846         TEST_ERROR
847 
848     return 0;
849 
850 error:
851     if(ptrgetTest)
852         HDfree(ptrgetTest);
853     H5E_BEGIN_TRY {
854         H5Pclose(dxpl_id);
855     } H5E_END_TRY
856 
857     return -1;
858 }
859 
860