1 /******************************************************************************
2  * $Id: gh5_convenience.cpp 26010 2013-05-17 23:31:00Z warmerdam $
3  *
4  * Project:  Hierarchical Data Format Release 5 (HDF5)
5  * Purpose:  HDF5 convenience functions.
6  * Author:   Frank Warmerdam <warmerdam@pobox.com>
7  *
8  ******************************************************************************
9  * Copyright (c) 2009, Frank Warmerdam <warmerdam@pobox.com>
10  *
11  * Permission is hereby granted, free of charge, to any person obtaining a
12  * copy of this software and associated documentation files (the "Software"),
13  * to deal in the Software without restriction, including without limitation
14  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
15  * and/or sell copies of the Software, and to permit persons to whom the
16  * Software is furnished to do so, subject to the following conditions:
17  *
18  * The above copyright notice and this permission notice shall be included
19  * in all copies or substantial portions of the Software.
20  *
21  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
22  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
24  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
26  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
27  * DEALINGS IN THE SOFTWARE.
28  ****************************************************************************/
29 
30 #include "gh5_convenience.h"
31 
32 CPL_CVSID("$Id: gh5_convenience.cpp 26010 2013-05-17 23:31:00Z warmerdam $");
33 
34 /************************************************************************/
35 /*                    GH5_FetchAttribute(CPLString)                     */
36 /************************************************************************/
37 
GH5_FetchAttribute(hid_t loc_id,const char * pszAttrName,CPLString & osResult,bool bReportError)38 bool GH5_FetchAttribute( hid_t loc_id, const char *pszAttrName,
39                         CPLString &osResult, bool bReportError )
40 
41 {
42     bool retVal = false;
43 
44     hid_t hAttr = H5Aopen_name( loc_id, pszAttrName );
45 
46     osResult.clear();
47 
48     if( hAttr < 0 )
49     {
50         if( bReportError )
51             CPLError( CE_Failure, CPLE_AppDefined,
52                       "Attempt to read attribute %s failed, not found.",
53                       pszAttrName );
54         return false;
55     }
56 
57     hid_t hAttrTypeID      = H5Aget_type( hAttr );
58     hid_t hAttrNativeType  = H5Tget_native_type( hAttrTypeID, H5T_DIR_DEFAULT );
59 
60     if( H5Tget_class( hAttrNativeType ) == H5T_STRING )
61     {
62 	int nAttrSize = H5Tget_size( hAttrTypeID );
63         char *pachBuffer = (char *) CPLCalloc(nAttrSize+1,1);
64 	H5Aread( hAttr, hAttrNativeType, pachBuffer );
65 
66         osResult = pachBuffer;
67         CPLFree( pachBuffer );
68 
69         retVal = true;
70     }
71 
72     else
73     {
74         if( bReportError )
75             CPLError( CE_Failure, CPLE_AppDefined,
76                       "Attribute %s of unsupported type for conversion to string.",
77                       pszAttrName );
78 
79         retVal = false;
80     }
81 
82     H5Tclose( hAttrNativeType );
83     H5Tclose( hAttrTypeID );
84     H5Aclose( hAttr );
85     return retVal;
86 }
87 
88 /************************************************************************/
89 /*                      GH5_FetchAttribute(double)                      */
90 /************************************************************************/
91 
GH5_FetchAttribute(hid_t loc_id,const char * pszAttrName,double & dfResult,bool bReportError)92 bool GH5_FetchAttribute( hid_t loc_id, const char *pszAttrName,
93                          double &dfResult, bool bReportError )
94 
95 {
96     hid_t hAttr = H5Aopen_name( loc_id, pszAttrName );
97 
98     dfResult = 0.0;
99     if( hAttr < 0 )
100     {
101         if( bReportError )
102             CPLError( CE_Failure, CPLE_AppDefined,
103                       "Attempt to read attribute %s failed, not found.",
104                       pszAttrName );
105         return false;
106     }
107 
108     hid_t hAttrTypeID      = H5Aget_type( hAttr );
109     hid_t hAttrNativeType  = H5Tget_native_type( hAttrTypeID, H5T_DIR_DEFAULT );
110 
111 /* -------------------------------------------------------------------- */
112 /*      Confirm that we have a single element value.                    */
113 /* -------------------------------------------------------------------- */
114 
115     hid_t hAttrSpace       = H5Aget_space( hAttr );
116     hsize_t anSize[64];
117     int nAttrDims       = H5Sget_simple_extent_dims( hAttrSpace, anSize, NULL );
118 
119     int i, nAttrElements = 1;
120 
121     for( i=0; i < nAttrDims; i++ ) {
122         nAttrElements *= (int) anSize[i];
123     }
124 
125     if( nAttrElements != 1 )
126     {
127         if( bReportError )
128             CPLError( CE_Failure, CPLE_AppDefined,
129                       "Attempt to read attribute %s failed, count=%d, not 1.",
130                       pszAttrName, nAttrElements );
131 
132         H5Sclose( hAttrSpace );
133         H5Tclose( hAttrNativeType );
134         H5Tclose( hAttrTypeID );
135         H5Aclose( hAttr );
136         return false;
137     }
138 
139 /* -------------------------------------------------------------------- */
140 /*      Read the value.                                                 */
141 /* -------------------------------------------------------------------- */
142     void *buf = (void *)CPLMalloc( H5Tget_size( hAttrNativeType ));
143     H5Aread( hAttr, hAttrNativeType, buf );
144 
145 /* -------------------------------------------------------------------- */
146 /*      Translate to double.                                            */
147 /* -------------------------------------------------------------------- */
148     if( H5Tequal( H5T_NATIVE_INT, hAttrNativeType ) )
149         dfResult = *((int *) buf);
150     else if( H5Tequal( H5T_NATIVE_FLOAT,    hAttrNativeType ) )
151         dfResult = *((float *) buf);
152     else if( H5Tequal( H5T_NATIVE_DOUBLE,    hAttrNativeType ) )
153         dfResult = *((double *) buf);
154     else
155     {
156         if( bReportError )
157             CPLError( CE_Failure, CPLE_AppDefined,
158                       "Attribute %s of unsupported type for conversion to double.",
159                       pszAttrName );
160         CPLFree( buf );
161 
162         H5Sclose( hAttrSpace );
163         H5Tclose( hAttrNativeType );
164         H5Tclose( hAttrTypeID );
165         H5Aclose( hAttr );
166 
167         return false;
168     }
169 
170     CPLFree( buf );
171 
172     H5Sclose( hAttrSpace );
173     H5Tclose( hAttrNativeType );
174     H5Tclose( hAttrTypeID );
175     H5Aclose( hAttr );
176     return true;
177 }
178 
179 /************************************************************************/
180 /*                          GH5_GetDataType()                           */
181 /*                                                                      */
182 /*      Transform HDF5 datatype to GDAL datatype                        */
183 /************************************************************************/
GH5_GetDataType(hid_t TypeID)184 GDALDataType GH5_GetDataType(hid_t TypeID)
185 {
186     if( H5Tequal( H5T_NATIVE_CHAR,        TypeID ) )
187 	return GDT_Byte;
188     else if( H5Tequal( H5T_NATIVE_SCHAR,  TypeID ) )
189 	return GDT_Byte;
190     else if( H5Tequal( H5T_NATIVE_UCHAR,  TypeID ) )
191 	return GDT_Byte;
192     else if( H5Tequal( H5T_NATIVE_SHORT,  TypeID ) )
193 	return GDT_Int16;
194     else if( H5Tequal( H5T_NATIVE_USHORT, TypeID ) )
195 	return GDT_UInt16;
196     else if( H5Tequal( H5T_NATIVE_INT,    TypeID ) )
197 	return GDT_Int32;
198     else if( H5Tequal( H5T_NATIVE_UINT,   TypeID ) )
199 	return GDT_UInt32;
200     else if( H5Tequal( H5T_NATIVE_LONG,   TypeID ) )
201     {
202         if( sizeof(long) == 4 )
203             return GDT_Int32;
204         else
205             return GDT_Unknown;
206     }
207     else if( H5Tequal( H5T_NATIVE_ULONG,  TypeID ) )
208     {
209         if( sizeof(unsigned long) == 4 )
210             return GDT_UInt32;
211         else
212             return GDT_Unknown;
213     }
214     else if( H5Tequal( H5T_NATIVE_FLOAT,  TypeID ) )
215 	return GDT_Float32;
216     else if( H5Tequal( H5T_NATIVE_DOUBLE, TypeID ) )
217 	return GDT_Float64;
218     else if( H5Tequal( H5T_NATIVE_LLONG,  TypeID ) )
219 	return GDT_Unknown;
220     else if( H5Tequal( H5T_NATIVE_ULLONG, TypeID ) )
221 	return GDT_Unknown;
222     else if( H5Tequal( H5T_NATIVE_DOUBLE, TypeID ) )
223 	return GDT_Unknown;
224 
225     return GDT_Unknown;
226 }
227 
228