From 3c05eacda70e3ac00ca45287aa4c8de7262a0673 Mon Sep 17 00:00:00 2001 From: peterhillman Date: Tue, 8 Sep 2020 10:03:03 +1200 Subject: [PATCH] Address issues reported by Undefined Behavior Sanitizer running IlmImfTest (#828) * add join() to IlmThread for avoiding use-after-free race condition Signed-off-by: Peter Hillman * Use intptr_t in pointer math with negatives (pointer overflow behavior undefined) Signed-off-by: Peter Hillman * fix undefined behavior reading non-aligned 32/64 bit ints Signed-off-by: Peter Hillman * fix undefined behavior warnings in IlmImfTest Signed-off-by: Peter Hillman * cleaner pointer casting/typo fix Signed-off-by: Peter Hillman --- IlmImf/ImfCompositeDeepScanLine.cpp | 9 +++--- IlmImf/ImfDeepScanLineInputFile.cpp | 28 +++++++++++++---- IlmImf/ImfDeepScanLineOutputFile.cpp | 30 +++++++++++++++++-- IlmImf/ImfFrameBuffer.cpp | 4 +-- IlmImf/ImfInputFile.cpp | 13 ++++---- IlmImf/ImfMisc.cpp | 9 ++++-- IlmImf/ImfOutputFile.cpp | 15 ++++++---- IlmImf/ImfRgbaFile.cpp | 24 ++++++++++----- IlmImf/ImfScanLineInputFile.cpp | 19 +++++++----- IlmImf/ImfTiledInputFile.cpp | 5 ++-- IlmImf/ImfTiledOutputFile.cpp | 5 ++-- IlmImf/ImfTiledRgbaFile.cpp | 13 ++++++-- .../IlmImfTest/testCompositeDeepScanLine.cpp | 3 +- IlmImfTest/testDwaCompressorSimd.cpp | 3 +- IlmImfTest/testMultiPartApi.cpp | 15 ++-------- IlmImfTest/testMultiPartThreading.cpp | 16 ++-------- .../testOptimizedInterleavePatterns.cpp | 12 ++++++-- IlmImfTest/testPreviewImage.cpp | 2 +- IlmImfTest/testSharedFrameBuffer.cpp | 23 ++++++++------ 25 files changed, 207 insertions(+), 93 deletions(-) diff --git a/IlmImf/ImfCompositeDeepScanLine.cpp b/IlmImf/ImfCompositeDeepScanLine.cpp index fac7fc432..1572c069e 100644 --- a/IlmImf/ImfCompositeDeepScanLine.cpp +++ b/IlmImf/ImfCompositeDeepScanLine.cpp @@ -323,7 +323,6 @@ class LineCompositeTask : public Task }; - void composite_line(int y, int start, @@ -386,16 +385,18 @@ composite_line(int y, { float value = output_pixel[ _Data->_bufferMap[channel_number] ]; // value to write - + intptr_t base = reinterpret_cast(it.slice().base); // cast to half float if necessary if(it.slice().type==OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT) { - * (float *)(it.slice().base + y*it.slice().yStride + x*it.slice().xStride) = value; + float* ptr = reinterpret_cast(base + y*it.slice().yStride + x*it.slice().xStride); + *ptr = value; } else if(it.slice().type==HALF) { - * (half *)(it.slice().base + y*it.slice().yStride + x*it.slice().xStride) = half(value); + half* ptr = reinterpret_cast(base + y*it.slice().yStride + x*it.slice().xStride); + *ptr = half(value); } channel_number++; diff --git a/IlmImf/ImfDeepScanLineInputFile.cpp b/IlmImf/ImfDeepScanLineInputFile.cpp index 0844d2349..c39bd225a 100644 --- a/IlmImf/ImfDeepScanLineInputFile.cpp +++ b/IlmImf/ImfDeepScanLineInputFile.cpp @@ -1425,6 +1425,20 @@ DeepScanLineInputFile::readPixels (int scanLine) } +namespace +{ +struct I64Bytes +{ + uint8_t b[8]; +}; + + +union bytesOrInt64 +{ + I64Bytes b; + Int64 i; +}; +} void DeepScanLineInputFile::rawPixelData (int firstScanLine, char *pixelData, @@ -1507,12 +1521,16 @@ DeepScanLineInputFile::rawPixelData (int firstScanLine, // copy the values we have read into the output block *(int *) pixelData = yInFile; - *(Int64 *) (pixelData+4) =sampleCountTableSize; - *(Int64 *) (pixelData+12) = packedDataSize; - + bytesOrInt64 tmp; + tmp.i=sampleCountTableSize; + memcpy(pixelData+4,&tmp.b,8); + tmp.i = packedDataSize; + memcpy(pixelData+12,&tmp.b,8); + // didn't read the unpackedsize - do that now - Xdr::read (*_data->_streamData->is, *(Int64 *) (pixelData+20)); - + Xdr::read (*_data->_streamData->is,tmp.i); + memcpy(pixelData+20,&tmp.b,8); + // read the actual data _data->_streamData->is->read(pixelData+28, sampleCountTableSize+packedDataSize); diff --git a/IlmImf/ImfDeepScanLineOutputFile.cpp b/IlmImf/ImfDeepScanLineOutputFile.cpp index 6e302440b..d455df9e9 100644 --- a/IlmImf/ImfDeepScanLineOutputFile.cpp +++ b/IlmImf/ImfDeepScanLineOutputFile.cpp @@ -1411,6 +1411,23 @@ DeepScanLineOutputFile::copyPixels (DeepScanLineInputPart &in) copyPixels(*in.file); } + +// helper structure to read Int64 from non 8 byte aligned addresses +namespace +{ +struct I64Bytes +{ + uint8_t b[8]; +}; + + +union bytesOrInt64 +{ + I64Bytes b; + Int64 i; +}; +} + void DeepScanLineOutputFile::copyPixels (DeepScanLineInputFile &in) { @@ -1487,9 +1504,16 @@ DeepScanLineOutputFile::copyPixels (DeepScanLineInputFile &in) // extract header from block to pass to writePixelData - Int64 packedSampleCountSize = *(Int64 *) (&data[4]); - Int64 packedDataSize = *(Int64 *) (&data[12]); - Int64 unpackedDataSize = *(Int64 *) (&data[20]); + bytesOrInt64 tmp; + memcpy(&tmp.b,&data[4],8); + Int64 packedSampleCountSize = tmp.i; + + memcpy(&tmp.b,&data[12],8); + Int64 packedDataSize = tmp.i; + + memcpy(&tmp.b,&data[20],8); + Int64 unpackedDataSize = tmp.i; + const char * sampleCountTable = &data[0]+28; const char * pixelData = sampleCountTable + packedSampleCountSize; diff --git a/IlmImf/ImfFrameBuffer.cpp b/IlmImf/ImfFrameBuffer.cpp index a11ab4e63..a6b26b2a4 100644 --- a/IlmImf/ImfFrameBuffer.cpp +++ b/IlmImf/ImfFrameBuffer.cpp @@ -89,7 +89,7 @@ Slice::Make ( bool xTileCoords, bool yTileCoords) { - char* base = reinterpret_cast (const_cast (ptr)); + intptr_t base = reinterpret_cast (const_cast (ptr)); if (xStride == 0) { switch (type) @@ -117,7 +117,7 @@ Slice::Make ( return Slice ( type, - base - offx - offy, + reinterpret_cast(base - offx - offy), xStride, yStride, xSampling, diff --git a/IlmImf/ImfInputFile.cpp b/IlmImf/ImfInputFile.cpp index 8695c65bf..6bcb451ec 100644 --- a/IlmImf/ImfInputFile.cpp +++ b/IlmImf/ImfInputFile.cpp @@ -308,6 +308,10 @@ bufferedReadPixels (InputFile::Data* ifd, int scanLine1, int scanLine2) while (modp (yStart, toSlice.ySampling) != 0) ++yStart; + + intptr_t fromBase = reinterpret_cast(fromSlice.base); + intptr_t toBase = reinterpret_cast(toSlice.base); + for (int y = yStart; y <= maxYThisRow; y += toSlice.ySampling) @@ -316,14 +320,13 @@ bufferedReadPixels (InputFile::Data* ifd, int scanLine1, int scanLine2) // Set the pointers to the start of the y scanline in // this row of tiles // - - fromPtr = fromSlice.base + + fromPtr = reinterpret_cast (fromBase + (y - tileRange.min.y) * fromSlice.yStride + - xStart * fromSlice.xStride; + xStart * fromSlice.xStride); - toPtr = toSlice.base + + toPtr = reinterpret_cast (toBase + divp (y, toSlice.ySampling) * toSlice.yStride + - divp (xStart, toSlice.xSampling) * toSlice.xStride; + divp (xStart, toSlice.xSampling) * toSlice.xStride); // // Copy all pixels for the scanline in this row of tiles diff --git a/IlmImf/ImfMisc.cpp b/IlmImf/ImfMisc.cpp index b397b9f98..bae4622b7 100644 --- a/IlmImf/ImfMisc.cpp +++ b/IlmImf/ImfMisc.cpp @@ -1390,9 +1390,10 @@ namespace // struct FBytes { uint8_t b[4]; }; -union bytesOrFloat { +union bytesUintOrFloat { FBytes b; float f; + unsigned int u; } ; } @@ -1408,7 +1409,9 @@ convertInPlace (char *& writePtr, for (size_t j = 0; j < numPixels; ++j) { - Xdr::write (writePtr, *(const unsigned int *) readPtr); + union bytesUintOrFloat tmp; + tmp.b = * reinterpret_cast( readPtr ); + Xdr::write (writePtr, tmp.u); readPtr += sizeof(unsigned int); } break; @@ -1426,7 +1429,7 @@ convertInPlace (char *& writePtr, for (size_t j = 0; j < numPixels; ++j) { - union bytesOrFloat tmp; + union bytesUintOrFloat tmp; tmp.b = * reinterpret_cast( readPtr ); Xdr::write (writePtr, tmp.f); readPtr += sizeof(float); diff --git a/IlmImf/ImfOutputFile.cpp b/IlmImf/ImfOutputFile.cpp index d0e34988e..899303ea6 100644 --- a/IlmImf/ImfOutputFile.cpp +++ b/IlmImf/ImfOutputFile.cpp @@ -558,13 +558,18 @@ LineBufferTask::execute () // If necessary, convert the pixel data to Xdr format. // Then store the pixel data in _ofd->lineBuffer. // - - const char *linePtr = slice.base + - divp (y, slice.ySampling) * + // slice.base may be 'negative' but + // pointer arithmetic is not allowed to overflow, so + // perform computation with the non-pointer 'intptr_t' instead + // + intptr_t base = reinterpret_cast(slice.base); + intptr_t linePtr = base + divp (y, slice.ySampling) * slice.yStride; - const char *readPtr = linePtr + dMinX * slice.xStride; - const char *endPtr = linePtr + dMaxX * slice.xStride; + const char *readPtr = reinterpret_cast(linePtr + + dMinX * slice.xStride); + const char *endPtr = reinterpret_cast(linePtr + + dMaxX * slice.xStride); copyFromFrameBuffer (writePtr, readPtr, endPtr, slice.xStride, _ofd->format, diff --git a/IlmImf/ImfRgbaFile.cpp b/IlmImf/ImfRgbaFile.cpp index 68fa51cb5..9e781abeb 100644 --- a/IlmImf/ImfRgbaFile.cpp +++ b/IlmImf/ImfRgbaFile.cpp @@ -369,6 +369,7 @@ RgbaOutputFile::ToYca::writePixels (int numScanLines) "\"" << _outputFile.fileName() << "\"."); } + intptr_t base = reinterpret_cast(_fbBase); if (_writeY && !_writeC) { // @@ -385,8 +386,9 @@ RgbaOutputFile::ToYca::writePixels (int numScanLines) for (int j = 0; j < _width; ++j) { - _tmpBuf[j] = _fbBase[_fbYStride * _currentScanLine + - _fbXStride * (j + _xMin)]; + _tmpBuf[j] = *reinterpret_cast(base + sizeof(Rgba)* + (_fbYStride * _currentScanLine + + _fbXStride * (j + _xMin))); } // @@ -418,10 +420,13 @@ RgbaOutputFile::ToYca::writePixels (int numScanLines) // frame buffer into _tmpBuf. // + intptr_t base = reinterpret_cast(_fbBase); + for (int j = 0; j < _width; ++j) { - _tmpBuf[j + N2] = _fbBase[_fbYStride * _currentScanLine + - _fbXStride * (j + _xMin)]; + const Rgba* ptr = reinterpret_cast(base+sizeof(Rgba)* + (_fbYStride * _currentScanLine + _fbXStride * (j + _xMin)) ); + _tmpBuf[j + N2] = *ptr; } // @@ -1081,9 +1086,13 @@ RgbaInputFile::FromYca::readPixels (int scanLine) fixSaturation (_yw, _width, _buf2, _tmpBuf); - for (int i = 0; i < _width; ++i) - _fbBase[_fbYStride * scanLine + _fbXStride * (i + _xMin)] = _tmpBuf[i]; + intptr_t base = reinterpret_cast(_fbBase); + for (int i = 0; i < _width; ++i) + { + Rgba* ptr = reinterpret_cast(base + sizeof(Rgba)*(_fbYStride * scanLine + _fbXStride * (i + _xMin))); + *ptr = _tmpBuf[i]; + } _currentScanLine = scanLine; } @@ -1335,10 +1344,11 @@ RgbaInputFile::readPixels (int scanLine1, int scanLine2) // const Slice* s = _inputFile->frameBuffer().findSlice(_channelNamePrefix + "Y"); Box2i dataWindow = _inputFile->header().dataWindow(); + intptr_t base = reinterpret_cast(s->base); for( int scanLine = scanLine1 ; scanLine <= scanLine2 ; scanLine++ ) { - char* rowBase = s->base + scanLine*s->yStride; + intptr_t rowBase = base + scanLine*s->yStride; for(int x = dataWindow.min.x ; x <= dataWindow.max.x ; ++x ) { Rgba* pixel = reinterpret_cast(rowBase+x*s->xStride); diff --git a/IlmImf/ImfScanLineInputFile.cpp b/IlmImf/ImfScanLineInputFile.cpp index b020cb9bb..a0e9a3678 100644 --- a/IlmImf/ImfScanLineInputFile.cpp +++ b/IlmImf/ImfScanLineInputFile.cpp @@ -636,12 +636,14 @@ LineBufferTask::execute () // The frame buffer contains a slice for this channel. // - char *linePtr = slice.base + + intptr_t base = reinterpret_cast(slice.base); + + intptr_t linePtr = base + intptr_t( divp (y, slice.ySampling) ) * intptr_t( slice.yStride ); - char *writePtr = linePtr + intptr_t( dMinX ) * intptr_t( slice.xStride ); - char *endPtr = linePtr + intptr_t( dMaxX ) * intptr_t( slice.xStride ); + char *writePtr = reinterpret_cast (linePtr + intptr_t( dMinX ) * intptr_t( slice.xStride )); + char *endPtr = reinterpret_cast (linePtr + intptr_t( dMaxX ) * intptr_t( slice.xStride )); copyIntoFrameBuffer (readPtr, writePtr, endPtr, slice.xStride, slice.fill, @@ -794,20 +796,21 @@ void LineBufferTaskIIF::getWritePointer outWritePointerRight = 0; } - const char* linePtr1 = firstSlice.base + + intptr_t base = reinterpret_cast(firstSlice.base); + + intptr_t linePtr1 = (base + divp (y, firstSlice.ySampling) * - firstSlice.yStride; + firstSlice.yStride); int dMinX1 = divp (_ifd->minX, firstSlice.xSampling); int dMaxX1 = divp (_ifd->maxX, firstSlice.xSampling); // Construct the writePtr so that we start writing at // linePtr + Min offset in the line. - outWritePointerRight = (unsigned short*)(linePtr1 + + outWritePointerRight = reinterpret_cast(linePtr1 + dMinX1 * firstSlice.xStride ); - size_t bytesToCopy = ((linePtr1 + dMaxX1 * firstSlice.xStride ) - - (linePtr1 + dMinX1 * firstSlice.xStride )) + 2; + size_t bytesToCopy = ((dMaxX1 * firstSlice.xStride ) - (dMinX1 * firstSlice.xStride )) + 2; size_t shortsToCopy = bytesToCopy / sizeOfSingleValue; size_t pixelsToCopy = (shortsToCopy / nbSlicesInBank ) + 1; diff --git a/IlmImf/ImfTiledInputFile.cpp b/IlmImf/ImfTiledInputFile.cpp index 3e7fda333..95edba917 100644 --- a/IlmImf/ImfTiledInputFile.cpp +++ b/IlmImf/ImfTiledInputFile.cpp @@ -609,10 +609,11 @@ TileBufferTask::execute () // The frame buffer contains a slice for this channel. // - char *writePtr = slice.base + + intptr_t base = reinterpret_cast(slice.base); + char *writePtr = reinterpret_cast(base + (y - yOffset) * slice.yStride + (tileRange.min.x - xOffset) * - slice.xStride; + slice.xStride); char *endPtr = writePtr + (numPixelsPerScanLine - 1) * slice.xStride; diff --git a/IlmImf/ImfTiledOutputFile.cpp b/IlmImf/ImfTiledOutputFile.cpp index 52f7577ab..1cb164fdc 100644 --- a/IlmImf/ImfTiledOutputFile.cpp +++ b/IlmImf/ImfTiledOutputFile.cpp @@ -789,10 +789,11 @@ TileBufferTask::execute () // The frame buffer contains data for this channel. // - const char *readPtr = slice.base + + intptr_t base = reinterpret_cast(slice.base); + const char *readPtr = reinterpret_cast(base + (y - yOffset) * slice.yStride + (tileRange.min.x - xOffset) * - slice.xStride; + slice.xStride); const char *endPtr = readPtr + (numPixelsPerScanLine - 1) * diff --git a/IlmImf/ImfTiledRgbaFile.cpp b/IlmImf/ImfTiledRgbaFile.cpp index 157aec0ab..ff90a7b3b 100644 --- a/IlmImf/ImfTiledRgbaFile.cpp +++ b/IlmImf/ImfTiledRgbaFile.cpp @@ -227,11 +227,14 @@ TiledRgbaOutputFile::ToYa::writeTile (int dx, int dy, int lx, int ly) Box2i dw = _outputFile.dataWindowForTile (dx, dy, lx, ly); int width = dw.max.x - dw.min.x + 1; + intptr_t base= reinterpret_cast(_fbBase); for (int y = dw.min.y, y1 = 0; y <= dw.max.y; ++y, ++y1) { for (int x = dw.min.x, x1 = 0; x <= dw.max.x; ++x, ++x1) - _buf[y1][x1] = _fbBase[x * _fbXStride + y * _fbYStride]; - + { + Rgba* ptr = reinterpret_cast(base + sizeof(Rgba)*(x * _fbXStride + y * _fbYStride)); + _buf[y1][x1] = *ptr; + } RGBAtoYCA (_yw, width, _writeA, _buf[y1], _buf[y1]); } @@ -750,6 +753,9 @@ TiledRgbaInputFile::FromYa::readTile (int dx, int dy, int lx, int ly) Box2i dw = _inputFile.dataWindowForTile (dx, dy, lx, ly); int width = dw.max.x - dw.min.x + 1; + intptr_t base= reinterpret_cast(_fbBase); + + for (int y = dw.min.y, y1 = 0; y <= dw.max.y; ++y, ++y1) { @@ -763,7 +769,8 @@ TiledRgbaInputFile::FromYa::readTile (int dx, int dy, int lx, int ly) for (int x = dw.min.x, x1 = 0; x <= dw.max.x; ++x, ++x1) { - _fbBase[x * _fbXStride + y * _fbYStride] = _buf[y1][x1]; + Rgba* ptr = reinterpret_cast(base + sizeof(Rgba)*(x * _fbXStride + y * _fbYStride)); + *ptr = _buf[y1][x1]; } } } diff --git a/IlmImfTest/testCompositeDeepScanLine.cpp b/IlmImfTest/testCompositeDeepScanLine.cpp index 94a7ea962..c85a07ce0 100644 --- a/IlmImfTest/testCompositeDeepScanLine.cpp +++ b/IlmImfTest/testCompositeDeepScanLine.cpp @@ -341,8 +341,9 @@ class data { if(!dontbotherloadingdepth || (_channels[i]!="Z" && _channels[i]!="ZBack") ) { + intptr_t base = reinterpret_cast(&data[i]); framebuf.insert(_channels[i].c_str(), - Slice(_type,(char *) (&data[i] - (dw.min.x + dw.min.y*(dw.size().x+1))*_channels.size() ), + Slice(_type,reinterpret_cast(base - sizeof(T)*(dw.min.x + dw.min.y*(dw.size().x+1))*_channels.size() ), sizeof(T)*_channels.size(), sizeof(T)*(dw.size().x+1)*_channels.size()) ); diff --git a/IlmImfTest/testDwaCompressorSimd.cpp b/IlmImfTest/testDwaCompressorSimd.cpp index 0691ada6b..8c6015832 100644 --- a/IlmImfTest/testDwaCompressorSimd.cpp +++ b/IlmImfTest/testDwaCompressorSimd.cpp @@ -97,8 +97,9 @@ compareBufferRelative (const SimdAlignedBuffer64f &src, { for (int i=0; i<64; ++i) { + double diff = fabs(src._buffer[i] - dst._buffer[i]); - double relDiff = diff / fabs(src._buffer[i]); + double relDiff = src._buffer[i]==0 ? 0.0 : diff / fabs(src._buffer[i]); if (relDiff > relErrThresh && diff > absErrThresh) { diff --git a/IlmImfTest/testMultiPartApi.cpp b/IlmImfTest/testMultiPartApi.cpp index c0bfb6882..8ce19b579 100644 --- a/IlmImfTest/testMultiPartApi.cpp +++ b/IlmImfTest/testMultiPartApi.cpp @@ -391,18 +391,9 @@ generateRandomFile (int partCount, const std::string & fn) int numYLevels = part->numYLevels(); // Allocating space. - switch (pixelTypes[i]) - { - case 0: - tiledUintData[i].resizeErase(numYLevels, numXLevels); - break; - case 1: - tiledFloatData[i].resizeErase(numYLevels, numXLevels); - break; - case 2: - tiledHalfData[i].resizeErase(numYLevels, numXLevels); - break; - } + tiledUintData[i].resizeErase(numYLevels, numXLevels); + tiledFloatData[i].resizeErase(numYLevels, numXLevels); + tiledHalfData[i].resizeErase(numYLevels, numXLevels); tiledFrameBuffers[i].resizeErase(numYLevels, numXLevels); diff --git a/IlmImfTest/testMultiPartThreading.cpp b/IlmImfTest/testMultiPartThreading.cpp index c4e05704a..d764121a9 100644 --- a/IlmImfTest/testMultiPartThreading.cpp +++ b/IlmImfTest/testMultiPartThreading.cpp @@ -560,19 +560,9 @@ generateRandomFile (int partCount, const std::string & fn) int numXLevels = part->numXLevels(); int numYLevels = part->numYLevels(); - // Allocating space. - switch (pixelTypes[i]) - { - case 0: - tiledUintData[i].resizeErase(numYLevels, numXLevels); - break; - case 1: - tiledFloatData[i].resizeErase(numYLevels, numXLevels); - break; - case 2: - tiledHalfData[i].resizeErase(numYLevels, numXLevels); - break; - } + tiledUintData[i].resizeErase(numYLevels, numXLevels); + tiledFloatData[i].resizeErase(numYLevels, numXLevels); + tiledHalfData[i].resizeErase(numYLevels, numXLevels); tiledFrameBuffers[i].resizeErase(numYLevels, numXLevels); diff --git a/IlmImfTest/testOptimizedInterleavePatterns.cpp b/IlmImfTest/testOptimizedInterleavePatterns.cpp index c8ffd3671..07e64a128 100644 --- a/IlmImfTest/testOptimizedInterleavePatterns.cpp +++ b/IlmImfTest/testOptimizedInterleavePatterns.cpp @@ -196,7 +196,11 @@ bool compare(const FrameBuffer& asRead, for (int x = dataWindow.min.x; x <= dataWindow.max.x; x++) { - char * ptr = (i.slice().base+i.slice().yStride*y +i.slice().xStride*x); + // + // extract value read back from file + // + intptr_t base = reinterpret_cast(i.slice().base); + char * ptr = reinterpret_cast(base+i.slice().yStride*intptr_t(y) +i.slice().xStride*intptr_t(x)); half readHalf; switch (i.slice().type) { @@ -218,8 +222,10 @@ bool compare(const FrameBuffer& asRead, if (p!=asWritten.end()) { - char * ptr = p.slice().base+p.slice().yStride*y + - p.slice().xStride*x; + + intptr_t base =reinterpret_cast( p.slice().base); + char * ptr = reinterpret_cast(base+p.slice().yStride*intptr_t(y) + + p.slice().xStride*intptr_t(x)); switch (p.slice().type) { case IMF::FLOAT : diff --git a/IlmImfTest/testPreviewImage.cpp b/IlmImfTest/testPreviewImage.cpp index 5b32c5010..4b8949822 100644 --- a/IlmImfTest/testPreviewImage.cpp +++ b/IlmImfTest/testPreviewImage.cpp @@ -150,7 +150,7 @@ readWriteFiles (const char fileName1[], file2.setFrameBuffer (pixels2 - dx - dy * w, 1, w); file2.readPixels (dw.min.y, dw.max.y); - for (int i = 0; i < w * h; ++h) + for (size_t i = 0; i < w * h; ++i) { assert (pixels1[i].r == pixels2[i].r); assert (pixels1[i].g == pixels2[i].g); diff --git a/IlmImfTest/testSharedFrameBuffer.cpp b/IlmImfTest/testSharedFrameBuffer.cpp index 0b2293c23..47c700ab8 100644 --- a/IlmImfTest/testSharedFrameBuffer.cpp +++ b/IlmImfTest/testSharedFrameBuffer.cpp @@ -115,11 +115,7 @@ WriterThread::WriterThread (RgbaOutputFile *outfile): _outfile (outfile) void WriterThread::run () { - // - // Signal that the thread has started - // - threadSemaphore.post(); while (true) { @@ -136,6 +132,12 @@ WriterThread::run () break; } } + + // + // Signal that the thread has finished + // + + threadSemaphore.post(); } @@ -146,7 +148,7 @@ class ReaderThread : public Thread ReaderThread (RgbaInputFile *infile, int start, int step); virtual void run (); - + private: RgbaInputFile * _infile; @@ -165,17 +167,20 @@ ReaderThread::ReaderThread (RgbaInputFile *infile, int start, int step): void ReaderThread::run () { - // - // Signal that the thread has started - // - threadSemaphore.post (); int num = _infile->header().dataWindow().max.y - _infile->header().dataWindow().min.y + 1; for (int i = _start; i < num; i += _step) _infile->readPixels (i); + + // + // Signal that the thread has finished + // + + threadSemaphore.post (); + }