Skip to content

Commit

Permalink
preliminary fix for multi-scanline deep formats
Browse files Browse the repository at this point in the history
Signed-off-by: Peter Hillman <[email protected]>
  • Loading branch information
peterhillman committed Feb 6, 2024
1 parent 057dd80 commit 76b5ea6
Show file tree
Hide file tree
Showing 6 changed files with 351 additions and 194 deletions.
53 changes: 22 additions & 31 deletions src/lib/OpenEXR/ImfDeepScanLineInputFile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -176,8 +176,6 @@ struct DeepScanLineInputFile::Data
bool fileIsComplete; // True if no scanlines are missing
// in the file
int nextLineBufferMinY; // minimum y of the next linebuffer
vector<size_t> bytesPerLine; // combined size of a line over all
// channels
vector<size_t> offsetInLineBuffer; // offset for each scanline in its
// linebuffer
vector<InSliceInfo*> slices; // info about channels in file
Expand All @@ -201,7 +199,7 @@ struct DeepScanLineInputFile::Data
Array2D<unsigned int> sampleCount; // the number of samples
// in each pixel unless bigFile is true

Array<unsigned int> lineSampleCount; // the number of samples
vector<size_t> lineSampleCount; // the number of samples
// in each line

Array<bool> gotSampleCount; // for each scanline, indicating if
Expand Down Expand Up @@ -535,6 +533,8 @@ readSampleCountForLineBlock (
int lineBlockId,
Array2D<unsigned int>* sampleCountBuffer,
int sampleCountMinY,
int sliceMinY,
int sliceMaxY,
bool writeToSlice)
{
streamData->is->seekg (data->lineOffsets[lineBlockId]);
Expand Down Expand Up @@ -695,7 +695,7 @@ readSampleCountForLineBlock (
//
// Store the data in external slice
//
if (writeToSlice)
if (writeToSlice && y>=sliceMinY && y<=sliceMaxY)
{
sampleCount (base, xStride, yStride, x, y) = count;
}
Expand Down Expand Up @@ -797,10 +797,13 @@ LineBufferTask::execute ()
uint64_t uncompressedSize = 0;
int maxY = min (_lineBuffer->maxY, _ifd->maxY);

//
// NOTE - assumes sampling on all channels is (1,1), which is required elsewhere
//
for (int i = _lineBuffer->minY - _ifd->minY; i <= maxY - _ifd->minY;
++i)
{
uncompressedSize += (int) _ifd->bytesPerLine[i];
uncompressedSize += (int) _ifd->lineSampleCount[i]*_ifd->combinedSampleSize;
}

//
Expand All @@ -810,15 +813,15 @@ LineBufferTask::execute ()
//

if (_lineBuffer->compressor != 0) delete _lineBuffer->compressor;
uint64_t maxBytesPerLine = 0;
uint64_t maxSamplesPerLine = 0;
for (int i = _lineBuffer->minY - _ifd->minY; i <= maxY - _ifd->minY;
++i)
{
if (_ifd->bytesPerLine[i] > maxBytesPerLine)
maxBytesPerLine = _ifd->bytesPerLine[i];
if (_ifd->lineSampleCount[i] > maxSamplesPerLine)
maxSamplesPerLine = _ifd->lineSampleCount[i];
}
_lineBuffer->compressor = newCompressor (
_ifd->header.compression (), maxBytesPerLine, _ifd->header);
_ifd->header.compression (), maxSamplesPerLine*_ifd->combinedSampleSize, _ifd->header);

if (_lineBuffer->compressor &&
_lineBuffer->packedDataSize < uncompressedSize)
Expand Down Expand Up @@ -852,12 +855,12 @@ LineBufferTask::execute ()
_lineBuffer->format = Compressor::XDR;
_lineBuffer->uncompressedData = _lineBuffer->buffer;

if (_lineBuffer->packedDataSize != maxBytesPerLine)
if (_lineBuffer->packedDataSize != maxSamplesPerLine*_ifd->combinedSampleSize)
{
THROW (
IEX_NAMESPACE::InputExc,
"Incorrect size for uncompressed data. Expected "
<< maxBytesPerLine << " got "
<< maxSamplesPerLine*_ifd->combinedSampleSize << " got "
<< _lineBuffer->packedDataSize << " bytes");
}
}
Expand Down Expand Up @@ -1053,6 +1056,7 @@ newLineBufferTask (
lineBlockId,
&lineBuffer->_tempCountBuffer,
lineBuffer->minY,
0,0,
false);
}

