1 //-*****************************************************************************
2 //
3 // Copyright (c) 2009-2012,
4 // Sony Pictures Imageworks, Inc. and
5 // Industrial Light & Magic, a division of Lucasfilm Entertainment Company Ltd.
6 //
7 // All rights reserved.
8 //
9 // Redistribution and use in source and binary forms, with or without
10 // modification, are permitted provided that the following conditions are
11 // met:
12 // * Redistributions of source code must retain the above copyright
13 // notice, this list of conditions and the following disclaimer.
14 // * Redistributions in binary form must reproduce the above
15 // copyright notice, this list of conditions and the following disclaimer
16 // in the documentation and/or other materials provided with the
17 // distribution.
18 // * Neither the name of Sony Pictures Imageworks, nor
19 // Industrial Light & Magic nor the names of their contributors may be used
20 // to endorse or promote products derived from this software without specific
21 // prior written permission.
22 //
23 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
26 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
27 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
28 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
29 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
30 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
31 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
33 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 //
35 //-*****************************************************************************
36
37 #include <Alembic/AbcCoreHDF5/HDF5Util.h>
38
39 namespace Alembic {
40 namespace AbcCoreHDF5 {
41 namespace ALEMBIC_VERSION_NS {
42
43 //-*****************************************************************************
44 //-*****************************************************************************
45 // CREATION ORDER FOR GROUPS
46 //-*****************************************************************************
47 //-*****************************************************************************
CreationOrderPlist()48 hid_t CreationOrderPlist()
49 {
50 herr_t status;
51 hid_t ID = H5Pcreate( H5P_GROUP_CREATE );
52 ABCA_ASSERT( ID >= 0,
53 "CreationOrderPlist: "
54 "H5Pcreate() failed" );
55
56 status = H5Pset_link_creation_order( ID,
57 ( H5P_CRT_ORDER_TRACKED |
58 H5P_CRT_ORDER_INDEXED ) );
59 ABCA_ASSERT( status >= 0,
60 "CreationOrderPlist: "
61 "H5Pset_link_creation_order() failed" );
62
63 return ID;
64 }
65
66 //-*****************************************************************************
67 //-*****************************************************************************
68 // GZIP COMPRESSION FOR DATASETS
69 //-*****************************************************************************
70 //-*****************************************************************************
DsetGzipCreatePlist(const Dimensions & dims,int level)71 hid_t DsetGzipCreatePlist( const Dimensions &dims, int level )
72 {
73 herr_t status;
74 hid_t ID = H5Pcreate( H5P_DATASET_CREATE );
75 ABCA_ASSERT( ID >= 0,
76 "DsetGzipCreatePlist: H5Pcreate failed" );
77
78 // Chunking.
79 HDimensions hdims( dims );
80 status = H5Pset_chunk( ID, hdims.rank(), hdims.rootPtr() );
81 ABCA_ASSERT( status >= 0,
82 "DsetGzipCreatePlist: "
83 "H5Pset_chunk() failed" );
84
85 level = level < 0 ? 0 : level > 9 ? 9 : level;
86 status = H5Pset_deflate( ID, ( unsigned int )level );
87 ABCA_ASSERT( status >= 0,
88 "DsetGzipCreatePlist: "
89 "H5Pset_link_creation_order() failed" );
90
91 return ID;
92 }
93
94 //-*****************************************************************************
EquivalentDatatypes(hid_t iA,hid_t iB)95 bool EquivalentDatatypes( hid_t iA, hid_t iB )
96 {
97 if ( iA >= 0 && iB >= 0 && H5Tequal( iA, iB ) > 0 )
98 return true;
99
100 return false;
101 }
102
103 //-*****************************************************************************
ObjectExists(H5Node & iParent,const std::string & iName)104 bool ObjectExists( H5Node& iParent, const std::string &iName )
105 {
106 ABCA_ASSERT( iParent.isValidObject(),
107 "Invalid parent node passed into HDF5Util GroupExists: "
108 << iName << std::endl );
109
110 HDF5Hierarchy* H5HPtr = iParent.getH5HPtr();
111
112 if ( H5HPtr )
113 {
114 return H5HPtr->childExists( iParent.getRef(), iName );
115 }
116 else
117 {
118 // First, check to make sure the link exists.
119 hid_t iParentObject = iParent.getObject();
120
121 htri_t exi = H5Lexists( iParentObject, iName.c_str(), H5P_DEFAULT );
122 if ( exi < 1 )
123 {
124 return false;
125 }
126 else
127 {
128 return true;
129 }
130 }
131 }
132
133 //-*****************************************************************************
GroupExists(H5Node & iParent,const std::string & iName)134 bool GroupExists( H5Node& iParent, const std::string &iName )
135 {
136 ABCA_ASSERT( iParent.isValidObject(),
137 "Invalid parent node passed into HDF5Util GroupExists: "
138 << iName << std::endl );
139
140 HDF5Hierarchy* h5HPtr = iParent.getH5HPtr();
141
142 if ( h5HPtr )
143 {
144 return h5HPtr->childExists( iParent.getRef(), iName );
145 }
146 else
147 {
148 // First, check to make sure the link exists.
149 hid_t iParentObject = iParent.getObject();
150
151 htri_t exi = H5Lexists( iParentObject, iName.c_str(), H5P_DEFAULT );
152 if ( exi < 1 )
153 {
154 return false;
155 }
156
157 // Now make sure it is a group.
158 H5O_info_t oinfo;
159 herr_t status = H5Oget_info_by_name( iParentObject,
160 iName.c_str(), &oinfo,
161 H5P_DEFAULT );
162 if ( status < 0 )
163 {
164 return false;
165 }
166
167 if ( oinfo.type != H5O_TYPE_GROUP )
168 {
169 return false;
170 }
171
172 return true;
173 }
174 }
175
176 //-*****************************************************************************
DatasetExists(H5Node & iParent,const std::string & iName)177 bool DatasetExists( H5Node& iParent, const std::string &iName )
178 {
179 ABCA_ASSERT( iParent.isValidObject(),
180 "Invalid parent group passed into HDF5Util DatasetExists: "
181 << iName << std::endl );
182
183 HDF5Hierarchy* h5HPtr = iParent.getH5HPtr();
184
185 if ( h5HPtr )
186 {
187 return h5HPtr->childExists( iParent.getRef(), iName );
188 }
189 else
190 {
191 hid_t iParentObject = iParent.getObject();
192
193 // First, check to make sure the link exists.
194 htri_t exi = H5Lexists( iParentObject, iName.c_str(), H5P_DEFAULT );
195 if ( exi < 1 )
196 {
197 return false;
198 }
199
200 // Now make sure it is a group.
201 H5O_info_t oinfo;
202 herr_t status = H5Oget_info_by_name( iParentObject,
203 iName.c_str(), &oinfo,
204 H5P_DEFAULT );
205 if ( status < 0 )
206 {
207 return false;
208 }
209
210 if ( oinfo.type != H5O_TYPE_DATASET )
211 {
212 return false;
213 }
214
215 return true;
216 }
217 }
218
219 //-*****************************************************************************
OpenGroup(H5Node & iParent,const std::string & iName)220 H5Node OpenGroup( H5Node& iParent, const std::string& iName )
221 {
222 ABCA_ASSERT( iParent.isValidObject(),
223 "Invalid parent group passed into HDF5Util OpenGroup: "
224 << iName << std::endl );
225
226 HDF5Hierarchy* h5HPtr = iParent.getH5HPtr();
227
228 if ( h5HPtr )
229 {
230 hobj_ref_t childRef = h5HPtr->getChildRef( iParent.getRef(), iName );
231
232 hid_t childId = H5Rdereference( iParent.getObject(),
233 H5R_OBJECT,
234 &childRef );
235
236 return H5Node( childId, childRef, h5HPtr );
237 }
238 else
239 {
240 hid_t childId = H5Gopen2( iParent.getObject(),
241 iName.c_str(),
242 H5P_DEFAULT );
243
244 return H5Node( childId, 0, NULL );
245 }
246 }
247
248 //-*****************************************************************************
CloseObject(H5Node & iNode)249 void CloseObject( H5Node& iNode )
250 {
251 if ( iNode.isValidObject() )
252 {
253 H5Oclose( iNode.getObject() );
254 iNode.setObject( -1 );
255 }
256 }
257
258 //-*****************************************************************************
AttrExists(H5Node & iParent,const std::string & iName)259 bool AttrExists( H5Node& iParent, const std::string& iName )
260 {
261 ABCA_ASSERT( iParent.isValidObject(),
262 "Invalid parent object in ReadMetaData" );
263
264 HDF5Hierarchy* h5HPtr = iParent.getH5HPtr();
265
266 if ( h5HPtr )
267 {
268 return h5HPtr->attrExists( iParent.getRef(), iName );
269 }
270 else
271 {
272 return H5Aexists( iParent.getObject(), iName.c_str() ) > 0;
273 }
274 }
275
276 } // End namespace ALEMBIC_VERSION_NS
277 } // End namespace AbcCoreHDF5
278 } // End namespace Alembic
279
280