Alien-FreeImage
view release on metacpan or search on metacpan
src/Source/OpenEXR/IlmImf/ImfDeepScanLineInputFile.cpp view on Meta::CPAN
int linesInBuffer; // number of scanlines each buffer
// holds
int partNumber; // part number
int numThreads; // number of threads
bool multiPartBackwardSupport; // if we are reading a multipart file using single file API
MultiPartInputFile* multiPartFile; // for multipart files opened as single part
bool memoryMapped; // if the stream is memory mapped
Array2D<unsigned int> sampleCount; // the number of samples
// in each pixel
Array<unsigned int> lineSampleCount; // the number of samples
// in each line
Array<bool> gotSampleCount; // for each scanline, indicating if
// we have got its sample count table
char* sampleCountSliceBase; // pointer to the start of
// the sample count array
int sampleCountXStride; // x stride of the sample count array
int sampleCountYStride; // y stride of the sample count array
bool frameBufferValid; // set by setFrameBuffer: excepts if readPixelSampleCounts if false
Array<char> sampleCountTableBuffer;
// the buffer for sample count table
Compressor* sampleCountTableComp;
// the decompressor for sample count table
int combinedSampleSize; // total size of all channels combined: used to sanity check sample table size
int maxSampleCountTableSize;
// the max size in bytes for a pixel
// sample count table
InputStreamMutex* _streamData;
bool _deleteStream;
Data (int numThreads);
~Data ();
inline LineBuffer * getLineBuffer (int number); // hash function from line
// buffer indices into our
// vector of line buffers
};
DeepScanLineInputFile::Data::Data (int numThreads):
partNumber(-1),
numThreads(numThreads),
multiPartBackwardSupport(false),
multiPartFile(NULL),
memoryMapped(false),
frameBufferValid(false),
_streamData(NULL),
_deleteStream(false)
{
//
// We need at least one lineBuffer, but if threading is used,
// to keep n threads busy we need 2*n lineBuffers
//
lineBuffers.resize (max (1, 2 * numThreads));
for (size_t i = 0; i < lineBuffers.size(); i++)
lineBuffers[i] = 0;
sampleCountTableComp = 0;
}
DeepScanLineInputFile::Data::~Data ()
{
for (size_t i = 0; i < lineBuffers.size(); i++)
if (lineBuffers[i] != 0)
delete lineBuffers[i];
for (size_t i = 0; i < slices.size(); i++)
delete slices[i];
if (sampleCountTableComp != 0)
delete sampleCountTableComp;
if (multiPartBackwardSupport)
delete multiPartFile;
}
inline LineBuffer *
DeepScanLineInputFile::Data::getLineBuffer (int lineBufferNumber)
{
return lineBuffers[lineBufferNumber % lineBuffers.size()];
}
namespace {
void
reconstructLineOffsets (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is,
LineOrder lineOrder,
vector<Int64> &lineOffsets)
{
Int64 position = is.tellg();
try
{
for (unsigned int i = 0; i < lineOffsets.size(); i++)
{
Int64 lineOffset = is.tellg();
int y;
OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::read <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (is, y);
Int64 packed_offset;
Int64 packed_sample;
OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::read <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (is, packed_offset);
OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::read <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (is, packed_sample);
//next is unpacked sample table size - skip this too
Xdr::skip <StreamIO> (is, packed_offset+packed_sample+8);
if (lineOrder == INCREASING_Y)
lineOffsets[i] = lineOffset;
else
lineOffsets[lineOffsets.size() - i - 1] = lineOffset;
}
}
catch (...)
{
//
// Suppress all exceptions. This functions is
// called only to reconstruct the line offset
// table for incomplete files, and exceptions
// are likely.
//
}
is.clear();
is.seekg (position);
}
void
readLineOffsets (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is,
LineOrder lineOrder,
vector<Int64> &lineOffsets,
bool &complete)
{
for (unsigned int i = 0; i < lineOffsets.size(); i++)
{
OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::read <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (is, lineOffsets[i]);
}
complete = true;
for (unsigned int i = 0; i < lineOffsets.size(); i++)
{
if (lineOffsets[i] <= 0)
{
//
// Invalid data in the line offset table mean that
// the file is probably incomplete (the table is
// the last thing written to the file). Either
// some process is still busy writing the file,
// or writing the file was aborted.
//
// We should still be able to read the existing
// parts of the file. In order to do this, we
// have to make a sequential scan over the scan
// line data to reconstruct the line offset table.
//
complete = false;
reconstructLineOffsets (is, lineOrder, lineOffsets);
break;
}
}
}
void
readPixelData (InputStreamMutex *streamData,
DeepScanLineInputFile::Data *ifd,
int minY,
char *&buffer,
Int64 &packedDataSize,
Int64 &unpackedDataSize)
{
//
// Read a single line buffer from the input file.
//
// If the input file is not memory-mapped, we copy the pixel data into
// into the array pointed to by buffer. If the file is memory-mapped,
// then we change where buffer points to instead of writing into the
// array (hence buffer needs to be a reference to a char *).
//
int lineBufferNumber = (minY - ifd->minY) / ifd->linesInBuffer;
Int64 lineOffset = ifd->lineOffsets[lineBufferNumber];
if (lineOffset == 0)
THROW (IEX_NAMESPACE::InputExc, "Scan line " << minY << " is missing.");
//
// Seek to the start of the scan line in the file,
// if necessary.
//
if (!isMultiPart(ifd->version))
{
if (ifd->nextLineBufferMinY != minY)
streamData->is->seekg (lineOffset);
}
else
{
//
// In a multi-part file, the file pointer may have been moved by
// other parts, so we have to ask tellg() where we are.
//
if (streamData->is->tellg() != ifd->lineOffsets[lineBufferNumber])
streamData->is->seekg (lineOffset);
}
( run in 1.326 second using v1.01-cache-2.11-cpan-39bf76dae61 )