8340411: open source several 2D imaging tests

Reviewed-by: azvegint
This commit is contained in:
Phil Race 2024-09-23 18:26:52 +00:00
parent 833ff29983
commit 8dcf7b8fa7
4 changed files with 485 additions and 0 deletions

View File

@ -0,0 +1,147 @@
/*
* Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 4184283
* @summary Checks rendering of dithered byte packed image does not crash.
*/
import java.awt.Color;
import java.awt.Component;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.awt.image.IndexColorModel;
import java.awt.image.MemoryImageSource;
import java.awt.image.WritableRaster;
public class DitherTest extends Component {
final static int NOOP = 0;
final static int RED = 1;
final static int GREEN = 2;
final static int BLUE = 3;
final static int ALPHA = 4;
final static int SATURATION = 5;
final static byte red[] = {(byte)0, (byte)132, (byte)0, (byte)132, (byte)0, (byte)132,
(byte)0, (byte)198, (byte)198, (byte)165, (byte)255, (byte)165, (byte)132,
(byte)255, (byte)0, (byte)255};
final static byte green[] = {(byte)0, (byte)0, (byte)130, (byte)130, (byte)0,
(byte)0, (byte)130, (byte)195, (byte)223, (byte)203, (byte)251, (byte)162,
(byte)132, (byte)0, (byte)255, (byte)255};
final static byte blue[] = {(byte)0, (byte)0, (byte)0, (byte)0, (byte)132, (byte)132,
(byte)132, (byte)198, (byte)198, (byte)247, (byte)247, (byte)165, (byte)132,
(byte)0, (byte)0, (byte)0};
static IndexColorModel cm16 = new IndexColorModel( 4, 16, red, green, blue);
public static void main(String args[]) {
int imageWidth = 256;
int imageHeight = 256;
WritableRaster raster = cm16.createCompatibleWritableRaster(imageWidth, imageHeight);
BufferedImage intermediateImage = new BufferedImage(cm16, raster, false, null);
Image calculatedImage = calculateImage();
Graphics2D ig = intermediateImage.createGraphics();
// Clear background and fill a red rectangle just to prove that we can draw on intermediateImage
ig.setColor(Color.white);
ig.fillRect(0,0,imageWidth,imageHeight);
ig.drawImage(calculatedImage, 0, 0, imageWidth, imageHeight, null);
ig.setColor(Color.red);
ig.fillRect(0,0,5,5);
BufferedImage destImage = new BufferedImage(imageWidth, imageWidth, BufferedImage.TYPE_INT_RGB);
Graphics2D dg = destImage.createGraphics();
dg.drawImage(intermediateImage, 0, 0, imageWidth, imageHeight, null);
}
private static void applymethod(int c[], int method, int step, int total, int vals[]) {
if (method == NOOP)
return;
int val = ((total < 2)
? vals[0]
: vals[0] + ((vals[1] - vals[0]) * step / (total - 1)));
switch (method) {
case RED:
c[0] = val;
break;
case GREEN:
c[1] = val;
break;
case BLUE:
c[2] = val;
break;
case ALPHA:
c[3] = val;
break;
case SATURATION:
int max = Math.max(Math.max(c[0], c[1]), c[2]);
int min = max * (255 - val) / 255;
if (c[0] == 0) c[0] = min;
if (c[1] == 0) c[1] = min;
if (c[2] == 0) c[2] = min;
break;
}
}
private static Image calculateImage() {
int xvals[] = { 0, 255 };
int yvals[] = { 0, 255 };
int xmethod = RED;
int ymethod = BLUE;
int width = 256;
int height = 256;
int pixels[] = new int[width * height];
int c[] = new int[4];
int index = 0;
for (int j = 0; j < height; j++) {
for (int i = 0; i < width; i++) {
c[0] = c[1] = c[2] = 0;
c[3] = 255;
if (xmethod < ymethod) {
applymethod(c, xmethod, i, width, xvals);
applymethod(c, ymethod, j, height, yvals);
} else {
applymethod(c, ymethod, j, height, yvals);
applymethod(c, xmethod, i, width, xvals);
}
pixels[index++] = ((c[3] << 24) |
(c[0] << 16) |
(c[1] << 8) |
(c[2] << 0));
}
}
DitherTest dt = new DitherTest();
return dt.createImage(new MemoryImageSource(width, height, ColorModel.getRGBdefault(), pixels, 0, width));
}
}

View File

