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