Coverage Report

Created: 2026-07-05 06:05

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/alembic/lib/Alembic/AbcCoreFactory/IFactory.cpp
Line
Count
Source
1
//-*****************************************************************************
2
//
3
// Copyright (c) 2013-2015,
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 <fstream>
38
#include <Alembic/AbcCoreOgawa/All.h>
39
#include <Alembic/AbcCoreLayer/Read.h>
40
#include <Alembic/AbcCoreFactory/IFactory.h>
41
42
#ifdef ALEMBIC_WITH_HDF5
43
#include <Alembic/AbcCoreHDF5/All.h>
44
#endif
45
46
namespace Alembic {
47
namespace AbcCoreFactory {
48
namespace ALEMBIC_VERSION_NS {
49
50
IFactory::IFactory()
51
188
{
52
188
    m_cacheHierarchy = true;
53
188
    m_numStreams = 1;
54
188
    m_readStrategy = kMemoryMappedFiles;
55
188
    m_policy = Alembic::Abc::ErrorHandler::kThrowPolicy;
56
188
}
57
58
IFactory::~IFactory()
59
188
{
60
188
}
61
62
Alembic::Abc::IArchive IFactory::getArchive( const std::string & iFileName,
63
                                             CoreType & oType )
64
188
{
65
66
    // try Ogawa first, use kQuietNoop at first in case we fail
67
188
    Alembic::AbcCoreOgawa::ReadArchive ogawa(
68
188
        m_numStreams,
69
188
        m_readStrategy == kMemoryMappedFiles);
70
188
    Alembic::Abc::IArchive archive( ogawa, iFileName,
71
188
        Alembic::Abc::ErrorHandler::kQuietNoopPolicy, m_cachePtr );
72
73
188
    if ( archive.valid() )
74
44
    {
75
44
        oType = kOgawa;
76
44
        archive.getErrorHandler().setPolicy( m_policy );
77
44
        return archive;
78
44
    }
79
80
#ifdef ALEMBIC_WITH_HDF5
81
    Alembic::AbcCoreHDF5::ReadArchive hdf( m_cacheHierarchy );
82
    archive = Alembic::Abc::IArchive( hdf, iFileName,
83
        Alembic::Abc::ErrorHandler::kQuietNoopPolicy, m_cachePtr );
84
    if ( archive.valid() )
85
    {
86
        oType = kHDF5;
87
        archive.getErrorHandler().setPolicy( m_policy );
88
        return archive;
89
    }
90
#else
91
    // check the first 8 bytes to see if this is an HDF5 file according to
92
    // www.hdfgroup.org/HDF5/doc/H5.format.html#Superblock
93
144
    std::ifstream filestream;
94
144
    filestream.open(iFileName.c_str(), std::ios::binary);
95
96
144
    if (filestream.is_open())
97
144
    {
98
144
        char bf[8] = {0, 0, 0, 0, 0, 0, 0, 0};
99
144
        filestream.read(bf, 8);
100
144
        filestream.close();
101
102
144
        if (bf[0] == '\211' && bf[1] == 'H' && bf[2] == 'D' && bf[3] == 'F' &&
103
0
            bf[4] == '\r' && bf[5] == '\n' && bf[6] == '\032' && bf[7] == '\n')
104
0
        {
105
0
            oType = kHDF5;
106
0
            return Alembic::Abc::IArchive();
107
0
        }
108
144
    }
109
144
#endif
110
111
144
    oType = kUnknown;
112
144
    return Alembic::Abc::IArchive();
113
144
}
114
115
Alembic::Abc::IArchive IFactory::getArchive( const std::string & iFileName )
116
188
{
117
188
    CoreType coreType;
118
188
    return getArchive( iFileName, coreType );
119
188
}
120
121
Alembic::Abc::IArchive IFactory::getArchive(
122
    const std::vector< std::string > & iFileNames)
123
0
{
124
0
    CoreType coreType;
125
0
    return getArchive(iFileNames, coreType);
126
0
}
127
128
Alembic::Abc::IArchive IFactory::getArchive(
129
    const std::vector< std::string > & iFileNames, CoreType & oType )
130
0
{
131
0
    Alembic::AbcCoreLayer::ReadArchive layer;
132
133
0
    Alembic::AbcCoreLayer::ArchiveReaderPtrs archives;
134
135
    // first read our archives, skipping over bad ones
136
0
    CoreType coreType;
137
0
    std::vector< std::string >::const_iterator it = iFileNames.begin();
138
0
    for ( ; it != iFileNames.end(); ++it )
139
0
    {
140
0
        Alembic::Abc::IArchive archive = getArchive( *it, coreType );
141
0
        if ( archive.getPtr() )
142
0
        {
143
0
            archives.push_back( archive.getPtr() );
144
0
        }
145
0
    }
146
147
    // if we have just one, no reason to layer
148
0
    if ( archives.size() == 1 )
149
0
    {
150
0
        oType = coreType;
151
0
        return Alembic::Abc::IArchive( archives[0], m_policy );
152
0
    }
153
0
    else if ( ! archives.empty() )
154
0
    {
155
0
        Alembic::AbcCoreAbstract::ArchiveReaderPtr arPtr = layer( archives );
156
0
        oType = kLayer;
157
0
        return Alembic::Abc::IArchive( arPtr, m_policy );
158
0
    }
159
160
    // no valid archives pushed, so invalid
161
0
    oType = kUnknown;
162
0
    return Alembic::Abc::IArchive();
163
0
}
164
165
Alembic::Abc::IArchive IFactory::getArchive(
166
    const std::vector< std::istream * > & iStreams, CoreType & oType)
167
0
{
168
    // Ogawa is the only one which can do this
169
0
    Alembic::AbcCoreOgawa::ReadArchive ogawa( iStreams );
170
0
    Alembic::Abc::IArchive archive( ogawa, "", m_policy, m_cachePtr );
171
0
    if ( archive.valid() )
172
0
    {
173
0
        oType = kOgawa;
174
0
        return archive;
175
0
    }
176
177
0
    oType = kUnknown;
178
0
    return Alembic::Abc::IArchive();
179
0
}
180
181
} // End namespace ALEMBIC_VERSION_NS
182
} // End namespace AbcCoreFactory
183
} // End namespace Alembic