@ -0,0 +1,108 @@
/*
* Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 4213160
* @summary Should generate a black image
*/
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.awt.image.DataBuffer;
import java.awt.image.DataBufferByte;
import java.awt.image.IndexColorModel;
import java.awt.image.Raster;
import java.awt.image.WritableRaster;
import java.awt.geom.AffineTransform;
public class MultiOp {
public static void main(String[] argv) {
int width = 256;
int height = 256;
int pixelBits = 2; // 1, 2, 4, or 8
// 1 and 8 make the code throw ImagingOpException, 2 and 4
// make the code SEGV on Sol.
byte[] lut1Arr = new byte[] {0, (byte)255 };
byte[] lut2Arr = new byte[] {0, (byte)85, (byte)170, (byte)255};
byte[] lut4Arr = new byte[] {0, (byte)17, (byte)34, (byte)51,
(byte)68, (byte)85,(byte) 102, (byte)119,
(byte)136, (byte)153, (byte)170, (byte)187,
(byte)204, (byte)221, (byte)238, (byte)255};
byte[] lut8Arr = new byte[256];
for (int i = 0; i < 256; i++) {
lut8Arr[i] = (byte)i;
}
// Create the binary image
int bytesPerRow = width * pixelBits / 8;
byte[] imageData = new byte[height * bytesPerRow];
ColorModel cm = null;
switch (pixelBits) {
case 1:
cm = new IndexColorModel(pixelBits, lut1Arr.length,
lut1Arr, lut1Arr, lut1Arr);
break;
case 2:
cm = new IndexColorModel(pixelBits, lut2Arr.length,
lut2Arr, lut2Arr, lut2Arr);
break;
case 4:
cm = new IndexColorModel(pixelBits, lut4Arr.length,
lut4Arr, lut4Arr, lut4Arr);
break;
case 8:
cm = new IndexColorModel(pixelBits, lut8Arr.length,
lut8Arr, lut8Arr, lut8Arr);
break;
default:
{new Exception("Invalid # of bit per pixel").printStackTrace();}
}
DataBuffer db = new DataBufferByte(imageData, imageData.length);
WritableRaster r = Raster.createPackedRaster(db, width, height,
pixelBits, null);
BufferedImage srcImage = new BufferedImage(cm, r, false, null);
BufferedImage destImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
Graphics2D g = destImage.createGraphics();
AffineTransform af = AffineTransform.getScaleInstance(.5, .5);
// This draw image is the problem
g.drawImage(srcImage, af, null);
int blackPixel = Color.black.getRGB();
for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) {
if (destImage.getRGB(x, y) != blackPixel) {
throw new RuntimeException("Not black");
}
}
}
}
}

View File

@ -0,0 +1,88 @@
/*
* Copyright (c) 2002, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 4673490
* @summary This test verifies that Toolkit images with a 1-bit
* IndexColorModel (known as ByteBinary) and a transparent index are rendered properly.
*/
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.awt.image.IndexColorModel;
public class ByteBinaryBitmask {
public static void main(String argv[]) throws Exception {
/* Create the image */
int w = 16, h = 16;
byte[] bw = { (byte)255, (byte)0, };
IndexColorModel icm = new IndexColorModel(1, 2, bw, bw, bw, 0);
BufferedImage img = new BufferedImage(w, h, BufferedImage.TYPE_BYTE_BINARY, icm);
Graphics2D g2d = img.createGraphics();
g2d.setColor(Color.white);
g2d.fillRect(0, 0, w, h);
g2d.setColor(Color.black);
int xoff = 5;
g2d.fillRect(xoff, 5, 1, 10); // 1 pixel wide
int dw = 200, dh = 50;
BufferedImage dest = new BufferedImage(dw, dh, BufferedImage.TYPE_INT_RGB);
Graphics2D g = dest.createGraphics();
g.setColor(Color.green);
g.fillRect(0, 0, dw, dh);
int x1 = 10;
int x2 = 50;
int x3 = 90;
int x4 = 130;
g.drawImage(img, x1, 10, null);
g.drawImage(img, x2, 10, null);
g.drawImage(img, x3, 10, null);
g.drawImage(img, x4, 10, null);
int blackPix = Color.black.getRGB();
for (int y = 0; y < dh; y++) {
boolean isBlack = false;
for (int x = 0; x < dw; x++) {
int rgb = dest.getRGB(x, y);
if (rgb == blackPix) {
/* Src image has a one pixel wide vertical rect at off "xoff" and
* this is drawn at x1/x2/x3/x4) so the sum of those are the x locations
* to expect black.
*/
if (x != (x1 + xoff) && x != (x2 + xoff) && x != (x3 + xoff) && x!= (x4 + xoff)) {
throw new RuntimeException("wrong x location: " +x);
}
if (isBlack) {
throw new RuntimeException("black after black");
}
}
isBlack = rgb == blackPix;
}
}
}
}

