From 76b5ea610dcb4eb830371b82d326fdc7e084d842 Mon Sep 17 00:00:00 2001 From: Peter Hillman Date: Wed, 7 Feb 2024 11:13:16 +1300 Subject: [PATCH] preliminary fix for multi-scanline deep formats Signed-off-by: Peter Hillman --- src/lib/OpenEXR/ImfDeepScanLineInputFile.cpp | 53 +-- src/lib/OpenEXR/ImfDeepScanLineOutputFile.cpp | 24 +- src/lib/OpenEXR/ImfMisc.cpp | 34 +- src/lib/OpenEXR/ImfMisc.h | 5 +- src/lib/OpenEXR/ImfZstdCompressor.cpp | 2 +- .../OpenEXRTest/testDeepScanLineBasic.cpp | 427 ++++++++++++------ 6 files changed, 351 insertions(+), 194 deletions(-) diff --git a/src/lib/OpenEXR/ImfDeepScanLineInputFile.cpp b/src/lib/OpenEXR/ImfDeepScanLineInputFile.cpp index f17d821c90..900fa07b83 100644 --- a/src/lib/OpenEXR/ImfDeepScanLineInputFile.cpp +++ b/src/lib/OpenEXR/ImfDeepScanLineInputFile.cpp @@ -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 bytesPerLine; // combined size of a line over all - // channels vector offsetInLineBuffer; // offset for each scanline in its // linebuffer vector slices; // info about channels in file @@ -201,7 +199,7 @@ struct DeepScanLineInputFile::Data Array2D sampleCount; // the number of samples // in each pixel unless bigFile is true - Array lineSampleCount; // the number of samples + vector lineSampleCount; // the number of samples // in each line Array gotSampleCount; // for each scanline, indicating if @@ -535,6 +533,8 @@ readSampleCountForLineBlock ( int lineBlockId, Array2D* sampleCountBuffer, int sampleCountMinY, + int sliceMinY, + int sliceMaxY, bool writeToSlice) { streamData->is->seekg (data->lineOffsets[lineBlockId]); @@ -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; } @@ -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; } // @@ -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) @@ -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"); } } @@ -1053,6 +1056,7 @@ newLineBufferTask ( lineBlockId, &lineBuffer->_tempCountBuffer, lineBuffer->minY, + 0,0, false); } @@ -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); @@ -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; @@ -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. @@ -2032,6 +2034,7 @@ DeepScanLineInputFile::readPixels ( vector offsetInLineBuffer; offsetInLineBufferTable ( bytesPerLine, + 1, minYInLineBuffer - _data->minY, maxYInLineBuffer - _data->minY, _data->linesInBuffer, @@ -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, diff --git a/src/lib/OpenEXR/ImfDeepScanLineOutputFile.cpp b/src/lib/OpenEXR/ImfDeepScanLineOutputFile.cpp index 915a59e5fc..84287f2e99 100644 --- a/src/lib/OpenEXR/ImfDeepScanLineOutputFile.cpp +++ b/src/lib/OpenEXR/ImfDeepScanLineOutputFile.cpp @@ -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 (ptr, count); + } } + // // If the next scanline isn't past the bounds of the lineBuffer // then we have partially filled the linebuffer, @@ -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 (ptr, count); - tableDataSize += sizeof (int); - } - } + + + uint64_t tableDataSize = sizeof(int)*(_ofd->maxX-_ofd->minX+1)*(_lineBuffer->maxY-_lineBuffer->minY+1); if (_lineBuffer->sampleCountTableCompressor) { diff --git a/src/lib/OpenEXR/ImfMisc.cpp b/src/lib/OpenEXR/ImfMisc.cpp index fbf035d4d1..1406d7be36 100644 --- a/src/lib/OpenEXR/ImfMisc.cpp +++ b/src/lib/OpenEXR/ImfMisc.cpp @@ -202,13 +202,14 @@ bytesPerDeepLineTable ( void offsetInLineBufferTable ( - const vector& bytesPerLine, + const vector& samplesPerLine, + size_t bytesPerSample, int scanline1, int scanline2, int linesInLineBuffer, vector& offsetInLineBuffer) { - offsetInLineBuffer.resize (bytesPerLine.size ()); + offsetInLineBuffer.resize (samplesPerLine.size ()); size_t offset = 0; @@ -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& bytesPerLine, - int linesInLineBuffer, - vector& offsetInLineBuffer) -{ - offsetInLineBufferTable ( - bytesPerLine, - 0, - bytesPerLine.size () - 1, - linesInLineBuffer, - offsetInLineBuffer); -} + void + offsetInLineBufferTable ( + const vector& samplesPerLine, + int linesInLineBuffer, + vector& offsetInLineBuffer) + { + offsetInLineBufferTable ( + samplesPerLine, + 1, + 0, + samplesPerLine.size () - 1, + linesInLineBuffer, + offsetInLineBuffer); + } int lineBufferMinY (int y, int minY, int linesInLineBuffer) diff --git a/src/lib/OpenEXR/ImfMisc.h b/src/lib/OpenEXR/ImfMisc.h index cb65ab6701..8e5b81ca05 100644 --- a/src/lib/OpenEXR/ImfMisc.h +++ b/src/lib/OpenEXR/ImfMisc.h @@ -123,7 +123,8 @@ size_t bytesPerDeepLineTable ( IMF_EXPORT void offsetInLineBufferTable ( - const std::vector& bytesPerLine, + const std::vector& samplesPerLine, + size_t bytesPerSample, int scanline1, int scanline2, int linesInLineBuffer, @@ -131,7 +132,7 @@ void offsetInLineBufferTable ( IMF_EXPORT void offsetInLineBufferTable ( - const std::vector& bytesPerLine, + const std::vector& samplesPerLine, int linesInLineBuffer, std::vector& offsetInLineBuffer); diff --git a/src/lib/OpenEXR/ImfZstdCompressor.cpp b/src/lib/OpenEXR/ImfZstdCompressor.cpp index d35a3deecd..e97cab1f81 100644 --- a/src/lib/OpenEXR/ImfZstdCompressor.cpp +++ b/src/lib/OpenEXR/ImfZstdCompressor.cpp @@ -143,4 +143,4 @@ ZstdCompressor::BLOSC_uncompress_impl_single_blob ( return size; } -OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT \ No newline at end of file +OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT diff --git a/src/test/OpenEXRTest/testDeepScanLineBasic.cpp b/src/test/OpenEXRTest/testDeepScanLineBasic.cpp index 61cfde844e..8d30a079d6 100644 --- a/src/test/OpenEXRTest/testDeepScanLineBasic.cpp +++ b/src/test/OpenEXRTest/testDeepScanLineBasic.cpp @@ -81,23 +81,46 @@ generateRandomFile ( header.setType (DEEPSCANLINE); + + // + // bulkWrite mode stores the entire image; + // otherwise only single scanline is written + // + int bufferHeight = bulkWrite ? height : 1; + Array> data (channelCount); for (int i = 0; i < channelCount; i++) - data[i].resizeErase (height, width); + data[i].resizeErase (bufferHeight, width); + + sampleCount.resizeErase(height,width); + + // + // for single scanline mode, a separate duplicate buffer with a single scanline + // + Array2D localSampleCount(1,width); - sampleCount.resizeErase (height, width); remove (filename.c_str ()); DeepScanLineOutputFile file (filename.c_str (), header, 8); DeepFrameBuffer frameBuffer; - frameBuffer.insertSampleCountSlice (Slice ( - IMF::UINT, // type // 7 - (char*) (&sampleCount[0][0] - dataWindow.min.x - dataWindow.min.y * width), // base - sizeof (unsigned int) * 1, // xStride - sizeof (unsigned int) * width)); // yStride - + if(bulkWrite) + { + frameBuffer.insertSampleCountSlice (Slice ( + IMF::UINT, // type // 7 + (char*) (&sampleCount[0][0] - dataWindow.min.x - dataWindow.min.y * width), // base + sizeof (unsigned int) * 1, // xStride + sizeof (unsigned int) * width)); // yStride + } + else + { + frameBuffer.insertSampleCountSlice (Slice ( + IMF::UINT, // type // 7 + (char*) (&localSampleCount[0][0] - dataWindow.min.x), // base of single scanline + sizeof (unsigned int) * 1, // xStride + 0)); // yStride is zero, since all scanlines are stored in the same place + } for (int i = 0; i < channelCount; i++) { PixelType type = NUM_PIXELTYPES; @@ -116,14 +139,28 @@ generateRandomFile ( int pointerSize = sizeof (char*); - frameBuffer.insert ( - str, // name // 6 - DeepSlice ( - type, // type // 7 - (char*) (&data[i][0][0] - dataWindow.min.x - dataWindow.min.y * width), // base // 8 - pointerSize * 1, // xStride// 9 - pointerSize * width, // yStride// 10 - sampleSize)); // sampleStride + if(bulkWrite) + { + frameBuffer.insert ( + str, // name // 6 + DeepSlice ( + type, // type // 7 + (char*) (&data[i][0][0] - dataWindow.min.x - dataWindow.min.y * width), // base // 8 + pointerSize * 1, // xStride// 9 + pointerSize * width, // yStride// 10 + sampleSize)); // sampleStride + } + else + { + frameBuffer.insert ( + str, // name // 6 + DeepSlice ( + type, // type // 7 + (char*) (&data[i][0][0] - dataWindow.min.x ), // base // 8 + pointerSize * 1, // xStride// 9 + 0, // yStride// 10 + sampleSize)); // sampleStride + } } file.setFrameBuffer (frameBuffer); @@ -184,11 +221,21 @@ generateRandomFile ( } file.writePixels (height); + + for (int i = 0; i < height; i++) + for (int j = 0; j < width; j++) + for (int k = 0; k < channelCount; k++) + { + if (channelTypes[k] == 0) delete[](unsigned int*) data[k][i][j]; + if (channelTypes[k] == 1) delete[](half*) data[k][i][j]; + if (channelTypes[k] == 2) delete[](float*) data[k][i][j]; + } + } else { cout << "per-line " << flush; - for (int i = 0; i < height; i++) + for (int row = 0; row < height; row++) { // // Fill in data at the last minute. @@ -199,8 +246,10 @@ generateRandomFile ( int samples = random_int (maxSamples); // big files write very sparse data for efficiency: most pixels have no samples - if (bigFile && (i % 63 != 0 || j % 63 != 0)) { samples = 0; } - sampleCount[i][j] = samples; + if (bigFile && (row % 63 != 0 || j % 63 != 0)) { samples = 0; } + + localSampleCount[0][j] = samples; + sampleCount[row][j] = samples; for (int k = 0; k < channelCount; k++) { @@ -208,42 +257,42 @@ generateRandomFile ( if (samples > 0) { if (channelTypes[k] == 0) - data[k][i][j] = new unsigned int[sampleCount[i][j]]; + data[k][0][j] = new unsigned int[localSampleCount[0][j]]; if (channelTypes[k] == 1) - data[k][i][j] = new half[sampleCount[i][j]]; + data[k][0][j] = new half[localSampleCount[0][j]]; if (channelTypes[k] == 2) - data[k][i][j] = new float[sampleCount[i][j]]; - for (unsigned int l = 0; l < sampleCount[i][j]; l++) + data[k][0][j] = new float[localSampleCount[0][j]]; + for (unsigned int l = 0; l < localSampleCount[0][j]; l++) { if (channelTypes[k] == 0) - ((unsigned int*) data[k][i][j])[l] = - (i * width + j) % 2049; + ((unsigned int*) data[k][0][j])[l] = + (row * width + j) % 2049; if (channelTypes[k] == 1) - ((half*) data[k][i][j])[l] = - (i * width + j) % 2049; + ((half*) data[k][0][j])[l] = + (row * width + j) % 2049; if (channelTypes[k] == 2) - ((float*) data[k][i][j])[l] = - (i * width + j) % 2049; + ((float*) data[k][0][j])[l] = + (row * width + j) % 2049; } } else { - data[k][i][j] = nullptr; + data[k][0][j] = nullptr; } } } file.writePixels (1); + for (int j = 0; j < width; j++) + for (int k = 0; k < channelCount; k++) + { + if (channelTypes[k] == 0) delete[](unsigned int*) data[k][0][j]; + if (channelTypes[k] == 1) delete[](half*) data[k][0][j]; + if (channelTypes[k] == 2) delete[](float*) data[k][0][j]; + } } } - for (int i = 0; i < height; i++) - for (int j = 0; j < width; j++) - for (int k = 0; k < channelCount; k++) - { - if (channelTypes[k] == 0) delete[](unsigned int*) data[k][i][j]; - if (channelTypes[k] == 1) delete[](half*) data[k][i][j]; - if (channelTypes[k] == 2) delete[](float*) data[k][i][j]; - } + } void @@ -277,23 +326,37 @@ readFile ( int width = dataWindow.max.x - dataWindow.min.x + 1; int height = dataWindow.max.y - dataWindow.min.y + 1; + int bufferHeight = bulkRead ? height : 1; + Array2D localSampleCount; - localSampleCount.resizeErase (height, width); + localSampleCount.resizeErase (bufferHeight, width); // also test filling channels. Generate up to 2 extra channels int fillChannels = random_int (3); Array> data (channelCount + fillChannels); for (int i = 0; i < channelCount + fillChannels; i++) - data[i].resizeErase (height, width); + data[i].resizeErase (bufferHeight, width); DeepFrameBuffer frameBuffer; - frameBuffer.insertSampleCountSlice (Slice ( - IMF::UINT, // type // 7 - (char*) (&localSampleCount[0][0] - dataWindow.min.x - dataWindow.min.y * width), // base // 8) - sizeof (unsigned int) * 1, // xStride// 9 - sizeof (unsigned int) * width)); // yStride// 10 + + if(bulkRead) + { + frameBuffer.insertSampleCountSlice (Slice ( + IMF::UINT, // type // 7 + (char*) (&localSampleCount[0][0] - dataWindow.min.x - dataWindow.min.y * width), // base // 8) + sizeof (unsigned int) * 1, // xStride// 9 + sizeof (unsigned int) * width)); // yStride// 10 + } + else + { + frameBuffer.insertSampleCountSlice (Slice ( + IMF::UINT, // type // 7 + (char*) (&localSampleCount[0][0] - dataWindow.min.x), // base // 8) + sizeof (unsigned int) * 1, // xStride// 9 + 0)); // yStride// 10 + } vector read_channel (channelCount); @@ -320,14 +383,28 @@ readFile ( int pointerSize = sizeof (char*); - frameBuffer.insert ( - str, // name // 6 - DeepSlice ( - type, // type // 7 - (char*) (&data[i][0][0] - dataWindow.min.x - dataWindow.min.y * width), // base // 8) - pointerSize * 1, // xStride// 9 - pointerSize * width, // yStride// 10 - sampleSize)); // sampleStride + if(bulkRead) + { + frameBuffer.insert ( + str, // name // 6 + DeepSlice ( + type, // type // 7 + (char*) (&data[i][0][0] - dataWindow.min.x - dataWindow.min.y * width), // base // 8) + pointerSize * 1, // xStride// 9 + pointerSize * width, // yStride// 10 + sampleSize)); // sampleStride + } + else + { + frameBuffer.insert ( + str, // name // 6 + DeepSlice ( + type, // type // 7 + (char*) (&data[i][0][0] - dataWindow.min.x ), // base // 8) + pointerSize * 1, // xStride// 9 + 0, // yStride// 10 + sampleSize)); // sampleStride + } channels_added++; } } @@ -346,14 +423,27 @@ readFile ( // generate channel names that aren't in file but (might) interleave with existing file ss << i << "fill"; string str = ss.str (); - frameBuffer.insert (str, // name // 6 - DeepSlice (type, // type // 7 - (char *) (&data[i+channelCount][0][0] - - dataWindow.min.x - - dataWindow.min.y * width), // base // 8) - pointerSize * 1, // xStride// 9 - pointerSize * width, // yStride// 10 - sampleSize)); // sampleStride + if(bulkRead) + { + frameBuffer.insert (str, // name // 6 + DeepSlice (type, // type // 7 + (char *) (&data[i+channelCount][0][0] + - dataWindow.min.x + - dataWindow.min.y * width), // base // 8) + pointerSize * 1, // xStride// 9 + pointerSize * width, // yStride// 10 + sampleSize)); // sampleStride + } + else + { + frameBuffer.insert (str, // name // 6 + DeepSlice (type, // type // 7 + (char *) (&data[i+channelCount][0][0] + - dataWindow.min.x), // base // 8) + pointerSize * 1, // xStride// 9 + 0, // yStride// 10 + sampleSize)); // sampleStride + } } file.setFrameBuffer (frameBuffer); @@ -395,120 +485,192 @@ readFile ( } file.readPixels (dataWindow.min.y, dataWindow.max.y); + + for (int i = 0; i < height; i++) + for (int j = 0; j < width; j++) + for (int k = 0; k < channelCount; k++) + { + if (!randomChannels || read_channel[k] == 1) + { + for (unsigned int l = 0; l < sampleCount[i][j]; l++) + { + + if (channelTypes[k] == 0) + { + unsigned int* value = + (unsigned int*) (data[k][i][j]); + + if (value[l] != + static_cast (i * width + j) % + 2049) + cout << j << ", " << i << " error, should be " + << (i * width + j) % 2049 << ", is " + << value[l] << endl + << flush; + assert ( + value[l] == + static_cast (i * width + j) % + 2049); + } + if (channelTypes[k] == 1) + { + half* value = (half*) (data[k][i][j]); + if (value[l] != (i * width + j) % 2049) + cout << j << ", " << i << " error, should be " + << (i * width + j) % 2049 << ", is " + << value[l] << endl + << flush; + assert ( + ((half*) (data[k][i][j]))[l] == + (i * width + j) % 2049); + } + if (channelTypes[k] == 2) + { + float* value = (float*) (data[k][i][j]); + if (value[l] != (i * width + j) % 2049) + cout << j << ", " << i << " error, should be " + << (i * width + j) % 2049 << ", is " + << value[l] << endl + << flush; + assert ( + ((float*) (data[k][i][j]))[l] == + (i * width + j) % 2049); + } + } + } + } + + for (int i = 0; i < height; i++) + for (int j = 0; j < width; j++) + { + for (int k = 0; k < channelCount; k++) + { + if (!randomChannels || read_channel[k] == 1) + { + if (channelTypes[k] == 0) + delete[](unsigned int*) data[k][i][j]; + if (channelTypes[k] == 1) delete[](half*) data[k][i][j]; + if (channelTypes[k] == 2) delete[](float*) data[k][i][j]; + } + } + for (int f = 0; f < fillChannels; ++f) + { + delete[](float*) data[f + channelCount][i][j]; + } + } } else { cout << "per-line " << flush; - for (int i = 0; i < dataWindow.max.y - dataWindow.min.y + 1; i++) + for (int row = 0; row < dataWindow.max.y - dataWindow.min.y + 1; row++) { - int y = i + dataWindow.min.y; + int y = row + dataWindow.min.y; file.readPixelSampleCounts (y); for (int j = 0; j < width; j++) - assert (localSampleCount[i][j] == sampleCount[i][j]); + assert (localSampleCount[0][j] == sampleCount[row][j]); for (int j = 0; j < width; j++) { for (int k = 0; k < channelCount; k++) { - if (localSampleCount[i][j] > 0 && + if (localSampleCount[0][j] > 0 && (!randomChannels || read_channel[k] == 1)) { if (channelTypes[k] == 0) - data[k][i][j] = - new unsigned int[localSampleCount[i][j]]; + data[k][0][j] = + new unsigned int[localSampleCount[0][j]]; if (channelTypes[k] == 1) - data[k][i][j] = new half[localSampleCount[i][j]]; + data[k][0][j] = new half[localSampleCount[0][j]]; if (channelTypes[k] == 2) - data[k][i][j] = new float[localSampleCount[i][j]]; + data[k][0][j] = new float[localSampleCount[0][j]]; } else { - data[k][i][j] = nullptr; + data[k][0][j] = nullptr; } } for (int f = 0; f < fillChannels; ++f) { - data[f + channelCount][i][j] = - new float[localSampleCount[i][j]]; + data[f + channelCount][0][j] = + new float[localSampleCount[0][j]]; } } file.readPixels (y); - } - } - - for (int i = 0; i < height; i++) - for (int j = 0; j < width; j++) - for (int k = 0; k < channelCount; k++) + for (int j = 0; j < width; j++) { - if (!randomChannels || read_channel[k] == 1) + for (int k = 0; k < channelCount; k++) { - for (unsigned int l = 0; l < sampleCount[i][j]; l++) + if (!randomChannels || read_channel[k] == 1) { - if (channelTypes[k] == 0) - { - unsigned int* value = - (unsigned int*) (data[k][i][j]); - if (value[l] != - static_cast (i * width + j) % - 2049) - cout << j << ", " << i << " error, should be " - << (i * width + j) % 2049 << ", is " - << value[l] << endl - << flush; - assert ( - value[l] == - static_cast (i * width + j) % - 2049); - } - if (channelTypes[k] == 1) + for (unsigned int l = 0; l < sampleCount[row][j]; l++) { - half* value = (half*) (data[k][i][j]); - if (value[l] != (i * width + j) % 2049) - cout << j << ", " << i << " error, should be " - << (i * width + j) % 2049 << ", is " - << value[l] << endl - << flush; - assert ( - ((half*) (data[k][i][j]))[l] == - (i * width + j) % 2049); - } - if (channelTypes[k] == 2) - { - float* value = (float*) (data[k][i][j]); - if (value[l] != (i * width + j) % 2049) - cout << j << ", " << i << " error, should be " - << (i * width + j) % 2049 << ", is " - << value[l] << endl - << flush; - assert ( - ((float*) (data[k][i][j]))[l] == - (i * width + j) % 2049); + if (channelTypes[k] == 0) + { + unsigned int* value = + (unsigned int*) (data[k][0][j]); + if (value[l] != + static_cast (row * width + j) % + 2049) + cout << j << ", " << row << " error, should be " + << (row * width + j) % 2049 << ", is " + << value[l] << endl + << flush; + assert ( + value[l] == + static_cast (row * width + j) % + 2049); + } + if (channelTypes[k] == 1) + { + half* value = (half*) (data[k][0][j]); + if (value[l] != (row * width + j) % 2049) + cout << j << ", " << row << " error, should be " + << (row * width + j) % 2049 << ", is " + << value[l] << endl + << flush; + assert ( + ((half*) (data[k][0][j]))[l] == + (row * width + j) % 2049); + } + if (channelTypes[k] == 2) + { + float* value = (float*) (data[k][0][j]); + if (value[l] != (row * width + j) % 2049) + cout << j << ", " << row << " error, should be " + << (row * width + j) % 2049 << ", is " + << value[l] << endl + << flush; + assert ( + ((float*) (data[k][0][j]))[l] == + (row * width + j) % 2049); + } } } } } - for (int i = 0; i < height; i++) - for (int j = 0; j < width; j++) - { - for (int k = 0; k < channelCount; k++) + for (int j = 0; j < width; j++) { - if (!randomChannels || read_channel[k] == 1) + for (int k = 0; k < channelCount; k++) { - if (channelTypes[k] == 0) - delete[](unsigned int*) data[k][i][j]; - if (channelTypes[k] == 1) delete[](half*) data[k][i][j]; - if (channelTypes[k] == 2) delete[](float*) data[k][i][j]; + if (!randomChannels || read_channel[k] == 1) + { + if (channelTypes[k] == 0) + delete[](unsigned int*) data[k][0][j]; + if (channelTypes[k] == 1) delete[](half*) data[k][0][j]; + if (channelTypes[k] == 2) delete[](float*) data[k][0][j]; + } + } + for (int f = 0; f < fillChannels; ++f) + { + delete[](float*) data[f + channelCount][0][j]; } - } - for (int f = 0; f < fillChannels; ++f) - { - delete[](float*) data[f + channelCount][i][j]; } } + } } void @@ -527,13 +689,14 @@ readWriteTest ( for (int i = 0; i < testTimes; i++) { - int compressionIndex = i % 3; + int compressionIndex = i % 4; Compression compression; switch (compressionIndex) { case 0: compression = NO_COMPRESSION; break; case 1: compression = RLE_COMPRESSION; break; case 2: compression = ZIPS_COMPRESSION; break; + case 3: compression = ZSTD_COMPRESSION; break; } generateRandomFile (