JDK-4690476 : NegativeArraySizeException from AffineTransformOp with shear
  • Type: Bug
  • Component: client-libs
  • Sub-Component: 2d
  • Affected Version: 1.4.0
  • Priority: P4
  • Status: Open
  • Resolution: Unresolved
  • OS: windows_98
  • CPU: x86
  • Submitted: 2002-05-23
  • Updated: 2007-01-27
Related Reports
Relates :  
Description

Name: rmT116609			Date: 05/23/2002


FULL PRODUCT VERSION :
java version "1.4.0"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.0-b92)
Java HotSpot(TM) Client VM (build 1.4.0-b92, mixed mode)


FULL OPERATING SYSTEM VERSION :
Windows 98 [Version 4.10.2222]

A DESCRIPTION OF THE PROBLEM :
I get a java.lang.NegativeArraySizeException at java.awt.image.DataBufferInt.<init>(DataBufferInt.java:41)
when using an java.awt.image.AffineTransformOp with the following:

affine transformation with shear large image (2552 x 3300) indexed color space

Changing the affine transformation to the identity matrix or to a scaled-only matrix works fine.

This is with bilinear interpolation. Nearest neighbor throws an exception in a different place.

One theory is that 1-bit images aren't supported as well, so the transformation try to create a hug image of more standard format, and it is so big that width times height overflows int thus giving a negative number.


STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. see sample source code below


EXPECTED VERSUS ACTUAL BEHAVIOR :
Expected sheared and scaled image, actually get exception thrown.

ERROR MESSAGES/STACK TRACES THAT OCCUR :
	java.lang.NegativeArraySizeException
		at java.awt.image.DataBufferInt.<init>(DataBufferInt.java:41)
		at java.awt.image.Raster.createPackedRaster(Raster.java:452)
		at java.awt.image.DirectColorModel.createCompatibleWritableRaster(Direct
ColorModel.java:1015)
		at java.awt.image.BufferedImage.<init>(BufferedImage.java:259)
		at java.awt.image.AffineTransformOp.createCompatibleDestImage(AffineTran
sformOp.java:440)
		at java.awt.image.AffineTransformOp.filter(AffineTransformOp.java:204)
		at AOPTest.testAOP(AOPTest.java:48)
		at AOPTest.main(AOPTest.java:54)


This bug can be reproduced always.

---------- BEGIN SOURCE ----------
import java.awt.*;
import java.awt.image.*;
import java.awt.geom.*;

/**
	AffineTransformOp on 1-bit image throws java.lang.NegativeArraySizeException.

	Creates array of size width * height, which in this case is 2552 * 3300,
	which is not a negative number and furthermore width and height are checked
	to be non-negative in a couple places before the point of the exception.
*/
public class AOPTest {
  static void testAOP() {
	int w = 2552, h=3300;

	DataBufferByte db = new DataBufferByte(w/8 * h);

	WritableRaster r = Raster.createPackedRaster(db, w,h, 1, null);;
	ColorModel cm = new IndexColorModel(1, 2, new int[] {  0x00ffffff, 0xff000000 },
0, true, 0, DataBuffer.TYPE_BYTE);

	BufferedImage img = new BufferedImage(cm, r, false, new java.util.Hashtable());

	AffineTransform at = new AffineTransform(0.239879937304075, 23.7487, 18.3669,
0.240187545454545, 0.0, 0.0);
	double determinant = at.getDeterminant();  // from Javadoc: " If the determinant
is non-zero, then this transform is invertible..."
	if (determinant==0.0) System.out.println("matrix not invertable!"); else
System.out.println(determinant+"!=0.0, so invertable, so not bug 4348056");
	//at = new AffineTransform();     // identity transform OK
	//at = new AffineTransform(0.239879937304075, 0.0, 0.0, 0.240187545454545, 0.0,
0.0);     // no shears OK

	AffineTransformOp aop = new AffineTransformOp(at, AffineTransformOp.TYPE_BILINEAR);

	//AffineTransformOp aop = new AffineTransformOp(at,
AffineTransformOp.TYPE_NEAREST_NEIGHBOR);
	// nearest neighbor gives:
	// java.lang.IllegalArgumentException: Dimensions (width=61223 height=61400) are
too large
	//    at java.awt.image.SampleModel.<init>(SampleModel.java:112)

	img = aop.filter(img, null);
  }


  public static void main(String[] args) {
	try {
		testAOP();
	} catch (Exception e) {
		e.printStackTrace();
		System.out.println(e);
	}
  }
}

---------- END SOURCE ----------

CUSTOMER WORKAROUND :
Set m01 and m10 to 0.0. You don't get shearing, but you get scaling and you don't get an exception.
(Review ID: 146939) 
======================================================================