Use signed arithmetic when reading rectangle (#1131)

* Use signed arithmetic when reading rectangle

An operation such as DirectBitsRect can fail if the origin is -ve and we're applying a screen image ratio. See for example P564B1400.pict

* Fix copy/paste error in testNegativeOrigin()

---------

Co-authored-by: Harald Kuhr <harald.kuhr@gmail.com>
This commit is contained in:
Rolf Howarth 2025-05-30 15:14:23 +01:00 committed by GitHub
parent defadbbbcd
commit 5af87372aa
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 22 additions and 4 deletions

View File

@ -2406,10 +2406,10 @@ public final class PICTImageReader extends ImageReaderBase {
* @throws IOException if an I/O error occurs while reading the image.
*/
private void readRectangle(DataInput pStream, Rectangle pDestRect) throws IOException {
int y = pStream.readUnsignedShort();
int x = pStream.readUnsignedShort();
int h = pStream.readUnsignedShort();
int w = pStream.readUnsignedShort();
int y = pStream.readShort();
int x = pStream.readShort();
int h = pStream.readShort();
int w = pStream.readShort();
pDestRect.setLocation(getXPtCoord(x), getYPtCoord(y));
pDestRect.setSize(getXPtCoord(w - x), getYPtCoord(h - y));

View File

@ -84,6 +84,7 @@ public class PICTImageReaderTest extends ImageReaderAbstractTest<PICTImageReader
new TestData(getClassLoaderResource("/pict/FC10.PCT"), new Dimension(2265, 2593)),
// 1000 DPI with bounding box not matching DPI
new TestData(getClassLoaderResource("/pict/oom.pict"), new Dimension(1713, 1263)),
new TestData(getClassLoaderResource("/pict/P564B1400.pict"), new Dimension(1745, 1022)),
new TestData(getClassLoaderResource("/pict/cow.pict"), new Dimension(787, 548)),
new TestData(getClassLoaderResource("/pict/CatDV==2.0=1=.pict"), new Dimension(375, 165)),
new TestData(getClassLoaderResource("/pict/Picture14.pict"), new Dimension(404, 136)),
@ -252,6 +253,23 @@ public class PICTImageReaderTest extends ImageReaderAbstractTest<PICTImageReader
reader.read(0);
}
@Test
public void testNegativeOrigin() throws IOException {
PICTImageReader reader = createReader();
try (ImageInputStream stream = ImageIO.createImageInputStream(getClassLoaderResource("/pict/P564B1400.pict"))) {
reader.setInput(stream);
// This file has a DirectBitsRect opcode with a destination of (0,-1) which wraps to 65535 if we read
// it using unsigned arithmetic
BufferedImage image = reader.read(0, null);
assertRGBEquals("RGB values differ", 0xfffcfcfc, image.getRGB(10, 10), 1); // was transparent 00ffffff
assertRGBEquals("RGB values differ", 0xffe6e6e6, image.getRGB(100, 500), 1);
}
finally {
reader.dispose();
}
}
@Test
public void testFrameBoundsIssue() throws IOException {
PICTImageReader reader = createReader();