|
Packit |
c2c737 |
///////////////////////////////////////////////////////////////////////////
|
|
Packit |
c2c737 |
//
|
|
Packit |
c2c737 |
// Copyright (c) 2004, Industrial Light & Magic, a division of Lucas
|
|
Packit |
c2c737 |
// Digital Ltd. LLC
|
|
Packit |
c2c737 |
//
|
|
Packit |
c2c737 |
// All rights reserved.
|
|
Packit |
c2c737 |
//
|
|
Packit |
c2c737 |
// Redistribution and use in source and binary forms, with or without
|
|
Packit |
c2c737 |
// modification, are permitted provided that the following conditions are
|
|
Packit |
c2c737 |
// met:
|
|
Packit |
c2c737 |
// * Redistributions of source code must retain the above copyright
|
|
Packit |
c2c737 |
// notice, this list of conditions and the following disclaimer.
|
|
Packit |
c2c737 |
// * Redistributions in binary form must reproduce the above
|
|
Packit |
c2c737 |
// copyright notice, this list of conditions and the following disclaimer
|
|
Packit |
c2c737 |
// in the documentation and/or other materials provided with the
|
|
Packit |
c2c737 |
// distribution.
|
|
Packit |
c2c737 |
// * Neither the name of Industrial Light & Magic nor the names of
|
|
Packit |
c2c737 |
// its contributors may be used to endorse or promote products derived
|
|
Packit |
c2c737 |
// from this software without specific prior written permission.
|
|
Packit |
c2c737 |
//
|
|
Packit |
c2c737 |
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
Packit |
c2c737 |
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
Packit |
c2c737 |
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
Packit |
c2c737 |
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
Packit |
c2c737 |
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
Packit |
c2c737 |
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
Packit |
c2c737 |
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
Packit |
c2c737 |
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
Packit |
c2c737 |
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
Packit |
c2c737 |
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
Packit |
c2c737 |
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
Packit |
c2c737 |
//
|
|
Packit |
c2c737 |
///////////////////////////////////////////////////////////////////////////
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
//-----------------------------------------------------------------------------
|
|
Packit |
c2c737 |
//
|
|
Packit |
c2c737 |
// class Header
|
|
Packit |
c2c737 |
//
|
|
Packit |
c2c737 |
//-----------------------------------------------------------------------------
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
#include <ImfHeader.h>
|
|
Packit |
c2c737 |
#include <ImfStdIO.h>
|
|
Packit |
c2c737 |
#include <ImfVersion.h>
|
|
Packit |
c2c737 |
#include <ImfCompressor.h>
|
|
Packit |
c2c737 |
#include <ImfMisc.h>
|
|
Packit |
c2c737 |
#include <ImfBoxAttribute.h>
|
|
Packit |
c2c737 |
#include <ImfChannelListAttribute.h>
|
|
Packit |
c2c737 |
#include <ImfChromaticitiesAttribute.h>
|
|
Packit |
c2c737 |
#include <ImfCompressionAttribute.h>
|
|
Packit |
c2c737 |
#include <ImfDeepImageStateAttribute.h>
|
|
Packit |
c2c737 |
#include <ImfDoubleAttribute.h>
|
|
Packit |
c2c737 |
#include <ImfDwaCompressor.h>
|
|
Packit |
c2c737 |
#include <ImfEnvmapAttribute.h>
|
|
Packit |
c2c737 |
#include <ImfFloatAttribute.h>
|
|
Packit |
c2c737 |
#include <ImfFloatVectorAttribute.h>
|
|
Packit |
c2c737 |
#include <ImfIntAttribute.h>
|
|
Packit |
c2c737 |
#include <ImfKeyCodeAttribute.h>
|
|
Packit |
c2c737 |
#include <ImfLineOrderAttribute.h>
|
|
Packit |
c2c737 |
#include <ImfMatrixAttribute.h>
|
|
Packit |
c2c737 |
#include <ImfOpaqueAttribute.h>
|
|
Packit |
c2c737 |
#include <ImfPreviewImageAttribute.h>
|
|
Packit |
c2c737 |
#include <ImfRationalAttribute.h>
|
|
Packit |
c2c737 |
#include <ImfStringAttribute.h>
|
|
Packit |
c2c737 |
#include <ImfStringVectorAttribute.h>
|
|
Packit |
c2c737 |
#include <ImfTileDescriptionAttribute.h>
|
|
Packit |
c2c737 |
#include <ImfTimeCodeAttribute.h>
|
|
Packit |
c2c737 |
#include <ImfVecAttribute.h>
|
|
Packit |
c2c737 |
#include <ImfPartType.h>
|
|
Packit |
c2c737 |
#include "IlmThreadMutex.h"
|
|
Packit |
c2c737 |
#include "Iex.h"
|
|
Packit |
c2c737 |
#include <sstream>
|
|
Packit |
c2c737 |
#include <stdlib.h>
|
|
Packit |
c2c737 |
#include <time.h>
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
#include "ImfNamespace.h"
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
using namespace std;
|
|
Packit |
c2c737 |
using IMATH_NAMESPACE::Box2i;
|
|
Packit |
c2c737 |
using IMATH_NAMESPACE::V2i;
|
|
Packit |
c2c737 |
using IMATH_NAMESPACE::V2f;
|
|
Packit |
c2c737 |
using ILMTHREAD_NAMESPACE::Mutex;
|
|
Packit |
c2c737 |
using ILMTHREAD_NAMESPACE::Lock;
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
namespace {
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
int maxImageWidth = 0;
|
|
Packit |
c2c737 |
int maxImageHeight = 0;
|
|
Packit |
c2c737 |
int maxTileWidth = 0;
|
|
Packit |
c2c737 |
int maxTileHeight = 0;
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
void
|
|
Packit |
c2c737 |
initialize (Header &header,
|
|
Packit |
c2c737 |
const Box2i &displayWindow,
|
|
Packit |
c2c737 |
const Box2i &dataWindow,
|
|
Packit |
c2c737 |
float pixelAspectRatio,
|
|
Packit |
c2c737 |
const V2f &screenWindowCenter,
|
|
Packit |
c2c737 |
float screenWindowWidth,
|
|
Packit |
c2c737 |
LineOrder lineOrder,
|
|
Packit |
c2c737 |
Compression compression)
|
|
Packit |
c2c737 |
{
|
|
Packit |
c2c737 |
header.insert ("displayWindow", Box2iAttribute (displayWindow));
|
|
Packit |
c2c737 |
header.insert ("dataWindow", Box2iAttribute (dataWindow));
|
|
Packit |
c2c737 |
header.insert ("pixelAspectRatio", FloatAttribute (pixelAspectRatio));
|
|
Packit |
c2c737 |
header.insert ("screenWindowCenter", V2fAttribute (screenWindowCenter));
|
|
Packit |
c2c737 |
header.insert ("screenWindowWidth", FloatAttribute (screenWindowWidth));
|
|
Packit |
c2c737 |
header.insert ("lineOrder", LineOrderAttribute (lineOrder));
|
|
Packit |
c2c737 |
header.insert ("compression", CompressionAttribute (compression));
|
|
Packit |
c2c737 |
header.insert ("channels", ChannelListAttribute ());
|
|
Packit |
c2c737 |
}
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
template <size_t N>
|
|
Packit |
c2c737 |
void checkIsNullTerminated (const char (&str)[N], const char *what)
|
|
Packit |
c2c737 |
{
|
|
Packit |
c2c737 |
for (size_t i = 0; i < N; ++i) {
|
|
Packit |
c2c737 |
if (str[i] == '\0')
|
|
Packit |
c2c737 |
return;
|
|
Packit |
c2c737 |
}
|
|
Packit |
c2c737 |
std::stringstream s;
|
|
Packit |
c2c737 |
s << "Invalid " << what << ": it is more than " << (N - 1)
|
|
Packit |
c2c737 |
<< " characters long.";
|
|
Packit |
c2c737 |
throw IEX_NAMESPACE::InputExc(s);
|
|
Packit |
c2c737 |
}
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
} // namespace
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
Header::Header (int width,
|
|
Packit |
c2c737 |
int height,
|
|
Packit |
c2c737 |
float pixelAspectRatio,
|
|
Packit |
c2c737 |
const V2f &screenWindowCenter,
|
|
Packit |
c2c737 |
float screenWindowWidth,
|
|
Packit |
c2c737 |
LineOrder lineOrder,
|
|
Packit |
c2c737 |
Compression compression)
|
|
Packit |
c2c737 |
:
|
|
Packit |
c2c737 |
_map()
|
|
Packit |
c2c737 |
{
|
|
Packit |
c2c737 |
staticInitialize();
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
Box2i displayWindow (V2i (0, 0), V2i (width - 1, height - 1));
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
initialize (*this,
|
|
Packit |
c2c737 |
displayWindow,
|
|
Packit |
c2c737 |
displayWindow,
|
|
Packit |
c2c737 |
pixelAspectRatio,
|
|
Packit |
c2c737 |
screenWindowCenter,
|
|
Packit |
c2c737 |
screenWindowWidth,
|
|
Packit |
c2c737 |
lineOrder,
|
|
Packit |
c2c737 |
compression);
|
|
Packit |
c2c737 |
}
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
Header::Header (int width,
|
|
Packit |
c2c737 |
int height,
|
|
Packit |
c2c737 |
const Box2i &dataWindow,
|
|
Packit |
c2c737 |
float pixelAspectRatio,
|
|
Packit |
c2c737 |
const V2f &screenWindowCenter,
|
|
Packit |
c2c737 |
float screenWindowWidth,
|
|
Packit |
c2c737 |
LineOrder lineOrder,
|
|
Packit |
c2c737 |
Compression compression)
|
|
Packit |
c2c737 |
:
|
|
Packit |
c2c737 |
_map()
|
|
Packit |
c2c737 |
{
|
|
Packit |
c2c737 |
staticInitialize();
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
Box2i displayWindow (V2i (0, 0), V2i (width - 1, height - 1));
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
initialize (*this,
|
|
Packit |
c2c737 |
displayWindow,
|
|
Packit |
c2c737 |
dataWindow,
|
|
Packit |
c2c737 |
pixelAspectRatio,
|
|
Packit |
c2c737 |
screenWindowCenter,
|
|
Packit |
c2c737 |
screenWindowWidth,
|
|
Packit |
c2c737 |
lineOrder,
|
|
Packit |
c2c737 |
compression);
|
|
Packit |
c2c737 |
}
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
Header::Header (const Box2i &displayWindow,
|
|
Packit |
c2c737 |
const Box2i &dataWindow,
|
|
Packit |
c2c737 |
float pixelAspectRatio,
|
|
Packit |
c2c737 |
const V2f &screenWindowCenter,
|
|
Packit |
c2c737 |
float screenWindowWidth,
|
|
Packit |
c2c737 |
LineOrder lineOrder,
|
|
Packit |
c2c737 |
Compression compression)
|
|
Packit |
c2c737 |
:
|
|
Packit |
c2c737 |
_map()
|
|
Packit |
c2c737 |
{
|
|
Packit |
c2c737 |
staticInitialize();
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
initialize (*this,
|
|
Packit |
c2c737 |
displayWindow,
|
|
Packit |
c2c737 |
dataWindow,
|
|
Packit |
c2c737 |
pixelAspectRatio,
|
|
Packit |
c2c737 |
screenWindowCenter,
|
|
Packit |
c2c737 |
screenWindowWidth,
|
|
Packit |
c2c737 |
lineOrder,
|
|
Packit |
c2c737 |
compression);
|
|
Packit |
c2c737 |
}
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
Header::Header (const Header &other): _map()
|
|
Packit |
c2c737 |
{
|
|
Packit |
c2c737 |
for (AttributeMap::const_iterator i = other._map.begin();
|
|
Packit |
c2c737 |
i != other._map.end();
|
|
Packit |
c2c737 |
++i)
|
|
Packit |
c2c737 |
{
|
|
Packit |
c2c737 |
insert (*i->first, *i->second);
|
|
Packit |
c2c737 |
}
|
|
Packit |
c2c737 |
}
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
Header::~Header ()
|
|
Packit |
c2c737 |
{
|
|
Packit |
c2c737 |
for (AttributeMap::iterator i = _map.begin();
|
|
Packit |
c2c737 |
i != _map.end();
|
|
Packit |
c2c737 |
++i)
|
|
Packit |
c2c737 |
{
|
|
Packit |
c2c737 |
delete i->second;
|
|
Packit |
c2c737 |
}
|
|
Packit |
c2c737 |
}
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
Header &
|
|
Packit |
c2c737 |
Header::operator = (const Header &other)
|
|
Packit |
c2c737 |
{
|
|
Packit |
c2c737 |
if (this != &other)
|
|
Packit |
c2c737 |
{
|
|
Packit |
c2c737 |
for (AttributeMap::iterator i = _map.begin();
|
|
Packit |
c2c737 |
i != _map.end();
|
|
Packit |
c2c737 |
++i)
|
|
Packit |
c2c737 |
{
|
|
Packit |
c2c737 |
delete i->second;
|
|
Packit |
c2c737 |
}
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
_map.erase (_map.begin(), _map.end());
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
for (AttributeMap::const_iterator i = other._map.begin();
|
|
Packit |
c2c737 |
i != other._map.end();
|
|
Packit |
c2c737 |
++i)
|
|
Packit |
c2c737 |
{
|
|
Packit |
c2c737 |
insert (*i->first, *i->second);
|
|
Packit |
c2c737 |
}
|
|
Packit |
c2c737 |
}
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
return *this;
|
|
Packit |
c2c737 |
}
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
void
|
|
Packit |
c2c737 |
Header::erase (const char name[])
|
|
Packit |
c2c737 |
{
|
|
Packit |
c2c737 |
if (name[0] == 0)
|
|
Packit |
c2c737 |
THROW (IEX_NAMESPACE::ArgExc, "Image attribute name cannot be an empty string.");
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
AttributeMap::iterator i = _map.find (name);
|
|
Packit |
c2c737 |
if (i != _map.end())
|
|
Packit |
c2c737 |
_map.erase (i);
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
}
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
void
|
|
Packit |
c2c737 |
Header::erase (const string &name)
|
|
Packit |
c2c737 |
{
|
|
Packit |
c2c737 |
erase (name.c_str());
|
|
Packit |
c2c737 |
}
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
void
|
|
Packit |
c2c737 |
Header::insert (const char name[], const Attribute &attribute)
|
|
Packit |
c2c737 |
{
|
|
Packit |
c2c737 |
if (name[0] == 0)
|
|
Packit |
c2c737 |
THROW (IEX_NAMESPACE::ArgExc, "Image attribute name cannot be an empty string.");
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
AttributeMap::iterator i = _map.find (name);
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
if (i == _map.end())
|
|
Packit |
c2c737 |
{
|
|
Packit |
c2c737 |
Attribute *tmp = attribute.copy();
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
try
|
|
Packit |
c2c737 |
{
|
|
Packit |
c2c737 |
_map[name] = tmp;
|
|
Packit |
c2c737 |
}
|
|
Packit |
c2c737 |
catch (...)
|
|
Packit |
c2c737 |
{
|
|
Packit |
c2c737 |
delete tmp;
|
|
Packit |
c2c737 |
throw;
|
|
Packit |
c2c737 |
}
|
|
Packit |
c2c737 |
}
|
|
Packit |
c2c737 |
else
|
|
Packit |
c2c737 |
{
|
|
Packit |
c2c737 |
if (strcmp (i->second->typeName(), attribute.typeName()))
|
|
Packit |
c2c737 |
THROW (IEX_NAMESPACE::TypeExc, "Cannot assign a value of "
|
|
Packit |
c2c737 |
"type \"" << attribute.typeName() << "\" "
|
|
Packit |
c2c737 |
"to image attribute \"" << name << "\" of "
|
|
Packit |
c2c737 |
"type \"" << i->second->typeName() << "\".");
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
Attribute *tmp = attribute.copy();
|
|
Packit |
c2c737 |
delete i->second;
|
|
Packit |
c2c737 |
i->second = tmp;
|
|
Packit |
c2c737 |
}
|
|
Packit |
c2c737 |
}
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
void
|
|
Packit |
c2c737 |
Header::insert (const string &name, const Attribute &attribute)
|
|
Packit |
c2c737 |
{
|
|
Packit |
c2c737 |
insert (name.c_str(), attribute);
|
|
Packit |
c2c737 |
}
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
Attribute &
|
|
Packit |
c2c737 |
Header::operator [] (const char name[])
|
|
Packit |
c2c737 |
{
|
|
Packit |
c2c737 |
AttributeMap::iterator i = _map.find (name);
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
if (i == _map.end())
|
|
Packit |
c2c737 |
THROW (IEX_NAMESPACE::ArgExc, "Cannot find image attribute \"" << name << "\".");
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
return *i->second;
|
|
Packit |
c2c737 |
}
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
const Attribute &
|
|
Packit |
c2c737 |
Header::operator [] (const char name[]) const
|
|
Packit |
c2c737 |
{
|
|
Packit |
c2c737 |
AttributeMap::const_iterator i = _map.find (name);
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
if (i == _map.end())
|
|
Packit |
c2c737 |
THROW (IEX_NAMESPACE::ArgExc, "Cannot find image attribute \"" << name << "\".");
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
return *i->second;
|
|
Packit |
c2c737 |
}
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
Attribute &
|
|
Packit |
c2c737 |
Header::operator [] (const string &name)
|
|
Packit |
c2c737 |
{
|
|
Packit |
c2c737 |
return this->operator[] (name.c_str());
|
|
Packit |
c2c737 |
}
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
const Attribute &
|
|
Packit |
c2c737 |
Header::operator [] (const string &name) const
|
|
Packit |
c2c737 |
{
|
|
Packit |
c2c737 |
return this->operator[] (name.c_str());
|
|
Packit |
c2c737 |
}
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
Header::Iterator
|
|
Packit |
c2c737 |
Header::begin ()
|
|
Packit |
c2c737 |
{
|
|
Packit |
c2c737 |
return _map.begin();
|
|
Packit |
c2c737 |
}
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
Header::ConstIterator
|
|
Packit |
c2c737 |
Header::begin () const
|
|
Packit |
c2c737 |
{
|
|
Packit |
c2c737 |
return _map.begin();
|
|
Packit |
c2c737 |
}
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
Header::Iterator
|
|
Packit |
c2c737 |
Header::end ()
|
|
Packit |
c2c737 |
{
|
|
Packit |
c2c737 |
return _map.end();
|
|
Packit |
c2c737 |
}
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
Header::ConstIterator
|
|
Packit |
c2c737 |
Header::end () const
|
|
Packit |
c2c737 |
{
|
|
Packit |
c2c737 |
return _map.end();
|
|
Packit |
c2c737 |
}
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
Header::Iterator
|
|
Packit |
c2c737 |
Header::find (const char name[])
|
|
Packit |
c2c737 |
{
|
|
Packit |
c2c737 |
return _map.find (name);
|
|
Packit |
c2c737 |
}
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
Header::ConstIterator
|
|
Packit |
c2c737 |
Header::find (const char name[]) const
|
|
Packit |
c2c737 |
{
|
|
Packit |
c2c737 |
return _map.find (name);
|
|
Packit |
c2c737 |
}
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
Header::Iterator
|
|
Packit |
c2c737 |
Header::find (const string &name)
|
|
Packit |
c2c737 |
{
|
|
Packit |
c2c737 |
return find (name.c_str());
|
|
Packit |
c2c737 |
}
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
Header::ConstIterator
|
|
Packit |
c2c737 |
Header::find (const string &name) const
|
|
Packit |
c2c737 |
{
|
|
Packit |
c2c737 |
return find (name.c_str());
|
|
Packit |
c2c737 |
}
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
IMATH_NAMESPACE::Box2i &
|
|
Packit |
c2c737 |
Header::displayWindow ()
|
|
Packit |
c2c737 |
{
|
|
Packit |
c2c737 |
return static_cast <Box2iAttribute &>
|
|
Packit |
c2c737 |
((*this)["displayWindow"]).value();
|
|
Packit |
c2c737 |
}
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
const IMATH_NAMESPACE::Box2i &
|
|
Packit |
c2c737 |
Header::displayWindow () const
|
|
Packit |
c2c737 |
{
|
|
Packit |
c2c737 |
return static_cast <const Box2iAttribute &>
|
|
Packit |
c2c737 |
((*this)["displayWindow"]).value();
|
|
Packit |
c2c737 |
}
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
IMATH_NAMESPACE::Box2i &
|
|
Packit |
c2c737 |
Header::dataWindow ()
|
|
Packit |
c2c737 |
{
|
|
Packit |
c2c737 |
return static_cast <Box2iAttribute &>
|
|
Packit |
c2c737 |
((*this)["dataWindow"]).value();
|
|
Packit |
c2c737 |
}
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
const IMATH_NAMESPACE::Box2i &
|
|
Packit |
c2c737 |
Header::dataWindow () const
|
|
Packit |
c2c737 |
{
|
|
Packit |
c2c737 |
return static_cast <const Box2iAttribute &>
|
|
Packit |
c2c737 |
((*this)["dataWindow"]).value();
|
|
Packit |
c2c737 |
}
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
float &
|
|
Packit |
c2c737 |
Header::pixelAspectRatio ()
|
|
Packit |
c2c737 |
{
|
|
Packit |
c2c737 |
return static_cast <FloatAttribute &>
|
|
Packit |
c2c737 |
((*this)["pixelAspectRatio"]).value();
|
|
Packit |
c2c737 |
}
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
const float &
|
|
Packit |
c2c737 |
Header::pixelAspectRatio () const
|
|
Packit |
c2c737 |
{
|
|
Packit |
c2c737 |
return static_cast <const FloatAttribute &>
|
|
Packit |
c2c737 |
((*this)["pixelAspectRatio"]).value();
|
|
Packit |
c2c737 |
}
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
IMATH_NAMESPACE::V2f &
|
|
Packit |
c2c737 |
Header::screenWindowCenter ()
|
|
Packit |
c2c737 |
{
|
|
Packit |
c2c737 |
return static_cast <V2fAttribute &>
|
|
Packit |
c2c737 |
((*this)["screenWindowCenter"]).value();
|
|
Packit |
c2c737 |
}
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
const IMATH_NAMESPACE::V2f &
|
|
Packit |
c2c737 |
Header::screenWindowCenter () const
|
|
Packit |
c2c737 |
{
|
|
Packit |
c2c737 |
return static_cast <const V2fAttribute &>
|
|
Packit |
c2c737 |
((*this)["screenWindowCenter"]).value();
|
|
Packit |
c2c737 |
}
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
float &
|
|
Packit |
c2c737 |
Header::screenWindowWidth ()
|
|
Packit |
c2c737 |
{
|
|
Packit |
c2c737 |
return static_cast <FloatAttribute &>
|
|
Packit |
c2c737 |
((*this)["screenWindowWidth"]).value();
|
|
Packit |
c2c737 |
}
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
const float &
|
|
Packit |
c2c737 |
Header::screenWindowWidth () const
|
|
Packit |
c2c737 |
{
|
|
Packit |
c2c737 |
return static_cast <const FloatAttribute &>
|
|
Packit |
c2c737 |
((*this)["screenWindowWidth"]).value();
|
|
Packit |
c2c737 |
}
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
ChannelList &
|
|
Packit |
c2c737 |
Header::channels ()
|
|
Packit |
c2c737 |
{
|
|
Packit |
c2c737 |
return static_cast <ChannelListAttribute &>
|
|
Packit |
c2c737 |
((*this)["channels"]).value();
|
|
Packit |
c2c737 |
}
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
const ChannelList &
|
|
Packit |
c2c737 |
Header::channels () const
|
|
Packit |
c2c737 |
{
|
|
Packit |
c2c737 |
return static_cast <const ChannelListAttribute &>
|
|
Packit |
c2c737 |
((*this)["channels"]).value();
|
|
Packit |
c2c737 |
}
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
LineOrder &
|
|
Packit |
c2c737 |
Header::lineOrder ()
|
|
Packit |
c2c737 |
{
|
|
Packit |
c2c737 |
return static_cast <LineOrderAttribute &>
|
|
Packit |
c2c737 |
((*this)["lineOrder"]).value();
|
|
Packit |
c2c737 |
}
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
const LineOrder &
|
|
Packit |
c2c737 |
Header::lineOrder () const
|
|
Packit |
c2c737 |
{
|
|
Packit |
c2c737 |
return static_cast <const LineOrderAttribute &>
|
|
Packit |
c2c737 |
((*this)["lineOrder"]).value();
|
|
Packit |
c2c737 |
}
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
Compression &
|
|
Packit |
c2c737 |
Header::compression ()
|
|
Packit |
c2c737 |
{
|
|
Packit |
c2c737 |
return static_cast <CompressionAttribute &>
|
|
Packit |
c2c737 |
((*this)["compression"]).value();
|
|
Packit |
c2c737 |
}
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
const Compression &
|
|
Packit |
c2c737 |
Header::compression () const
|
|
Packit |
c2c737 |
{
|
|
Packit |
c2c737 |
return static_cast <const CompressionAttribute &>
|
|
Packit |
c2c737 |
((*this)["compression"]).value();
|
|
Packit |
c2c737 |
}
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
void
|
|
Packit |
c2c737 |
Header::setName(const string& name)
|
|
Packit |
c2c737 |
{
|
|
Packit |
c2c737 |
insert ("name", StringAttribute (name));
|
|
Packit |
c2c737 |
}
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
bool
|
|
Packit |
c2c737 |
Header::hasName() const
|
|
Packit |
c2c737 |
{
|
|
Packit |
c2c737 |
return findTypedAttribute <StringAttribute> ("name") != 0;
|
|
Packit |
c2c737 |
}
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
string &
|
|
Packit |
c2c737 |
Header::name()
|
|
Packit |
c2c737 |
{
|
|
Packit |
c2c737 |
return typedAttribute <StringAttribute> ("name").value();
|
|
Packit |
c2c737 |
}
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
const string &
|
|
Packit |
c2c737 |
Header::name() const
|
|
Packit |
c2c737 |
{
|
|
Packit |
c2c737 |
return typedAttribute <StringAttribute> ("name").value();
|
|
Packit |
c2c737 |
}
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
void
|
|
Packit |
c2c737 |
Header::setType(const string& type)
|
|
Packit |
c2c737 |
{
|
|
Packit |
c2c737 |
if (isSupportedType(type) == false)
|
|
Packit |
c2c737 |
{
|
|
Packit |
c2c737 |
throw IEX_NAMESPACE::ArgExc (type + "is not a supported image type." +
|
|
Packit |
c2c737 |
"The following are supported: " +
|
|
Packit |
c2c737 |
SCANLINEIMAGE + ", " +
|
|
Packit |
c2c737 |
TILEDIMAGE + ", " +
|
|
Packit |
c2c737 |
DEEPSCANLINE + " or " +
|
|
Packit |
c2c737 |
DEEPTILE + ".");
|
|
Packit |
c2c737 |
}
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
insert ("type", StringAttribute (type));
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
// (TODO) Should we do it here?
|
|
Packit |
c2c737 |
if (isDeepData(type) && hasVersion() == false)
|
|
Packit |
c2c737 |
{
|
|
Packit |
c2c737 |
setVersion(1);
|
|
Packit |
c2c737 |
}
|
|
Packit |
c2c737 |
}
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
bool
|
|
Packit |
c2c737 |
Header::hasType() const
|
|
Packit |
c2c737 |
{
|
|
Packit |
c2c737 |
return findTypedAttribute <StringAttribute> ("type") != 0;
|
|
Packit |
c2c737 |
}
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
string &
|
|
Packit |
c2c737 |
Header::type()
|
|
Packit |
c2c737 |
{
|
|
Packit |
c2c737 |
return typedAttribute <StringAttribute> ("type").value();
|
|
Packit |
c2c737 |
}
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
const string &
|
|
Packit |
c2c737 |
Header::type() const
|
|
Packit |
c2c737 |
{
|
|
Packit |
c2c737 |
return typedAttribute <StringAttribute> ("type").value();
|
|
Packit |
c2c737 |
}
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
void
|
|
Packit |
c2c737 |
Header::setView(const string& view)
|
|
Packit |
c2c737 |
{
|
|
Packit |
c2c737 |
insert ("view", StringAttribute (view));
|
|
Packit |
c2c737 |
}
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
bool
|
|
Packit |
c2c737 |
Header::hasView() const
|
|
Packit |
c2c737 |
{
|
|
Packit |
c2c737 |
return findTypedAttribute <StringAttribute> ("view") != 0;
|
|
Packit |
c2c737 |
}
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
string &
|
|
Packit |
c2c737 |
Header::view()
|
|
Packit |
c2c737 |
{
|
|
Packit |
c2c737 |
return typedAttribute <StringAttribute> ("view").value();
|
|
Packit |
c2c737 |
}
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
const string &
|
|
Packit |
c2c737 |
Header::view() const
|
|
Packit |
c2c737 |
{
|
|
Packit |
c2c737 |
return typedAttribute <StringAttribute> ("view").value();
|
|
Packit |
c2c737 |
}
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
void
|
|
Packit |
c2c737 |
Header::setVersion(const int version)
|
|
Packit |
c2c737 |
{
|
|
Packit |
c2c737 |
if (version != 1)
|
|
Packit |
c2c737 |
{
|
|
Packit |
c2c737 |
throw IEX_NAMESPACE::ArgExc ("We can only process version 1");
|
|
Packit |
c2c737 |
}
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
insert ("version", IntAttribute (version));
|
|
Packit |
c2c737 |
}
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
bool
|
|
Packit |
c2c737 |
Header::hasVersion() const
|
|
Packit |
c2c737 |
{
|
|
Packit |
c2c737 |
return findTypedAttribute <IntAttribute> ("version") != 0;
|
|
Packit |
c2c737 |
}
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
int &
|
|
Packit |
c2c737 |
Header::version()
|
|
Packit |
c2c737 |
{
|
|
Packit |
c2c737 |
return typedAttribute <IntAttribute> ("version").value();
|
|
Packit |
c2c737 |
}
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
const int &
|
|
Packit |
c2c737 |
Header::version() const
|
|
Packit |
c2c737 |
{
|
|
Packit |
c2c737 |
return typedAttribute <IntAttribute> ("version").value();
|
|
Packit |
c2c737 |
}
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
void
|
|
Packit |
c2c737 |
Header::setChunkCount(int chunks)
|
|
Packit |
c2c737 |
{
|
|
Packit |
c2c737 |
insert("chunkCount",IntAttribute(chunks));
|
|
Packit |
c2c737 |
}
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
bool
|
|
Packit |
c2c737 |
Header::hasChunkCount() const
|
|
Packit |
c2c737 |
{
|
|
Packit |
c2c737 |
return findTypedAttribute<IntAttribute>("chunkCount") != 0;
|
|
Packit |
c2c737 |
}
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
int&
|
|
Packit |
c2c737 |
Header::chunkCount()
|
|
Packit |
c2c737 |
{
|
|
Packit |
c2c737 |
return typedAttribute <IntAttribute> ("chunkCount").value();
|
|
Packit |
c2c737 |
}
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
const int&
|
|
Packit |
c2c737 |
Header::chunkCount() const
|
|
Packit |
c2c737 |
{
|
|
Packit |
c2c737 |
return typedAttribute <IntAttribute> ("chunkCount").value();
|
|
Packit |
c2c737 |
}
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
void
|
|
Packit |
c2c737 |
Header::setTileDescription(const TileDescription& td)
|
|
Packit |
c2c737 |
{
|
|
Packit |
c2c737 |
insert ("tiles", TileDescriptionAttribute (td));
|
|
Packit |
c2c737 |
}
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
bool
|
|
Packit |
c2c737 |
Header::hasTileDescription() const
|
|
Packit |
c2c737 |
{
|
|
Packit |
c2c737 |
return findTypedAttribute <TileDescriptionAttribute> ("tiles") != 0;
|
|
Packit |
c2c737 |
}
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
TileDescription &
|
|
Packit |
c2c737 |
Header::tileDescription ()
|
|
Packit |
c2c737 |
{
|
|
Packit |
c2c737 |
return typedAttribute <TileDescriptionAttribute> ("tiles").value();
|
|
Packit |
c2c737 |
}
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
const TileDescription &
|
|
Packit |
c2c737 |
Header::tileDescription () const
|
|
Packit |
c2c737 |
{
|
|
Packit |
c2c737 |
return typedAttribute <TileDescriptionAttribute> ("tiles").value();
|
|
Packit |
c2c737 |
}
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
void
|
|
Packit |
c2c737 |
Header::setPreviewImage (const PreviewImage &pi)
|
|
Packit |
c2c737 |
{
|
|
Packit |
c2c737 |
insert ("preview", PreviewImageAttribute (pi));
|
|
Packit |
c2c737 |
}
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
PreviewImage &
|
|
Packit |
c2c737 |
Header::previewImage ()
|
|
Packit |
c2c737 |
{
|
|
Packit |
c2c737 |
return typedAttribute <PreviewImageAttribute> ("preview").value();
|
|
Packit |
c2c737 |
}
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
const PreviewImage &
|
|
Packit |
c2c737 |
Header::previewImage () const
|
|
Packit |
c2c737 |
{
|
|
Packit |
c2c737 |
return typedAttribute <PreviewImageAttribute> ("preview").value();
|
|
Packit |
c2c737 |
}
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
bool
|
|
Packit |
c2c737 |
Header::hasPreviewImage () const
|
|
Packit |
c2c737 |
{
|
|
Packit |
c2c737 |
return findTypedAttribute <PreviewImageAttribute> ("preview") != 0;
|
|
Packit |
c2c737 |
}
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
void
|
|
Packit |
c2c737 |
Header::sanityCheck (bool isTiled, bool isMultipartFile) const
|
|
Packit |
c2c737 |
{
|
|
Packit |
c2c737 |
//
|
|
Packit |
c2c737 |
// The display window and the data window must each
|
|
Packit |
c2c737 |
// contain at least one pixel. In addition, the
|
|
Packit |
c2c737 |
// coordinates of the window corners must be small
|
|
Packit |
c2c737 |
// enough to keep expressions like max-min+1 or
|
|
Packit |
c2c737 |
// max+min from overflowing.
|
|
Packit |
c2c737 |
//
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
const Box2i &displayWindow = this->displayWindow();
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
if (displayWindow.min.x > displayWindow.max.x ||
|
|
Packit |
c2c737 |
displayWindow.min.y > displayWindow.max.y ||
|
|
Packit |
c2c737 |
displayWindow.min.x <= -(INT_MAX / 2) ||
|
|
Packit |
c2c737 |
displayWindow.min.y <= -(INT_MAX / 2) ||
|
|
Packit |
c2c737 |
displayWindow.max.x >= (INT_MAX / 2) ||
|
|
Packit |
c2c737 |
displayWindow.max.y >= (INT_MAX / 2))
|
|
Packit |
c2c737 |
{
|
|
Packit |
c2c737 |
throw IEX_NAMESPACE::ArgExc ("Invalid display window in image header.");
|
|
Packit |
c2c737 |
}
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
const Box2i &dataWindow = this->dataWindow();
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
if (dataWindow.min.x > dataWindow.max.x ||
|
|
Packit |
c2c737 |
dataWindow.min.y > dataWindow.max.y ||
|
|
Packit |
c2c737 |
dataWindow.min.x <= -(INT_MAX / 2) ||
|
|
Packit |
c2c737 |
dataWindow.min.y <= -(INT_MAX / 2) ||
|
|
Packit |
c2c737 |
dataWindow.max.x >= (INT_MAX / 2) ||
|
|
Packit |
c2c737 |
dataWindow.max.y >= (INT_MAX / 2))
|
|
Packit |
c2c737 |
{
|
|
Packit |
c2c737 |
throw IEX_NAMESPACE::ArgExc ("Invalid data window in image header.");
|
|
Packit |
c2c737 |
}
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
if (maxImageWidth > 0 &&
|
|
Packit |
c2c737 |
maxImageWidth < (dataWindow.max.x - dataWindow.min.x + 1))
|
|
Packit |
c2c737 |
{
|
|
Packit |
c2c737 |
THROW (IEX_NAMESPACE::ArgExc, "The width of the data window exceeds the "
|
|
Packit |
c2c737 |
"maximum width of " << maxImageWidth << "pixels.");
|
|
Packit |
c2c737 |
}
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
if (maxImageHeight > 0 &&
|
|
Packit |
c2c737 |
maxImageHeight < dataWindow.max.y - dataWindow.min.y + 1)
|
|
Packit |
c2c737 |
{
|
|
Packit |
c2c737 |
THROW (IEX_NAMESPACE::ArgExc, "The width of the data window exceeds the "
|
|
Packit |
c2c737 |
"maximum width of " << maxImageHeight << "pixels.");
|
|
Packit |
c2c737 |
}
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
// chunk table must be smaller than the maximum image area
|
|
Packit |
c2c737 |
// (only reachable for unknown types or damaged files: will have thrown earlier
|
|
Packit |
c2c737 |
// for regular image types)
|
|
Packit |
c2c737 |
if( maxImageHeight>0 && maxImageWidth>0 &&
|
|
Packit |
c2c737 |
hasChunkCount() && chunkCount()>Int64(maxImageWidth)*Int64(maxImageHeight))
|
|
Packit |
c2c737 |
{
|
|
Packit |
c2c737 |
THROW (IEX_NAMESPACE::ArgExc, "chunkCount exceeds maximum area of "
|
|
Packit |
c2c737 |
<< Int64(maxImageWidth)*Int64(maxImageHeight) << " pixels." );
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
}
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
//
|
|
Packit |
c2c737 |
// The pixel aspect ratio must be greater than 0.
|
|
Packit |
c2c737 |
// In applications, numbers like the the display or
|
|
Packit |
c2c737 |
// data window dimensions are likely to be multiplied
|
|
Packit |
c2c737 |
// or divided by the pixel aspect ratio; to avoid
|
|
Packit |
c2c737 |
// arithmetic exceptions, we limit the pixel aspect
|
|
Packit |
c2c737 |
// ratio to a range that is smaller than theoretically
|
|
Packit |
c2c737 |
// possible (real aspect ratios are likely to be close
|
|
Packit |
c2c737 |
// to 1.0 anyway).
|
|
Packit |
c2c737 |
//
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
float pixelAspectRatio = this->pixelAspectRatio();
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
const float MIN_PIXEL_ASPECT_RATIO = 1e-6f;
|
|
Packit |
c2c737 |
const float MAX_PIXEL_ASPECT_RATIO = 1e+6f;
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
if (pixelAspectRatio < MIN_PIXEL_ASPECT_RATIO ||
|
|
Packit |
c2c737 |
pixelAspectRatio > MAX_PIXEL_ASPECT_RATIO)
|
|
Packit |
c2c737 |
{
|
|
Packit |
c2c737 |
throw IEX_NAMESPACE::ArgExc ("Invalid pixel aspect ratio in image header.");
|
|
Packit |
c2c737 |
}
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
//
|
|
Packit |
c2c737 |
// The screen window width must not be less than 0.
|
|
Packit |
c2c737 |
// The size of the screen window can vary over a wide
|
|
Packit |
c2c737 |
// range (fish-eye lens to astronomical telescope),
|
|
Packit |
c2c737 |
// so we can't limit the screen window width to a
|
|
Packit |
c2c737 |
// small range.
|
|
Packit |
c2c737 |
//
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
float screenWindowWidth = this->screenWindowWidth();
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
if (screenWindowWidth < 0)
|
|
Packit |
c2c737 |
throw IEX_NAMESPACE::ArgExc ("Invalid screen window width in image header.");
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
//
|
|
Packit |
c2c737 |
// If the file has multiple parts, verify that each header has attribute
|
|
Packit |
c2c737 |
// name and type.
|
|
Packit |
c2c737 |
// (TODO) We may want to check more stuff here.
|
|
Packit |
c2c737 |
//
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
if (isMultipartFile)
|
|
Packit |
c2c737 |
{
|
|
Packit |
c2c737 |
if (!hasName())
|
|
Packit |
c2c737 |
{
|
|
Packit |
c2c737 |
throw IEX_NAMESPACE::ArgExc ("Headers in a multipart file should"
|
|
Packit |
c2c737 |
" have name attribute.");
|
|
Packit |
c2c737 |
}
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
if (!hasType())
|
|
Packit |
c2c737 |
{
|
|
Packit |
c2c737 |
throw IEX_NAMESPACE::ArgExc ("Headers in a multipart file should"
|
|
Packit |
c2c737 |
" have type attribute.");
|
|
Packit |
c2c737 |
}
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
}
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
const std::string & part_type=hasType() ? type() : "";
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
if(part_type!="" && !isSupportedType(part_type))
|
|
Packit |
c2c737 |
{
|
|
Packit |
c2c737 |
//
|
|
Packit |
c2c737 |
// skip remaining sanity checks with unsupported types - they may not hold
|
|
Packit |
c2c737 |
//
|
|
Packit |
c2c737 |
return;
|
|
Packit |
c2c737 |
}
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
//
|
|
Packit |
c2c737 |
// If the file is tiled, verify that the tile description has reasonable
|
|
Packit |
c2c737 |
// values and check to see if the lineOrder is one of the predefined 3.
|
|
Packit |
c2c737 |
// If the file is not tiled, then the lineOrder can only be INCREASING_Y
|
|
Packit |
c2c737 |
// or DECREASING_Y.
|
|
Packit |
c2c737 |
//
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
LineOrder lineOrder = this->lineOrder();
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
if (isTiled)
|
|
Packit |
c2c737 |
{
|
|
Packit |
c2c737 |
if (!hasTileDescription())
|
|
Packit |
c2c737 |
{
|
|
Packit |
c2c737 |
throw IEX_NAMESPACE::ArgExc ("Tiled image has no tile "
|
|
Packit |
c2c737 |
"description attribute.");
|
|
Packit |
c2c737 |
}
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
const TileDescription &tileDesc = tileDescription();
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
if (tileDesc.xSize <= 0 || tileDesc.ySize <= 0)
|
|
Packit |
c2c737 |
throw IEX_NAMESPACE::ArgExc ("Invalid tile size in image header.");
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
if (maxTileWidth > 0 &&
|
|
Packit |
c2c737 |
maxTileWidth < int(tileDesc.xSize))
|
|
Packit |
c2c737 |
{
|
|
Packit |
c2c737 |
THROW (IEX_NAMESPACE::ArgExc, "The width of the tiles exceeds the maximum "
|
|
Packit |
c2c737 |
"width of " << maxTileWidth << "pixels.");
|
|
Packit |
c2c737 |
}
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
if (maxTileHeight > 0 &&
|
|
Packit |
c2c737 |
maxTileHeight < int(tileDesc.ySize))
|
|
Packit |
c2c737 |
{
|
|
Packit |
c2c737 |
THROW (IEX_NAMESPACE::ArgExc, "The width of the tiles exceeds the maximum "
|
|
Packit |
c2c737 |
"width of " << maxTileHeight << "pixels.");
|
|
Packit |
c2c737 |
}
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
if (tileDesc.mode != ONE_LEVEL &&
|
|
Packit |
c2c737 |
tileDesc.mode != MIPMAP_LEVELS &&
|
|
Packit |
c2c737 |
tileDesc.mode != RIPMAP_LEVELS)
|
|
Packit |
c2c737 |
throw IEX_NAMESPACE::ArgExc ("Invalid level mode in image header.");
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
if (tileDesc.roundingMode != ROUND_UP &&
|
|
Packit |
c2c737 |
tileDesc.roundingMode != ROUND_DOWN)
|
|
Packit |
c2c737 |
throw IEX_NAMESPACE::ArgExc ("Invalid level rounding mode in image header.");
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
if (lineOrder != INCREASING_Y &&
|
|
Packit |
c2c737 |
lineOrder != DECREASING_Y &&
|
|
Packit |
c2c737 |
lineOrder != RANDOM_Y)
|
|
Packit |
c2c737 |
throw IEX_NAMESPACE::ArgExc ("Invalid line order in image header.");
|
|
Packit |
c2c737 |
}
|
|
Packit |
c2c737 |
else
|
|
Packit |
c2c737 |
{
|
|
Packit |
c2c737 |
if (lineOrder != INCREASING_Y &&
|
|
Packit |
c2c737 |
lineOrder != DECREASING_Y)
|
|
Packit |
c2c737 |
throw IEX_NAMESPACE::ArgExc ("Invalid line order in image header.");
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
}
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
//
|
|
Packit |
c2c737 |
// The compression method must be one of the predefined values.
|
|
Packit |
c2c737 |
//
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
if (!isValidCompression (this->compression()))
|
|
Packit |
c2c737 |
throw IEX_NAMESPACE::ArgExc ("Unknown compression type in image header.");
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
if(isDeepData(part_type))
|
|
Packit |
c2c737 |
{
|
|
Packit |
c2c737 |
if (!isValidDeepCompression (this->compression()))
|
|
Packit |
c2c737 |
throw IEX_NAMESPACE::ArgExc ("Compression type in header not valid for deep data");
|
|
Packit |
c2c737 |
}
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
//
|
|
Packit |
c2c737 |
// Check the channel list:
|
|
Packit |
c2c737 |
//
|
|
Packit |
c2c737 |
// If the file is tiled then for each channel, the type must be one of the
|
|
Packit |
c2c737 |
// predefined values, and the x and y sampling must both be 1.
|
|
Packit |
c2c737 |
//
|
|
Packit |
c2c737 |
// If the file is not tiled then for each channel, the type must be one
|
|
Packit |
c2c737 |
// of the predefined values, the x and y coordinates of the data window's
|
|
Packit |
c2c737 |
// upper left corner must be divisible by the x and y subsampling factors,
|
|
Packit |
c2c737 |
// and the width and height of the data window must be divisible by the
|
|
Packit |
c2c737 |
// x and y subsampling factors.
|
|
Packit |
c2c737 |
//
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
const ChannelList &channels = this->channels();
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
if (isTiled)
|
|
Packit |
c2c737 |
{
|
|
Packit |
c2c737 |
for (ChannelList::ConstIterator i = channels.begin();
|
|
Packit |
c2c737 |
i != channels.end();
|
|
Packit |
c2c737 |
++i)
|
|
Packit |
c2c737 |
{
|
|
Packit |
c2c737 |
if (i.channel().type != OPENEXR_IMF_INTERNAL_NAMESPACE::UINT &&
|
|
Packit |
c2c737 |
i.channel().type != OPENEXR_IMF_INTERNAL_NAMESPACE::HALF &&
|
|
Packit |
c2c737 |
i.channel().type != OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT)
|
|
Packit |
c2c737 |
{
|
|
Packit |
c2c737 |
THROW (IEX_NAMESPACE::ArgExc, "Pixel type of \"" << i.name() << "\" "
|
|
Packit |
c2c737 |
"image channel is invalid.");
|
|
Packit |
c2c737 |
}
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
if (i.channel().xSampling != 1)
|
|
Packit |
c2c737 |
{
|
|
Packit |
c2c737 |
THROW (IEX_NAMESPACE::ArgExc, "The x subsampling factor for the "
|
|
Packit |
c2c737 |
"\"" << i.name() << "\" channel "
|
|
Packit |
c2c737 |
"is not 1.");
|
|
Packit |
c2c737 |
}
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
if (i.channel().ySampling != 1)
|
|
Packit |
c2c737 |
{
|
|
Packit |
c2c737 |
THROW (IEX_NAMESPACE::ArgExc, "The y subsampling factor for the "
|
|
Packit |
c2c737 |
"\"" << i.name() << "\" channel "
|
|
Packit |
c2c737 |
"is not 1.");
|
|
Packit |
c2c737 |
}
|
|
Packit |
c2c737 |
}
|
|
Packit |
c2c737 |
}
|
|
Packit |
c2c737 |
else
|
|
Packit |
c2c737 |
{
|
|
Packit |
c2c737 |
for (ChannelList::ConstIterator i = channels.begin();
|
|
Packit |
c2c737 |
i != channels.end();
|
|
Packit |
c2c737 |
++i)
|
|
Packit |
c2c737 |
{
|
|
Packit |
c2c737 |
if (i.channel().type != OPENEXR_IMF_INTERNAL_NAMESPACE::UINT &&
|
|
Packit |
c2c737 |
i.channel().type != OPENEXR_IMF_INTERNAL_NAMESPACE::HALF &&
|
|
Packit |
c2c737 |
i.channel().type != OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT)
|
|
Packit |
c2c737 |
{
|
|
Packit |
c2c737 |
THROW (IEX_NAMESPACE::ArgExc, "Pixel type of \"" << i.name() << "\" "
|
|
Packit |
c2c737 |
"image channel is invalid.");
|
|
Packit |
c2c737 |
}
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
if (i.channel().xSampling < 1)
|
|
Packit |
c2c737 |
{
|
|
Packit |
c2c737 |
THROW (IEX_NAMESPACE::ArgExc, "The x subsampling factor for the "
|
|
Packit |
c2c737 |
"\"" << i.name() << "\" channel "
|
|
Packit |
c2c737 |
"is invalid.");
|
|
Packit |
c2c737 |
}
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
if (i.channel().ySampling < 1)
|
|
Packit |
c2c737 |
{
|
|
Packit |
c2c737 |
THROW (IEX_NAMESPACE::ArgExc, "The y subsampling factor for the "
|
|
Packit |
c2c737 |
"\"" << i.name() << "\" channel "
|
|
Packit |
c2c737 |
"is invalid.");
|
|
Packit |
c2c737 |
}
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
if (dataWindow.min.x % i.channel().xSampling)
|
|
Packit |
c2c737 |
{
|
|
Packit |
c2c737 |
THROW (IEX_NAMESPACE::ArgExc, "The minimum x coordinate of the "
|
|
Packit |
c2c737 |
"image's data window is not a multiple "
|
|
Packit |
c2c737 |
"of the x subsampling factor of "
|
|
Packit |
c2c737 |
"the \"" << i.name() << "\" channel.");
|
|
Packit |
c2c737 |
}
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
if (dataWindow.min.y % i.channel().ySampling)
|
|
Packit |
c2c737 |
{
|
|
Packit |
c2c737 |
THROW (IEX_NAMESPACE::ArgExc, "The minimum y coordinate of the "
|
|
Packit |
c2c737 |
"image's data window is not a multiple "
|
|
Packit |
c2c737 |
"of the y subsampling factor of "
|
|
Packit |
c2c737 |
"the \"" << i.name() << "\" channel.");
|
|
Packit |
c2c737 |
}
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
if ((dataWindow.max.x - dataWindow.min.x + 1) %
|
|
Packit |
c2c737 |
i.channel().xSampling)
|
|
Packit |
c2c737 |
{
|
|
Packit |
c2c737 |
THROW (IEX_NAMESPACE::ArgExc, "Number of pixels per row in the "
|
|
Packit |
c2c737 |
"image's data window is not a multiple "
|
|
Packit |
c2c737 |
"of the x subsampling factor of "
|
|
Packit |
c2c737 |
"the \"" << i.name() << "\" channel.");
|
|
Packit |
c2c737 |
}
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
if ((dataWindow.max.y - dataWindow.min.y + 1) %
|
|
Packit |
c2c737 |
i.channel().ySampling)
|
|
Packit |
c2c737 |
{
|
|
Packit |
c2c737 |
THROW (IEX_NAMESPACE::ArgExc, "Number of pixels per column in the "
|
|
Packit |
c2c737 |
"image's data window is not a multiple "
|
|
Packit |
c2c737 |
"of the y subsampling factor of "
|
|
Packit |
c2c737 |
"the \"" << i.name() << "\" channel.");
|
|
Packit |
c2c737 |
}
|
|
Packit |
c2c737 |
}
|
|
Packit |
c2c737 |
}
|
|
Packit |
c2c737 |
}
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
void
|
|
Packit |
c2c737 |
Header::setMaxImageSize (int maxWidth, int maxHeight)
|
|
Packit |
c2c737 |
{
|
|
Packit |
c2c737 |
maxImageWidth = maxWidth;
|
|
Packit |
c2c737 |
maxImageHeight = maxHeight;
|
|
Packit |
c2c737 |
}
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
void
|
|
Packit |
c2c737 |
Header::setMaxTileSize (int maxWidth, int maxHeight)
|
|
Packit |
c2c737 |
{
|
|
Packit |
c2c737 |
maxTileWidth = maxWidth;
|
|
Packit |
c2c737 |
maxTileHeight = maxHeight;
|
|
Packit |
c2c737 |
}
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
bool
|
|
Packit |
c2c737 |
Header::readsNothing()
|
|
Packit |
c2c737 |
{
|
|
Packit |
c2c737 |
return _readsNothing;
|
|
Packit |
c2c737 |
}
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
Int64
|
|
Packit |
c2c737 |
Header::writeTo (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &os, bool isTiled) const
|
|
Packit |
c2c737 |
{
|
|
Packit |
c2c737 |
//
|
|
Packit |
c2c737 |
// Write a "magic number" to identify the file as an image file.
|
|
Packit |
c2c737 |
// Write the current file format version number.
|
|
Packit |
c2c737 |
//
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
int version = EXR_VERSION;
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
//
|
|
Packit |
c2c737 |
// Write all attributes. If we have a preview image attribute,
|
|
Packit |
c2c737 |
// keep track of its position in the file.
|
|
Packit |
c2c737 |
//
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
Int64 previewPosition = 0;
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
const Attribute *preview =
|
|
Packit |
c2c737 |
findTypedAttribute <PreviewImageAttribute> ("preview");
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
for (ConstIterator i = begin(); i != end(); ++i)
|
|
Packit |
c2c737 |
{
|
|
Packit |
c2c737 |
//
|
|
Packit |
c2c737 |
// Write the attribute's name and type.
|
|
Packit |
c2c737 |
//
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::write <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (os, i.name());
|
|
Packit |
c2c737 |
OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::write <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (os, i.attribute().typeName());
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
//
|
|
Packit |
c2c737 |
// Write the size of the attribute value,
|
|
Packit |
c2c737 |
// and the value itself.
|
|
Packit |
c2c737 |
//
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
StdOSStream oss;
|
|
Packit |
c2c737 |
i.attribute().writeValueTo (oss, version);
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
std::string s = oss.str();
|
|
Packit |
c2c737 |
OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::write <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (os, (int) s.length());
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
if (&i.attribute() == preview)
|
|
Packit |
c2c737 |
previewPosition = os.tellp();
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
os.write (s.data(), int(s.length()));
|
|
Packit |
c2c737 |
}
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
//
|
|
Packit |
c2c737 |
// Write zero-length attribute name to mark the end of the header.
|
|
Packit |
c2c737 |
//
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::write <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (os, "");
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
return previewPosition;
|
|
Packit |
c2c737 |
}
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
void
|
|
Packit |
c2c737 |
Header::readFrom (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is, int &version)
|
|
Packit |
c2c737 |
{
|
|
Packit |
c2c737 |
//
|
|
Packit |
c2c737 |
// Read all attributes.
|
|
Packit |
c2c737 |
//
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
int attrCount = 0;
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
while (true)
|
|
Packit |
c2c737 |
{
|
|
Packit |
c2c737 |
//
|
|
Packit |
c2c737 |
// Read the name of the attribute.
|
|
Packit |
c2c737 |
// A zero-length attribute name indicates the end of the header.
|
|
Packit |
c2c737 |
//
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
char name[Name::SIZE];
|
|
Packit |
c2c737 |
OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::read <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (is, Name::MAX_LENGTH, name);
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
if (name[0] == 0)
|
|
Packit |
c2c737 |
{
|
|
Packit |
c2c737 |
if (attrCount == 0) _readsNothing = true;
|
|
Packit |
c2c737 |
else _readsNothing = false;
|
|
Packit |
c2c737 |
break;
|
|
Packit |
c2c737 |
}
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
attrCount++;
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
checkIsNullTerminated (name, "attribute name");
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
//
|
|
Packit |
c2c737 |
// Read the attribute type and the size of the attribute value.
|
|
Packit |
c2c737 |
//
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
char typeName[Name::SIZE];
|
|
Packit |
c2c737 |
int size;
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::read <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (is, Name::MAX_LENGTH, typeName);
|
|
Packit |
c2c737 |
checkIsNullTerminated (typeName, "attribute type name");
|
|
Packit |
c2c737 |
OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::read <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (is, size);
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
AttributeMap::iterator i = _map.find (name);
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
if (i != _map.end())
|
|
Packit |
c2c737 |
{
|
|
Packit |
c2c737 |
//
|
|
Packit |
c2c737 |
// The attribute already exists (for example,
|
|
Packit |
c2c737 |
// because it is a predefined attribute).
|
|
Packit |
c2c737 |
// Read the attribute's new value from the file.
|
|
Packit |
c2c737 |
//
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
if (strncmp (i->second->typeName(), typeName, sizeof (typeName)))
|
|
Packit |
c2c737 |
THROW (IEX_NAMESPACE::InputExc, "Unexpected type for image attribute "
|
|
Packit |
c2c737 |
"\"" << name << "\".");
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
i->second->readValueFrom (is, size, version);
|
|
Packit |
c2c737 |
}
|
|
Packit |
c2c737 |
else
|
|
Packit |
c2c737 |
{
|
|
Packit |
c2c737 |
//
|
|
Packit |
c2c737 |
// The new attribute does not exist yet.
|
|
Packit |
c2c737 |
// If the attribute type is of a known type,
|
|
Packit |
c2c737 |
// read the attribute value. If the attribute
|
|
Packit |
c2c737 |
// is of an unknown type, read its value and
|
|
Packit |
c2c737 |
// store it as an OpaqueAttribute.
|
|
Packit |
c2c737 |
//
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
Attribute *attr;
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
if (Attribute::knownType (typeName))
|
|
Packit |
c2c737 |
attr = Attribute::newAttribute (typeName);
|
|
Packit |
c2c737 |
else
|
|
Packit |
c2c737 |
attr = new OpaqueAttribute (typeName);
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
try
|
|
Packit |
c2c737 |
{
|
|
Packit |
c2c737 |
attr->readValueFrom (is, size, version);
|
|
Packit |
c2c737 |
_map[name] = attr;
|
|
Packit |
c2c737 |
}
|
|
Packit |
c2c737 |
catch (...)
|
|
Packit |
c2c737 |
{
|
|
Packit |
c2c737 |
delete attr;
|
|
Packit |
c2c737 |
throw;
|
|
Packit |
c2c737 |
}
|
|
Packit |
c2c737 |
}
|
|
Packit |
c2c737 |
}
|
|
Packit |
c2c737 |
}
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
void
|
|
Packit |
c2c737 |
staticInitialize ()
|
|
Packit |
c2c737 |
{
|
|
Packit |
c2c737 |
static Mutex criticalSection;
|
|
Packit |
c2c737 |
Lock lock (criticalSection);
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
static bool initialized = false;
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
if (!initialized)
|
|
Packit |
c2c737 |
{
|
|
Packit |
c2c737 |
//
|
|
Packit |
c2c737 |
// One-time initialization -- register
|
|
Packit |
c2c737 |
// some predefined attribute types.
|
|
Packit |
c2c737 |
//
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
Box2fAttribute::registerAttributeType();
|
|
Packit |
c2c737 |
Box2iAttribute::registerAttributeType();
|
|
Packit |
c2c737 |
ChannelListAttribute::registerAttributeType();
|
|
Packit |
c2c737 |
CompressionAttribute::registerAttributeType();
|
|
Packit |
c2c737 |
ChromaticitiesAttribute::registerAttributeType();
|
|
Packit |
c2c737 |
DeepImageStateAttribute::registerAttributeType();
|
|
Packit |
c2c737 |
DoubleAttribute::registerAttributeType();
|
|
Packit |
c2c737 |
EnvmapAttribute::registerAttributeType();
|
|
Packit |
c2c737 |
FloatAttribute::registerAttributeType();
|
|
Packit |
c2c737 |
FloatVectorAttribute::registerAttributeType();
|
|
Packit |
c2c737 |
IntAttribute::registerAttributeType();
|
|
Packit |
c2c737 |
KeyCodeAttribute::registerAttributeType();
|
|
Packit |
c2c737 |
LineOrderAttribute::registerAttributeType();
|
|
Packit |
c2c737 |
M33dAttribute::registerAttributeType();
|
|
Packit |
c2c737 |
M33fAttribute::registerAttributeType();
|
|
Packit |
c2c737 |
M44dAttribute::registerAttributeType();
|
|
Packit |
c2c737 |
M44fAttribute::registerAttributeType();
|
|
Packit |
c2c737 |
PreviewImageAttribute::registerAttributeType();
|
|
Packit |
c2c737 |
RationalAttribute::registerAttributeType();
|
|
Packit |
c2c737 |
StringAttribute::registerAttributeType();
|
|
Packit |
c2c737 |
StringVectorAttribute::registerAttributeType();
|
|
Packit |
c2c737 |
TileDescriptionAttribute::registerAttributeType();
|
|
Packit |
c2c737 |
TimeCodeAttribute::registerAttributeType();
|
|
Packit |
c2c737 |
V2dAttribute::registerAttributeType();
|
|
Packit |
c2c737 |
V2fAttribute::registerAttributeType();
|
|
Packit |
c2c737 |
V2iAttribute::registerAttributeType();
|
|
Packit |
c2c737 |
V3dAttribute::registerAttributeType();
|
|
Packit |
c2c737 |
V3fAttribute::registerAttributeType();
|
|
Packit |
c2c737 |
V3iAttribute::registerAttributeType();
|
|
Packit |
c2c737 |
DwaCompressor::initializeFuncs();
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
initialized = true;
|
|
Packit |
c2c737 |
}
|
|
Packit |
c2c737 |
}
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
|
|
Packit |
c2c737 |
OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
|