Expand Down Expand Up @@ -1162,7 +1166,7 @@ DeepScanLineInputFile::initialize (const Header& header)
_data->sampleCount.resizeErase (
_data->maxY - _data->minY + 1, _data->maxX - _data->minX + 1);
}
_data->lineSampleCount.resizeErase (_data->maxY - _data->minY + 1);
_data->lineSampleCount.resize (_data->maxY - _data->minY + 1);

Compressor* compressor =
newCompressor (_data->header.compression (), 0, _data->header);
Expand Down Expand Up @@ -1211,8 +1215,6 @@ DeepScanLineInputFile::initialize (const Header& header)
_data->maxSampleCountTableSize,
_data->header);

_data->bytesPerLine.resize (_data->maxY - _data->minY + 1);

const ChannelList& c = header.channels ();

_data->combinedSampleSize = 0;
Expand Down Expand Up @@ -1652,8 +1654,8 @@ DeepScanLineInputFile::setFrameBuffer (const DeepFrameBuffer& frameBuffer)

for (long i = 0; i < _data->gotSampleCount.size (); i++)
_data->gotSampleCount[i] = false;
for (size_t i = 0; i < _data->bytesPerLine.size (); i++)
_data->bytesPerLine[i] = 0;
for (size_t i = 0; i < _data->lineSampleCount.size (); i++)
_data->lineSampleCount[i] = 0;

//
// Store the new frame buffer.
Expand Down Expand Up @@ -2032,6 +2034,7 @@ DeepScanLineInputFile::readPixels (
vector<size_t> offsetInLineBuffer;
offsetInLineBufferTable (
bytesPerLine,
1,
minYInLineBuffer - _data->minY,
maxYInLineBuffer - _data->minY,
_data->linesInBuffer,
Expand Down Expand Up @@ -2279,32 +2282,20 @@ DeepScanLineInputFile::readPixelSampleCounts (int scanline1, int scanline2)
lineBlockId,
_data->bigFile ? nullptr : &_data->sampleCount,
_data->minY,
true);
scanLineMin,scanLineMax,true);

int minYInLineBuffer =
lineBlockId * _data->linesInBuffer + _data->minY;
int maxYInLineBuffer = min (
minYInLineBuffer + _data->linesInBuffer - 1, _data->maxY);

//
// For each line within the block, get the count of bytes.
//

bytesPerDeepLineTable (
_data->header,
minYInLineBuffer,
maxYInLineBuffer,
_data->sampleCountSliceBase,
_data->sampleCountXStride,
_data->sampleCountYStride,
_data->bytesPerLine);

//
// For each scanline within the block, get the offset.
//

offsetInLineBufferTable (
_data->bytesPerLine,
_data->lineSampleCount,
_data->combinedSampleSize,
minYInLineBuffer - _data->minY,
maxYInLineBuffer - _data->minY,
_data->linesInBuffer,
Expand Down
24 changes: 12 additions & 12 deletions src/lib/OpenEXR/ImfDeepScanLineOutputFile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -646,8 +646,17 @@ LineBufferTask::execute ()
slice.type);
}
}