View File

@ -0,0 +1,142 @@
/*
* Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/**
* @test
* @bug 4192756
* @summary Tests that using a non-default colormodel generates correct images under 16/24 bit mode
*/
import java.awt.Color;
import java.awt.Component;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.awt.image.DirectColorModel;
import java.awt.image.ComponentColorModel;
import java.awt.image.MemoryImageSource;
import java.util.Arrays;
/*
* NOTE: This bug only appears under specific conditions. If the background of
* the surface is red, then you are not running under the conditions necessary
* to test for the regression so the results of this test will be inconclusive.
*
* The test should be run under any of the following screen depths/surfaces:
*
* 15-bit, otherwise known as 555 RGB or 32768 (thousands) colors
* 16-bit, otherwise known as 565 RGB or 65536 (thousands) colors
* 24-bit, otherwise known as 16777216 (millions) colors
*
* The test draws 2 rectangles. Both rectangles should be half black (left)
* and half blue (right). If the top rectangle is all black, the test fails.
* If the background is red, the results are inconclusive (see above).
*/
public class CustomSourceCM extends Component {
public static int IMG_W = 80;
public static int IMG_H = 30;
static void test(int imageType) {
int w = IMG_W + 20;
int h = IMG_H * 2 + 40;
BufferedImage bi = new BufferedImage(w, h, imageType);
DirectColorModel dcm;
/* the next dozen lines or so are intended to help
* ascertain if the destination surface is of the type
* that exhibited the original bug, making the background
* white in those cases. It is not strictly necessary.
* It is only for a manual tester to be able to tell by looking.
* The real test is the check for black and blue later on.
*/
Graphics2D g = bi.createGraphics();
g.setColor(Color.red);
g.fillRect(0, 0, w, h);
ColorModel cm = bi.getColorModel();
if (cm instanceof ComponentColorModel) {
g.setColor(Color.white);
g.fillRect(0, 0, w, h);
} else if (cm instanceof DirectColorModel) {
dcm = (DirectColorModel) cm;
if (dcm.getPixelSize() < 24) {
g.setColor(Color.white);
g.fillRect(0, 0, w, h);
}
}
// Construct a ColorModel and data for a 16-bit 565 image...
dcm = new DirectColorModel(16, 0x1f, 0x7e0, 0xf800);
// Create an image which is black on the left, blue on the right.
int[] pixels = new int[IMG_W * IMG_H];
int blue = dcm.getBlueMask();
int off = 0;
for (int y = 0; y < IMG_H; y++) {
Arrays.fill(pixels, off, off+IMG_W/2, 0);
Arrays.fill(pixels, off+IMG_W/2, off+IMG_W, blue);
off += IMG_W;
}
MemoryImageSource mis = new MemoryImageSource(IMG_W, IMG_H, dcm,
pixels, 0, IMG_W);
CustomSourceCM comp = new CustomSourceCM();
Image img = comp.createImage(mis);
// Draw the image on to the surface.
g.drawImage(img, 10, 10, null);
// Create a similar effect with 2 fillrects, below the image.
g.setColor(Color.black);
g.fillRect(10, 60, IMG_W/2, IMG_H);
g.setColor(Color.blue);
g.fillRect(10+IMG_W/2, 60, IMG_W/2, IMG_H);
// Now sample points in the image to confirm they are the expected color.
int bluePix = Color.blue.getRGB();
int blackPix = Color.black.getRGB();
int black_topLeft = bi.getRGB(10+IMG_W/4, 10+IMG_H/2);
int blue_topRight = bi.getRGB(10+IMG_W*3/4, 10+IMG_H/2);
int black_bottomLeft = bi.getRGB(10+IMG_W/4, 60+IMG_H/2);
int blue_bottomRight = bi.getRGB(10+IMG_W*3/4, 60+IMG_H/2);
if ((black_topLeft != blackPix) || (black_bottomLeft != blackPix) ||
(blue_topRight != bluePix) || (blue_bottomRight != bluePix)) {
String fileName = "failed " + imageType + ".png";
try {
javax.imageio.ImageIO.write(bi, "png", new java.io.File(fileName));
} catch (Exception e) { };
throw new RuntimeException("unexpected colors");
}
}
public static void main(String argv[]) {
test(BufferedImage.TYPE_USHORT_555_RGB);
test(BufferedImage.TYPE_USHORT_565_RGB);
test(BufferedImage.TYPE_3BYTE_BGR);
}
}