|
Packit |
0d464f |
///////////////////////////////////////////////////////////////////////////
|
|
Packit |
0d464f |
//
|
|
Packit |
0d464f |
// Copyright (c) 2004, Industrial Light & Magic, a division of Lucas
|
|
Packit |
0d464f |
// Digital Ltd. LLC
|
|
Packit |
0d464f |
//
|
|
Packit |
0d464f |
// All rights reserved.
|
|
Packit |
0d464f |
//
|
|
Packit |
0d464f |
// Redistribution and use in source and binary forms, with or without
|
|
Packit |
0d464f |
// modification, are permitted provided that the following conditions are
|
|
Packit |
0d464f |
// met:
|
|
Packit |
0d464f |
// * Redistributions of source code must retain the above copyright
|
|
Packit |
0d464f |
// notice, this list of conditions and the following disclaimer.
|
|
Packit |
0d464f |
// * Redistributions in binary form must reproduce the above
|
|
Packit |
0d464f |
// copyright notice, this list of conditions and the following disclaimer
|
|
Packit |
0d464f |
// in the documentation and/or other materials provided with the
|
|
Packit |
0d464f |
// distribution.
|
|
Packit |
0d464f |
// * Neither the name of Industrial Light & Magic nor the names of
|
|
Packit |
0d464f |
// its contributors may be used to endorse or promote products derived
|
|
Packit |
0d464f |
// from this software without specific prior written permission.
|
|
Packit |
0d464f |
//
|
|
Packit |
0d464f |
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
Packit |
0d464f |
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
Packit |
0d464f |
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
Packit |
0d464f |
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
Packit |
0d464f |
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
Packit |
0d464f |
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
Packit |
0d464f |
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
Packit |
0d464f |
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
Packit |
0d464f |
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
Packit |
0d464f |
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
Packit |
0d464f |
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
Packit |
0d464f |
//
|
|
Packit |
0d464f |
///////////////////////////////////////////////////////////////////////////
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
//-----------------------------------------------------------------------------
|
|
Packit |
0d464f |
//
|
|
Packit |
0d464f |
// class InputFile
|
|
Packit |
0d464f |
//
|
|
Packit |
0d464f |
//-----------------------------------------------------------------------------
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
#include "ImfInputFile.h"
|
|
Packit |
0d464f |
#include "ImfScanLineInputFile.h"
|
|
Packit |
0d464f |
#include "ImfTiledInputFile.h"
|
|
Packit |
0d464f |
#include "ImfChannelList.h"
|
|
Packit |
0d464f |
#include "ImfMisc.h"
|
|
Packit |
0d464f |
#include "ImfStdIO.h"
|
|
Packit |
0d464f |
#include "ImfVersion.h"
|
|
Packit |
0d464f |
#include "ImfPartType.h"
|
|
Packit |
0d464f |
#include "ImfInputPartData.h"
|
|
Packit |
0d464f |
#include "ImfMultiPartInputFile.h"
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
#include <ImfCompositeDeepScanLine.h>
|
|
Packit |
0d464f |
#include <ImfDeepScanLineInputFile.h>
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
#include "ImathFun.h"
|
|
Packit |
0d464f |
#include "IlmThreadMutex.h"
|
|
Packit |
0d464f |
#include "Iex.h"
|
|
Packit |
0d464f |
#include "half.h"
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
#include <fstream>
|
|
Packit |
0d464f |
#include <algorithm>
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
#include "ImfNamespace.h"
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
using IMATH_NAMESPACE::Box2i;
|
|
Packit |
0d464f |
using IMATH_NAMESPACE::divp;
|
|
Packit |
0d464f |
using IMATH_NAMESPACE::modp;
|
|
Packit |
0d464f |
using ILMTHREAD_NAMESPACE::Mutex;
|
|
Packit |
0d464f |
using ILMTHREAD_NAMESPACE::Lock;
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
//
|
|
Packit |
0d464f |
// Struct InputFile::Data stores things that will be
|
|
Packit |
0d464f |
// needed between calls to readPixels
|
|
Packit |
0d464f |
//
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
struct InputFile::Data : public Mutex
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
Header header;
|
|
Packit |
0d464f |
int version;
|
|
Packit |
0d464f |
bool isTiled;
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
TiledInputFile * tFile;
|
|
Packit |
0d464f |
ScanLineInputFile * sFile;
|
|
Packit |
0d464f |
DeepScanLineInputFile * dsFile;
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
LineOrder lineOrder; // the file's lineorder
|
|
Packit |
0d464f |
int minY; // data window's min y coord
|
|
Packit |
0d464f |
int maxY; // data window's max x coord
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
FrameBuffer tFileBuffer;
|
|
Packit |
0d464f |
FrameBuffer * cachedBuffer;
|
|
Packit |
0d464f |
CompositeDeepScanLine * compositor; // for loading deep files
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
int cachedTileY;
|
|
Packit |
0d464f |
int offset;
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
int numThreads;
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
int partNumber;
|
|
Packit |
0d464f |
InputPartData* part;
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
bool multiPartBackwardSupport;
|
|
Packit |
0d464f |
MultiPartInputFile* multiPartFile;
|
|
Packit |
0d464f |
InputStreamMutex * _streamData;
|
|
Packit |
0d464f |
bool _deleteStream;
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
Data (int numThreads);
|
|
Packit |
0d464f |
~Data ();
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
void deleteCachedBuffer();
|
|
Packit |
0d464f |
};
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
InputFile::Data::Data (int numThreads):
|
|
Packit |
0d464f |
isTiled (false),
|
|
Packit |
0d464f |
tFile (0),
|
|
Packit |
0d464f |
sFile (0),
|
|
Packit |
0d464f |
dsFile(0),
|
|
Packit |
0d464f |
cachedBuffer (0),
|
|
Packit |
0d464f |
compositor(0),
|
|
Packit |
0d464f |
cachedTileY (-1),
|
|
Packit |
0d464f |
numThreads (numThreads),
|
|
Packit |
0d464f |
partNumber (-1),
|
|
Packit |
0d464f |
part(NULL),
|
|
Packit |
0d464f |
multiPartBackwardSupport (false),
|
|
Packit |
0d464f |
multiPartFile (0),
|
|
Packit |
0d464f |
_streamData(0),
|
|
Packit |
0d464f |
_deleteStream(false)
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
// empty
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
InputFile::Data::~Data ()
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
if (tFile)
|
|
Packit |
0d464f |
delete tFile;
|
|
Packit |
0d464f |
if (sFile)
|
|
Packit |
0d464f |
delete sFile;
|
|
Packit |
0d464f |
if (dsFile)
|
|
Packit |
0d464f |
delete dsFile;
|
|
Packit |
0d464f |
if (compositor)
|
|
Packit |
0d464f |
delete compositor;
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
deleteCachedBuffer();
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
if (multiPartBackwardSupport && multiPartFile)
|
|
Packit |
0d464f |
delete multiPartFile;
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
void
|
|
Packit |
0d464f |
InputFile::Data::deleteCachedBuffer()
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
//
|
|
Packit |
0d464f |
// Delete the cached frame buffer, and all memory
|
|
Packit |
0d464f |
// allocated for the slices in the cached frameBuffer.
|
|
Packit |
0d464f |
//
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
if (cachedBuffer)
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
for (FrameBuffer::Iterator k = cachedBuffer->begin();
|
|
Packit |
0d464f |
k != cachedBuffer->end();
|
|
Packit |
0d464f |
++k)
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
Slice &s = k.slice();
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
switch (s.type)
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
case OPENEXR_IMF_INTERNAL_NAMESPACE::UINT:
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
delete [] (((unsigned int *)s.base) + offset);
|
|
Packit |
0d464f |
break;
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
case OPENEXR_IMF_INTERNAL_NAMESPACE::HALF:
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
delete [] ((half *)s.base + offset);
|
|
Packit |
0d464f |
break;
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
case OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT:
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
delete [] (((float *)s.base) + offset);
|
|
Packit |
0d464f |
break;
|
|
Packit |
0d464f |
case NUM_PIXELTYPES :
|
|
Packit |
0d464f |
throw(IEX_NAMESPACE::ArgExc("Invalid pixel type"));
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
//
|
|
Packit |
0d464f |
// delete the cached frame buffer
|
|
Packit |
0d464f |
//
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
delete cachedBuffer;
|
|
Packit |
0d464f |
cachedBuffer = 0;
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
namespace {
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
void
|
|
Packit |
0d464f |
bufferedReadPixels (InputFile::Data* ifd, int scanLine1, int scanLine2)
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
//
|
|
Packit |
0d464f |
// bufferedReadPixels reads each row of tiles that intersect the
|
|
Packit |
0d464f |
// scan-line range (scanLine1 to scanLine2). The previous row of
|
|
Packit |
0d464f |
// tiles is cached in order to prevent redundent tile reads when
|
|
Packit |
0d464f |
// accessing scanlines sequentially.
|
|
Packit |
0d464f |
//
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
int minY = std::min (scanLine1, scanLine2);
|
|
Packit |
0d464f |
int maxY = std::max (scanLine1, scanLine2);
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
if (minY < ifd->minY || maxY > ifd->maxY)
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
throw IEX_NAMESPACE::ArgExc ("Tried to read scan line outside "
|
|
Packit |
0d464f |
"the image file's data window.");
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
//
|
|
Packit |
0d464f |
// The minimum and maximum y tile coordinates that intersect this
|
|
Packit |
0d464f |
// scanline range
|
|
Packit |
0d464f |
//
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
int minDy = (minY - ifd->minY) / ifd->tFile->tileYSize();
|
|
Packit |
0d464f |
int maxDy = (maxY - ifd->minY) / ifd->tFile->tileYSize();
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
//
|
|
Packit |
0d464f |
// Figure out which one is first in the file so we can read without seeking
|
|
Packit |
0d464f |
//
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
int yStart, yEnd, yStep;
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
if (ifd->lineOrder == DECREASING_Y)
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
yStart = maxDy;
|
|
Packit |
0d464f |
yEnd = minDy - 1;
|
|
Packit |
0d464f |
yStep = -1;
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
else
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
yStart = minDy;
|
|
Packit |
0d464f |
yEnd = maxDy + 1;
|
|
Packit |
0d464f |
yStep = 1;
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
//
|
|
Packit |
0d464f |
// the number of pixels in a row of tiles
|
|
Packit |
0d464f |
//
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
Box2i levelRange = ifd->tFile->dataWindowForLevel(0);
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
//
|
|
Packit |
0d464f |
// Read the tiles into our temporary framebuffer and copy them into
|
|
Packit |
0d464f |
// the user's buffer
|
|
Packit |
0d464f |
//
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
for (int j = yStart; j != yEnd; j += yStep)
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
Box2i tileRange = ifd->tFile->dataWindowForTile (0, j, 0);
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
int minYThisRow = std::max (minY, tileRange.min.y);
|
|
Packit |
0d464f |
int maxYThisRow = std::min (maxY, tileRange.max.y);
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
if (j != ifd->cachedTileY)
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
//
|
|
Packit |
0d464f |
// We don't have any valid buffered info, so we need to read in
|
|
Packit |
0d464f |
// from the file.
|
|
Packit |
0d464f |
//
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
ifd->tFile->readTiles (0, ifd->tFile->numXTiles (0) - 1, j, j);
|
|
Packit |
0d464f |
ifd->cachedTileY = j;
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
//
|
|
Packit |
0d464f |
// Copy the data from our cached framebuffer into the user's
|
|
Packit |
0d464f |
// framebuffer.
|
|
Packit |
0d464f |
//
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
for (FrameBuffer::ConstIterator k = ifd->cachedBuffer->begin();
|
|
Packit |
0d464f |
k != ifd->cachedBuffer->end();
|
|
Packit |
0d464f |
++k)
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
Slice fromSlice = k.slice(); // slice to write from
|
|
Packit |
0d464f |
Slice toSlice = ifd->tFileBuffer[k.name()]; // slice to write to
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
char *fromPtr, *toPtr;
|
|
Packit |
0d464f |
int size = pixelTypeSize (toSlice.type);
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
int xStart = levelRange.min.x;
|
|
Packit |
0d464f |
int yStart = minYThisRow;
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
while (modp (xStart, toSlice.xSampling) != 0)
|
|
Packit |
0d464f |
++xStart;
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
while (modp (yStart, toSlice.ySampling) != 0)
|
|
Packit |
0d464f |
++yStart;
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
for (int y = yStart;
|
|
Packit |
0d464f |
y <= maxYThisRow;
|
|
Packit |
0d464f |
y += toSlice.ySampling)
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
//
|
|
Packit |
0d464f |
// Set the pointers to the start of the y scanline in
|
|
Packit |
0d464f |
// this row of tiles
|
|
Packit |
0d464f |
//
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
fromPtr = fromSlice.base +
|
|
Packit |
0d464f |
(y - tileRange.min.y) * fromSlice.yStride +
|
|
Packit |
0d464f |
xStart * fromSlice.xStride;
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
toPtr = toSlice.base +
|
|
Packit |
0d464f |
divp (y, toSlice.ySampling) * toSlice.yStride +
|
|
Packit |
0d464f |
divp (xStart, toSlice.xSampling) * toSlice.xStride;
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
//
|
|
Packit |
0d464f |
// Copy all pixels for the scanline in this row of tiles
|
|
Packit |
0d464f |
//
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
for (int x = xStart;
|
|
Packit |
0d464f |
x <= levelRange.max.x;
|
|
Packit |
0d464f |
x += toSlice.xSampling)
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
for (int i = 0; i < size; ++i)
|
|
Packit |
0d464f |
toPtr[i] = fromPtr[i];
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
fromPtr += fromSlice.xStride * toSlice.xSampling;
|
|
Packit |
0d464f |
toPtr += toSlice.xStride;
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
} // namespace
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
InputFile::InputFile (const char fileName[], int numThreads):
|
|
Packit |
0d464f |
_data (new Data (numThreads))
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
_data->_streamData = NULL;
|
|
Packit |
0d464f |
_data->_deleteStream=true;
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
OPENEXR_IMF_INTERNAL_NAMESPACE::IStream* is = 0;
|
|
Packit |
0d464f |
try
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
is = new StdIFStream (fileName);
|
|
Packit |
0d464f |
readMagicNumberAndVersionField(*is, _data->version);
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
//
|
|
Packit |
0d464f |
// compatibility to read multipart file.
|
|
Packit |
0d464f |
//
|
|
Packit |
0d464f |
if (isMultiPart(_data->version))
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
compatibilityInitialize(*is);
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
else
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
_data->_streamData = new InputStreamMutex();
|
|
Packit |
0d464f |
_data->_streamData->is = is;
|
|
Packit |
0d464f |
_data->header.readFrom (*_data->_streamData->is, _data->version);
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
// fix type attribute in single part regular image types
|
|
Packit |
0d464f |
// (may be wrong if an old version of OpenEXR converts
|
|
Packit |
0d464f |
// a tiled image to scanline or vice versa)
|
|
Packit |
0d464f |
if(!isNonImage(_data->version) &&
|
|
Packit |
0d464f |
!isMultiPart(_data->version) &&
|
|
Packit |
0d464f |
_data->header.hasType())
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
_data->header.setType(isTiled(_data->version) ? TILEDIMAGE : SCANLINEIMAGE);
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
_data->header.sanityCheck (isTiled (_data->version));
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
initialize();
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
catch (IEX_NAMESPACE::BaseExc &e)
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
if (is) delete is;
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
if ( _data && !_data->multiPartBackwardSupport && _data->_streamData)
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
delete _data->_streamData;
|
|
Packit |
0d464f |
_data->_streamData=NULL;
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
if (_data) delete _data;
|
|
Packit |
0d464f |
_data=NULL;
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
REPLACE_EXC (e, "Cannot read image file "
|
|
Packit |
0d464f |
"\"" << fileName << "\". " << e);
|
|
Packit |
0d464f |
throw;
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
catch (...)
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
if (is) delete is;
|
|
Packit |
0d464f |
if (_data && !_data->multiPartBackwardSupport && _data->_streamData)
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
delete _data->_streamData;
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
if (_data) delete _data;
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
throw;
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
InputFile::InputFile (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is, int numThreads):
|
|
Packit |
0d464f |
_data (new Data (numThreads))
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
_data->_streamData=NULL;
|
|
Packit |
0d464f |
_data->_deleteStream=false;
|
|
Packit |
0d464f |
try
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
readMagicNumberAndVersionField(is, _data->version);
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
//
|
|
Packit |
0d464f |
// Backward compatibility to read multpart file.
|
|
Packit |
0d464f |
//
|
|
Packit |
0d464f |
if (isMultiPart(_data->version))
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
compatibilityInitialize(is);
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
else
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
_data->_streamData = new InputStreamMutex();
|
|
Packit |
0d464f |
_data->_streamData->is = &is;
|
|
Packit |
0d464f |
_data->header.readFrom (*_data->_streamData->is, _data->version);
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
// fix type attribute in single part regular image types
|
|
Packit |
0d464f |
// (may be wrong if an old version of OpenEXR converts
|
|
Packit |
0d464f |
// a tiled image to scanline or vice versa)
|
|
Packit |
0d464f |
if(!isNonImage(_data->version) &&
|
|
Packit |
0d464f |
!isMultiPart(_data->version) &&
|
|
Packit |
0d464f |
_data->header.hasType())
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
_data->header.setType(isTiled(_data->version) ? TILEDIMAGE : SCANLINEIMAGE);
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
_data->header.sanityCheck (isTiled (_data->version));
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
initialize();
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
catch (IEX_NAMESPACE::BaseExc &e)
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
if (_data && !_data->multiPartBackwardSupport && _data->_streamData) delete _data->_streamData;
|
|
Packit |
0d464f |
if (_data) delete _data;
|
|
Packit |
0d464f |
_data=NULL;
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
REPLACE_EXC (e, "Cannot read image file "
|
|
Packit |
0d464f |
"\"" << is.fileName() << "\". " << e);
|
|
Packit |
0d464f |
throw;
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
catch (...)
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
if (_data && !_data->multiPartBackwardSupport && _data->_streamData) delete _data->_streamData;
|
|
Packit |
0d464f |
if (_data) delete _data;
|
|
Packit |
0d464f |
_data=NULL;
|
|
Packit |
0d464f |
throw;
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
InputFile::InputFile (InputPartData* part) :
|
|
Packit |
0d464f |
_data (new Data (part->numThreads))
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
_data->_deleteStream=false;
|
|
Packit |
0d464f |
multiPartInitialize (part);
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
void
|
|
Packit |
0d464f |
InputFile::compatibilityInitialize (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream& is)
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
is.seekg(0);
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
//
|
|
Packit |
0d464f |
// Construct a MultiPartInputFile, initialize InputFile
|
|
Packit |
0d464f |
// with the part 0 data.
|
|
Packit |
0d464f |
// (TODO) may want to have a way to set the reconstruction flag.
|
|
Packit |
0d464f |
//
|
|
Packit |
0d464f |
_data->multiPartBackwardSupport = true;
|
|
Packit |
0d464f |
_data->multiPartFile = new MultiPartInputFile(is, _data->numThreads);
|
|
Packit |
0d464f |
InputPartData* part = _data->multiPartFile->getPart(0);
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
multiPartInitialize (part);
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
void
|
|
Packit |
0d464f |
InputFile::multiPartInitialize (InputPartData* part)
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
_data->_streamData = part->mutex;
|
|
Packit |
0d464f |
_data->version = part->version;
|
|
Packit |
0d464f |
_data->header = part->header;
|
|
Packit |
0d464f |
_data->partNumber = part->partNumber;
|
|
Packit |
0d464f |
_data->part = part;
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
initialize();
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
void
|
|
Packit |
0d464f |
InputFile::initialize ()
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
if (!_data->part)
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
if(_data->header.hasType() && _data->header.type()==DEEPSCANLINE)
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
_data->isTiled=false;
|
|
Packit |
0d464f |
const Box2i &dataWindow = _data->header.dataWindow();
|
|
Packit |
0d464f |
_data->minY = dataWindow.min.y;
|
|
Packit |
0d464f |
_data->maxY = dataWindow.max.y;
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
_data->dsFile = new DeepScanLineInputFile (_data->header,
|
|
Packit |
0d464f |
_data->_streamData->is,
|
|
Packit |
0d464f |
_data->version,
|
|
Packit |
0d464f |
_data->numThreads);
|
|
Packit |
0d464f |
_data->compositor = new CompositeDeepScanLine;
|
|
Packit |
0d464f |
_data->compositor->addSource(_data->dsFile);
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
else if (isTiled (_data->version))
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
_data->isTiled = true;
|
|
Packit |
0d464f |
_data->lineOrder = _data->header.lineOrder();
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
//
|
|
Packit |
0d464f |
// Save the dataWindow information
|
|
Packit |
0d464f |
//
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
const Box2i &dataWindow = _data->header.dataWindow();
|
|
Packit |
0d464f |
_data->minY = dataWindow.min.y;
|
|
Packit |
0d464f |
_data->maxY = dataWindow.max.y;
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
_data->tFile = new TiledInputFile (_data->header,
|
|
Packit |
0d464f |
_data->_streamData->is,
|
|
Packit |
0d464f |
_data->version,
|
|
Packit |
0d464f |
_data->numThreads);
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
else if(!_data->header.hasType() || _data->header.type()==SCANLINEIMAGE)
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
_data->sFile = new ScanLineInputFile (_data->header,
|
|
Packit |
0d464f |
_data->_streamData->is,
|
|
Packit |
0d464f |
_data->numThreads);
|
|
Packit |
0d464f |
}else{
|
|
Packit |
0d464f |
// type set but not recognised
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
THROW(IEX_NAMESPACE::ArgExc, "InputFile cannot handle parts of type " << _data->header.type());
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
else
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
if(_data->header.hasType() && _data->header.type()==DEEPSCANLINE)
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
_data->isTiled=false;
|
|
Packit |
0d464f |
const Box2i &dataWindow = _data->header.dataWindow();
|
|
Packit |
0d464f |
_data->minY = dataWindow.min.y;
|
|
Packit |
0d464f |
_data->maxY = dataWindow.max.y;
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
_data->dsFile = new DeepScanLineInputFile (_data->part);
|
|
Packit |
0d464f |
_data->compositor = new CompositeDeepScanLine;
|
|
Packit |
0d464f |
_data->compositor->addSource(_data->dsFile);
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
else if (isTiled (_data->header.type()))
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
_data->isTiled = true;
|
|
Packit |
0d464f |
_data->lineOrder = _data->header.lineOrder();
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
//
|
|
Packit |
0d464f |
// Save the dataWindow information
|
|
Packit |
0d464f |
//
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
const Box2i &dataWindow = _data->header.dataWindow();
|
|
Packit |
0d464f |
_data->minY = dataWindow.min.y;
|
|
Packit |
0d464f |
_data->maxY = dataWindow.max.y;
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
_data->tFile = new TiledInputFile (_data->part);
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
else if(!_data->header.hasType() || _data->header.type()==SCANLINEIMAGE)
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
_data->sFile = new ScanLineInputFile (_data->part);
|
|
Packit |
0d464f |
}else{
|
|
Packit |
0d464f |
THROW(IEX_NAMESPACE::ArgExc, "InputFile cannot handle parts of type " << _data->header.type());
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
#include <iostream>
|
|
Packit |
0d464f |
InputFile::~InputFile ()
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
if (_data->_deleteStream)
|
|
Packit |
0d464f |
delete _data->_streamData->is;
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
// unless this file was opened via the multipart API,
|
|
Packit |
0d464f |
// delete the streamData object too
|
|
Packit |
0d464f |
if (_data->partNumber==-1 && _data->_streamData)
|
|
Packit |
0d464f |
delete _data->_streamData;
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
if (_data) delete _data;
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
const char *
|
|
Packit |
0d464f |
InputFile::fileName () const
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
return _data->_streamData->is->fileName();
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
const Header &
|
|
Packit |
0d464f |
InputFile::header () const
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
return _data->header;
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
int
|
|
Packit |
0d464f |
InputFile::version () const
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
return _data->version;
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
void
|
|
Packit |
0d464f |
InputFile::setFrameBuffer (const FrameBuffer &frameBuffer)
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
if (_data->isTiled)
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
Lock lock (*_data);
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
//
|
|
Packit |
0d464f |
// We must invalidate the cached buffer if the new frame
|
|
Packit |
0d464f |
// buffer has a different set of channels than the old
|
|
Packit |
0d464f |
// frame buffer, or if the type of a channel has changed.
|
|
Packit |
0d464f |
//
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
const FrameBuffer &oldFrameBuffer = _data->tFileBuffer;
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
FrameBuffer::ConstIterator i = oldFrameBuffer.begin();
|
|
Packit |
0d464f |
FrameBuffer::ConstIterator j = frameBuffer.begin();
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
while (i != oldFrameBuffer.end() && j != frameBuffer.end())
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
if (strcmp (i.name(), j.name()) || i.slice().type != j.slice().type)
|
|
Packit |
0d464f |
break;
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
++i;
|
|
Packit |
0d464f |
++j;
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
if (i != oldFrameBuffer.end() || j != frameBuffer.end())
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
//
|
|
Packit |
0d464f |
// Invalidate the cached buffer.
|
|
Packit |
0d464f |
//
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
_data->deleteCachedBuffer ();
|
|
Packit |
0d464f |
_data->cachedTileY = -1;
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
//
|
|
Packit |
0d464f |
// Create new a cached frame buffer. It can hold a single
|
|
Packit |
0d464f |
// row of tiles. The cached buffer can be reused for each
|
|
Packit |
0d464f |
// row of tiles because we set the yTileCoords parameter of
|
|
Packit |
0d464f |
// each Slice to true.
|
|
Packit |
0d464f |
//
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
const Box2i &dataWindow = _data->header.dataWindow();
|
|
Packit |
0d464f |
_data->cachedBuffer = new FrameBuffer();
|
|
Packit |
0d464f |
_data->offset = dataWindow.min.x;
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
int tileRowSize = (dataWindow.max.x - dataWindow.min.x + 1) *
|
|
Packit |
0d464f |
_data->tFile->tileYSize();
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
for (FrameBuffer::ConstIterator k = frameBuffer.begin();
|
|
Packit |
0d464f |
k != frameBuffer.end();
|
|
Packit |
0d464f |
++k)
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
Slice s = k.slice();
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
switch (s.type)
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
case OPENEXR_IMF_INTERNAL_NAMESPACE::UINT:
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
_data->cachedBuffer->insert
|
|
Packit |
0d464f |
(k.name(),
|
|
Packit |
0d464f |
Slice (UINT,
|
|
Packit |
0d464f |
(char *)(new unsigned int[tileRowSize] -
|
|
Packit |
0d464f |
_data->offset),
|
|
Packit |
0d464f |
sizeof (unsigned int),
|
|
Packit |
0d464f |
sizeof (unsigned int) *
|
|
Packit |
0d464f |
_data->tFile->levelWidth(0),
|
|
Packit |
0d464f |
1, 1,
|
|
Packit |
0d464f |
s.fillValue,
|
|
Packit |
0d464f |
false, true));
|
|
Packit |
0d464f |
break;
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
case OPENEXR_IMF_INTERNAL_NAMESPACE::HALF:
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
_data->cachedBuffer->insert
|
|
Packit |
0d464f |
(k.name(),
|
|
Packit |
0d464f |
Slice (HALF,
|
|
Packit |
0d464f |
(char *)(new half[tileRowSize] -
|
|
Packit |
0d464f |
_data->offset),
|
|
Packit |
0d464f |
sizeof (half),
|
|
Packit |
0d464f |
sizeof (half) *
|
|
Packit |
0d464f |
_data->tFile->levelWidth(0),
|
|
Packit |
0d464f |
1, 1,
|
|
Packit |
0d464f |
s.fillValue,
|
|
Packit |
0d464f |
false, true));
|
|
Packit |
0d464f |
break;
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
case OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT:
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
_data->cachedBuffer->insert
|
|
Packit |
0d464f |
(k.name(),
|
|
Packit |
0d464f |
Slice (OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT,
|
|
Packit |
0d464f |
(char *)(new float[tileRowSize] -
|
|
Packit |
0d464f |
_data->offset),
|
|
Packit |
0d464f |
sizeof(float),
|
|
Packit |
0d464f |
sizeof(float) *
|
|
Packit |
0d464f |
_data->tFile->levelWidth(0),
|
|
Packit |
0d464f |
1, 1,
|
|
Packit |
0d464f |
s.fillValue,
|
|
Packit |
0d464f |
false, true));
|
|
Packit |
0d464f |
break;
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
default:
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
throw IEX_NAMESPACE::ArgExc ("Unknown pixel data type.");
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
_data->tFile->setFrameBuffer (*_data->cachedBuffer);
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
_data->tFileBuffer = frameBuffer;
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
else if(_data->compositor)
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
_data->compositor->setFrameBuffer(frameBuffer);
|
|
Packit |
0d464f |
}else {
|
|
Packit |
0d464f |
_data->sFile->setFrameBuffer(frameBuffer);
|
|
Packit |
0d464f |
_data->tFileBuffer = frameBuffer;
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
const FrameBuffer &
|
|
Packit |
0d464f |
InputFile::frameBuffer () const
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
if(_data->compositor)
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
return _data->compositor->frameBuffer();
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
else if(_data->isTiled)
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
Lock lock (*_data);
|
|
Packit |
0d464f |
return _data->tFileBuffer;
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
else
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
return _data->sFile->frameBuffer();
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
bool
|
|
Packit |
0d464f |
InputFile::isComplete () const
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
if (_data->dsFile)
|
|
Packit |
0d464f |
return _data->dsFile->isComplete();
|
|
Packit |
0d464f |
else if (_data->isTiled)
|
|
Packit |
0d464f |
return _data->tFile->isComplete();
|
|
Packit |
0d464f |
else
|
|
Packit |
0d464f |
return _data->sFile->isComplete();
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
bool
|
|
Packit |
0d464f |
InputFile::isOptimizationEnabled() const
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
if(_data->sFile)
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
return _data->sFile->isOptimizationEnabled();
|
|
Packit |
0d464f |
}else{
|
|
Packit |
0d464f |
return false;
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
void
|
|
Packit |
0d464f |
InputFile::readPixels (int scanLine1, int scanLine2)
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
if (_data->compositor)
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
_data->compositor->readPixels(scanLine1,scanLine2);
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
else if (_data->isTiled)
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
Lock lock (*_data);
|
|
Packit |
0d464f |
bufferedReadPixels (_data, scanLine1, scanLine2);
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
else
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
_data->sFile->readPixels (scanLine1, scanLine2);
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
void
|
|
Packit |
0d464f |
InputFile::readPixels (int scanLine)
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
readPixels (scanLine, scanLine);
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
void
|
|
Packit |
0d464f |
InputFile::rawPixelData (int firstScanLine,
|
|
Packit |
0d464f |
const char *&pixelData,
|
|
Packit |
0d464f |
int &pixelDataSize)
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
try
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
if (_data->dsFile)
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
throw IEX_NAMESPACE::ArgExc ("Tried to read a raw scanline "
|
|
Packit |
0d464f |
"from a deep image.");
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
else if (_data->isTiled)
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
throw IEX_NAMESPACE::ArgExc ("Tried to read a raw scanline "
|
|
Packit |
0d464f |
"from a tiled image.");
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
_data->sFile->rawPixelData (firstScanLine, pixelData, pixelDataSize);
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
catch (IEX_NAMESPACE::BaseExc &e)
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
REPLACE_EXC (e, "Error reading pixel data from image "
|
|
Packit |
0d464f |
"file \"" << fileName() << "\". " << e);
|
|
Packit |
0d464f |
throw;
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
void
|
|
Packit |
0d464f |
InputFile::rawTileData (int &dx, int &dy,
|
|
Packit |
0d464f |
int &lx, int &ly,
|
|
Packit |
0d464f |
const char *&pixelData,
|
|
Packit |
0d464f |
int &pixelDataSize)
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
try
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
if (!_data->isTiled)
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
throw IEX_NAMESPACE::ArgExc ("Tried to read a raw tile "
|
|
Packit |
0d464f |
"from a scanline-based image.");
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
_data->tFile->rawTileData (dx, dy, lx, ly, pixelData, pixelDataSize);
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
catch (IEX_NAMESPACE::BaseExc &e)
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
REPLACE_EXC (e, "Error reading tile data from image "
|
|
Packit |
0d464f |
"file \"" << fileName() << "\". " << e);
|
|
Packit |
0d464f |
throw;
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
TiledInputFile*
|
|
Packit |
0d464f |
InputFile::tFile()
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
if (!_data->isTiled)
|
|
Packit |
0d464f |
{
|
|
Packit |
0d464f |
throw IEX_NAMESPACE::ArgExc ("Cannot get a TiledInputFile pointer "
|
|
Packit |
0d464f |
"from an InputFile that is not tiled.");
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
return _data->tFile;
|
|
Packit |
0d464f |
}
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
|
|
Packit |
0d464f |
OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
|