char* ptr = _lineBuffer->sampleCountTableBuffer+(_ofd->maxX-_ofd->minX+1)*sizeof(int)*(y - _lineBuffer->minY);
int count = 0;
for (int j = _ofd->minX; j <= _ofd->maxX; j++)
{
count += _ofd->getSampleCount (j, y);
Xdr::write<CharPtrIO> (ptr, count);
}
}


//
// If the next scanline isn't past the bounds of the lineBuffer
// then we have partially filled the linebuffer,
Expand Down Expand Up @@ -691,18 +700,9 @@ LineBufferTask::execute ()
// Compress the pixel sample count table.
//

char* ptr = _lineBuffer->sampleCountTableBuffer;
uint64_t tableDataSize = 0;
for (int i = _lineBuffer->minY; i <= _lineBuffer->maxY; i++)
{
int count = 0;
for (int j = _ofd->minX; j <= _ofd->maxX; j++)
{
count += _ofd->getSampleCount (j, i);
Xdr::write<CharPtrIO> (ptr, count);
tableDataSize += sizeof (int);
}
}


uint64_t tableDataSize = sizeof(int)*(_ofd->maxX-_ofd->minX+1)*(_lineBuffer->maxY-_lineBuffer->minY+1);

if (_lineBuffer->sampleCountTableCompressor)
{
Expand Down
34 changes: 18 additions & 16 deletions src/lib/OpenEXR/ImfMisc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -202,13 +202,14 @@ bytesPerDeepLineTable (

void
offsetInLineBufferTable (
const vector<size_t>& bytesPerLine,
const vector<size_t>& samplesPerLine,
size_t bytesPerSample,
int scanline1,
int scanline2,
int linesInLineBuffer,
vector<size_t>& offsetInLineBuffer)
{
offsetInLineBuffer.resize (bytesPerLine.size ());
offsetInLineBuffer.resize (samplesPerLine.size ());

size_t offset = 0;

Expand All @@ -217,23 +218,24 @@ offsetInLineBufferTable (
if (i % linesInLineBuffer == 0) offset = 0;

offsetInLineBuffer[i] = offset;
offset += bytesPerLine[i];
offset += samplesPerLine[i]*bytesPerSample;
}
}

void
offsetInLineBufferTable (
const vector<size_t>& bytesPerLine,
int linesInLineBuffer,
vector<size_t>& offsetInLineBuffer)
{
offsetInLineBufferTable (
bytesPerLine,
0,
bytesPerLine.size () - 1,
linesInLineBuffer,
offsetInLineBuffer);
}
void
offsetInLineBufferTable (
const vector<size_t>& samplesPerLine,
int linesInLineBuffer,
vector<size_t>& offsetInLineBuffer)
{
offsetInLineBufferTable (
samplesPerLine,
1,
0,
samplesPerLine.size () - 1,
linesInLineBuffer,
offsetInLineBuffer);
}

int
lineBufferMinY (int y, int minY, int linesInLineBuffer)
Expand Down
5 changes: 3 additions & 2 deletions src/lib/OpenEXR/ImfMisc.h
Original file line number Diff line number Diff line change
Expand Up @@ -123,15 +123,16 @@ size_t bytesPerDeepLineTable (

IMF_EXPORT
void offsetInLineBufferTable (
const std::vector<size_t>& bytesPerLine,
const std::vector<size_t>& samplesPerLine,
size_t bytesPerSample,
int scanline1,
int scanline2,
int linesInLineBuffer,
std::vector<size_t>& offsetInLineBuffer);

IMF_EXPORT
void offsetInLineBufferTable (
const std::vector<size_t>& bytesPerLine,
const std::vector<size_t>& samplesPerLine,
int linesInLineBuffer,
std::vector<size_t>& offsetInLineBuffer);

Expand Down
2 changes: 1 addition & 1 deletion src/lib/OpenEXR/ImfZstdCompressor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -143,4 +143,4 @@ ZstdCompressor::BLOSC_uncompress_impl_single_blob (
return size;
}

OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
Loading

0 comments on commit 76b5ea6

Please sign in to comment.