undefect. CWE-407 — 63 sites patched across 27 ecosystems

Authors: russell@unturf.com · brackishbert@gmail.com · foxhop.net · TimeHexOn.com

Patches, unit tests, benchmarks, whitepaper, and outreach briefs.
Public domain — no copyright claimed. Use freely.
This commit is contained in:
russell@unturf.com 2026-03-26 17:11:57 -04:00
commit 0a580b313d
70422 changed files with 17213626 additions and 0 deletions

View file

@ -0,0 +1,147 @@
/*
* Copyright (c) 2013, 2016, 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
* @key headful
* @bug 8024343 8042098
* @summary Test verifies that accelerated pipelines
* correctly draws primitives in XOR mode.
* @run main/othervm -Dsun.java2d.xrender=True AcceleratedXORModeTest
*/
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsEnvironment;
import java.awt.image.BufferedImage;
import java.awt.image.VolatileImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
public class AcceleratedXORModeTest {
public static void main(String argv[]) {
String fileName = argv.length > 0 ? argv[0] : null;
new AcceleratedXORModeTest(fileName).test();
}
static final Color backColor = Color.red;
static final Color color1 = Color.green;
static final Color color2 = Color.yellow;
static final Color xorColor1 = Color.blue;
static final Color xorColor2 = Color.white;
static final int width = 700, height = 300;
VolatileImage vImg = null;
String fileName;
public AcceleratedXORModeTest(String fileName) {
this.fileName = fileName;
}
void draw(Graphics2D g) {
g.setColor(backColor);
g.fillRect(0, 0, width, height);
g.setXORMode(xorColor1);
drawPattern(g, 100);
g.setXORMode(xorColor2);
drawPattern(g, 400);
g.dispose();
}
void test(BufferedImage bi) {
comparePattern(bi, 150, xorColor1.getRGB());
comparePattern(bi, 450, xorColor2.getRGB());
}
void comparePattern(BufferedImage bi, int startX, int xorColor) {
int[] expectedColors = {
backColor.getRGB() ^ color1.getRGB() ^ xorColor,
backColor.getRGB() ^ color1.getRGB() ^ xorColor ^
color2.getRGB() ^ xorColor,
backColor.getRGB() ^ color2.getRGB() ^ xorColor
};
for (int i = 0; i < 3; i++) {
int x = startX + 100 * i;
int rgb = bi.getRGB(x, 150);
if (rgb != expectedColors[i]) {
String msg = "Colors mismatch: x = " + x +
", got " + new Color(rgb) + ", expected " +
new Color(expectedColors[i]);
System.err.println(msg);
write(bi);
throw new RuntimeException("FAILED: " + msg);
}
}
}
void drawPattern(Graphics2D g, int x) {
g.setColor(color1);
g.fillRect(x, 0, 200, 300);
g.setColor(color2);
g.fillRect(x+100, 0, 200, 300);
}
GraphicsConfiguration getDefaultGC() {
return GraphicsEnvironment.getLocalGraphicsEnvironment().
getDefaultScreenDevice().getDefaultConfiguration();
}
void createVImg() {
if (vImg != null) {
vImg.flush();
vImg = null;
}
vImg = getDefaultGC().createCompatibleVolatileImage(width, height);
}
void write(BufferedImage bi) {
if (fileName != null) {
try {
ImageIO.write(bi, "png", new File(fileName));
} catch (IOException e) {
System.err.println("Can't write image file " + fileName);
}
}
}
void test() {
createVImg();
BufferedImage bi = null;
do {
int valCode = vImg.validate(getDefaultGC());
if (valCode == VolatileImage.IMAGE_INCOMPATIBLE) {
createVImg();
}
Graphics2D g = vImg.createGraphics();
draw(g);
bi = vImg.getSnapshot();
} while (vImg.contentsLost());
if (bi != null) {
test(bi);
write(bi);
}
}
}

View file

@ -0,0 +1,130 @@
/*
* Copyright (c) 2016, 2022, 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.
*/
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsEnvironment;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.font.FontRenderContext;
import java.awt.font.GlyphVector;
import java.awt.image.BufferedImage;
import java.awt.image.VolatileImage;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.TimeUnit;
import static java.awt.image.BufferedImage.TYPE_INT_ARGB;
/**
* @test
* @key headful
* @bug 8158072 7172749 8283794
*/
public final class ClassCastExceptionForInvalidSurface {
static GraphicsEnvironment ge
= GraphicsEnvironment.getLocalGraphicsEnvironment();
static GraphicsConfiguration gc
= ge.getDefaultScreenDevice().getDefaultConfiguration();
static volatile VolatileImage vi = gc.createCompatibleVolatileImage(10, 10);
static volatile Throwable failed;
static BlockingQueue<VolatileImage> list = new ArrayBlockingQueue<>(50);
// Will run the test no more than 15 seconds
static long endtime = System.nanoTime() + TimeUnit.SECONDS.toNanos(15);
public static void main(final String[] args) throws InterruptedException {
// Catch all uncaught exceptions and treat them as test failure
Thread.setDefaultUncaughtExceptionHandler((t, e) -> failed = e);
// Data for rendering
BufferedImage bi = new BufferedImage(10, 10, TYPE_INT_ARGB);
FontRenderContext frc = new FontRenderContext(null, false, false);
Font font = new Font("Serif", Font.PLAIN, 12);
GlyphVector gv = font.createGlyphVector(frc, new char[]{'a', '1'});
Thread t1 = new Thread(() -> {
while (!isComplete()) {
vi = gc.createCompatibleVolatileImage(10, 10);
if (!list.offer(vi)) {
vi.flush();
}
}
list.forEach(Image::flush);
});
Thread t2 = new Thread(() -> {
while (!isComplete()) {
VolatileImage vi = list.poll();
if (vi != null) {
vi.flush();
}
}
});
Thread t3 = new Thread(() -> {
while (!isComplete()) {
vi.createGraphics().drawImage(bi, 1, 1, null);
}
});
Thread t4 = new Thread(() -> {
while (!isComplete()) {
vi.createGraphics().drawGlyphVector(gv, 0, 0);
vi.createGraphics().drawOval(0, 0, 10, 10);
vi.createGraphics().drawLine(0, 0, 10, 10);
vi.createGraphics().drawString("123", 1, 1);
vi.createGraphics().draw(new Rectangle(0, 0, 10, 10));
vi.createGraphics().fillOval(0, 0, 10, 10);
final Graphics2D graphics = vi.createGraphics();
graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
graphics.fillPolygon(new int[] {0, 10, 10, 0},
new int [] {0, 0, 10, 10}, 4);
}
});
t1.start();
t2.start();
t3.start();
t4.start();
t1.join();
t2.join();
t3.join();
t4.join();
if (failed != null) {
System.err.println("Test failed");
failed.printStackTrace();
}
}
private static boolean isComplete() {
return endtime - System.nanoTime() < 0 || failed != null;
}
}

View file

@ -0,0 +1,180 @@
/*
* Copyright (c) 2007, 2018, 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
* @key headful
* @bug 6659345 8198613
* @summary Tests that various paints work correctly when preceeded by a
* textured operaiton.
* @author Dmitri.Trembovetski@sun.com: area=Graphics
* @run main/othervm AccelPaintsTest
*/
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GradientPaint;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsEnvironment;
import java.awt.LinearGradientPaint;
import java.awt.MultipleGradientPaint.CycleMethod;
import java.awt.Paint;
import java.awt.RadialGradientPaint;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.TexturePaint;
import java.awt.Transparency;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.awt.image.VolatileImage;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class AccelPaintsTest extends JPanel {
BufferedImage bi =
new BufferedImage(80, 100, BufferedImage.TYPE_INT_ARGB_PRE);
RadialGradientPaint rgp =
new RadialGradientPaint(100, 100, 100, new float[] {0f, 0.2f, 0.6f, 1f},
new Color[] { Color.red,
Color.yellow,
Color.blue,
Color.green},
CycleMethod.REFLECT);
LinearGradientPaint lgp =
new LinearGradientPaint(30, 30, 120, 130, new float[] {0f, 0.2f, 0.6f, 1f},
new Color[] {Color.red,
Color.yellow,
Color.blue,
Color.green});
GradientPaint gp =
new GradientPaint(30, 30, Color.red, 120, 130, Color.yellow, true);
TexturePaint tp =
new TexturePaint(bi, new Rectangle2D.Float(30, 30, 120, 130));
public AccelPaintsTest() {
Graphics g = bi.getGraphics();
g.setColor(Color.blue);
g.fillRect(0, 0, bi.getWidth(), bi.getHeight());
setPreferredSize(new Dimension(250, 4*120));
}
private void renderWithPaint(Graphics2D g2d, Paint p) {
g2d.drawImage(bi, 130, 30, null);
g2d.setPaint(p);
g2d.fillRect(30, 30, 80, 100);
}
private void render(Graphics2D g2d) {
renderWithPaint(g2d, rgp);
g2d.translate(0, 100);
renderWithPaint(g2d, lgp);
g2d.translate(0, 100);
renderWithPaint(g2d, gp);
g2d.translate(0, 100);
renderWithPaint(g2d, tp);
g2d.translate(0, 100);
}
private void test() {
GraphicsConfiguration gc =
GraphicsEnvironment.getLocalGraphicsEnvironment().
getDefaultScreenDevice().getDefaultConfiguration();
if (gc.getColorModel().getPixelSize() < 16) {
System.out.println("<16 bit depth detected, test passed");
return;
}
VolatileImage vi =
gc.createCompatibleVolatileImage(250, 4*120, Transparency.OPAQUE);
BufferedImage res;
do {
vi.validate(gc);
Graphics2D g2d = vi.createGraphics();
g2d.setColor(Color.white);
g2d.fillRect(0, 0, vi.getWidth(), vi.getHeight());
render(g2d);
res = vi.getSnapshot();
} while (vi.contentsLost());
for (int y = 0; y < bi.getHeight(); y++) {
for (int x = 0; x < bi.getWidth(); x++) {
if (res.getRGB(x, y) == Color.black.getRGB()) {
System.err.printf("Test FAILED: found black at %d,%d\n",
x, y);
try {
String fileName = "AccelPaintsTest.png";
ImageIO.write(res, "png", new File(fileName));
System.err.println("Dumped rendering to " + fileName);
} catch (IOException e) {}
throw new RuntimeException("Test FAILED: found black");
}
}
}
}
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D)g;
render(g2d);
}
public static void main(String[] args)
throws InterruptedException, InvocationTargetException
{
if (args.length > 0 && args[0].equals("-show")) {
EventQueue.invokeAndWait(new Runnable() {
public void run() {
JFrame f = new JFrame("RadialGradientTest");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
AccelPaintsTest t = new AccelPaintsTest();
f.add(t);
f.pack();
f.setVisible(true);
}
});
} else {
AccelPaintsTest t = new AccelPaintsTest();
t.test();
System.out.println("Test Passed.");
}
}
}

View file

@ -0,0 +1,134 @@
/*
* Copyright (c) 2006, 2018, 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.
*/
import java.awt.Color;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsEnvironment;
import java.awt.RenderingHints;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;
import java.awt.image.VolatileImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
/**
* @test
* @key headful
* @bug 6429665 6588884 8198613
* @summary Tests that the transform is correctly handled
* @author Dmitri.Trembovetski area=Graphics
* @run main AcceleratedScaleTest
* @run main/othervm -Dsun.java2d.d3d=true AcceleratedScaleTest
*/
public class AcceleratedScaleTest {
private static final int IMAGE_SIZE = 200;
private static VolatileImage destVI;
private static void initVI(GraphicsConfiguration gc) {
int res;
if (destVI == null) {
res = VolatileImage.IMAGE_INCOMPATIBLE;
} else {
res = destVI.validate(gc);
}
if (res == VolatileImage.IMAGE_INCOMPATIBLE) {
if (destVI != null) destVI.flush();
destVI = gc.createCompatibleVolatileImage(IMAGE_SIZE, IMAGE_SIZE);
destVI.validate(gc);
res = VolatileImage.IMAGE_RESTORED;
}
if (res == VolatileImage.IMAGE_RESTORED) {
Graphics vig = destVI.getGraphics();
vig.setColor(Color.red);
vig.fillRect(0, 0, destVI.getWidth(), destVI.getHeight());
vig.dispose();
}
}
public static void main(String[] args) {
Frame f = new Frame();
f.pack();
GraphicsConfiguration gc = f.getGraphicsConfiguration();
if (gc.getColorModel().getPixelSize() < 16) {
System.out.printf("Bit depth: %d . Test considered passed.",
gc.getColorModel().getPixelSize());
f.dispose();
return;
}
BufferedImage bi =
new BufferedImage(IMAGE_SIZE/4, IMAGE_SIZE/4,
BufferedImage.TYPE_INT_RGB);
Graphics2D g = (Graphics2D)bi.getGraphics();
g.setColor(Color.red);
g.fillRect(0, 0, bi.getWidth(), bi.getHeight());
BufferedImage snapshot;
do {
initVI(gc);
g = (Graphics2D)destVI.getGraphics();
// "accelerate" BufferedImage
for (int i = 0; i < 5; i++) {
g.drawImage(bi, 0, 0, null);
}
g.setColor(Color.white);
g.fillRect(0, 0, destVI.getWidth(), destVI.getHeight());
// this will force the use of Transform primitive instead of
// Scale (the latter doesn't do bilinear filtering required by
// VALUE_RENDER_QUALITY, which triggers the bug in D3D pipeline
g.setRenderingHint(RenderingHints.KEY_RENDERING,
RenderingHints.VALUE_RENDER_QUALITY);
g.drawImage(bi, 0, 0, destVI.getWidth(), destVI.getHeight(), null);
g.fillRect(0, 0, destVI.getWidth(), destVI.getHeight());
g.drawImage(bi, 0, 0, destVI.getWidth(), destVI.getHeight(), null);
snapshot = destVI.getSnapshot();
} while (destVI.contentsLost());
f.dispose();
int whitePixel = Color.white.getRGB();
for (int y = 0; y < snapshot.getHeight(); y++) {
for (int x = 0; x < snapshot.getWidth(); x++) {
if (snapshot.getRGB(x, y) == whitePixel) {
System.out.printf("Found untouched pixel at %dx%d\n", x, y);
System.out.println("Dumping the dest. image to " +
"AcceleratedScaleTest_dst.png");
try {
ImageIO.write(snapshot, "png",
new File("AcceleratedScaleTest_dst.png"));
} catch (IOException ex) {
ex.printStackTrace();
}
throw new RuntimeException("Test failed.");
}
}
}
System.out.println("Test Passed.");
}
}

View file

@ -0,0 +1,105 @@
/*
* Copyright (c) 2011, 2016, 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
* @key headful
* @bug 6997116
* @summary Test verifies that rendering of images with bitmap transparency
* to a D3D surface does not cause an ClassCastException.
*
* @run main/othervm -Dsun.java2d.d3d=True DrawBitmaskToSurfaceTest
*/
import java.awt.Graphics;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.awt.image.IndexColorModel;
import java.util.concurrent.CountDownLatch;
import javax.swing.JFrame;
public class DrawBitmaskToSurfaceTest extends JFrame {
private final Image src;
private static java.util.concurrent.CountDownLatch latch = null;
private static Throwable theError = null;
public DrawBitmaskToSurfaceTest() {
src = createTestImage();
}
private static Image createTestImage() {
byte[] r = new byte[]{(byte)0x00, (byte)0x80, (byte)0xff, (byte)0xff};
byte[] g = new byte[]{(byte)0x00, (byte)0x80, (byte)0xff, (byte)0x00};
byte[] b = new byte[]{(byte)0x00, (byte)0x80, (byte)0xff, (byte)0x00};
IndexColorModel icm = new IndexColorModel(2, 4, r, g, b, 3);
BufferedImage img = new BufferedImage(100, 100,
BufferedImage.TYPE_BYTE_INDEXED,
icm);
return img;
}
@Override
public void paint(final Graphics g) {
try {
System.err.println("paint frame....");
g.drawImage(src, 30, 30, this);
} catch (Throwable e) {
theError = e;
} finally {
if (latch != null) {
latch.countDown();
}
}
}
public static void main(final String[] args) throws Exception {
final JFrame frame = new DrawBitmaskToSurfaceTest();
frame.setBounds(10, 350, 200, 200);
frame.setVisible(true);
Thread.sleep(2000);
System.err.println("Change frame bounds...");
latch = new CountDownLatch(1);
frame.setBounds(10, 350, 90, 90);
frame.repaint();
try {
if (latch.getCount() > 0) {
latch.await();
}
} catch (InterruptedException e) {
}
frame.dispose();
if (theError != null) {
throw new RuntimeException("Test failed.", theError);
}
System.err.println("Test passed");
}
}

View file

@ -0,0 +1,52 @@
/*
* Copyright (c) 2007, 2017, 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
* @key headful
* @bug 6668439
* @summary Verifies that no exceptions are thrown when frame is resized to 0x0
* @author Dmitri.Trembovetski@sun.com: area=Graphics
* @run main/othervm IAEforEmptyFrameTest
* @run main/othervm -Dsun.java2d.d3d=false IAEforEmptyFrameTest
*/
import javax.swing.JFrame;
public class IAEforEmptyFrameTest {
public static void main(String[] args) {
JFrame f = null;
try {
f = new JFrame("IAEforEmptyFrameTest");
f.setUndecorated(true);
f.setBounds(100, 100, 320, 240);
f.setVisible(true);
try { Thread.sleep(1000); } catch (Exception z) {}
f.setBounds(0, 0, 0, 0);
try { Thread.sleep(1000); } catch (Exception z) {}
f.dispose();
} finally {
f.dispose();
};
}
}

View file

@ -0,0 +1,117 @@
/*
* Copyright (c) 2007, 2016, 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
* @key headful
* @bug 6648018
* @summary Tests that we don't run into infinite validation loop when copying
a VolatileImage to the screen
* @author Dmitri.Trembovetski@sun.com: area=Graphics
* @run main/othervm InfiniteValidationLoopTest
* @run main/othervm -Dsun.java2d.d3d=false InfiniteValidationLoopTest
*/
import java.awt.Color;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.GraphicsConfiguration;
import static java.awt.image.VolatileImage.*;
import java.awt.image.VolatileImage;
import java.util.concurrent.CountDownLatch;
public class InfiniteValidationLoopTest extends Frame {
private static volatile boolean failed = false;
private static final int LOOP_THRESHOLD = 50;
private static volatile CountDownLatch latch;
private VolatileImage vi;
public InfiniteValidationLoopTest() {
super("InfiniteValidationLoopTest");
}
@Override
public void paint(Graphics g) {
try {
runTest(g);
} finally {
latch.countDown();
}
}
private void runTest(Graphics g) {
int status = IMAGE_OK;
int count1 = 0;
do {
GraphicsConfiguration gc = getGraphicsConfiguration();
int count2 = 0;
while (vi == null || (status = vi.validate(gc)) != IMAGE_OK) {
if (++count2 > LOOP_THRESHOLD) {
System.err.println("Infinite loop detected: count2="+count2);
failed = true;
return;
}
if (vi == null || status == IMAGE_INCOMPATIBLE) {
if (vi != null) { vi.flush(); vi = null; }
vi = gc.createCompatibleVolatileImage(100, 100);
continue;
}
if (status == IMAGE_RESTORED) {
Graphics gg = vi.getGraphics();
gg.setColor(Color.green);
gg.fillRect(0, 0, vi.getWidth(), vi.getHeight());
break;
}
}
g.drawImage(vi, getInsets().left, getInsets().top, null);
if (++count1 > LOOP_THRESHOLD) {
System.err.println("Infinite loop detected: count1="+count1);
failed = true;
return;
}
} while (vi.contentsLost());
}
public static void main(String[] args) {
latch = new CountDownLatch(1);
InfiniteValidationLoopTest t1 = new InfiniteValidationLoopTest();
t1.pack();
t1.setSize(200, 200);
t1.setVisible(true);
try { latch.await(); } catch (InterruptedException ex) {}
t1.dispose();
latch = new CountDownLatch(1);
t1 = new InfiniteValidationLoopTest();
t1.pack();
t1.setSize(50, 50);
t1.setVisible(true);
try { latch.await(); } catch (InterruptedException ex) {}
t1.dispose();
if (failed) {
throw new
RuntimeException("Failed: infinite validattion loop detected");
}
System.out.println("Test PASSED");
}
}

View file

@ -0,0 +1,211 @@
/*
* Copyright (c) 2008, 2018, 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 6728834 6749060 8198613
* @summary Tests that LCD AA text rendering works properly with destinations
* being VolatileImage of all transparency types
* @author Dmitri.Trembovetski: area=Graphics
* @run main/manual/othervm -Dsun.java2d.d3d=false NonOpaqueDestLCDAATest
* @run main/manual/othervm NonOpaqueDestLCDAATest
*/
import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
import java.awt.Image;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.image.BufferedImage;
import java.awt.image.VolatileImage;
import java.io.File;
import java.util.concurrent.CountDownLatch;
import javax.imageio.ImageIO;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import static java.awt.Transparency.*;
public class NonOpaqueDestLCDAATest extends JFrame implements ActionListener {
private static volatile boolean passed = true;
private static CountDownLatch complete = new CountDownLatch(1);
public NonOpaqueDestLCDAATest() {
JTextArea desc = new JTextArea();
desc.setText(
"\n Instructions: the three text strings below should appear" +
" readable, without smudges or misshapen bold glyphs.\n" +
" You may need a magnifier to notice some bad colorfringing in "+
" in SW Translucent case, especially in vertical stems.\n\n"+
" Basically text rendered to TRANSLUCENT destination should look"+
" similar to one rendered to OPAQUE - it may differ in whether or" +
" not it's LCD, but it should look 'correct'\n\n"+
"If the text looks fine the test PASSED otherwise it FAILED.\n");
desc.setEditable(false);
desc.setBackground(Color.black);
desc.setForeground(Color.green);
add("North", desc);
JPanel renderPanel = new JPanel() {
@Override
public void paintComponent(Graphics g) {
render(g, getWidth(), getHeight());
}
};
renderPanel.setPreferredSize(new Dimension(1024, 650));
renderPanel.addComponentListener(new ComponentAdapter() {
@Override
public void componentResized(ComponentEvent e) {
images = null;
}
});
add("Center", renderPanel);
JButton passedBtn = new JButton("Passed");
JButton failedBtn = new JButton("Failed");
passedBtn.addActionListener(this);
failedBtn.addActionListener(this);
JPanel p = new JPanel();
p.add(passedBtn);
p.add(failedBtn);
add("South", p);
addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
complete.countDown();
}
});
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
}
public void render(Graphics g, int w, int h) {
initImages(w, h);
g.setColor(new Color(0xAD, 0xD8, 0xE6));
g.fillRect(0, 0, w, h);
Graphics2D g2d = (Graphics2D) g.create();
for (Image im : images) {
g2d.drawImage(im, 0, 0, null);
g2d.translate(0, im.getHeight(null));
}
}
String tr[] = { "OPAQUE", "BITMASK", "TRANSLUCENT" };
@Override
public void actionPerformed(ActionEvent e) {
if (e.getActionCommand().equals("Passed")) {
passed = true;
System.out.println("Test Passed");
} else if (e.getActionCommand().equals("Failed")) {
System.out.println("Test Failed");
for (int i = 0; i < images.length; i++) {
String f = "NonOpaqueDestLCDAATest_"+tr[i];
try {
if (images[i] instanceof VolatileImage) {
f += "_vi.png";
ImageIO.write(((VolatileImage)images[i]).
getSnapshot(), "png", new File(f));
} else {
f += "_bi.png";
ImageIO.write((BufferedImage)images[i],
"png", new File(f));
}
System.out.printf("Dumped %s image to %s\n", tr[i], f);
} catch (Throwable t) {}
}
passed = false;
}
dispose();
complete.countDown();
}
static void clear(Graphics2D g, int type, int w, int h) {
Graphics2D gg = (Graphics2D) g.create();
if (type > OPAQUE) {
gg.setColor(new Color(0, 0, 0, 0));
gg.setComposite(AlphaComposite.Src);
} else {
gg.setColor(new Color(0xAD, 0xD8, 0xE6));
}
gg.fillRect(0, 0, w, h);
}
private void render(Image im, int type, String s) {
Graphics2D g2d = (Graphics2D) im.getGraphics();
clear(g2d, type, im.getWidth(null), im.getHeight(null));
g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_HRGB);
Font f = new Font("Dialog", Font.BOLD, 40);// g2d.getFont().deriveFont(32.0f);
g2d.setColor(Color.white);
g2d.setFont(g2d.getFont().deriveFont(36.0f));
g2d.drawString(s, 10, im.getHeight(null) / 2);
}
Image images[];
private void initImages(int w, int h) {
if (images == null) {
images = new Image[6];
GraphicsConfiguration gc = getGraphicsConfiguration();
for (int i = OPAQUE; i <= TRANSLUCENT; i++) {
VolatileImage vi =
gc.createCompatibleVolatileImage(w,h/images.length,i);
images[i-1] = vi;
vi.validate(gc);
String s = "LCD AA Text rendered to " + tr[i - 1] + " HW destination";
render(vi, i, s);
s = "LCD AA Text rendered to " + tr[i - 1] + " SW destination";
images[i-1+3] = gc.createCompatibleImage(w, h/images.length, i);
render(images[i-1+3], i, s);
}
}
}
public static void main(String[] args) throws InterruptedException {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
NonOpaqueDestLCDAATest t = new NonOpaqueDestLCDAATest();
t.pack();
t.setVisible(true);
}
});
complete.await();
if (!passed) {
throw new RuntimeException("Test Failed!");
}
}
}

View file

@ -0,0 +1,237 @@
/*
* Copyright (c) 2007, 2022, 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
* @key headful
* @bug 6664068 6666931
* @summary Tests that resizing a window to which a tight loop is rendering
* doesn't produce artifacts or crashes
* @run main/othervm OnScreenRenderingResizeTest
* @run main/othervm -Dsun.java2d.d3d=false OnScreenRenderingResizeTest
*/
import java.awt.AWTException;
import java.awt.Color;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.EventQueue;
import java.awt.image.BufferedImage;
import java.awt.image.VolatileImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
public class OnScreenRenderingResizeTest {
private static volatile boolean nocheck = false;
private static int FRAME_W;
private static int FRAME_H;
private static int IMAGE_W;
private static int IMAGE_H;
private static final int tolerance = 12;
private static long RUN_TIME = 1000*20;
private static final Color renderColor = Color.green;
private static final Color bgColor = Color.white;
private static Frame frame;
private static void createAndShowGUI() {
frame = new Frame() {
public void paint(Graphics g) {}
public void update(Graphics g) {}
};
frame.setBackground(bgColor);
frame.setUndecorated(true);
frame.setAlwaysOnTop(true);
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) throws Exception {
for (String arg : args) {
if ("-inf".equals(arg)) {
System.err.println("Test will run indefinitely");
RUN_TIME = Long.MAX_VALUE;
} else if ("-nocheck".equals(arg)) {
System.err.println("Test will not check rendering results");
nocheck = true;
} else {
System.err.println("Usage: OnScreenRenderingResizeTest" +
" [-inf][-nocheck]");
}
}
try {
EventQueue.invokeAndWait(new Runnable() {
public void run() {
createAndShowGUI();
}
});
Thread.sleep(2000);
} catch (Exception ex) {
ex.printStackTrace();
}
try {
GraphicsConfiguration gc = frame.getGraphicsConfiguration();
Rectangle gcBounds = gc.getBounds();
FRAME_W = (gcBounds.width / 4);
FRAME_H = (gcBounds.height / 4);
IMAGE_W = (gcBounds.width / 8);
IMAGE_H = (gcBounds.height / 8);
frame.setBounds(gcBounds.width / 4, gcBounds.height / 4,
FRAME_W, FRAME_H);
BufferedImage output =
new BufferedImage(IMAGE_W, IMAGE_H,
BufferedImage.TYPE_INT_RGB);
output.setAccelerationPriority(0.0f);
Graphics g = output.getGraphics();
g.setColor(renderColor);
g.fillRect(0, 0, IMAGE_W, IMAGE_H);
int maxW = gcBounds.width / 2;
int maxH = gcBounds.height / 2;
int minW = FRAME_W;
int minH = FRAME_H;
int incW = 10, incH = 10, cnt = 0;
Robot robot = null;
if (!nocheck && gc.getColorModel().getPixelSize() > 8) {
try {
robot = new Robot();
robot.setAutoDelay(100);
robot.mouseMove(0,0);
} catch (AWTException ex) {
System.err.println("Robot creation failed, continuing.");
}
} else {
System.err.println("No screen rendering checks.");
}
VolatileImage vi = gc.
createCompatibleVolatileImage(IMAGE_W, IMAGE_H);
vi.validate(gc);
long timeStarted = System.currentTimeMillis();
while ((System.currentTimeMillis() - timeStarted) < RUN_TIME) {
if (++cnt > 100) {
int w = frame.getWidth() + incW;
int h = frame.getHeight() + incH;
if (w < minW || w > maxW ) {
incW = -incW;
}
if (h < minH || h > maxH ) {
incH = -incH;
}
frame.setSize(w, h);
if (robot != null) {
robot.waitForIdle();
}
cnt = 0;
}
// try to put the device into non-default state, for example,
// this operation below will set the transform
vi.validate(gc);
Graphics2D vig = (Graphics2D)vi.getGraphics();
vig.rotate(30.0f, IMAGE_W/2, IMAGE_H/2);
vig.drawImage(output, 0, 0,
IMAGE_W, IMAGE_H, null);
frame.getGraphics().
drawImage(output, 0, 0, null);
if (cnt == 90 && robot != null) {
robot.waitForIdle();
// area where we blit and should be either white or green
Point p = frame.getLocationOnScreen();
p.translate(10, 10);
BufferedImage bi =
robot.createScreenCapture(
new Rectangle(p.x, p.y,
(IMAGE_W / 2), (IMAGE_H / 2)));
int accepted1[] = {Color.white.getRGB(),
Color.green.getRGB()};
checkBI(bi, accepted1);
// the area where we didn't render should stay white
robot.waitForIdle();
p = frame.getLocationOnScreen();
p.translate(10, IMAGE_H + 10);
bi = robot.createScreenCapture(
new Rectangle(p.x, p.y,
frame.getWidth() - 20,
frame.getHeight() - 20 - (IMAGE_H)));
int accepted2[] = { Color.white.getRGB() };
checkBI(bi, accepted2);
}
Thread.yield();
}
} finally {
frame.dispose();
}
System.out.println("Test Passed");
}
private static void checkBI(BufferedImage bi, int accepted[]) {
for (int x = 0; x < bi.getWidth(); x++) {
for (int y = 0; y < bi.getHeight(); y++) {
int actual = bi.getRGB(x, y);
int alpha = (actual >> 24) & 0xFF;
int red = (actual >> 16) & 0xFF;
int green = (actual >> 8) & 0xFF;
int blue = (actual) & 0xFF;
boolean found = false;
for (int acc : accepted) {
int accAlpha = (acc >> 24) & 0xFF;
int accRed = (acc >> 16) & 0xFF;
int accGreen = (acc >> 8) & 0xFF;
int accBlue = (acc) & 0xFF;
if (!(Math.abs(alpha - accAlpha) > tolerance ||
Math.abs(red - accRed) > tolerance ||
Math.abs(green - accGreen) > tolerance ||
Math.abs(blue - accBlue) > tolerance)) {
found = true;
break;
}
}
if (!found) {
try {
String name = "OnScreenRenderingResizeTest.png";
ImageIO.write(bi, "png", new File(name));
System.out.println("Screen shot file: " + name);
} catch (IOException ex) {}
throw new
RuntimeException("Test failed at " + x + "-" + y +
" rgb=0x" + Integer.
toHexString(actual));
}
}
}
}
}

View file

@ -0,0 +1,75 @@
/*
* Copyright (c) 2007, 2018, 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
* @key headful
* @bug 6764257 8198613
* @summary Tests that the alpha in opaque images doesn't affect result of alpha
* compositing
* @author Dmitri.Trembovetski@sun.com: area=Graphics
* @run main/othervm OpaqueImageToSurfaceBlitTest
* @run main/othervm -Dsun.java2d.noddraw=true OpaqueImageToSurfaceBlitTest
*/
import java.awt.AlphaComposite;
import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferInt;
import java.awt.image.VolatileImage;
public class OpaqueImageToSurfaceBlitTest {
public static void main(String[] args) {
GraphicsEnvironment ge =
GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice gd = ge.getDefaultScreenDevice();
GraphicsConfiguration gc = gd.getDefaultConfiguration();
VolatileImage vi = gc.createCompatibleVolatileImage(16, 16);
vi.validate(gc);
BufferedImage bi =
new BufferedImage(2, 2, BufferedImage.TYPE_INT_RGB);
int data[] = ((DataBufferInt)bi.getRaster().getDataBuffer()).getData();
data[0] = 0x0000007f;
data[1] = 0x0000007f;
data[2] = 0xff00007f;
data[3] = 0xff00007f;
Graphics2D g = vi.createGraphics();
g.setComposite(AlphaComposite.SrcOver.derive(0.999f));
g.drawImage(bi, 0, 0, null);
bi = vi.getSnapshot();
if (bi.getRGB(0, 0) != bi.getRGB(1, 1)) {
throw new RuntimeException("Test FAILED: color at 0x0 ="+
Integer.toHexString(bi.getRGB(0, 0))+" differs from 1x1 ="+
Integer.toHexString(bi.getRGB(1,1)));
}
System.out.println("Test PASSED.");
}
}

View file

@ -0,0 +1,150 @@
/*
* Copyright (c) 2007, 2018, 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
* @key headful
* @bug 6694230 8198613
* @summary Tests that components overriding getInsets paint correctly
* @author Dmitri.Trembovetski@sun.com: area=Graphics
* @run main/othervm OverriddenInsetsTest
*/
import java.awt.Color;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.GraphicsEnvironment;
import java.awt.Insets;
import java.awt.Panel;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.concurrent.CountDownLatch;
import javax.imageio.ImageIO;
public class OverriddenInsetsTest {
public static final Insets INSETS1 = new Insets(25,25,0,0);
public static final Insets INSETS2 = new Insets(100,100,0,0);
static final CountDownLatch lock = new CountDownLatch(1);
static boolean failed = false;
public static void main(String[] args) {
if (GraphicsEnvironment.getLocalGraphicsEnvironment().
getDefaultScreenDevice().getDefaultConfiguration().
getColorModel().getPixelSize() < 16)
{
System.out.println("<16 bit mode detected, test passed");
}
final Frame f = new Frame("OverriddenInsetsTest");
f.setSize(260,260);
f.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
f.setVisible(false);
System.exit(0);
}
});
f.setBackground(Color.gray);
Panel p1 = new Panel() {
public Insets getInsets() {
return INSETS1;
}
};
p1.setLayout(null);
p1.setSize(250, 250);
Panel p = new Panel(){
@Override
public Insets getInsets() {
return INSETS2;
}
public void paint(Graphics g) {
// make sure Vista is done with its effects
try {
Thread.sleep(2000);
} catch (InterruptedException ex) {}
g.setColor(Color.red);
g.drawRect(0,0,getWidth()-1,getHeight()-1 );
g.setColor(Color.blue);
g.fillRect(0,0,getWidth()/2,getHeight()/2);
Point p = getLocationOnScreen();
try {
Robot r = new Robot();
BufferedImage bi =
r.createScreenCapture(new
Rectangle(p.x, p.y, getWidth()/2, getHeight()/2));
for (int y = 0; y < bi.getHeight(); y++) {
for (int x = 0; x < bi.getWidth(); x++) {
if (bi.getRGB(x, y) != Color.blue.getRGB()) {
failed = true;
System.err.printf("Test failed at %d %d c=%x\n",
x, y, bi.getRGB(x, y));
String name = "OverriddenInsetsTest_res.png";
try {
ImageIO.write(bi, "png", new File(name));
System.out.println("Dumped res to: "+name);
} catch (IOException e) {}
return;
}
}
}
} catch (Exception e) {
failed = true;
} finally {
lock.countDown();
}
}
};
p.setSize(200, 200);
p1.add(p);
p.setLocation(50, 50);
f.add(p1);
f.setVisible(true);
try {
lock.await();
} catch (InterruptedException ex) {
ex.printStackTrace();
}
if (args.length <= 0 || !"-show".equals(args[0])) {
f.dispose();
}
if (failed) {
throw new RuntimeException("Test FAILED.");
}
System.out.println("Test PASSED");
}
}

View file

@ -0,0 +1,175 @@
/*
* Copyright (c) 2007, 2016, 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
* @key headful
* @bug 6648018 6652662
* @summary Verifies that rendering to a cached onscreen Graphics works
* @author Dmitri.Trembovetski@sun.com: area=Graphics
* @run main/othervm RenderingToCachedGraphicsTest
* @run main/othervm -Dsun.java2d.d3d=false RenderingToCachedGraphicsTest
*/
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.GraphicsEnvironment;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.Toolkit;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.image.BufferStrategy;
import java.awt.image.BufferedImage;
import static java.awt.image.VolatileImage.*;
import java.awt.image.VolatileImage;
import java.io.File;
import java.util.concurrent.CountDownLatch;
import javax.imageio.ImageIO;
public class RenderingToCachedGraphicsTest extends Frame {
private static volatile boolean failed = false;
private static volatile CountDownLatch latch;
private Graphics cachedGraphics;
private Canvas renderCanvas;
public RenderingToCachedGraphicsTest() {
super("Test starts in 2 seconds");
renderCanvas = new Canvas() {
@Override
public void paint(Graphics g) {
if (getWidth() < 100 || getHeight() < 100) {
repaint();
return;
}
// wait for a bit so that Vista's Window manager's animation
// effects on window's appearance are completed (6652662)
try { Thread.sleep(2000); } catch (InterruptedException ex) {}
try {
runTest();
} catch (Throwable t) {
failed = true;
} finally {
latch.countDown();
}
}
@Override
public void update(Graphics g) {}
};
add("Center", renderCanvas);
}
private void runTest() {
// this will cause screen update manager to dump the accelerated surface
// for this canvas
renderCanvas.createBufferStrategy(2);
BufferStrategy bs = renderCanvas.getBufferStrategy();
do {
Graphics bsg = bs.getDrawGraphics();
bsg.setColor(Color.blue);
bsg.fillRect(0, 0,
renderCanvas.getWidth(), renderCanvas.getHeight());
} while (bs.contentsLost() || bs.contentsRestored());
// grab the "unaccelerated" onscreen surface
cachedGraphics = renderCanvas.getGraphics();
cachedGraphics.setColor(Color.red);
cachedGraphics.fillRect(0, 0, getWidth(), getHeight());
bs.dispose();
bs = null;
// now the update manager should be able to accelerate onscreen
// rendering to it again
cachedGraphics.setColor(Color.green);
// this causes restoration of the new accelerated onscreen surface
// (it is created in "lost" state)
cachedGraphics.fillRect(0, 0,
renderCanvas.getWidth(),
renderCanvas.getHeight());
Toolkit.getDefaultToolkit().sync();
// and now we should be able to render to it
cachedGraphics.fillRect(0, 0,
renderCanvas.getWidth(),
renderCanvas.getHeight());
Toolkit.getDefaultToolkit().sync();
Robot robot = null;
try {
robot = new Robot();
} catch (Exception e) {
e.printStackTrace();
failed = true;
return;
}
Point p = renderCanvas.getLocationOnScreen();
Rectangle r = new Rectangle(p.x, p.y,
renderCanvas.getWidth(),
renderCanvas.getHeight());
BufferedImage bi = robot.createScreenCapture(r);
for (int y = 0; y < bi.getHeight(); y++) {
for (int x = 0; x < bi.getWidth(); x++) {
if (bi.getRGB(x, y) != Color.green.getRGB()) {
System.err.println("Colors mismatch!");
String name = "RenderingToCachedGraphicsTest.png";
try {
ImageIO.write(bi, "png", new File(name));
System.err.println("Dumped grabbed image to: "+name);
} catch (Exception e) {}
failed = true;
return;
}
}
}
}
public static void main(String[] args) {
int depth = GraphicsEnvironment.getLocalGraphicsEnvironment().
getDefaultScreenDevice().getDefaultConfiguration().
getColorModel().getPixelSize();
if (depth < 16) {
System.out.println("Test PASSED (depth < 16bit)");
return;
}
latch = new CountDownLatch(1);
RenderingToCachedGraphicsTest t1 = new RenderingToCachedGraphicsTest();
t1.pack();
t1.setSize(300, 300);
t1.setVisible(true);
try { latch.await(); } catch (InterruptedException ex) {}
t1.dispose();
if (failed) {
throw new
RuntimeException("Failed: rendering didn't show up");
}
System.out.println("Test PASSED");
}
}

View file

@ -0,0 +1,109 @@
/*
* Copyright (c) 2007, 2018, 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
* @key headful
* @bug 6705443 8198613
* @summary tests that we don't crash during exit if font strikes were disposed
* during the lifetime of the application
*
* @run main/othervm -Dsun.java2d.font.reftype=weak StrikeDisposalCrashTest
* @run main/othervm -Dsun.java2d.font.reftype=weak -Dsun.java2d.noddraw=true StrikeDisposalCrashTest
*/
import java.awt.Font;
import java.awt.Frame;
import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.RenderingHints;
import java.awt.Toolkit;
import java.awt.image.VolatileImage;
public class StrikeDisposalCrashTest {
public static void main(String[] args) {
System.setProperty("sun.java2d.font.reftype", "weak");
GraphicsDevice gd[] =
GraphicsEnvironment.getLocalGraphicsEnvironment().getScreenDevices();
Frame frames[] = new Frame[gd.length];
for (int i = 0; i < frames.length; i++) {
GraphicsConfiguration gc = gd[i].getDefaultConfiguration();
Frame f = new Frame("Frame on "+gc, gc);
f.setSize(100, 100);
f.setLocation(gc.getBounds().x, gc.getBounds().y);
f.pack();
frames[i] = f;
}
Font f1 = new Font("Dialog", Font.PLAIN, 10);
Font f2 = new Font("Dialog", Font.ITALIC, 12);
for (int i = 0; i < frames.length/2; i++) {
// making sure the glyphs are cached in the accel. cache on
// one frame, then the other
renderText(frames[i], f1);
renderText(frames[frames.length -1 - i], f1);
// and now the other way around, with different glyphs
renderText(frames[frames.length -1 - i], f2);
renderText(frames[i], f2);
}
// try to force strike disposal (note that we have to use
// -Dsun.java2d.font.reftype=weak to facilitate the disposal)
System.gc();
System.runFinalization();
System.gc();
System.runFinalization();
for (Frame f : frames) {
f.dispose();
}
System.err.println("Exiting. If the test crashed after this it FAILED");
}
private static final String text =
"The quick brown fox jumps over the lazy dog 1234567890";
private static void renderText(Frame frame, Font f1) {
VolatileImage vi = frame.createVolatileImage(256, 32);
vi.validate(frame.getGraphicsConfiguration());
Graphics2D g = vi.createGraphics();
g.setFont(f1);
g.drawString(text, 0, vi.getHeight()/2);
g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
g.drawString(text, 0, vi.getHeight()/2);
g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_HRGB);
g.drawString(text, 0, vi.getHeight()/2);
Toolkit.getDefaultToolkit().sync();
}
}

View file

@ -0,0 +1,146 @@
/*
* Copyright (c) 2007, 2018, 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
* @key headful
* @bug 6630702 8198613
* @summary Tests that scrolling after paint() is performed correctly.
* This is really only applicable to Vista
* @author Dmitri.Trembovetski@sun.com: area=Graphics
* @run main/othervm SwingOnScreenScrollingTest
*/
import java.awt.AWTException;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.GraphicsEnvironment;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.image.BufferedImage;
import java.io.File;
import java.lang.reflect.InvocationTargetException;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
public class SwingOnScreenScrollingTest extends JPanel {
static JScrollPane pane;
static SwingOnScreenScrollingTest test;
public SwingOnScreenScrollingTest() {
}
public static void main(String[] args) {
int size = GraphicsEnvironment.
getLocalGraphicsEnvironment().
getDefaultScreenDevice().
getDefaultConfiguration().getColorModel().getPixelSize();
if (size < 16) {
System.err.println("<16 bit display mode detected. Test PASSED");
return;
}
final JFrame f = new JFrame("SwingOnScreenScrollingTest");
try {
EventQueue.invokeAndWait(new Runnable() {
public void run() {
test = new SwingOnScreenScrollingTest();
pane = new JScrollPane(test);
f.add(pane);
f.pack();
f.setSize(100, 200);
f.setVisible(true);
}
});
} catch (InvocationTargetException ex) {
ex.printStackTrace();
} catch (InterruptedException ex) {
ex.printStackTrace();
}
try {
Thread.sleep(500);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
EventQueue.invokeLater(new Runnable() {
public void run() {
BufferedImage bi;
bi = new BufferedImage(100, 300,
BufferedImage.TYPE_INT_RGB);
Graphics gg = bi.getGraphics();
test.paint(gg);
for (int y = 80; y < 200; y +=10) {
test.scrollRectToVisible(new Rectangle(0, y, 100, 100));
try {
Thread.sleep(200);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
Point p = pane.getViewport().getLocationOnScreen();
Robot r = null;
try {
r = new Robot();
} catch (AWTException ex) {
throw new RuntimeException(ex);
}
bi = r.createScreenCapture(new Rectangle(p.x+5, p.y+5, 30, 30));
for (int y = 0; y < bi.getHeight(); y++) {
for (int x = 0; x < bi.getHeight(); x++) {
int rgb = bi.getRGB(x, y);
if (bi.getRGB(x, y) != Color.red.getRGB()) {
System.err.printf("Test Failed at (%d,%d) c=0x%x\n",
x, y, rgb);
try {
String name =
"SwingOnScreenScrollingTest_out.png";
ImageIO.write(bi, "png", new File(name));
System.err.println("Wrote grabbed image to "+
name);
} catch (Throwable ex) {}
throw new RuntimeException("Test failed");
}
}
}
System.out.println("Test PASSED.");
f.dispose();
}
});
}
protected void paintComponent(Graphics g) {
g.setColor(Color.green);
g.fillRect(0, 0, getWidth(), 100);
g.setColor(Color.red);
g.fillRect(0, 100, getWidth(), getHeight()-100);
}
public Dimension getPreferredSize() {
return new Dimension(100, 300);
}
}

View file

@ -0,0 +1,219 @@
/*
* Copyright (c) 2007, 2018, 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
* @key headful
* @bug 6689025 8023483 8198613
* @summary Tests that transformed Paints are rendered correctly
* @author Dmitri.Trembovetski@sun.com: area=Graphics
* @run main/othervm TransformedPaintTest
*/
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GradientPaint;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsEnvironment;
import java.awt.LinearGradientPaint;
import java.awt.MultipleGradientPaint.CycleMethod;
import java.awt.Paint;
import java.awt.RadialGradientPaint;
import java.awt.TexturePaint;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.awt.image.VolatileImage;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class TransformedPaintTest {
private static enum PaintType {
COLOR,
GRADIENT,
LINEAR_GRADIENT,
RADIAL_GRADIENT,
TEXTURE
};
private static final int CELL_SIZE = 100;
private static final int R_WIDTH = 3 * CELL_SIZE;
private static final int R_HEIGHT = PaintType.values().length * CELL_SIZE;
private Paint createPaint(PaintType type, int startx, int starty,
int w, int h)
{
// make sure that the blue color doesn't show up when filling a
// w by h rect
w++; h++;
int endx = startx + w;
int endy = starty + h;
Rectangle2D.Float r = new Rectangle2D.Float(startx, starty, w, h);
switch (type) {
case COLOR: return Color.red;
case GRADIENT: return
new GradientPaint(startx, starty, Color.red,
endx, endy, Color.green);
case LINEAR_GRADIENT: return
new LinearGradientPaint(startx, starty, endx, endy,
new float[] { 0.0f, 0.999f, 1.0f },
new Color[] { Color.red, Color.green, Color.blue });
case RADIAL_GRADIENT: return
new RadialGradientPaint(startx, starty,
(float)Math.sqrt(w * w + h * h),
new float[] { 0.0f, 0.999f, 1.0f },
new Color[] { Color.red, Color.green, Color.blue },
CycleMethod.NO_CYCLE);
case TEXTURE: {
BufferedImage bi =
new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
Graphics2D g = (Graphics2D) bi.getGraphics();
g.setPaint(createPaint(PaintType.LINEAR_GRADIENT, 0, 0, w, h));
g.fillRect(0, 0, w, h);
return new TexturePaint(bi, r);
}
}
return Color.green;
}
private void renderLine(PaintType type, Graphics2D g,
int startx, int starty, int w, int h)
{
Paint p = createPaint(type, startx, starty, w, h);
g.setPaint(p);
// first, no transform
g.fillRect(startx, starty, w, h);
// translation only
g.translate(w, 0);
g.fillRect(startx, starty, w, h);
g.translate(-w, 0);
// complex transform
g.translate(startx + w*2, starty);
g.rotate(Math.toRadians(90), w/2, h/2);
g.translate(-startx, -starty);
g.fillRect(startx, starty, w, h);
}
private void render(Graphics2D g, int w, int h) {
int paintTypes = PaintType.values().length;
int ystep = h / paintTypes;
int y = 0;
for (PaintType type : PaintType.values()) {
renderLine(type, (Graphics2D)g.create(),
0, y, h / paintTypes, h / paintTypes);
y += ystep;
}
}
private void checkBI(BufferedImage bi) {
for (int y = 0; y < bi.getHeight(); y++) {
for (int x = 0; x < bi.getWidth(); x++) {
if (bi.getRGB(x, y) == Color.blue.getRGB()) {
try {
String fileName = "TransformedPaintTest_res.png";
ImageIO.write(bi, "png", new File(fileName));
System.err.println("Dumped image to: " + fileName);
} catch (IOException ex) {}
throw new RuntimeException("Test failed, blue color found");
}
}
}
}
private void runTest() {
GraphicsConfiguration gc = GraphicsEnvironment.
getLocalGraphicsEnvironment().getDefaultScreenDevice().
getDefaultConfiguration();
if (gc.getColorModel().getPixelSize() < 16) {
System.out.println("8-bit desktop depth found, test passed");
return;
}
VolatileImage vi = gc.createCompatibleVolatileImage(R_WIDTH, R_HEIGHT);
BufferedImage bi = null;
do {
vi.validate(gc);
Graphics2D g = vi.createGraphics();
render(g, vi.getWidth(), vi.getHeight());
bi = vi.getSnapshot();
} while (vi.contentsLost());
checkBI(bi);
System.out.println("Test PASSED.");
}
private static void showFrame(final TransformedPaintTest t) {
JFrame f = new JFrame("TransformedPaintTest");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
final BufferedImage bi =
new BufferedImage(R_WIDTH, R_HEIGHT, BufferedImage.TYPE_INT_RGB);
JPanel p = new JPanel() {
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
t.render(g2d, R_WIDTH, R_HEIGHT);
t.render(bi.createGraphics(), R_WIDTH, R_HEIGHT);
g2d.drawImage(bi, R_WIDTH + 5, 0, null);
g.setColor(Color.black);
g.drawString("Rendered to Back Buffer", 10, 20);
g.drawString("Rendered to BufferedImage", R_WIDTH + 15, 20);
}
};
p.setPreferredSize(new Dimension(2 * R_WIDTH + 5, R_HEIGHT));
f.add(p);
f.pack();
f.setVisible(true);
}
public static void main(String[] args) throws
InterruptedException, InvocationTargetException
{
boolean show = (args.length > 0 && "-show".equals(args[0]));
final TransformedPaintTest t = new TransformedPaintTest();
if (show) {
EventQueue.invokeAndWait(new Runnable() {
public void run() {
showFrame(t);
}
});
} else {
t.runTest();
}
}
}

View file

@ -0,0 +1,97 @@
/*
* Copyright (c) 2015, 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.
*/
import java.util.LinkedList;
import java.util.List;
import sun.java2d.Disposer;
import sun.java2d.DisposerRecord;
/**
* @test
* @bug 8129457
* @summary Check Disposer disposes all objects without any memory leaks
* @run main/othervm -Xmx128m TestDisposerLeak
* @modules java.desktop/sun.java2d
*/
public final class TestDisposerLeak {
private static final int COUNT = 30000;
private static volatile boolean disposerComplete;
private static volatile boolean readyForDispose;
static int disposeCount = 0;
public static void main(String[] args) throws Exception {
TestDisposerLeak test = new TestDisposerLeak();
test.testLeak();
while (!disposerComplete) {}
if (disposeCount != COUNT) {
System.err.println("dispose called " + disposeCount);
throw new RuntimeException("All objects are not disposed");
}else {
System.out.println("Test PASSED");
}
}
public void testLeak() throws Exception {
MyDisposerRec disposerRecord = new MyDisposerRec();
for (int i = 0; i < 30000; i++) {
Disposer.addObjectRecord(new Object(), disposerRecord);
}
generateOOME();
readyForDispose = true;
Disposer.addObjectRecord(new Object(), new EndRec());
generateOOME();
}
class MyDisposerRec implements DisposerRecord, Disposer.PollDisposable {
public void dispose() {
while (!readyForDispose) {}
disposeCount++;
Disposer.pollRemove();
}
}
class EndRec implements DisposerRecord, Disposer.PollDisposable {
public void dispose() {
disposerComplete = true;
}
}
private static void generateOOME() throws Exception {
List<Object> leak = new LinkedList<>();
try {
while (true) {
leak.add(new byte[1024 * 1024]);
}
} catch (OutOfMemoryError e) {
}
// Give the GC a chance at that weakref in case of slow systems
Thread.sleep(2000);
}
}

View file

@ -0,0 +1,152 @@
/*
* Copyright (c) 2022, JetBrains s.r.o.. 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.
*/
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Supplier;
import javax.swing.SwingUtilities;
import sun.java2d.Disposer;
import sun.java2d.DisposerRecord;
/**
* @test
* @bug 8289208
* @summary Verifies Disposer robustness in a multi-threaded environment.
* @run main/othervm -Xmx128m TestDisposerRace
* @modules java.desktop/sun.java2d
*/
public final class TestDisposerRace {
private static final AtomicInteger recordsCount = new AtomicInteger();
private static volatile boolean disposerDone = false;
private static final String KO_OVERFLOW = "Some records have not been disposed!";
private static final String KO_UNDERFLOW = "Disposed more records than were added!";
public static void main(String[] args) throws Exception {
new TestDisposerRace().run();
checkRecordsCountIsSane();
if (recordsCount.get() > 0) {
System.err.println(KO_OVERFLOW); // In case the next line fails to allocate due to OOME
throw new RuntimeException("Some records (" + recordsCount + ") have not been disposed");
}
}
interface ThrowingRunnable<E extends Exception> {
void run() throws E;
}
TestDisposerRace() {
addRecordsToDisposer(30_000);
}
void run() throws Exception {
generateOOME();
for (int i = 0; i < 1000; ++i) {
retryOnOOME(() -> SwingUtilities.invokeAndWait(Disposer::pollRemove));
// Adding records will race with the diposer trying to remove them
if (i % 10 == 0)
addRecordsToDisposer(1000);
}
retryOnOOME(() -> Disposer.addObjectRecord(new Object(), new FinalDisposerRecord()));
while (!disposerDone) {
generateOOME();
}
}
private static void checkRecordsCountIsSane() {
if (recordsCount.get() < 0) {
throw new RuntimeException(KO_UNDERFLOW);
}
}
private static <T> T retryOnOOME(Supplier<T> allocator) {
for(;;) {
try {
return allocator.get();
} catch (OutOfMemoryError ignored1) {
try {
Thread.sleep(1); // Give GC a little chance to run
} catch (InterruptedException ignored2) {}
}
}
}
private static <E extends Exception> void retryOnOOME(ThrowingRunnable<E> tr) throws E {
for(;;) {
try {
tr.run();
break;
} catch (OutOfMemoryError ignored1) {
try {
Thread.sleep(1); // Give GC a little chance to run
} catch (InterruptedException ignored2) {}
}
}
}
private void addRecordsToDisposer(int count) {
checkRecordsCountIsSane();
MyDisposerRecord disposerRecord = retryOnOOME(MyDisposerRecord::new);
while(count > 0) {
recordsCount.incrementAndGet(); // pre-add to make sure it doesn't go negative
var o = retryOnOOME(Object::new);
retryOnOOME(() -> Disposer.addObjectRecord(o, disposerRecord));
--count;
}
}
class MyDisposerRecord implements DisposerRecord {
public void dispose() {
recordsCount.decrementAndGet();
}
}
class FinalDisposerRecord implements DisposerRecord {
public void dispose() {
disposerDone = true;
}
}
private static void giveGCAChance() {
try {
Thread.sleep(2000);
} catch (InterruptedException ignored) {}
}
private static void generateOOME() throws Exception {
try {
final List<Object> leak = new LinkedList<>();
while (true) {
leak.add(new byte[1024 * 1024]);
}
} catch (OutOfMemoryError ignored) {}
giveGCAChance();
}
}

View file

@ -0,0 +1,57 @@
/*
* Copyright (c) 2014, 2016, 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.
*/
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsEnvironment;
import java.awt.image.BufferedImage;
import java.awt.image.VolatileImage;
/**
* @test
* @key headful
* @bug 8039774
* @summary Verifies that we get no exception, when we draw with scale
* BufferedImage to VolatileImage via intermediate texture.
* @author Sergey Bylokhov
* @run main/othervm -Dsun.java2d.accthreshold=0 DrawCachedImageAndTransform
*/
public final class DrawCachedImageAndTransform {
public static void main(String[] args) {
GraphicsEnvironment ge = GraphicsEnvironment
.getLocalGraphicsEnvironment();
GraphicsConfiguration gc = ge.getDefaultScreenDevice()
.getDefaultConfiguration();
VolatileImage vi = gc.createCompatibleVolatileImage(100, 100);
Graphics2D g2d = vi.createGraphics();
g2d.scale(2, 2);
BufferedImage img = new BufferedImage(50, 50,
BufferedImage.TYPE_INT_ARGB);
g2d.drawImage(img, 10, 25, Color.blue, null);
g2d.dispose();
}
}

View file

@ -0,0 +1,111 @@
/*
* Copyright (c) 2014, 2016, 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
* @key headful
* @bug 8036022
* @summary Test verifies that drawing shapes with XOR composite
* does not trigger an InternalError in GDI surface data.
* @run main/othervm -Dsun.java2d.d3d=True DrawXORModeTest
*/
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Stroke;
import java.awt.geom.Line2D;
import java.util.concurrent.CountDownLatch;
public class DrawXORModeTest extends Component {
public static void main(String[] args) {
final DrawXORModeTest c = new DrawXORModeTest();
final Frame f = new Frame("XOR mode test");
f.add(c);
f.pack();
f.setVisible(true);
try {
c.checkResult();
} finally {
f.dispose();
}
}
@Override
public void paint(Graphics g) {
if (g == null || !(g instanceof Graphics2D)) {
return;
}
g.setColor(Color.white);
g.setXORMode(Color.black);
Graphics2D dg = (Graphics2D) g;
Stroke stroke = new BasicStroke(1, BasicStroke.CAP_BUTT,
BasicStroke.JOIN_MITER,
10.0f,
new float[]{1.0f, 1.0f},
0.0f);
dg.setStroke(stroke);
try {
dg.draw(new Line2D.Float(10, 10, 20, 20));
} catch (Throwable e) {
synchronized (this) {
theError = e;
}
} finally {
didDraw.countDown();
}
}
@Override
public Dimension getPreferredSize() {
return new Dimension(400, 100);
}
public void checkResult() {
try {
didDraw.await();
} catch (InterruptedException e) {
}
synchronized (this) {
if (theError != null) {
System.out.println("Error: " + theError);
throw new RuntimeException("Test FAILED.");
}
}
System.out.println("Test PASSED.");
}
private Throwable theError = null;
private final CountDownLatch didDraw = new CountDownLatch(1);
}

View file

@ -0,0 +1,518 @@
/*
* Copyright (c) 2003, 2022, 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 4925447 4887054 8285604
* @key headful
* @summary verifies that most basic rendering operations going are successfully
* clipped against a complex clip shape
* @run main ClipShapeRendering
*/
/**
* This test creates a complex clip shape (basically, a rectangular hole
* cut out of the center of the rendering area) and then cycles through
* various rendering primitives (image copies, lines, text, and shapes)
* under various situations (default, scaled transform, and wide lines).
* After all of that, Robot is used to check whether the clip shape has
* been disturbed by any of the rendering (no pixels from the rendering
* operations should have done anything inside the clipped-out area); the
* test passes or fails based on whether the clip shape is undisturbed.
*
* There is a performance-test version of this app which runs all of the
* tests in loops and times the results. This can be useful to see, for
* example, the difference in performance between old and new internal
* implementations of this clip-shape situation. To run the performance
* test, run ClipShapeRendering -perf.
*/
import java.awt.AWTException;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Component;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.Robot;
import java.awt.Stroke;
import java.awt.Toolkit;
import java.awt.geom.AffineTransform;
import java.awt.geom.Area;
import java.awt.geom.GeneralPath;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.awt.image.DirectColorModel;
import java.awt.image.WritableRaster;
public class ClipShapeRendering extends Frame {
BufferedImage image;
BufferedImage imageBM;
static Image offScreenImage;
static boolean timeToRun = false;
static Color imageColor = Color.red;
static Color fillColor = Color.blue;
static boolean perfMode = false;
static boolean showCapture = false;
static Rectangle clipRect = new Rectangle(100, 100, 100, 100);
// move away from cursor
private final static int OFFSET_X = 20;
private final static int OFFSET_Y = 20;
public ClipShapeRendering() {
super("On-screen rendering test frame");
}
public void initImages(Color imageColor) {
int w = getWidth();
int h = getHeight();
ColorModel cm = new DirectColorModel(25, 0xff0000, 0xff00, 0xff, 0x1000000);
WritableRaster wr =
cm.createCompatibleWritableRaster(w, h);
imageBM = new BufferedImage(cm, wr,
cm.isAlphaPremultiplied(), null);
Graphics g2 = imageBM.createGraphics();
g2.setColor(imageColor);
g2.fillRect(0, 0, w, h);
image = new BufferedImage(w, h,
BufferedImage.TYPE_INT_RGB);
g2 = image.createGraphics();
g2.setColor(imageColor);
g2.fillRect(0,0, w, h);
g2.dispose();
offScreenImage = createImage(w, h);
}
public void paint(Graphics g) {
synchronized (this) {
timeToRun = true;
notifyAll();
}
}
public void runTests() {
initImages(imageColor);
// run off-screen test
System.out.println("Running OFF-SCREEN tests..");
runTest(offScreenImage.getGraphics());
// run on-screen test
System.out.println("Running ON-SCREEN tests..");
runTest(getGraphics());
}
/**
* Set various parameters on the Graphics object and call the
* rendering loop with each variation
*/
public void runTest(Graphics g) {
int w = getWidth();
int h = getHeight();
Area area = new Area( new Rectangle(0,0, w, h));
area.subtract(new Area(clipRect));
// Fill completely with background color
g.setColor(fillColor);
g.fillRect(0, 0, w, h);
// Set the clip shape
g.setClip(area);
// Now perform various rendering operations
g.setColor(Color.black);
Graphics2D g2 = (Graphics2D)g;
if (perfMode) {
System.out.println("Default Graphics Results:");
System.out.println("-------------------------");
}
renderingLoop(g2);
if (perfMode) {
System.out.println("Scaling Transform Results:");
System.out.println("-------------------------");
}
AffineTransform oldXform = g2.getTransform();
g2.scale(.9, 1.15);
renderingLoop(g2);
g2.setTransform(oldXform);
if (perfMode) {
System.out.println("Wide Lines Results:");
System.out.println("-------------------");
}
Stroke oldStroke = g2.getStroke();
g2.setStroke(new BasicStroke(5.0f));
renderingLoop(g2);
g2.setStroke(oldStroke);
}
public void renderingLoop(Graphics2D g) {
int numReps = 1;
int numTextReps = 1;
long start, end;
if (perfMode) {
numReps = 1000;
numTextReps = 50;
}
int w = getWidth();
int h = getHeight();
// Image copies
robot.waitForIdle();
start = System.currentTimeMillis();
for (int i = 0; i < numReps; ++i) {
g.drawImage(image, 0, 0, null);
g.drawImage(image, -10, -10, null);
g.drawImage(image, 50, 50, null);
g.drawImage(image, 40, 10, null);
}
for (int i = 0; i < numReps; ++i) {
g.drawImage(imageBM, 0, 0, Color.yellow, null);
g.drawImage(imageBM, -10, -10, Color.yellow, null);
g.drawImage(imageBM, 50, 50, Color.yellow, null);
g.drawImage(imageBM, 40, 10, Color.yellow, null);
}
robot.waitForIdle();
end = System.currentTimeMillis();
if (perfMode) {
System.out.println("Image Copies : " + (end - start) + " ms");
}
// Image scales
start = System.currentTimeMillis();
for (int i = 0; i < numReps; ++i) {
g.drawImage(image, 0, 0, 500, 500, null);
}
robot.waitForIdle();
end = System.currentTimeMillis();
if (perfMode) {
System.out.println("Image scales : " + (end - start) + " ms");
}
// Lines
start = System.currentTimeMillis();
for (int i = 0; i < numReps; ++i) {
g.drawLine(0, 0, w, h);
g.drawLine(0, h, w, 0);
g.drawLine(0, h / 2, w, h / 2);
g.drawLine(w / 2, 0, w / 2, h);
}
robot.waitForIdle();
end = System.currentTimeMillis();
if (perfMode) {
System.out.println("drawLine : " + (end - start) + " ms");
}
// Text
// Non-AA
start = System.currentTimeMillis();
for (int i = 0; i < numTextReps; ++i) {
for (int x = 0; x < w; x += 20) {
for (int y = 0; y < h; y += 17) {
g.drawString("This is a string, this is only a string", x,
y);
}
}
}
robot.waitForIdle();
end = System.currentTimeMillis();
if (perfMode) {
System.out.println("Text Non-AA : " + (end - start) + " ms");
}
// Anti-Aliased
Graphics2D g2 = (Graphics2D)g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
start = System.currentTimeMillis();
for (int i = 0; i < numTextReps; ++i) {
for (int x = 0; x < w; x += 20) {
for (int y = 0; y < h; y += 17) {
g.drawString("This is a string, this is only a string", x,
y);
}
}
}
robot.waitForIdle();
end = System.currentTimeMillis();
if (perfMode) {
System.out.println("Text General AA: " + (end - start) + " ms");
}
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_OFF);
// Text AA
g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
start = System.currentTimeMillis();
for (int i = 0; i < numTextReps; ++i) {
for (int x = 0; x < w; x += 20) {
for (int y = 0; y < h; y += 17) {
g.drawString("This is a string, this is only a string", x,
y);
}
}
}
robot.waitForIdle();
end = System.currentTimeMillis();
if (perfMode) {
System.out.println("Text textAA : " + (end - start) + " ms");
}
g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
RenderingHints.VALUE_TEXT_ANTIALIAS_OFF);
// Arcs
start = System.currentTimeMillis();
if (numReps > 1) {
numReps /= 10;
}
for (int i = 0; i < numReps; ++i) {
for (int x = 0; x < w; x += 20) {
for (int y = 0; y < h; y += 17) {
g.drawArc(x, y, 30, 30, 0, 45);
g.fillArc(x, y, 25, 25, 0, 45);
}
}
}
robot.waitForIdle();
end = System.currentTimeMillis();
if (perfMode) {
System.out.println("arcs : " + (end - start) + " ms");
}
// Ovals
start = System.currentTimeMillis();
if (numReps > 1) {
numReps /= 10;
}
for (int i = 0; i < numReps; ++i) {
for (int x = 0; x < w; x += 20) {
for (int y = 0; y < h; y += 17) {
g.drawOval(x, y, 20, 20);
g.fillOval(x, y, 15, 15);
}
}
}
robot.waitForIdle();
end = System.currentTimeMillis();
if (perfMode) {
System.out.println("ovals : " + (end - start) + " ms");
}
// Rects
start = System.currentTimeMillis();
for (int i = 0; i < numReps; ++i) {
for (int x = 0; x < w; x += 20) {
for (int y = 0; y < h; y += 17) {
g.drawRect(x, y, 20, 20);
g.fillRect(x, y, 18, 18);
}
}
}
robot.waitForIdle();
end = System.currentTimeMillis();
if (perfMode) {
System.out.println("rects : " + (end - start) + " ms");
}
// GeneralPath rendering
GeneralPath drawGP = new GeneralPath();
for (int i = 0; i < 30; ++i) {
Rectangle rect = new Rectangle(5 * i, 2 * i, 27, 19);
drawGP.append(rect, false);
}
GeneralPath fillGP = new GeneralPath();
for (int i = 0; i < 30; ++i) {
Rectangle rect = new Rectangle(5 * i, 100 + 2 * i, 27, 19);
fillGP.append(rect, false);
}
Graphics2D g2d = (Graphics2D)g;
start = System.currentTimeMillis();
for (int i = 0; i < numReps; ++i) {
g2d.draw(drawGP);
g2d.fill(fillGP);
}
robot.waitForIdle();
end = System.currentTimeMillis();
if (perfMode) {
System.out.println("GeneralPath : " + (end - start) + " ms");
}
}
public static void usage() {
System.err.println("java ClipShapeRendering [-perf] [-show]");
System.err.println(" -perf : runs performance benchmark (1000 reps)");
System.err.println(" -show : shows a frame with captured clip area");
System.exit(1);
}
public static boolean checkResult(BufferedImage clientPixels) {
int pixels[] = new int[clipRect.width * clipRect.height];
clientPixels.getRGB(0, 0, clipRect.width,
clipRect.height, pixels, 0,
clipRect.width);
int pixelIndex = 0;
for (int row = 0; row < clipRect.height; ++row) {
for (int col = 0; col < clipRect.width; ++col) {
if (!(new Color(pixels[pixelIndex])).equals(fillColor)) {
System.err.println("Incorrect color " +
Integer.toHexString(pixels[pixelIndex]) +
" instead of " +
Integer.toHexString(fillColor.getRGB()) +
" in pixel (" + (clipRect.x + col) +
", " + (clipRect.y + row) + ")");
return false;
}
pixelIndex++;
}
}
return true;
}
static volatile Robot robot;
public static void main(String args[]) throws Exception {
for (int i = 0; i < args.length; ++i) {
if (args[i].equals("-perf")) {
perfMode = true;
} else if (args[i].equals("-show")) {
showCapture = true;
} else {
usage();
}
}
try {
robot = new Robot();
} catch (AWTException e) {
throw new RuntimeException("Can't create robot: " + e);
}
ClipShapeRendering clipTest = new ClipShapeRendering();
clipTest.setSize(300, 300);
clipTest.setLocationRelativeTo(null);
clipTest.setAlwaysOnTop(true);
clipTest.setVisible(true);
try {
synchronized (clipTest) {
while (!timeToRun) {
clipTest.wait(300);
}
}
} catch (InterruptedException e) {}
clipTest.runTests();
// check off-screen rendering;
BufferedImage offScreenClientPixels =
(BufferedImage)clipTest.createImage(clipRect.width,
clipRect.height);
Graphics clientG = offScreenClientPixels.getGraphics();
clientG.drawImage(offScreenImage,
0, 0, clipRect.width, clipRect.height,
clipRect.x, clipRect.y,
clipRect.x + clipRect.width,
clipRect.y + clipRect.height,
null);
if (showCapture) {
CaptureFrame f =
new CaptureFrame("OffScreen Image", offScreenImage);
f.setVisible(true);
}
// check onscreen rendering
Point clientLoc = clipTest.getLocationOnScreen();
Rectangle r = (Rectangle)clipRect.clone();
r.translate(clientLoc.x, clientLoc.y);
// move mouse cursor away from captured region as in some system
// cursor remain visible in composite captured image
robot.mouseMove(r.x - OFFSET_X, r.y - OFFSET_Y);
robot.waitForIdle();
BufferedImage onScreenClientPixels = robot.createScreenCapture(r);
try { Thread.sleep(1000); } catch (Exception e) {}
if (showCapture) {
CaptureFrame f =
new CaptureFrame("Onscreen clip area", onScreenClientPixels);
f.setVisible(true);
} else {
clipTest.dispose();
}
System.out.print("Checking results for off-screen rendering..");
boolean offScreenPassed = checkResult(offScreenClientPixels);
System.out.println("done.");
System.out.print("Checking results for on-screen rendering..");
boolean onScreenPassed = checkResult(onScreenClientPixels);
System.out.println("done.");
if (!offScreenPassed || !onScreenPassed) {
javax.imageio.ImageIO.write(offScreenClientPixels, "png", new java.io.File("offscreen.png"));
javax.imageio.ImageIO.write(onScreenClientPixels, "png", new java.io.File("onscreen.png"));
throw new RuntimeException("Test failed. off-screen: " +
(offScreenPassed?"passed":"failed") +
" on-screen: " +
(onScreenPassed?"passed":"failed"));
}
System.out.println("Passed");
}
static {
System.setProperty("sun.java2d.pmoffscreen", "true");
}
}
class CaptureFrame extends Frame {
static int x = 300, y = 0;
Image clientPixels;
public CaptureFrame(String title, Image clientPixels) {
super("Capture Frame: " + title);
this.clientPixels = clientPixels;
int w = clientPixels.getWidth(null);
int h = clientPixels.getHeight(null);
setSize(w, h + 30);
setLocation(x, y);
x += w;
if (x + w > 1024) {
x = 300;
y += h;
}
add(new Component() {
public void paint(Graphics g) {
g.drawImage(CaptureFrame.this.clientPixels, 0, 0, null);
}
});
}
};

View file

@ -0,0 +1,121 @@
/*
* 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 4725045
* @key headful
* @summary verifies that there are no artifacts due to using
* GDI for copies to the back buffer (GDI should only be used
* for copies to the screen)
* @run main GdiBlitOffscreenTest
*/
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Point;
import java.awt.Robot;
import java.awt.image.BufferedImage;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
public class GdiBlitOffscreenTest {
static volatile JFrame f;
static final int imageW = 100, imageH = 100, FW = 500, FH = 500;
static volatile BufferedImage greenImage;
public static void main(String[] args) throws Exception {
// First, create an image.
greenImage = new BufferedImage(imageW, imageH,
BufferedImage.TYPE_INT_RGB);
Graphics redG = greenImage.getGraphics();
redG.setColor(Color.green);
redG.fillRect(0, 0, imageW, imageH);
redG.setColor(Color.white);
redG.drawString("Passed!", 30, 80);
Robot robot = new Robot();
try {
SwingUtilities.invokeAndWait(GdiBlitOffscreenTest::createUI);
robot.delay(1000);
robot.waitForIdle();
Point p = f.getLocationOnScreen();
Color c = robot.getPixelColor(p.x+FW/2, p.y+FH/2);
if (!c.equals(Color.green)) {
throw new RuntimeException("Color is " + c);
}
} finally {
if (f != null) {
SwingUtilities.invokeAndWait(f::dispose);
}
}
}
private static void createUI() {
f = new JFrame("GdiBlitOffscreenTest");
f.setSize(FW, FH);
f.setVisible(true);
// copy the image to the window.
Graphics g = f.getGraphics();
g.drawImage(greenImage, 0, 0, null);
// Now, get on with the rest of the test
JComponent app = new GdiBlitOffscreenTestComponent(imageW, imageH, greenImage);
app.setSize(500, 500);
f.getContentPane().add(app);
f.validate();
f.repaint();
}
}
class GdiBlitOffscreenTestComponent extends JComponent {
int imageW, imageH;
Image theImage;
public GdiBlitOffscreenTestComponent(int imageW, int imageH,
Image theImage)
{
this.theImage = theImage;
this.imageW = imageW;
this.imageH = imageH;
}
public void paintComponent(Graphics g) {
int imageX = (getWidth() - imageW) / 2;
int imageY = (getHeight() - imageH) / 2;
g.setColor(Color.blue);
g.fillRect(0, 0, getWidth(), getHeight());
g.setColor(Color.red);
g.fillRect(imageX, imageY, imageW, imageH);
g.setColor(Color.white);
g.drawString("Failed!", imageX + 30, imageY + 80);
g.drawImage(theImage, imageX, imageY, null);
}
}

View file

@ -0,0 +1,95 @@
/*
* 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 4693644
* @summary verifies that there are no artifacts due to copying with GDI
* @library /java/awt/regtesthelpers
* @build PassFailJFrame
* @run main/manual GdiLockTest
*/
import java.awt.Color;
import java.awt.Component;
import java.awt.Frame;
import java.awt.Graphics;
public class GdiLockTest {
static final String INSTRUCTIONS = """
A window will open up next to these instructions.
The text you see in that window should blink on and off.
If it never disappears, then the test has failed.
""";
public static void main(String[] argv) throws Exception {
PassFailJFrame.builder()
.title("GdiLockTest")
.instructions(INSTRUCTIONS)
.testTimeOut(5)
.rows(5)
.columns(45)
.testUI(GdiLockTest::createUI)
.build()
.awaitAndCheck();
}
private static Frame createUI() {
Frame f = new Frame("GdiLockTest");
f.setSize(300, 300);
GdiLockTestComponent test = new GdiLockTestComponent();
Thread t = new Thread(test);
f.add(test);
t.start();
return f;
}
}
class GdiLockTestComponent extends Component implements Runnable {
boolean textVisible = true;
public void paint(Graphics g) {
g.setColor(Color.white);
g.fillRect(0, 0, getWidth(), getHeight());
g.setColor(Color.black);
if (!textVisible) {
g.setClip(200, 200, 300, 300);
}
g.drawString("This text should be blinking", 10, 30);
if (!textVisible) {
g.setClip(0, 0, getWidth(), getHeight());
}
}
public void run() {
while (true) {
repaint();
textVisible = !textVisible;
try {
Thread.sleep(500);
} catch (Exception e) {}
}
}
}

View file

@ -0,0 +1,122 @@
/*
* Copyright (c) 2003, 2020, 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
* @key headful
* @bug 4873505 6588884
* @author cheth
* @summary verifies that drawImage behaves the bounds of a complex
* clip shape. This was a problem with our GDI renderer on Windows, where
* we would ignore the window insets.
* @run main InsetClipping
*/
/**
* This test works by setting up a clip area that equals the visible area
* of the Frame. When we perform any rendering operation to that window,
* we should not see the results of the operation because they should be
* clipped out. We create an Image with one color (red) and use a
* different background fill color (blue). We fill the area with the
* background color, then set the clip, then draw the image; if we detect
* the image color at pixel (0, 0) then we did not clip correctly and the
* test fails.
*/
import java.awt.Color;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Insets;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.geom.Area;
import java.awt.image.BufferedImage;
public class InsetClipping extends Frame {
BufferedImage image;
Area area;
static boolean painted = false;
static Color imageColor = Color.red;
static Color fillColor = Color.blue;
public InsetClipping() {
image = new BufferedImage( 300, 300,BufferedImage.TYPE_INT_RGB);
Graphics g2 = image.createGraphics();
g2.setColor(imageColor);
g2.fillRect(0,0, 300,300);
}
public void paint(Graphics g) {
Insets insets = getInsets();
area = new Area( new Rectangle(0,0, getWidth(), getHeight()));
area.subtract(new Area(new Rectangle(insets.left, insets.top,
getWidth() - insets.right,
getHeight() - insets.bottom)));
g.setColor(fillColor);
g.fillRect(0, 0, getWidth(), getHeight());
g.setClip(area);
g.drawImage(image, 0, 0, null);
painted = true;
}
public static void main(String args[]) {
InsetClipping clipTest = new InsetClipping();
clipTest.setSize(300, 300);
clipTest.setLocationRelativeTo(null);
clipTest.setVisible(true);
while (!painted) {
try {
Thread.sleep(100);
} catch (Exception e) {}
}
try {
Thread.sleep(2000);
} catch (InterruptedException ex) {}
try {
Robot robot = new Robot();
Point clientLoc = clipTest.getLocationOnScreen();
Insets insets = clipTest.getInsets();
clientLoc.x += insets.left;
clientLoc.y += insets.top;
BufferedImage clientPixels =
robot.createScreenCapture(new Rectangle(clientLoc.x,
clientLoc.y,
clientLoc.x + 2,
clientLoc.y + 2));
try {
Thread.sleep(2000);
} catch (Exception e) {}
int pixelVal = clientPixels.getRGB(2, 2);
clipTest.dispose();
if ((new Color(pixelVal)).equals(fillColor)) {
System.out.println("Passed");
} else {
throw new Error("Failed: incorrect color in pixel (2, 2)");
}
} catch (Exception e) {
System.out.println("Problems creating Robot");
}
}
}

View file

@ -0,0 +1,173 @@
/*
* Copyright (c) 2004, 2025, 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 6248561 6264014
* @key headful
* @requires (os.family != "mac")
* @summary Verifies that bitmask image copies work properly with the
* OGL pipeline when a SrcOver composite with extra alpha is involved.
* @run main/othervm -Dsun.java2d.opengl=True DrawBitmaskImage
* @run main/othervm DrawBitmaskImage
*/
/*
* @test
* @bug 6248561 6264014
* @key headful
* @requires (os.family == "mac")
* @summary Verifies that bitmask image copies work properly with the
* OGL pipeline when a SrcOver composite with extra alpha is involved.
* @run main/othervm -Dsun.java2d.opengl=True DrawBitmaskImage
* @run main/othervm DrawBitmaskImage
*/
import java.awt.AlphaComposite;
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
import java.awt.Panel;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Transparency;
import java.awt.Robot;
import java.awt.image.BufferedImage;
import java.awt.image.IndexColorModel;
import java.io.File;
import javax.imageio.ImageIO;
public class DrawBitmaskImage extends Panel {
static final int TESTW = 200, TESTH = 200;
private static volatile DrawBitmaskImage test;
private static volatile Frame frame;
public void paint(Graphics g) {
Graphics2D g2d = (Graphics2D)g;
g2d.setColor(Color.black);
g2d.fillRect(0, 0, getWidth(), getHeight());
g2d.setComposite(AlphaComposite.SrcOver.derive(0.50f));
BufferedImage img = getGraphicsConfiguration().createCompatibleImage(50, 50,
Transparency.BITMASK);
Graphics2D gimg = img.createGraphics();
gimg.setComposite(AlphaComposite.Src);
gimg.setColor(new Color(0, 0, 0, 0));
gimg.fillRect(0, 0, 50, 50);
gimg.setColor(Color.red);
gimg.fillRect(10, 10, 30, 30);
gimg.dispose();
g2d.drawImage(img, 10, 10, null);
// draw a second time to ensure that the cached copy is used
g2d.drawImage(img, 80, 10, null);
}
public Dimension getPreferredSize() {
return new Dimension(TESTW, TESTH);
}
static void createUI() {
test = new DrawBitmaskImage();
frame = new Frame("OpenGL DrawBitmaskImage Test");
Panel p = new Panel();
p.add(test);
frame.add(p);
frame.setSize(TESTW+100, TESTH+100);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) throws Exception {
Robot robot = new Robot();
EventQueue.invokeAndWait(DrawBitmaskImage::createUI);
robot.waitForIdle();
robot.delay(2000);
BufferedImage capture = null;
try {
GraphicsConfiguration gc = frame.getGraphicsConfiguration();
if (gc.getColorModel() instanceof IndexColorModel) {
System.out.println("IndexColorModel detected: " +
"test considered PASSED");
return;
}
Point pt1 = test.getLocationOnScreen();
Rectangle rect = new Rectangle(pt1.x, pt1.y, TESTW, TESTH);
capture = robot.createScreenCapture(rect);
} finally {
if (frame != null) {
EventQueue.invokeAndWait(frame::dispose);
}
}
// Test background color
int pixel = capture.getRGB(5, 10);
if (pixel != 0xff000000) {
saveImage(capture);
throw new RuntimeException("Failed: Incorrect color for " +
"background (actual=" +
Integer.toHexString(pixel) + ")");
}
// Test pixels (allow for small error in the actual red value)
pixel = capture.getRGB(25, 25);
System.out.println("pixel1 is " + Integer.toHexString(pixel));
if ((pixel < 0xff7e0000) || (pixel > 0xff900000)) {
saveImage(capture);
throw new RuntimeException("Failed: Incorrect color for " +
"first pixel (actual=" +
Integer.toHexString(pixel) + ")");
}
pixel = capture.getRGB(95, 25);
System.out.println("pixel2 is " + Integer.toHexString(pixel));
if ((pixel < 0xff7e0000) || (pixel > 0xff900000)) {
saveImage(capture);
throw new RuntimeException("Failed: Incorrect color for " +
"second pixel (actual=" +
Integer.toHexString(pixel) + ")");
}
}
static void saveImage(BufferedImage img) {
try {
File file = new File("capture.png");
ImageIO.write(img, "png", file);
} catch (Exception e) {
e.printStackTrace();
}
}
}

View file

@ -0,0 +1,514 @@
/*
* Copyright (c) 2004, 2025, 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 6514990
* @key headful
* @requires (os.family != "mac")
* @summary Verifies that calling
* Graphics2D.drawImage(BufferedImage, BufferedImageOp, x, y) to an
* OpenGL-accelerated destination produces the same results when performed
* in software via BufferedImageOp.filter().
* @run main/othervm -Dsun.java2d.opengl=True DrawBufImgOp -ignore
*/
/*
* @test
* @bug 6514990
* @key headful
* @requires (os.family == "mac")
* @summary Verifies that calling
* Graphics2D.drawImage(BufferedImage, BufferedImageOp, x, y) to an
* OpenGL-accelerated destination produces the same results when performed
* in software via BufferedImageOp.filter().
* @run main/othervm -Dsun.java2d.opengl=True DrawBufImgOp -ignore
*/
import java.awt.AlphaComposite;
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
import java.awt.Panel;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.image.BufferedImage;
import java.awt.image.ByteLookupTable;
import java.awt.image.ColorModel;
import java.awt.image.ConvolveOp;
import java.awt.image.IndexColorModel;
import java.awt.image.Kernel;
import java.awt.image.LookupOp;
import java.awt.image.RescaleOp;
import java.awt.image.ShortLookupTable;
import java.awt.image.VolatileImage;
import java.io.File;
import javax.imageio.ImageIO;
/**
* REMIND: This testcase was originally intended to automatically compare
* the results of the software BufferedImageOp implementations against
* the OGL-accelerated codepaths. However, there are just too many open
* bugs in the mediaLib-based codepaths (see below), which means that
* creating the reference image may cause crashes or exceptions,
* and even if we work around those cases using the "-ignore" flag,
* the visual results of the reference image are often buggy as well
* (so the comparison will fail even though the OGL results are correct).
* Therefore, for now we will run the testcase with the "-ignore" flag
* but without the "-compare" flag, so at least it will be checking for
* any exceptions/crashes in the OGL code. When we fix all of the
* outstanding bugs with the software codepaths, we can remove the
* "-ignore" flag and maybe even restore the "-compare" flag. In the
* meantime, it also functions well as a manual testcase (with either
* the "-show" or "-dump" options).
*/
public class DrawBufImgOp extends Canvas {
private static final int TESTW = 600;
private static final int TESTH = 500;
private static volatile DrawBufImgOp test;
private static volatile Frame frame;
/*
* If true, skips tests that are known to trigger bugs (which in
* turn may cause crashes, exceptions, or other artifacts).
*/
private static boolean ignore;
// Test both pow2 and non-pow2 sized images
private static final int[] srcSizes = { 32, 17 };
private static final int[] srcTypes = {
BufferedImage.TYPE_INT_RGB,
BufferedImage.TYPE_INT_ARGB,
BufferedImage.TYPE_INT_ARGB_PRE,
BufferedImage.TYPE_INT_BGR,
BufferedImage.TYPE_3BYTE_BGR,
BufferedImage.TYPE_4BYTE_ABGR,
BufferedImage.TYPE_USHORT_565_RGB,
BufferedImage.TYPE_BYTE_GRAY,
BufferedImage.TYPE_USHORT_GRAY,
};
private static final RescaleOp
rescale1band, rescale3band, rescale4band;
private static final LookupOp
lookup1bandbyte, lookup3bandbyte, lookup4bandbyte;
private static final LookupOp
lookup1bandshort, lookup3bandshort, lookup4bandshort;
private static final ConvolveOp
convolve3x3zero, convolve5x5zero, convolve7x7zero;
private static final ConvolveOp
convolve3x3noop, convolve5x5noop, convolve7x7noop;
static {
rescale1band = new RescaleOp(0.5f, 10.0f, null);
rescale3band = new RescaleOp(
new float[] { 0.6f, 0.4f, 0.6f },
new float[] { 10.0f, -3.0f, 5.0f },
null);
rescale4band = new RescaleOp(
new float[] { 0.6f, 0.4f, 0.6f, 0.9f },
new float[] { -1.0f, 5.0f, 3.0f, 1.0f },
null);
// REMIND: we should probably test non-zero offsets, but that
// would require massaging the source image data to avoid going
// outside the lookup table array bounds
int offset = 0;
{
byte invert[] = new byte[256];
byte halved[] = new byte[256];
for (int j = 0; j < 256 ; j++) {
invert[j] = (byte) (255-j);
halved[j] = (byte) (j / 2);
}
ByteLookupTable lut1 = new ByteLookupTable(offset, invert);
lookup1bandbyte = new LookupOp(lut1, null);
ByteLookupTable lut3 =
new ByteLookupTable(offset,
new byte[][] {invert, halved, invert});
lookup3bandbyte = new LookupOp(lut3, null);
ByteLookupTable lut4 =
new ByteLookupTable(offset,
new byte[][] {invert, halved, invert, halved});
lookup4bandbyte = new LookupOp(lut4, null);
}
{
short invert[] = new short[256];
short halved[] = new short[256];
for (int j = 0; j < 256 ; j++) {
invert[j] = (short) ((255-j) * 255);
halved[j] = (short) ((j / 2) * 255);
}
ShortLookupTable lut1 = new ShortLookupTable(offset, invert);
lookup1bandshort = new LookupOp(lut1, null);
ShortLookupTable lut3 =
new ShortLookupTable(offset,
new short[][] {invert, halved, invert});
lookup3bandshort = new LookupOp(lut3, null);
ShortLookupTable lut4 =
new ShortLookupTable(offset,
new short[][] {invert, halved, invert, halved});
lookup4bandshort = new LookupOp(lut4, null);
}
// 3x3 blur
float[] data3 = {
0.1f, 0.1f, 0.1f,
0.1f, 0.2f, 0.1f,
0.1f, 0.1f, 0.1f,
};
Kernel k3 = new Kernel(3, 3, data3);
// 5x5 edge
float[] data5 = {
-1.0f, -1.0f, -1.0f, -1.0f, -1.0f,
-1.0f, -1.0f, -1.0f, -1.0f, -1.0f,
-1.0f, -1.0f, 24.0f, -1.0f, -1.0f,
-1.0f, -1.0f, -1.0f, -1.0f, -1.0f,
-1.0f, -1.0f, -1.0f, -1.0f, -1.0f,
};
Kernel k5 = new Kernel(5, 5, data5);
// 7x7 blur
float[] data7 = {
0.02f, 0.02f, 0.02f, 0.02f, 0.02f, 0.02f, 0.02f,
0.02f, 0.02f, 0.02f, 0.02f, 0.02f, 0.02f, 0.02f,
0.02f, 0.02f, 0.02f, 0.02f, 0.02f, 0.02f, 0.02f,
0.02f, 0.02f, 0.02f, 0.02f, 0.02f, 0.02f, 0.02f,
0.02f, 0.02f, 0.02f, 0.02f, 0.02f, 0.02f, 0.02f,
0.02f, 0.02f, 0.02f, 0.02f, 0.02f, 0.02f, 0.02f,
0.02f, 0.02f, 0.02f, 0.02f, 0.02f, 0.02f, 0.02f,
};
Kernel k7 = new Kernel(7, 7, data7);
convolve3x3zero = new ConvolveOp(k3, ConvolveOp.EDGE_ZERO_FILL, null);
convolve5x5zero = new ConvolveOp(k5, ConvolveOp.EDGE_ZERO_FILL, null);
convolve7x7zero = new ConvolveOp(k7, ConvolveOp.EDGE_ZERO_FILL, null);
convolve3x3noop = new ConvolveOp(k3, ConvolveOp.EDGE_NO_OP, null);
convolve5x5noop = new ConvolveOp(k5, ConvolveOp.EDGE_NO_OP, null);
convolve7x7noop = new ConvolveOp(k7, ConvolveOp.EDGE_NO_OP, null);
}
public void paint(Graphics g) {
VolatileImage vimg = createVolatileImage(TESTW, TESTH);
vimg.validate(getGraphicsConfiguration());
Graphics2D g2d = vimg.createGraphics();
renderTest(g2d);
g2d.dispose();
g.drawImage(vimg, 0, 0, null);
}
/*
* foreach source image size (once with pow2, once with non-pow2)
*
* foreach BufferedImage type
*
* RescaleOp (1 band)
* RescaleOp (3 bands, if src has 3 bands)
* RescaleOp (4 bands, if src has 4 bands)
*
* foreach LookupTable type (once with ByteLUT, once with ShortLUT)
* LookupOp (1 band)
* LookupOp (3 bands, if src has 3 bands)
* LookupOp (4 bands, if src has 4 bands)
*
* foreach edge condition (once with ZERO_FILL, once with EDGE_NO_OP)
* ConvolveOp (3x3)
* ConvolveOp (5x5)
* ConvolveOp (7x7)
*/
private void renderTest(Graphics2D g2d) {
g2d.setColor(Color.white);
g2d.fillRect(0, 0, TESTW, TESTH);
int yorig = 2;
int xinc = 34;
int yinc = srcSizes[0] + srcSizes[1] + 2 + 2;
for (int srcType : srcTypes) {
int y = yorig;
for (int srcSize : srcSizes) {
int x = 2;
System.out.printf("type=%d size=%d\n", srcType, srcSize);
BufferedImage srcImg = makeSourceImage(srcSize, srcType);
ColorModel srcCM = srcImg.getColorModel();
// RescaleOp
g2d.drawImage(srcImg, rescale1band, x, y);
x += xinc;
// REMIND: 3-band RescaleOp.filter() throws IAE for images
// that contain an alpha channel (bug to be filed)
if (srcCM.getNumColorComponents() == 3 &&
!(ignore && srcCM.hasAlpha()))
{
g2d.drawImage(srcImg, rescale3band, x, y);
}
x += xinc;
if (srcCM.getNumComponents() == 4) {
g2d.drawImage(srcImg, rescale4band, x, y);
}
x += xinc;
// LookupOp
// REMIND: Our LUTs are only 256 elements long, so won't
// currently work with USHORT_GRAY data
if (srcType != BufferedImage.TYPE_USHORT_GRAY) {
g2d.drawImage(srcImg, lookup1bandbyte, x, y);
x += xinc;
if (srcCM.getNumColorComponents() == 3) {
g2d.drawImage(srcImg, lookup3bandbyte, x, y);
}
x += xinc;
if (srcCM.getNumComponents() == 4) {
g2d.drawImage(srcImg, lookup4bandbyte, x, y);
}
x += xinc;
// REMIND: LookupOp.createCompatibleDestImage() throws
// IAE for 3BYTE_BGR/4BYTE_ABGR (bug to be filed)
if (!(ignore &&
(srcType == BufferedImage.TYPE_3BYTE_BGR ||
srcType == BufferedImage.TYPE_4BYTE_ABGR)))
{
g2d.drawImage(srcImg, lookup1bandshort, x, y);
x += xinc;
// REMIND: 3-band LookupOp.filter() throws IAE for
// images that contain an alpha channel
// (bug to be filed)
if (srcCM.getNumColorComponents() == 3 &&
!(ignore && srcCM.hasAlpha()))
{
g2d.drawImage(srcImg, lookup3bandshort, x, y);
}
x += xinc;
if (srcCM.getNumComponents() == 4) {
g2d.drawImage(srcImg, lookup4bandshort, x, y);
}
x += xinc;
} else {
x += 3*xinc;
}
} else {
x += 6*xinc;
}
// ConvolveOp
// REMIND: ConvolveOp.filter() throws ImagingOpException
// for 3BYTE_BGR (see 4957775)
if (srcType != BufferedImage.TYPE_3BYTE_BGR) {
g2d.drawImage(srcImg, convolve3x3zero, x, y);
x += xinc;
g2d.drawImage(srcImg, convolve5x5zero, x, y);
x += xinc;
g2d.drawImage(srcImg, convolve7x7zero, x, y);
x += xinc;
g2d.drawImage(srcImg, convolve3x3noop, x, y);
x += xinc;
g2d.drawImage(srcImg, convolve5x5noop, x, y);
x += xinc;
g2d.drawImage(srcImg, convolve7x7noop, x, y);
x += xinc;
} else {
x += 6*xinc;
}
y += srcSize + 2;
}
yorig += yinc;
}
}
private BufferedImage makeSourceImage(int size, int type) {
int s2 = size/2;
BufferedImage img = new BufferedImage(size, size, type);
Graphics2D g2d = img.createGraphics();
g2d.setComposite(AlphaComposite.Src);
g2d.setColor(Color.orange);
g2d.fillRect(0, 0, size, size);
g2d.setColor(Color.red);
g2d.fillRect(0, 0, s2, s2);
g2d.setColor(Color.green);
g2d.fillRect(s2, 0, s2, s2);
g2d.setColor(Color.blue);
g2d.fillRect(0, s2, s2, s2);
g2d.setColor(new Color(255, 255, 0, 128));
g2d.fillRect(s2, s2, s2, s2);
g2d.setColor(Color.pink);
g2d.fillOval(s2-3, s2-3, 6, 6);
g2d.dispose();
return img;
}
public BufferedImage makeReferenceImage() {
BufferedImage img = new BufferedImage(TESTW, TESTH,
BufferedImage.TYPE_INT_RGB);
Graphics2D g2d = img.createGraphics();
renderTest(g2d);
g2d.dispose();
return img;
}
public Dimension getPreferredSize() {
return new Dimension(TESTW, TESTH);
}
private static void compareImages(BufferedImage refImg,
BufferedImage testImg,
int tolerance)
{
int x1 = 0;
int y1 = 0;
int x2 = refImg.getWidth();
int y2 = refImg.getHeight();
for (int y = y1; y < y2; y++) {
for (int x = x1; x < x2; x++) {
Color expected = new Color(refImg.getRGB(x, y));
Color actual = new Color(testImg.getRGB(x, y));
if (!isSameColor(expected, actual, tolerance)) {
saveImage("referenceimage", refImg);
saveImage("testimage", testImg);
throw new RuntimeException("Test failed at x="+x+" y="+y+
" (expected="+expected+
" actual="+actual+
")");
}
}
}
}
private static boolean isSameColor(Color c1, Color c2, int e) {
int r1 = c1.getRed();
int g1 = c1.getGreen();
int b1 = c1.getBlue();
int r2 = c2.getRed();
int g2 = c2.getGreen();
int b2 = c2.getBlue();
int rmin = Math.max(r2-e, 0);
int gmin = Math.max(g2-e, 0);
int bmin = Math.max(b2-e, 0);
int rmax = Math.min(r2+e, 255);
int gmax = Math.min(g2+e, 255);
int bmax = Math.min(b2+e, 255);
if (r1 >= rmin && r1 <= rmax &&
g1 >= gmin && g1 <= gmax &&
b1 >= bmin && b1 <= bmax)
{
return true;
}
return false;
}
static void createUI() {
test = new DrawBufImgOp();
Panel panel = new Panel();
panel.add(test);
frame = new Frame("OpenGL DrawBufImgOp Test");
frame.add(panel);
frame.setSize(TESTW+100, TESTH+100);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) throws Exception {
boolean show = false;
boolean dump = false;
boolean compare = false;
for (String arg : args) {
if (arg.equals("-show")) {
show = true;
} else if (arg.equals("-dump")) {
dump = true;
} else if (arg.equals("-compare")) {
compare = true;
} else if (arg.equals("-ignore")) {
ignore = true;
}
}
Robot robot = new Robot();
EventQueue.invokeAndWait(DrawBufImgOp::createUI);
robot.waitForIdle();
robot.delay(2000);
BufferedImage capture = null;
try {
GraphicsConfiguration gc = frame.getGraphicsConfiguration();
if (gc.getColorModel() instanceof IndexColorModel) {
System.out.println("IndexColorModel detected: " +
"test considered PASSED");
return;
}
Point pt1 = test.getLocationOnScreen();
Rectangle rect = new Rectangle(pt1.x, pt1.y, TESTW, TESTH);
capture = robot.createScreenCapture(rect);
} finally {
if (frame != null) {
EventQueue.invokeAndWait(frame::dispose);
}
}
// Compare the images (allow for +/- 1 bit differences in color comps)
if (dump || compare) {
BufferedImage ref = test.makeReferenceImage();
if (dump) {
saveImage("DrawBufImgOp_ref", ref);
saveImage("DrawBufImgOp_cap", capture);
}
if (compare) {
test.compareImages(ref, capture, 1);
}
}
}
static void saveImage(String name, BufferedImage img) {
try {
File file = new File(name + ".png");
ImageIO.write(img, "png", file);
} catch (Exception e) {
e.printStackTrace();
}
}
}

View file

@ -0,0 +1,145 @@
/*
* Copyright (c) 2004, 2025, 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 4993274
* @key headful
* @requires (os.family != "mac")
* @summary Verifies that managed image copies and transforms work properly
* with the OGL pipeline when a background color is specified.
* @run main/othervm -Dsun.java2d.opengl=True DrawImageBg
* @run main/othervm DrawImageBg
*/
/*
* @test
* @bug 4993274
* @key headful
* @requires (os.family == "mac")
* @summary Verifies that managed image copies and transforms work properly
* with the OGL pipeline when a background color is specified.
* @run main/othervm -Dsun.java2d.opengl=True DrawImageBg
* @run main/othervm DrawImageBg
*/
import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Panel;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.Transparency;
import java.awt.image.BufferedImage;
import java.io.File;
import javax.imageio.ImageIO;
public class DrawImageBg extends Panel {
static volatile Frame frame;
static volatile DrawImageBg test;
public void paint(Graphics g) {
Graphics2D g2d = (Graphics2D)g;
g2d.setColor(Color.black);
g2d.fillRect(0, 0, getWidth(), getHeight());
BufferedImage img = getGraphicsConfiguration().createCompatibleImage(50, 50,
Transparency.BITMASK);
Graphics2D gimg = img.createGraphics();
gimg.setComposite(AlphaComposite.Src);
gimg.setColor(new Color(0, 0, 0, 0));
gimg.fillRect(0, 0, 50, 50);
gimg.setColor(Color.red);
gimg.fillRect(10, 10, 30, 30);
gimg.dispose();
g2d.drawImage(img, 10, 10, Color.blue, null);
// draw a second time to ensure that the cached copy is used
g2d.drawImage(img, 80, 10, Color.blue, null);
}
static void createUI() {
frame = new Frame("OpenGL DrawImageBg Test");
test = new DrawImageBg();
frame.add(test);
frame.setSize(300, 300);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) throws Exception {
BufferedImage capture = null;
Robot robot = new Robot();
try {
EventQueue.invokeAndWait(DrawImageBg::createUI);
robot.waitForIdle();
robot.delay(3000);
// Grab the screen region
Point pt1 = test.getLocationOnScreen();
Rectangle rect = new Rectangle(pt1.x+80, pt1.y, 80, 80);
capture = robot.createScreenCapture(rect);
} finally {
if (frame != null) {
EventQueue.invokeAndWait(frame::dispose);
}
}
if (capture == null) {
throw new RuntimeException("Screen capture is null");
}
// Test inner and outer pixels
int pixel1 = capture.getRGB(5, 10);
if (pixel1 != 0xff0000ff) {
saveImage(capture);
throw new RuntimeException(getMsg("outer", pixel1));
}
int pixel2 = capture.getRGB(25, 25);
if (pixel2 != 0xffff0000) {
saveImage(capture);
throw new RuntimeException(getMsg("inner", pixel2));
}
}
static String getMsg(String r, int p1) {
return "Failed: Incorrect color for " + r + " pixel: got " + Integer.toHexString(p1);
}
static void saveImage(BufferedImage img) {
try {
File file = new File("capture.png");
ImageIO.write(img, "png", file);
} catch (Exception e) {
e.printStackTrace();
}
}
}

View file

@ -0,0 +1,134 @@
/*
* Copyright Amazon.com Inc. 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.
*/
import java.awt.Color;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.image.BufferStrategy;
import java.awt.image.BufferedImage;
import java.io.File;
import javax.imageio.ImageIO;
/**
* @test
* @bug 8378201
* @key headful
* @summary Verifies that WINDOW and FLIP_BACKBUFFER surfaces sharing the same X
* Window render and flip correctly
* @run main/othervm FlipCoexistTest
* @run main/othervm -Dsun.java2d.opengl=True FlipCoexistTest
*/
public final class FlipCoexistTest {
private static final int SIZE = 200;
private static final int TOLERANCE = 10;
public static void main(String[] args) throws Exception {
Frame f = new Frame("FlipCoexistTest");
try {
f.setUndecorated(true);
f.setSize(SIZE, SIZE);
f.setLocation(100, 100);
f.setVisible(true);
Robot robot = new Robot();
robot.waitForIdle();
robot.delay(1000);
int w = f.getWidth();
int h = f.getHeight();
// Fill window RED via direct render (WINDOW surface)
Graphics g = f.getGraphics();
g.setColor(Color.RED);
g.fillRect(0, 0, w, h);
g.dispose();
robot.waitForIdle();
robot.delay(500);
// Request flip if available, blit is also useful to cover
f.createBufferStrategy(2);
BufferStrategy bs = f.getBufferStrategy();
// Render BLUE to back buffer, do not flip yet
Graphics bg = bs.getDrawGraphics();
bg.setColor(Color.BLUE);
bg.fillRect(0, 0, w, h);
bg.dispose();
// Paint small GREEN rect via direct render
g = f.getGraphics();
g.setColor(Color.GREEN);
g.fillRect(0, 0, 10, 10);
g.dispose();
robot.waitForIdle();
robot.delay(500);
// GREEN rect must be visible
check(robot, f, 5, 5, Color.GREEN, "small rect");
// RED must survive the context round-trip
check(robot, f, w / 2, h / 2, Color.RED, "survived");
// Show back buffer, BLUE must appear
bs.show();
robot.waitForIdle();
robot.delay(500);
check(robot, f, w / 2, h / 2, Color.BLUE, "flip");
} finally {
f.dispose();
}
}
private static void check(Robot robot, Frame frame, int x, int y, Color exp,
String desc)
{
Point loc = frame.getLocationOnScreen();
Color c = robot.getPixelColor(loc.x + x, loc.y + y);
if (!isAlmostEqual(c, exp)) {
saveImage(robot, frame, desc);
throw new RuntimeException("%s: %s != %s".formatted(desc, exp, c));
}
}
private static void saveImage(Robot r, Frame f, String name) {
try {
Rectangle rect = f.getBounds();
BufferedImage img = r.createScreenCapture(rect);
ImageIO.write(img, "png", new File(name + ".png"));
} catch (Exception e) {
e.printStackTrace();
}
}
private static boolean isAlmostEqual(Color c1, Color c2) {
return Math.abs(c1.getRed() - c2.getRed()) <= TOLERANCE
&& Math.abs(c1.getGreen() - c2.getGreen()) <= TOLERANCE
&& Math.abs(c1.getBlue() - c2.getBlue()) <= TOLERANCE;
}
}

View file

@ -0,0 +1,138 @@
/*
* Copyright (c) 2004, 2025, 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 6219284 6358147 6274813 6578452
* @key headful
* @summary Verifies that OGLRenderer.drawPoly(),
* OGLTextRenderer.drawGlyphList(), and OGLMaskFill work properly when the
* operation parameters exceed the capacity of the render queue. With the
* single-threaded OpenGL pipeline, there are some operations that require
* a separate buffer to be spawned if the parameters cannot fit entirely on
* the standard buffer. This test exercises this special case.
* @run main/othervm -Dsun.java2d.opengl=True -Dsun.java2d.opengl.lcdshader=true LargeOps
*/
import java.awt.Canvas;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.Robot;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import javax.imageio.ImageIO;
public class LargeOps extends Canvas {
private static final int NUM_POINTS = 8000;
private int[] xPoints, yPoints;
private String str;
public LargeOps() {
xPoints = new int[NUM_POINTS];
yPoints = new int[NUM_POINTS];
for (int i = 0; i < NUM_POINTS; i++) {
xPoints[i] = (i % 2 == 0) ? 10 : 400;
yPoints[i] = (i % 2 == 1) ? i+3 : i;
}
StringBuilder sb = new StringBuilder();
for (int i = 0; i < NUM_POINTS; i+=11) {
sb.append("ThisIsATest");
}
str = sb.toString();
}
public void paint(Graphics g) {
Graphics2D g2d = (Graphics2D)g;
g2d.setColor(Color.white);
g2d.fillRect(0, 0, getWidth(), getHeight());
// draw large polyline
g2d.setColor(Color.green);
g2d.drawPolyline(xPoints, yPoints, NUM_POINTS);
// draw long string
g2d.setColor(Color.blue);
g2d.drawString(str, 10, 100);
// draw long string with larger pt size
Font font = g2d.getFont();
g2d.setFont(font.deriveFont(40.0f));
g2d.drawString(str, 10, 150);
// do the same with LCD hints enabled
g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_HRGB);
g2d.setFont(font);
g2d.drawString(str, 10, 200);
g2d.setFont(font.deriveFont(43.0f));
g2d.drawString(str, 10, 250);
g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_HBGR);
g2d.setFont(font);
g2d.drawString(str, 10, 300);
g2d.setFont(font.deriveFont(37.0f));
g2d.drawString(str, 10, 350);
}
static volatile Frame frame;
static volatile LargeOps test;
static void createUI() {
frame = new Frame("OpenGL LargeOps Test");
frame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
frame.dispose();
}
});
test = new LargeOps();
frame.add(test);
frame.setSize(600, 600);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) throws Exception {
try {
Robot robot = new Robot();
EventQueue.invokeAndWait(LargeOps::createUI);
robot.waitForIdle();
robot.delay(6000);
} finally {
if (frame != null) {
EventQueue.invokeAndWait(frame::dispose);
}
}
}
}

View file

@ -0,0 +1,122 @@
/*
* Copyright Amazon.com Inc. 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.
*/
import java.awt.Color;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.image.BufferedImage;
import java.io.File;
import javax.imageio.ImageIO;
/**
* @test
* @bug 8378201
* @key headful
* @summary Verifies that window content survives a GL context switch to another
* window and back
* @run main/othervm MultiWindowFillTest
* @run main/othervm -Dsun.java2d.opengl=True MultiWindowFillTest
*/
public final class MultiWindowFillTest {
private static final int SIZE = 100;
private static final int TOLERANCE = 10;
public static void main(String[] args) throws Exception {
Frame f1 = new Frame("f1");
Frame f2 = new Frame("f2");
try {
f1.setUndecorated(true);
f1.setSize(SIZE, SIZE);
f1.setLocation(100, 100);
f2.setUndecorated(true);
f2.setSize(SIZE, SIZE);
f2.setLocation(300, 100);
f1.setVisible(true);
f2.setVisible(true);
Robot robot = new Robot();
robot.waitForIdle();
robot.delay(1000);
int w = f1.getWidth();
int h = f1.getHeight();
// Fill both, initializes surfaces
fill(f1, Color.RED, w, h);
fill(f2, Color.BLUE, w, h);
// Touch both again
fill(f1, Color.RED, 2, 2);
fill(f2, Color.BLUE, 2, 2);
robot.waitForIdle();
robot.delay(1000);
check(robot, f1, w, h, Color.RED, "f1 red");
check(robot, f2, w, h, Color.BLUE, "f2 blue");
} finally {
f1.dispose();
f2.dispose();
}
}
private static void fill(Frame frame, Color c, int w, int h) {
Graphics g = frame.getGraphics();
g.setColor(c);
g.fillRect(0, 0, w, h);
g.dispose();
}
private static void check(Robot robot, Frame frame, int w, int h,
Color exp, String desc)
{
Point loc = frame.getLocationOnScreen();
Color c = robot.getPixelColor(loc.x + w / 2, loc.y + h / 2);
if (!isAlmostEqual(c, exp)) {
saveImage(robot, frame, desc);
throw new RuntimeException("%s: %s != %s".formatted(desc, exp, c));
}
}
private static void saveImage(Robot r, Frame f, String name) {
try {
Rectangle rect = f.getBounds();
BufferedImage img = r.createScreenCapture(rect);
ImageIO.write(img, "png", new File(name + ".png"));
} catch (Exception e) {
e.printStackTrace();
}
}
private static boolean isAlmostEqual(Color c1, Color c2) {
return Math.abs(c1.getRed() - c2.getRed()) <= TOLERANCE
&& Math.abs(c1.getGreen() - c2.getGreen()) <= TOLERANCE
&& Math.abs(c1.getBlue() - c2.getBlue()) <= TOLERANCE;
}
}

View file

@ -0,0 +1,186 @@
/*
* Copyright (c) 2004, 2025, 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 6277977 6319663 8369335
* @key headful
* @requires (os.family != "mac")
* @summary Verifies that blending operations do not inadvertantly leave
* non-opaque alpha values in the framebuffer. Note that this test is
* intended to run on GraphicsConfigs that support a stored alpha channel
* (to verify the bug at hand), but it is also a useful for testing the
* compositing results on any configuration.
* @run main/othervm -Dsun.java2d.opengl=True OpaqueDest
* @run main/othervm OpaqueDest
*/
/*
* @test
* @bug 6277977 6319663
* @key headful
* @requires (os.family == "mac")
* @summary Verifies that blending operations do not inadvertantly leave
* non-opaque alpha values in the framebuffer. Note that this test is
* intended to run on GraphicsConfigs that support a stored alpha channel
* (to verify the bug at hand), but it is also a useful for testing the
* compositing results on any configuration.
* @run main/othervm -Dsun.java2d.opengl=True OpaqueDest
* @run main/othervm OpaqueDest
*/
import java.awt.AlphaComposite;
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
import java.awt.Panel;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.image.BufferedImage;
import java.awt.image.IndexColorModel;
import java.io.File;
import javax.imageio.ImageIO;
public class OpaqueDest extends Canvas {
private static volatile Frame frame;
private static volatile OpaqueDest test;
private static final int W = 100, H = 100;
public void paint(Graphics g) {
Graphics2D g2d = (Graphics2D)g;
g2d.setColor(Color.red);
g2d.fillRect(0, 0, getWidth(), getHeight());
// This will clear the rectangle to black
g2d.setComposite(AlphaComposite.Clear);
g2d.fillRect(10, 10, 80, 80);
// If everything is working properly, then this will fill the
// rectangle with red again. Before this bug was fixed, the previous
// Clear operation would leave zero values in the destination's
// alpha channel (if present), and therefore a SrcIn operation
// would result in all-black.
g2d.setComposite(AlphaComposite.SrcIn);
g2d.fillRect(10, 10, 80, 80);
}
public Dimension getPreferredSize() {
return new Dimension(W, H);
}
static void createUI() {
test = new OpaqueDest();
frame = new Frame("OpenGL OpaqueDest Test");
Panel p = new Panel();
p.add(test);
frame.add(p);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) throws Exception {
Robot robot = new Robot();
EventQueue.invokeAndWait(OpaqueDest::createUI);
robot.waitForIdle();
robot.delay(2000);
BufferedImage capture = null;
try {
GraphicsConfiguration gc = frame.getGraphicsConfiguration();
if (gc.getColorModel() instanceof IndexColorModel) {
System.out.println("IndexColorModel detected: " +
"test considered PASSED");
return;
}
Point pt1 = test.getLocationOnScreen();
Rectangle rect = new Rectangle(pt1.x, pt1.y, W, H);
capture = robot.createScreenCapture(rect);
} finally {
if (frame != null) {
EventQueue.invokeAndWait(frame::dispose);
}
}
// Test all pixels (every one should be red)
for (int y = 0; y < W; y++) {
for (int x = 0; x < H; x++) {
int actual = capture.getRGB(x, y);
int expected = 0xffff0000;
if (!similar(actual, expected)) {
String msg = "Test failed at x="+x+" y="+y+
" (expected="+
Integer.toHexString(expected) +
" actual="+
Integer.toHexString(actual) +
")";
if ( ( x== 0) || ( x == W) || ( y == 0) || ( y == H)) {
System.err.println(msg);
} else {
saveImage(capture);
throw new RuntimeException(msg);
}
}
}
}
}
static boolean similar(int p1, int p2) {
int a1 = (p1 >> 24) & 0xff;
int r1 = (p1 >> 16) & 0xff;
int g1 = (p1 >> 8) & 0xff;
int b1 = p1 & 0xff;
int a2 = (p2 >> 24) & 0xff;
int r2 = (p2 >> 16) & 0xff;
int g2 = (p2 >> 8) & 0xff;
int b2 = p2 & 0xff;
int allowedDiff = 0x01; // tiny rounding error allowed.
return
(Math.abs(a1 - a2) <= allowedDiff) &&
(Math.abs(r1 - r2) <= allowedDiff) &&
(Math.abs(g1 - g2) <= allowedDiff) &&
(Math.abs(b1 - b2) <= allowedDiff);
}
static void saveImage(BufferedImage img) {
try {
File file = new File("capture.png");
ImageIO.write(img, "png", file);
} catch (Exception e) {
e.printStackTrace();
}
}
}

View file

@ -0,0 +1,210 @@
/*
* Copyright (c) 2004, 2025, 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 5104584 8237244 8369335
* @key headful
* @requires (os.family != "mac")
* @summary Verifies that scaling an image works properly when the
* source parameters are outside the source bounds.
* @run main/othervm -Dsun.java2d.opengl=True ScaleParamsOOB
* @run main/othervm ScaleParamsOOB
*/
/*
* @test
* @bug 5104584 8237244
* @key headful
* @requires (os.family == "mac")
* @summary Verifies that scaling an image works properly when the
* source parameters are outside the source bounds.
* @run main/othervm -Dsun.java2d.opengl=True ScaleParamsOOB
* @run main/othervm ScaleParamsOOB
*/
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Panel;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.image.BufferedImage;
import java.io.File;
import javax.imageio.ImageIO;
public class ScaleParamsOOB extends Panel {
private static final int TOLERANCE = 12;
private static volatile ScaleParamsOOB test;
private static volatile Frame frame;
private BufferedImage img;
public void paint(Graphics g) {
Graphics2D g2d = (Graphics2D)g;
g2d.setColor(Color.black);
g2d.fillRect(0, 0, getWidth(), getHeight());
BufferedImage img = getGraphicsConfiguration().createCompatibleImage(40, 40);
Graphics2D gimg = img.createGraphics();
gimg.setColor(Color.red);
gimg.fillRect(0, 0, 40, 40);
gimg.dispose();
// first time will be a sw->surface blit
g2d.drawImage(img,
10, 10, 90, 90,
-60, -60, 100, 100,
null);
// second time will be a texture->surface blit
g2d.drawImage(img,
110, 10, 190, 90,
-60, -60, 100, 100,
null);
}
public Dimension getPreferredSize() {
return new Dimension(300, 200);
}
private static void testRegion(BufferedImage bi,
Rectangle wholeRegion,
Rectangle affectedRegion)
{
int x1 = wholeRegion.x;
int y1 = wholeRegion.y;
int x2 = x1 + wholeRegion.width;
int y2 = y1 + wholeRegion.height;
int ax1 = affectedRegion.x;
int ay1 = affectedRegion.y;
int ax2 = ax1 + affectedRegion.width;
int ay2 = ay1 + affectedRegion.height;
for (int y = y1; y < y2; y++) {
for (int x = x1; x < x2; x++) {
int actual = bi.getRGB(x, y);
int expected = 0;
if (affectedRegion.contains(x, y)) {
expected = Color.red.getRGB();
} else {
expected = Color.black.getRGB();
}
int alpha = (actual >> 24) & 0xFF;
int red = (actual >> 16) & 0xFF;
int green = (actual >> 8) & 0xFF;
int blue = (actual) & 0xFF;
int standardAlpha = (expected >> 24) & 0xFF;
int standardRed = (expected >> 16) & 0xFF;
int standardGreen = (expected >> 8) & 0xFF;
int standardBlue = (expected) & 0xFF;
if ((Math.abs(alpha - standardAlpha) > TOLERANCE) ||
(Math.abs(red - standardRed) > TOLERANCE) ||
(Math.abs(green - standardGreen) > TOLERANCE) ||
(Math.abs(blue - standardBlue) > TOLERANCE)) {
String msg = ("Test failed at x="+x+" y="+y+
" (expected="+
Integer.toHexString(expected) +
" actual="+
Integer.toHexString(actual) +
")");
// log edge pixel differences, but don't fail the test.
if ((x == ax1) || (x == ax2) || (y == ay1) || (y == ay2)) {
System.err.println(msg);
} else {
saveImage(bi);
throw new RuntimeException(msg);
}
}
}
}
}
private static void createAndShowGUI() {
test = new ScaleParamsOOB();
frame = new Frame("OpenGL ScaleParamsOOB Test");
frame.setAlwaysOnTop(true);
frame.add(test);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) throws Exception {
Robot robot = new Robot();
EventQueue.invokeAndWait(() -> createAndShowGUI());
robot.waitForIdle();
robot.delay(2000);
// Grab the screen region
BufferedImage capture = null;
try {
Point pt1 = test.getLocationOnScreen();
Rectangle rect = new Rectangle(pt1.x, pt1.y, 200, 200);
capture = robot.createScreenCapture(rect);
} finally {
if (frame != null) {
EventQueue.invokeAndWait(frame::dispose);
}
}
// Test background color
int pixel = capture.getRGB(5, 5);
if (pixel != 0xff000000) {
saveImage(capture);
throw new RuntimeException("Failed: Incorrect color for " +
"background: " + Integer.toHexString(pixel));
}
// Test pixels
testRegion(capture,
new Rectangle(5, 5, 90, 90),
new Rectangle(40, 40, 20, 20));
testRegion(capture,
new Rectangle(105, 5, 90, 90),
new Rectangle(140, 40, 20, 20));
}
static void saveImage(BufferedImage img) {
try {
File file = new File("capture.png");
ImageIO.write(img, "png", file);
} catch (Exception e) {
e.printStackTrace();
}
}
}

View file

@ -0,0 +1,140 @@
/*
* Copyright (c) 2004, 2025, 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 5002133
* @key headful
* @requires (os.family != "mac")
* @summary Verifies that the OpenGL pipeline does not affect the color
* buffer when setting up a complex (shape) clip region. The test fails if
* the circular clip region is filled with a green color (the green region
* should not be visible at all).
* @run main/othervm -Dsun.java2d.opengl=True ShapeClip
* @run main/othervm ShapeClip
*/
/*
* @test
* @bug 5002133
* @key headful
* @requires (os.family == "mac")
* @summary Verifies that the OpenGL pipeline does not affect the color
* buffer when setting up a complex (shape) clip region. The test fails if
* the circular clip region is filled with a green color (the green region
* should not be visible at all).
* @run main/othervm -Dsun.java2d.opengl=True ShapeClip
* @run main/othervm ShapeClip
*/
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Panel;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.geom.Ellipse2D;
import java.awt.image.BufferedImage;
import java.io.File;
import javax.imageio.ImageIO;
public class ShapeClip extends Panel {
private static volatile Frame frame;
private static volatile ShapeClip test;
public void paint(Graphics g) {
Graphics2D g2d = (Graphics2D)g;
int width = getWidth();
int height = getHeight();
g2d.setColor(Color.black);
g2d.fillRect(0, 0, width, height);
g2d.setColor(Color.green);
g2d.fillRect(0, 0, 1, 1);
g2d.setClip(new Ellipse2D.Double(10, 10, 100, 100));
g2d.setColor(Color.blue);
g2d.fillRect(30, 30, 20, 20);
}
static void createUI() {
test = new ShapeClip();
frame = new Frame("OpenGL ShapeClip Test");
frame.add(test);
frame.setSize(200, 200);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) throws Exception {
Robot robot = new Robot();
EventQueue.invokeAndWait(ShapeClip::createUI);
robot.waitForIdle();
robot.delay(2000);
// Grab the screen region
BufferedImage capture = null;
try {
Point pt1 = test.getLocationOnScreen();
Rectangle rect = new Rectangle(pt1.x, pt1.y, 80, 80);
capture = robot.createScreenCapture(rect);
} finally {
if (frame != null) {
EventQueue.invokeAndWait(frame::dispose);
}
}
// Test blue rectangle
int pixel1 = capture.getRGB(40, 40);
if (pixel1 != 0xff0000ff) {
saveImage(capture);
throw new RuntimeException("Failed: Incorrect color for " +
"rectangle " + Integer.toHexString(pixel1));
}
// Test clip region (should be same color as background)
int pixel2 = capture.getRGB(60, 40);
if (pixel2 != 0xff000000) {
saveImage(capture);
throw new RuntimeException("Failed: Incorrect color for " +
"clip region " + Integer.toHexString(pixel2));
}
}
static void saveImage(BufferedImage img) {
try {
File file = new File("capture.png");
ImageIO.write(img, "png", file);
} catch (Exception e) {
e.printStackTrace();
}
}
}

View file

@ -0,0 +1,188 @@
/*
* Copyright (c) 2004, 2025, 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 4942939 4970674
* @key headful
* @requires (os.family != "mac")
* @summary Verifies that OGLMaskFill, OGLMaskBlit, and OGLTextRenderer
* operations work properly for non-SrcOver composites.
* @run main/othervm -Dsun.java2d.opengl=True SrcMaskOps
* @run main/othervm SrcMaskOps
*/
/*
* @test
* @bug 4942939 4970674
* @key headful
* @requires (os.family == "mac")
* @summary Verifies that OGLMaskFill, OGLMaskBlit, and OGLTextRenderer
* operations work properly for non-SrcOver composites.
* @run main/othervm -Dsun.java2d.opengl=True SrcMaskOps
* @run main/othervm SrcMaskOps
*/
import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.Frame;
import java.awt.GradientPaint;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Panel;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.Robot;
import java.awt.image.BufferedImage;
import java.io.File;
import javax.imageio.ImageIO;
public class SrcMaskOps extends Panel {
static volatile Frame frame;
static volatile SrcMaskOps test;
static final int SRX = 50;
static final int SRY = 50;
static final int GPX = 90;
static final int GPY = 50;
static final int DTX = 120;
static final int DTY = 70;
public void paint(Graphics g) {
Graphics2D g2d = (Graphics2D)g;
g2d.setColor(Color.white);
g2d.fillRect(0, 0, getWidth(), getHeight());
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setComposite(AlphaComposite.Src);
g2d.setColor(Color.blue);
g2d.drawRect(SRX, SRY, 20, 20);
g2d.setPaint(new GradientPaint(0.0f, 0.0f, Color.red,
100.0f, 100.f, Color.red, true));
g2d.drawRect(GPX, GPY, 20, 20);
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_OFF);
g2d.setColor(Color.red);
Font font = new Font(Font.DIALOG, Font.PLAIN, 20);
g2d.setFont(font);
g2d.drawString("HELLO", DTX, DTY);
}
static void createUI() {
frame = new Frame("OpenGL SrcMaskOps Test");
test = new SrcMaskOps();
frame.add(test);
frame.setSize(300, 300);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) throws Exception {
Robot robot = new Robot();
BufferedImage capture = null;
try {
EventQueue.invokeAndWait(SrcMaskOps::createUI);
robot.waitForIdle();
robot.delay(3000);
// Grab the screen region
Point pt1 = test.getLocationOnScreen();
Rectangle rect = new Rectangle(pt1.x, pt1.y, 300, 300);
capture = robot.createScreenCapture(rect);
} finally {
if (frame != null) {
EventQueue.invokeAndWait(frame::dispose);
}
}
// Test solid rectangle
int pixel1, pixel2;
pixel1 = capture.getRGB(SRX, SRY);
pixel2 = capture.getRGB(SRX+2, SRY+2);
if (!similar(pixel1, 0xff0000ff) || !similar(pixel2, 0xffffffff)) {
saveImage(capture);
throw new RuntimeException(getMsg("solid rectangle", pixel1, pixel2));
}
// Test GradientPaint rectangle
pixel1 = capture.getRGB(GPX, GPY);
pixel2 = capture.getRGB(GPX+2, GPY+2);
if (!similar(pixel1, 0xffff0000) || !similar(pixel2, 0xffffffff)) {
saveImage(capture);
throw new RuntimeException(getMsg("GradientPaint rectangle", pixel1, pixel2));
}
// Test solid text
pixel1 = capture.getRGB(DTX+2, DTY-5);
pixel2 = capture.getRGB(DTX+5, DTY-5);
if (!similar(pixel1, 0xffff0000) || !similar(pixel2, 0xffffffff)) {
saveImage(capture);
throw new RuntimeException(getMsg("solid text", pixel1, pixel2));
}
}
static boolean similar(int p1, int p2) {
int a1 = (p1 >> 24) & 0xff;
int r1 = (p1 >> 16) & 0xff;
int g1 = (p1 >> 8) & 0xff;
int b1 = p1 & 0xff;
int a2 = (p2 >> 24) & 0xff;
int r2 = (p2 >> 16) & 0xff;
int g2 = (p2 >> 8) & 0xff;
int b2 = p2 & 0xff;
int allowedDiff = 0x10;
return
(Math.abs(a1 - a2) <= allowedDiff) &&
(Math.abs(r1 - r2) <= allowedDiff) &&
(Math.abs(g1 - g2) <= allowedDiff) &&
(Math.abs(b1 - b2) <= allowedDiff);
}
static String getMsg(String r, int p1, int p2) {
return "Failed: Incorrect color[s] for " + r + " got " +
Integer.toHexString(p1) + " and " + Integer.toHexString(p2);
}
static void saveImage(BufferedImage img) {
try {
File file = new File("capture.png");
ImageIO.write(img, "png", file);
} catch (Exception e) {
e.printStackTrace();
}
}
}

View file

@ -0,0 +1,166 @@
/*
* Copyright (c) 2004, 2025, 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 6244071
* @key headful
* @requires (os.family != "mac")
* @summary Verifies that copying a subregion from a VolatileImage works
* properly with the OGL pipeline.
* @run main/othervm VolatileSubRegion
* @run main/othervm -Dsun.java2d.opengl=True -Dsun.java2d.opengl.fbobject=true VolatileSubRegion
* @run main/othervm -Dsun.java2d.opengl=True -Dsun.java2d.opengl.fbobject=false VolatileSubRegion
*/
/*
* @test
* @bug 6244071
* @key headful
* @requires (os.family == "mac")
* @summary Verifies that copying a subregion from a VolatileImage works
* properly with the OGL pipeline.
* @run main/othervm VolatileSubRegion
* @run main/othervm -Dsun.java2d.opengl=True -Dsun.java2d.opengl.fbobject=true VolatileSubRegion
* @run main/othervm -Dsun.java2d.opengl=True -Dsun.java2d.opengl.fbobject=false VolatileSubRegion
*/
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
import java.awt.Panel;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.image.BufferedImage;
import java.awt.image.IndexColorModel;
import java.awt.image.VolatileImage;
import java.io.File;
import javax.imageio.ImageIO;
public class VolatileSubRegion extends Panel {
private VolatileImage img;
public void paint(Graphics g) {
Graphics2D g2d = (Graphics2D)g;
if (img == null) {
img = createVolatileImage(200, 200);
Graphics2D goff = img.createGraphics();
goff.setColor(Color.green);
goff.fillRect(50, 0, 100, 50);
goff.setColor(Color.blue);
goff.fillRect(0, 0, 200, 200);
goff.setColor(Color.red);
goff.fillRect(50, 50, 100, 100);
goff.setColor(Color.yellow);
goff.fillRect(50, 150, 100, 50);
goff.dispose();
}
g2d.setColor(Color.white);
g2d.fillRect(0, 0, getWidth(), getHeight());
g2d.drawImage(img,
50, 50, 200, 200,
50, 50, 200, 200,
null);
}
private static volatile VolatileSubRegion test;
private static volatile Frame frame;
static void createUI() {
test = new VolatileSubRegion();
frame = new Frame("OpenGL VolatileSubRegion Test");
frame.add(test);
frame.setSize(300, 300);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) throws Exception {
Robot robot = new Robot();
EventQueue.invokeAndWait(VolatileSubRegion::createUI);
robot.waitForIdle();
robot.delay(2000);
BufferedImage capture = null;
try {
GraphicsConfiguration gc = frame.getGraphicsConfiguration();
if (gc.getColorModel() instanceof IndexColorModel) {
System.out.println("IndexColorModel detected: " +
"test considered PASSED");
return;
}
Point pt1 = test.getLocationOnScreen();
Rectangle rect = new Rectangle(pt1.x, pt1.y, 200, 200);
capture = robot.createScreenCapture(rect);
} finally {
if (frame != null) {
EventQueue.invokeAndWait(frame::dispose);
}
}
// Test pixels
int pixel1 = capture.getRGB(49, 50);
if (pixel1 != 0xffffffff) {
saveImage(capture);
throw new RuntimeException(getMsg("background pixel", pixel1));
}
int pixel2 = capture.getRGB(50, 50);
if (pixel2 != 0xffff0000) {
saveImage(capture);
throw new RuntimeException(getMsg("red region", pixel2));
}
int pixel3 = capture.getRGB(50, 150);
if (pixel3 != 0xffffff00) {
saveImage(capture);
throw new RuntimeException(getMsg("yellow region", pixel3));
}
}
static String getMsg(String r, int p1) {
return "Failed: Incorrect color for " + r + " : got " + Integer.toHexString(p1);
}
static void saveImage(BufferedImage img) {
try {
File file = new File("capture.png");
ImageIO.write(img, "png", file);
} catch (Exception e) {
e.printStackTrace();
}
}
}

View file

@ -0,0 +1,146 @@
/*
* Copyright (c) 2004, 2025, 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 4970836
* @key headful
* @requires (os.family != "mac")
* @summary Verifies that transformed VolatileImage copies work properly with
* the OGL pipeline.
* @run main/othervm XformVolatile
* @run main/othervm -Dsun.java2d.opengl=True -Dsun.java2d.opengl.fbobject=true XformVolatile
* @run main/othervm -Dsun.java2d.opengl=True -Dsun.java2d.opengl.fbobject=false XformVolatile
*/
/*
* @test
* @bug 4970836
* @key headful
* @requires (os.family == "mac")
* @summary Verifies that transformed VolatileImage copies work properly with
* the OGL pipeline.
* @run main/othervm XformVolatile
* @run main/othervm -Dsun.java2d.opengl=True -Dsun.java2d.opengl.fbobject=true XformVolatile
* @run main/othervm -Dsun.java2d.opengl=True -Dsun.java2d.opengl.fbobject=false XformVolatile
*/
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Panel;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.image.BufferedImage;
import java.awt.image.VolatileImage;
import java.io.File;
import javax.imageio.ImageIO;
public class XformVolatile extends Panel {
private static volatile Frame frame;
private static volatile XformVolatile test;
private volatile VolatileImage img;
public void paint(Graphics g) {
Graphics2D g2d = (Graphics2D)g;
if (img == null) {
img = createVolatileImage(200, 200);
Graphics2D goff = img.createGraphics();
goff.setColor(Color.blue);
goff.fillRect(0, 0, 200, 200);
goff.setColor(Color.red);
goff.fillPolygon(new int[] {10, 100, 190},
new int[] {190, 10, 190}, 3);
goff.dispose();
}
g2d.setColor(Color.black);
g2d.fillRect(0, 0, getWidth(), getHeight());
g2d.rotate(Math.toRadians(3.0));
g2d.drawImage(img, 0, 0, null);
}
static void createUI() {
test = new XformVolatile();
frame = new Frame("OpenGL XformVolatile Test");
frame.add(test);
frame.setSize(300, 300);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) throws Exception {
Robot robot = new Robot();
EventQueue.invokeAndWait(XformVolatile::createUI);
robot.waitForIdle();
robot.delay(2000);
// Grab the screen region
BufferedImage capture = null;
try {
Point pt1 = test.getLocationOnScreen();
Rectangle rect = new Rectangle(pt1.x, pt1.y, 200, 200);
capture = robot.createScreenCapture(rect);
} finally {
if (frame != null) {
EventQueue.invokeAndWait(frame::dispose);
}
}
// Test inner and outer pixels
int pixel1 = capture.getRGB(5, 175);
if (pixel1 != 0xff0000ff) {
saveImage(capture);
throw new RuntimeException(getMsg("inner", pixel1));
}
int pixel2 = capture.getRGB(5, 188);
if (pixel2 != 0xffff0000) {
saveImage(capture);
throw new RuntimeException(getMsg("inner", pixel2));
}
}
static String getMsg(String r, int p1) {
return "Failed: Incorrect color for " + r + " pixel: got " + Integer.toHexString(p1);
}
static void saveImage(BufferedImage img) {
try {
File file = new File("capture.png");
ImageIO.write(img, "png", file);
} catch (Exception e) {
e.printStackTrace();
}
}
}

View file

@ -0,0 +1,271 @@
/*
* Copyright (c) 2003, 2022, 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 4975116 7040022 8023577 8025447 8286624
* @key headful
* @summary verify the rounding of negative coordinates in Shape objects
* @run main/othervm CoordinateTruncationBug
*/
import java.awt.Frame;
import java.awt.Canvas;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Robot;
import java.awt.Rectangle;
import java.awt.Point;
import java.awt.Dimension;
import java.awt.Color;
import java.awt.AWTException;
import java.awt.geom.Line2D;
import java.awt.image.BufferedImage;
import java.awt.image.VolatileImage;
public class CoordinateTruncationBug {
static boolean failure;
static boolean verbose;
static final int W = 80;
static final int H = 80;
static final Line2D vertline = new Line2D.Float(-0.7f, 0f, -0.7f, H);
static final Line2D horizline = new Line2D.Float(0f, -0.7f, W, -0.7f);
public static void main(String argv[]) {
verbose = (argv.length > 0);
new Screen().test();
new BufImg().test();
new VolImg().test();
if (failure) {
throw new RuntimeException("Test failed due to 1 or more failures");
}
}
public static abstract class Test {
public abstract String getName();
public abstract void makeDest();
public abstract void runTest();
public abstract void dispose();
public abstract BufferedImage getSnapshot();
public void test() {
makeDest();
runTest();
dispose();
}
public void runTest(Graphics2D g2d) {
g2d.setColor(Color.white);
g2d.fillRect(0, 0, W, H);
if (!checkAllWhite()) {
System.err.println("Aborting test of "+getName()+
" due to readback failure!");
return;
}
g2d.setColor(Color.red);
g2d.draw(vertline);
g2d.draw(horizline);
if (!checkAllWhite()) {
System.err.println(getName()+" failed!");
failure = true;
}
}
public boolean checkAllWhite() {
BufferedImage bimg = getSnapshot();
if (bimg == null) {
System.err.println(getName()+" returned null snapshot!");
return false;
}
boolean ret = true;
for (int y = 0; y < H; y++) {
for (int x = 0; x < W; x++) {
int rgb = bimg.getRGB(x, y);
if (rgb != -1) {
System.err.println(getName()+"("+x+", "+y+") == "+
Integer.toHexString(rgb));
if (verbose) {
ret = false;
} else {
return false;
}
}
}
}
return ret;
}
}
public static class Screen extends Test {
Frame frame;
TestCanvas canvas;
public String getName() {
return "Screen";
}
public void makeDest() {
frame = new Frame("Screen test");
frame.setUndecorated(true);
canvas = new TestCanvas(this);
frame.add(canvas);
frame.pack();
frame.setLocationRelativeTo(null);
}
public void runTest() {
frame.show();
canvas.waitForTest();
}
public Graphics2D createGraphics() {
return null;
}
public BufferedImage getSnapshot() {
// bypass window animation
try {
Thread.sleep(500);
} catch (InterruptedException e) {
};
try {
Robot r = new Robot();
Point p = canvas.getLocationOnScreen();
return r.createScreenCapture(new Rectangle(p.x, p.y, W, H));
} catch (AWTException e) {
return null;
}
}
public void dispose() {
frame.hide();
frame.dispose();
}
public static class TestCanvas extends Canvas {
Test test;
boolean done;
public TestCanvas(Test test) {
this.test = test;
}
public Dimension getPreferredSize() {
return new Dimension(W, H);
}
public synchronized void waitForTest() {
while (!done) {
try {
wait();
} catch (InterruptedException e) {
System.err.println(getName()+" interrupted!");
failure = true;
break;
}
}
}
public void paint(Graphics g) {
if (!done) {
test.runTest((Graphics2D) g);
notifyDone();
}
}
public synchronized void notifyDone() {
done = true;
notifyAll();
}
}
}
public abstract static class Standalone extends Test {
public abstract Graphics2D createGraphics();
public void runTest() {
Graphics2D g2d = createGraphics();
runTest(g2d);
g2d.dispose();
}
}
public static class BufImg extends Standalone {
public BufferedImage bimg;
public String getName() {
return "BufferedImage";
}
public void makeDest() {
bimg = new BufferedImage(W, H, BufferedImage.TYPE_INT_RGB);
}
public Graphics2D createGraphics() {
return bimg.createGraphics();
}
public BufferedImage getSnapshot() {
return bimg;
}
public void dispose() {
}
}
public static class VolImg extends Standalone {
Frame frame;
VolatileImage vimg;
public String getName() {
return "VolatileImage";
}
public void makeDest() {
frame = new Frame();
frame.setSize(W, H);
frame.setLocationRelativeTo(null);
frame.show();
vimg = frame.createVolatileImage(W, H);
}
public Graphics2D createGraphics() {
return vimg.createGraphics();
}
public BufferedImage getSnapshot() {
return vimg.getSnapshot();
}
public void dispose() {
vimg.flush();
frame.hide();
frame.dispose();
}
}
}

View file

@ -0,0 +1,185 @@
/*
* Copyright (c) 2007, 2022, 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
* @key headful
* @bug 5009033 6603000 6666362 8159142 8198613
* @summary Verifies that images transformed with bilinear filtering do not
* leave artifacts at the edges.
* @run main/othervm -Dsun.java2d.uiScale=2.5 DrawImageBilinear
* @run main/othervm -Dsun.java2d.uiScale=2.5 -Dsun.java2d.d3d=false DrawImageBilinear
*/
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.Robot;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;
import java.awt.image.IndexColorModel;
import java.awt.image.VolatileImage;
public class DrawImageBilinear extends Canvas {
private static final int SIZE = 5;
private static boolean done;
private BufferedImage bimg1, bimg2;
private VolatileImage vimg;
private static BufferedImage capture;
private static DrawImageBilinear test;
private static Frame frame;
private void renderPattern(Graphics g) {
g.setColor(Color.red);
g.fillRect(0, 0, SIZE, SIZE);
g.dispose();
}
public void paint(Graphics g) {
Graphics2D g2d = (Graphics2D)g;
if (bimg1 == null) {
bimg1 = (BufferedImage)createImage(SIZE, SIZE);
bimg1.setAccelerationPriority(0.0f);
renderPattern(bimg1.createGraphics());
bimg2 = (BufferedImage)createImage(SIZE, SIZE);
renderPattern(bimg2.createGraphics());
vimg = createVolatileImage(SIZE, SIZE);
vimg.validate(getGraphicsConfiguration());
renderPattern(vimg.createGraphics());
}
do {
g2d.setColor(Color.white);
g2d.fillRect(0, 0, getWidth(), getHeight());
g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
RenderingHints.VALUE_INTERPOLATION_BILINEAR);
// first time will be a sw->surface blit
g2d.drawImage(bimg1, 10, 10, 40, 40, null);
// second time will be a texture->surface blit
g2d.drawImage(bimg2, 80, 10, 40, 40, null);
g2d.drawImage(bimg2, 80, 10, 40, 40, null);
// third time will be a pbuffer->surface blit
if (vimg.validate(getGraphicsConfiguration()) !=
VolatileImage.IMAGE_OK) {
renderPattern(vimg.createGraphics());
}
g2d.drawImage(vimg, 150, 10, 40, 40, null);
Toolkit.getDefaultToolkit().sync();
} while (vimg.contentsLost());
}
public Dimension getPreferredSize() {
return new Dimension(200, 100);
}
private static void testRegion(BufferedImage bi,
Rectangle affectedRegion)
{
int x1 = affectedRegion.x;
int y1 = affectedRegion.y;
int x2 = x1 + affectedRegion.width;
int y2 = y1 + affectedRegion.height;
for (int y = y1; y < y2; y++) {
for (int x = x1; x < x2; x++) {
int actual = bi.getRGB(x, y);
if ((actual != 0xfffe0000) && (actual != 0xffff0000)) {
throw new RuntimeException("Test failed at x="+x+" y="+y+
" (expected=0xffff0000"+
" actual=0x"+
Integer.toHexString(actual) +
")");
}
}
}
}
private static void createAndShowGUI() {
test = new DrawImageBilinear();
frame = new Frame();
frame.add(test);
frame.setUndecorated(true);
frame.setAlwaysOnTop(true);
frame.setLocationRelativeTo(null);
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) throws Exception {
try {
EventQueue.invokeAndWait(() -> createAndShowGUI());
GraphicsConfiguration gc = frame.getGraphicsConfiguration();
if (gc.getColorModel() instanceof IndexColorModel) {
System.out.println("IndexColorModel detected: " +
"test considered PASSED");
return;
}
Robot robot = new Robot();
robot.setAutoDelay(100);
robot.mouseMove(0,0);
robot.waitForIdle();
Point pt1 = frame.getLocationOnScreen();
Rectangle rect =
new Rectangle(pt1.x, pt1.y,
frame.getWidth(), frame.getHeight());
capture = robot.createScreenCapture(rect);
robot.waitForIdle();
if (capture == null) {
throw new RuntimeException("Failed: capture is null");
}
// Test background color
int pixel = capture.getRGB(5, 5);
if (pixel != 0xffffffff) {
throw new RuntimeException("Failed: Incorrect color for " +
"background");
}
// Test pixels
testRegion(capture, new Rectangle(10, 10, 40, 40));
testRegion(capture, new Rectangle(80, 10, 40, 40));
testRegion(capture, new Rectangle(150, 10, 40, 40));
} finally {
if (frame != null) {
frame.dispose();
}
}
}
}

View file

@ -0,0 +1,69 @@
/*
* Copyright (c) 2001, 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 4515761
* @summary verify that drawRoundRect produces correct output for 0 w/h
*/
import java.awt.Color;
import static java.awt.Color.*;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
public class DrawRoundRect0Bug {
public static void main(String argv[]) {
BufferedImage img = new BufferedImage(250, 250, BufferedImage.TYPE_INT_RGB);
Graphics2D g = img.createGraphics();
g.setColor(white);
g.fillRect(0, 0, img.getWidth(), img.getHeight());
g.setColor(green);
g.drawLine(150, 90, 150, 110);
if (img.getRGB(150, 100) != green.getRGB()) {
throw new RuntimeException("Vertical line not green");
}
g.setColor(blue);
g.drawRoundRect(160, 90, 0, 20, 4, 4);
if (img.getRGB(160, 100) != blue.getRGB()) {
throw new RuntimeException("Vertical (ie zero width) round rect not blue");
}
g.setColor(green);
g.drawLine(150, 140, 170, 140);
if (img.getRGB(160, 140) != green.getRGB()) {
throw new RuntimeException("Horizontal line not green");
}
g.setColor(blue);
g.drawRoundRect(150, 150, 20, 0, 4, 4);
if (img.getRGB(160, 150) != blue.getRGB()) {
throw new RuntimeException("Horizontal (ie zero height) round rect not blue");
}
}
}

View file

@ -0,0 +1,300 @@
/*
* Copyright (c) 2014, 2018, 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.
*/
import java.awt.AWTException;
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsEnvironment;
import java.awt.HeadlessException;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.Toolkit;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.image.BufferedImage;
import java.awt.image.VolatileImage;
import java.io.File;
import java.io.IOException;
import java.util.HashSet;
import javax.imageio.ImageIO;
import sun.awt.ConstrainableGraphics;
/**
* @test
* @key headful
* @bug 6335200 6419610 8198613
* @summary Tests that we don't render anything if specific empty clip is set
* @author Dmitri.Trembovetski@Sun.COM: area=Graphics
* @modules java.desktop/sun.awt
* @run main EmptyClipRenderingTest
* @run main/othervm -Dsun.java2d.noddraw=true EmptyClipRenderingTest
* @run main/othervm -Dsun.java2d.pmoffscreen=true EmptyClipRenderingTest
*/
public class EmptyClipRenderingTest {
static final int IMG_W = 400;
static final int IMG_H = 400;
// generated rectangles
static HashSet<Rectangle> rects;
volatile boolean isActivated = false;
volatile boolean isPainted;
private static boolean showErrors = false;
public EmptyClipRenderingTest() {
// initialize clip/render region rectangles
initClips();
HashSet<RuntimeException> errors = new HashSet<RuntimeException>();
BufferedImage screenResult = testOnscreen();
try {
testResult(screenResult, "Screen");
} catch (RuntimeException e) {
errors.add(e);
}
BufferedImage destBI =
new BufferedImage(IMG_W, IMG_H, BufferedImage.TYPE_INT_RGB);
runTest((Graphics2D)destBI.getGraphics());
try {
testResult(destBI, "BufferedImage");
} catch (RuntimeException e) {
errors.add(e);
}
GraphicsConfiguration gc =
GraphicsEnvironment.getLocalGraphicsEnvironment().
getDefaultScreenDevice().getDefaultConfiguration();
VolatileImage destVI = gc.createCompatibleVolatileImage(IMG_W, IMG_H);
destVI.validate(gc);
runTest((Graphics2D)destVI.getGraphics());
try {
testResult(destVI.getSnapshot(), "VolatileImage");
} catch (RuntimeException e) {
errors.add(e);
}
if (errors.isEmpty()) {
System.err.println("Test PASSED.");
} else {
for (RuntimeException re : errors) {
re.printStackTrace();
}
if (showErrors) {
System.err.println("Test FAILED: "+ errors.size() +
" subtest failures.");
} else {
throw new RuntimeException("Test FAILED: "+ errors.size() +
" subtest failures.");
}
}
}
/**
* Recursively adds 4 new rectangles: two vertical and two horizontal
* based on the passed rectangle area. The area is then shrunk and the
* process repeated for smaller area.
*/
private static void add4Rects(HashSet<Rectangle> rects, Rectangle area) {
if (area.width < 10 || area.height < 10) {
rects.add(area);
return;
}
// two vertical rects
rects.add(new Rectangle(area.x, area.y, 5, area.height));
rects.add(new Rectangle(area.x + area.width - 5, area.y, 5, area.height));
// two horizontal rects
int width = area.width - 2*(5 + 1);
rects.add(new Rectangle(area.x+6, area.y, width, 5));
rects.add(new Rectangle(area.x+6, area.y + area.height - 5, width, 5));
// reduce the area and repeat
area.grow(-6, -6);
add4Rects(rects, area);
}
/**
* Generate a bunch of non-intersecting rectangles
*/
private static void initClips() {
rects = new HashSet<Rectangle>();
add4Rects(rects, new Rectangle(0, 0, IMG_W, IMG_H));
System.err.println("Total number of test rects: " + rects.size());
}
/**
* Render the pattern to the screen, capture the output with robot and
* return it.
*/
private BufferedImage testOnscreen() throws HeadlessException {
final Canvas destComponent;
final Object lock = new Object();
Frame f = new Frame("Test Frame");
f.setUndecorated(true);
f.add(destComponent = new Canvas() {
public void paint(Graphics g) {
isPainted = true;
}
public Dimension getPreferredSize() {
return new Dimension(IMG_W, IMG_H);
}
});
f.addWindowListener(new WindowAdapter() {
public void windowActivated(WindowEvent e) {
if (!isActivated) {
synchronized (lock) {
isActivated = true;
lock.notify();
}
}
}
});
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
synchronized(lock) {
while (!isActivated) {
try {
lock.wait(100);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
}
Robot r;
try {
r = new Robot();
} catch (AWTException ex) {
throw new RuntimeException("Can't create Robot");
}
BufferedImage bi;
int attempt = 0;
do {
if (++attempt > 10) {
throw new RuntimeException("Too many attempts: " + attempt);
}
isPainted = false;
runTest((Graphics2D) destComponent.getGraphics());
r.waitForIdle();
Toolkit.getDefaultToolkit().sync();
bi = r.createScreenCapture(
new Rectangle(destComponent.getLocationOnScreen().x,
destComponent.getLocationOnScreen().y,
destComponent.getWidth(),
destComponent.getHeight()));
} while (isPainted);
f.setVisible(false);
f.dispose();
return bi;
}
/**
* Run the test: cycle through all the rectangles, use one as clip and
* another as the area to render to.
* Set the clip in the same way Swing does it when repainting:
* first constrain the graphics to the damaged area, and repaint everything
*/
void runTest(Graphics2D destGraphics) {
destGraphics.setColor(Color.black);
destGraphics.fillRect(0, 0, IMG_W, IMG_H);
destGraphics.setColor(Color.red);
for (Rectangle clip : rects) {
Graphics2D g2d = (Graphics2D)destGraphics.create();
g2d.setColor(Color.red);
// mimic what swing does in BufferStrategyPaintManager
if (g2d instanceof ConstrainableGraphics) {
((ConstrainableGraphics)g2d).constrain(clip.x, clip.y,
clip.width, clip.height);
}
g2d.setClip(clip);
for (Rectangle renderRegion : rects) {
if (renderRegion != clip) {
// from CellRendererPane's paintComponent
Graphics2D rG = (Graphics2D)
g2d.create(renderRegion.x, renderRegion.y,
renderRegion.width, renderRegion.height);
rG.fillRect(0,0, renderRegion.width, renderRegion.height);
}
}
}
}
void testResult(final BufferedImage bi, final String desc) {
for (int y = 0; y < bi.getHeight(); y++) {
for (int x = 0; x < bi.getWidth(); x++) {
if (bi.getRGB(x, y) != Color.black.getRGB()) {
if (showErrors) {
Frame f = new Frame("Error: " + desc);
f.add(new Component() {
public void paint(Graphics g) {
g.drawImage(bi, 0, 0, null);
}
public Dimension getPreferredSize() {
return new Dimension(bi.getWidth(),
bi.getHeight());
}
});
f.pack();
f.setVisible(true);
}
try {
String fileName =
"EmptyClipRenderingTest_"+desc+"_res.png";
System.out.println("Writing resulting image: "+fileName);
ImageIO.write(bi, "png", new File(fileName));
} catch (IOException ex) {
ex.printStackTrace();
}
throw new RuntimeException("Dest: "+desc+
" was rendered to at x="+
x + " y=" + y +
" pixel="+Integer.toHexString(bi.getRGB(x,y)));
}
}
}
}
public static void main(String argv[]) {
for (String arg : argv) {
if (arg.equals("-show")) {
showErrors = true;
} else {
usage("Incorrect argument:" + arg);
}
}
new EmptyClipRenderingTest();
}
private static void usage(String string) {
System.out.println(string);
System.out.println("Usage: EmptyClipRenderingTest [-show]");
}
}

View file

@ -0,0 +1,661 @@
/*
* Copyright (c) 2002, 2018, 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
* @key headful
* @bug 4678208 4771101 6328481 6588884 8198613
* @summary verify the pixelization of degenerate polylines and polygons
* @run main PolyVertTest
* @run main/othervm -Dsun.java2d.d3d=True PolyVertTest -hwonly
*/
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
import java.awt.image.*;
public class PolyVertTest {
static int TESTWIDTH;
static int TESTHEIGHT;
static final int REG_TEST_WIDTH = 10;
static final int REG_TEST_HEIGHT = 10;
static final int FULL_TEST_WIDTH = 50;
static final int FULL_TEST_HEIGHT = 200;
static final int FRINGE = 2;
static final int GREEN = Color.green.getRGB();
static final int RED = Color.red.getRGB();
static BufferedImage refImg;
static BufferedImage errorImg;
static Graphics errorG;
static Component testCanvas;
static int totalbadpixels;
static int totalfuzzypixels;
static int numbadtests;
static int numfuzzytests;
static int numframes;
static int fuzzystarty;
static boolean counting;
static boolean showerrors;
static boolean showresults;
static boolean fringe;
static boolean forceerror;
static boolean fulltest = true;
static boolean hwonly;
static WindowListener windowCloser = new WindowAdapter() {
public void windowClosing(WindowEvent e) {
e.getWindow().hide();
if (--numframes <= 0) {
System.exit(0);
}
}
};
public PolyVertTest() {
/*
setBackground(Color.white);
setForeground(Color.black);
*/
}
static int polypts[][][] = {
{
// void polygon (no points)
{}, {},
},
{
// one point
{ 0 }, { 0 },
},
{
// two points
{ 0, 5 }, { 0, 0 },
{ 0, 0, 6, 1,
10, 0, 6, 1,
20, 0, 6, 1 },
{ 0, 0, 6, 1,
10, 0, 1, 1, 15, 0, 1, 1,
20, 0, 1, 1, 25, 0, 1, 1 },
{ 10, 0, 1, 1,
20, 0, 1, 1 },
},
{
// open triangle
{ 0, 5, 5 }, { 0, 0, 5 },
{ 0, 0, 6, 1, 5, 1, 1, 5,
10, 0, 6, 1, 15, 1, 1, 5, 11, 1, 1, 1,
12, 2, 1, 1, 13, 3, 1, 1, 14, 4, 1, 1,
20, 0, 6, 1, 25, 1, 1, 5, 21, 1, 1, 1,
22, 2, 1, 1, 23, 3, 1, 1, 24, 4, 1, 1 },
{ 0, 0, 6, 1, 5, 1, 1, 5,
10, 0, 6, 1, 15, 1, 1, 5, 11, 1, 1, 1,
12, 2, 1, 1, 13, 3, 1, 1, 14, 4, 1, 1,
20, 0, 6, 1, 25, 1, 1, 5, 21, 1, 1, 1,
22, 2, 1, 1, 23, 3, 1, 1, 24, 4, 1, 1 },
{ 10, 0, 1, 1,
20, 0, 1, 1 },
},
{
// closed triangle
{ 0, 5, 5, 0 }, { 0, 0, 5, 0 },
{ 0, 0, 6, 1, 5, 1, 1, 5, 1, 1, 1, 1,
2, 2, 1, 1, 3, 3, 1, 1, 4, 4, 1, 1,
10, 0, 6, 1, 15, 1, 1, 5, 11, 1, 1, 1,
12, 2, 1, 1, 13, 3, 1, 1, 14, 4, 1, 1,
20, 0, 6, 1, 25, 1, 1, 5, 21, 1, 1, 1,
22, 2, 1, 1, 23, 3, 1, 1, 24, 4, 1, 1 },
{ 1, 0, 5, 1, 5, 1, 1, 5, 1, 1, 1, 1,
2, 2, 1, 1, 3, 3, 1, 1, 4, 4, 1, 1,
10, 0, 6, 1, 15, 1, 1, 5, 11, 1, 1, 1,
12, 2, 1, 1, 13, 3, 1, 1, 14, 4, 1, 1,
20, 0, 6, 1, 25, 1, 1, 5, 21, 1, 1, 1,
22, 2, 1, 1, 23, 3, 1, 1, 24, 4, 1, 1 },
{ 0, 0, 1, 1,
10, 0, 1, 1,
20, 0, 1, 1 },
},
{
// empty line
{ 0, 0 }, { 0, 0 },
{ 0, 0, 1, 1,
10, 0, 1, 1,
20, 0, 1, 1 },
},
{
// empty triangle
{ 0, 0, 0 }, { 0, 0, 0 },
{ 0, 0, 1, 1,
10, 0, 1, 1,
20, 0, 1, 1 },
},
};
public static void render(Graphics2D g2d) {
g2d.setColor(Color.white);
g2d.fillRect(0, 0, TESTWIDTH, TESTHEIGHT);
g2d.setColor(Color.black);
if (forceerror) {
g2d.fillRect(2, 2, 2, 2);
g2d.fillRect(15, 5, 1, 1);
}
if (!fulltest) {
g2d.draw(new Rectangle2D.Double(5, 5, 0, 0));
return;
}
g2d.drawLine(10, 10, 10, 10);
g2d.draw(new Line2D.Double(20, 10, 20, 10));
g2d.drawRect(10, 20, 0, 0);
g2d.draw(new Rectangle2D.Double(20, 20, 0, 0));
g2d.setXORMode(Color.white);
g2d.drawLine(10, 30, 10, 30);
g2d.draw(new Line2D.Double(20, 30, 20, 30));
g2d.drawRect(10, 40, 0, 0);
g2d.draw(new Rectangle2D.Double(20, 40, 0, 0));
g2d.setPaintMode();
int y = 50;
for (int i = 0; i < polypts.length; i++) {
int data[][] = polypts[i];
int xpoints[] = data[0];
int ypoints[] = data[1];
int npoints = xpoints.length;
g2d.translate(10, y);
g2d.drawPolyline(xpoints, ypoints, npoints);
g2d.translate(10, 0);
g2d.drawPolygon(xpoints, ypoints, npoints);
g2d.translate(10, 0);
g2d.draw(new Polygon(xpoints, ypoints, npoints));
g2d.translate(-30, -y);
y += 10;
}
g2d.setXORMode(Color.white);
for (int i = 0; i < polypts.length; i++) {
int data[][] = polypts[i];
int xpoints[] = data[0];
int ypoints[] = data[1];
int npoints = xpoints.length;
g2d.translate(10, y);
g2d.drawPolyline(xpoints, ypoints, npoints);
g2d.translate(10, 0);
g2d.drawPolygon(xpoints, ypoints, npoints);
g2d.translate(10, 0);
g2d.draw(new Polygon(xpoints, ypoints, npoints));
g2d.translate(-30, -y);
y += 10;
}
g2d.setPaintMode();
}
public Dimension getPreferredSize() {
return new Dimension(500, 500);
}
public static void usage(int exitcode) {
System.err.println("usage: java PolyVertTest [<option>]*");
System.err.println(" -usage "+
"print this usage summary");
System.err.println(" -count "+
"run all tests and accumulate error counts");
System.err.println(" -forceerror "+
"force at least one error in each test");
System.err.println(" -fringe "+
"draw a yellow fringe around problems");
System.err.println(" -showerrors "+
"display results window for tests with problems");
System.err.println(" -showresults "+
"display results window for all tests");
System.err.println(" -quicktest "+
"only run test cases reported in bug reports");
System.err.println(" -fulltest "+
"run full suite of test cases for a 'unit test'");
System.err.println(" -hwonly "+
"only run tests for screen and VolatileImage");
System.exit(exitcode);
}
public static void main(String argv[]) {
for (int i = 0; i < argv.length; i++) {
String arg = argv[i];
if (arg.equalsIgnoreCase("-count")) {
counting = true;
} else if (arg.equalsIgnoreCase("-forceerror")) {
forceerror = true;
} else if (arg.equalsIgnoreCase("-fringe")) {
fringe = true;
} else if (arg.equalsIgnoreCase("-showerrors")) {
showerrors = true;
} else if (arg.equalsIgnoreCase("-showresults")) {
showresults = true;
} else if (arg.equalsIgnoreCase("-quicktest")) {
fulltest = false;
} else if (arg.equalsIgnoreCase("-fulltest")) {
fulltest = true;
} else if (arg.equalsIgnoreCase("-hwonly")) {
hwonly = true;
} else if (arg.equalsIgnoreCase("-usage")) {
usage(0);
} else {
System.err.println("unknown option: "+arg);
usage(1);
}
}
if (fulltest) {
TESTWIDTH = FULL_TEST_WIDTH;
TESTHEIGHT = FULL_TEST_HEIGHT;
} else {
TESTWIDTH = REG_TEST_WIDTH;
TESTHEIGHT = REG_TEST_HEIGHT;
}
// Prevents premature exit by the WindowAdapter if the user
// closes the last visible results window before we've
// finished our tests.
numframes++;
makeReferenceImage();
testScreen();
testVolatileImage();
if (!hwonly) {
testBufferedImage();
testOffscreen();
testCompatibleImages();
}
if (totalfuzzypixels > 0) {
System.err.println(totalfuzzypixels+" fuzzy pixels found in "+
numfuzzytests+" tests");
}
if (totalbadpixels > 0) {
throw new RuntimeException(totalbadpixels+" bad pixels found in "+
numbadtests+" tests");
}
System.out.println("Test done - no bad pixels found");
--numframes;
if (counting || ((showresults || showerrors) && numframes == 0)) {
System.exit(0);
}
}
public static void makeReferenceImage() {
refImg = new BufferedImage(TESTWIDTH, TESTHEIGHT,
BufferedImage.TYPE_INT_RGB);
Graphics g = refImg.getGraphics();
g.setColor(Color.white);
g.fillRect(0, 0, TESTWIDTH, TESTHEIGHT);
g.setColor(Color.black);
if (!fulltest) {
g.fillRect(5, 5, 1, 1);
g.dispose();
return;
}
for (int y = 10; y < 50; y += 10) {
g.fillRect(10, y, 1, 1);
g.fillRect(20, y, 1, 1);
}
int y = 50;
for (int i = 0; i < polypts.length; i++) {
int data[][] = polypts[i];
g.translate(10, y);
if (data.length > 2) {
int rectvals[] = data[2];
for (int j = 0; j < rectvals.length; j += 4) {
g.fillRect(rectvals[j+0], rectvals[j+1],
rectvals[j+2], rectvals[j+3]);
}
}
g.translate(-10, -y);
y += 10;
}
fuzzystarty = y;
for (int i = 0; i < polypts.length; i++) {
int data[][] = polypts[i];
g.translate(10, y);
if (data.length > 2) {
int rectvals[] = data.length > 3 ? data[3] : data[2];
for (int j = 0; j < rectvals.length; j += 4) {
g.fillRect(rectvals[j+0], rectvals[j+1],
rectvals[j+2], rectvals[j+3]);
}
}
g.translate(-10, -y);
y += 10;
}
g.dispose();
}
public static void initerrorbuf() {
if (errorImg == null) {
droperrorbuf();
errorImg = new BufferedImage(TESTWIDTH, TESTHEIGHT,
BufferedImage.TYPE_INT_RGB);
}
if (errorG == null) {
errorG = errorImg.getGraphics();
}
errorG.setColor(Color.green);
errorG.fillRect(0, 0, TESTWIDTH, TESTHEIGHT);
errorG.setColor(Color.red);
}
public static void droperrorbuf() {
errorImg = null;
if (errorG != null) {
errorG.dispose();
}
errorG = null;
}
public static void test(Image img, String name) {
Graphics2D g2d = (Graphics2D) img.getGraphics();
render(g2d);
g2d.dispose();
verify(img, name);
}
public static void test(BufferedImage bimg, String name) {
Graphics2D g2d = bimg.createGraphics();
render(g2d);
g2d.dispose();
verify(bimg, name);
}
public static void verify(Image img, String name) {
BufferedImage bimg;
if (img instanceof BufferedImage) {
bimg = (BufferedImage) img;
} else {
bimg = new BufferedImage(TESTWIDTH, TESTHEIGHT,
BufferedImage.TYPE_INT_RGB);
Graphics g = bimg.getGraphics();
g.drawImage(img, 0, 0, null);
g.dispose();
}
verify(bimg, name);
}
public static boolean isFuzzyPixel(int X, int Y) {
int ytrans = fuzzystarty;
if (!fulltest || Y < ytrans) {
return false;
}
for (int i = 0; i < polypts.length; i++) {
int data[][] = polypts[i];
if (data.length > 4) {
int rectvals[] = data[4];
for (int j = 0; j < rectvals.length; j += 4) {
int rectx = rectvals[j+0] + 10;
int recty = rectvals[j+1] + ytrans;
int rectw = rectvals[j+2];
int recth = rectvals[j+3];
if (X >= rectx && Y >= recty &&
X < rectx + rectw && Y < recty + recth)
{
return true;
}
}
}
ytrans += 10;
}
return false;
}
public static void verify(BufferedImage bimg, String name) {
int numbadpixels = 0;
int numfuzzypixels = 0;
for (int y = 0; y < TESTHEIGHT; y++) {
for (int x = 0; x < TESTWIDTH; x++) {
if (refImg.getRGB(x, y) != bimg.getRGB(x, y)) {
boolean isfuzzy = isFuzzyPixel(x, y);
if (showerrors || showresults) {
if (errorG == null) {
initerrorbuf();
}
errorG.setColor(isfuzzy ? Color.blue : Color.red);
errorG.fillRect(x, y, 1, 1);
} else if (!counting && !isfuzzy) {
throw new RuntimeException("Error at "+x+", "+y+
" while testing: "+name);
}
if (isfuzzy) {
numfuzzypixels++;
} else {
numbadpixels++;
}
}
}
}
if (numbadpixels > 0 || numfuzzypixels > 0) {
if (numbadpixels > 0) {
totalbadpixels += numbadpixels;
numbadtests++;
}
if (numfuzzypixels > 0) {
totalfuzzypixels += numfuzzypixels;
numfuzzytests++;
}
System.out.println(numbadpixels+" bad pixels and "+
numfuzzypixels+" questionable pixels "+
"found while testing "+name);
if (showerrors || showresults) {
displaydiffs(bimg, name);
}
} else if (showresults) {
if (errorG == null) {
initerrorbuf();
}
displaydiffs(bimg, name);
}
}
public static void displaydiffs(BufferedImage bimg, String name) {
if (fringe) {
errorG.setColor(Color.yellow);
for (int y = 0; y < TESTHEIGHT; y++) {
for (int x = 0; x < TESTWIDTH; x++) {
if (errorImg.getRGB(x, y) == RED) {
for (int iy = y-FRINGE; iy <= y+FRINGE; iy++) {
for (int ix = x-FRINGE; ix <= x+FRINGE; ix++) {
if (ix >= 0 && ix < TESTWIDTH &&
iy >= 0 && iy < TESTHEIGHT &&
errorImg.getRGB(ix, iy) == GREEN)
{
errorG.fillRect(ix, iy, 1, 1);
}
}
}
}
}
}
}
Frame f = new Frame("Results for "+name);
f.setLayout(new BorderLayout());
f.addWindowListener(windowCloser);
++numframes;
Panel p = new Panel();
p.add(new ImageCanvas(bimg));
p.add(new ImageCanvas(errorImg));
p.add(new ImageCanvas(refImg));
f.add(p, "Center");
droperrorbuf();
f.pack();
f.show();
}
public static void testBufferedImage() {
testBufferedImage(BufferedImage.TYPE_INT_RGB, "IntXrgb");
testBufferedImage(BufferedImage.TYPE_INT_ARGB, "IntArgb");
testBufferedImage(BufferedImage.TYPE_3BYTE_BGR, "ThreeByte");
testBufferedImage(BufferedImage.TYPE_4BYTE_ABGR, "FourByte");
testBufferedImage(BufferedImage.TYPE_USHORT_555_RGB, "UShort555");
testBufferedImage(BufferedImage.TYPE_BYTE_GRAY, "ByteGray");
testBufferedImage(BufferedImage.TYPE_BYTE_INDEXED, "Indexed");
}
public static void testBufferedImage(int type, String name) {
BufferedImage bimg = new BufferedImage(TESTWIDTH, TESTHEIGHT, type);
test(bimg, name);
}
public static void testScreen() {
Frame f = new Frame("PolyVertTest");
TestCanvas child = new TestCanvas();
testCanvas = child;
f.add(child);
f.pack();
f.show();
BufferedImage bimg = child.getImage();
f.hide();
verify(bimg, "Screen");
}
public static void testOffscreen() {
Image img = testCanvas.createImage(TESTWIDTH, TESTHEIGHT);
test(img, "Offscreen");
}
public static void testCompatibleImages() {
GraphicsEnvironment genv =
GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice gdevs[] = genv.getScreenDevices();
for (int i = 0; i < gdevs.length; i++) {
testCompatibleImages(gdevs[i]);
}
}
public static void testCompatibleImages(GraphicsDevice gdev) {
GraphicsConfiguration gconfigs[] = gdev.getConfigurations();
for (int i = 0; i < gconfigs.length; i++) {
testCompatibleImages(gconfigs[i]);
}
}
public static void testCompatibleImages(GraphicsConfiguration gconfig) {
test(gconfig.createCompatibleImage(TESTWIDTH, TESTHEIGHT),
gconfig+".createCompat()");
test(gconfig.createCompatibleImage(TESTWIDTH, TESTHEIGHT,
Transparency.OPAQUE),
gconfig+".createCompat(OPAQUE)");
test(gconfig.createCompatibleImage(TESTWIDTH, TESTHEIGHT,
Transparency.BITMASK),
gconfig+".createCompat(BITMASK)");
test(gconfig.createCompatibleImage(TESTWIDTH, TESTHEIGHT,
Transparency.TRANSLUCENT),
gconfig+".createCompat(TRANSLUCENT)");
test(gconfig.createCompatibleVolatileImage(TESTWIDTH, TESTHEIGHT),
gconfig+".createCompatVolatile()");
}
public static void testVolatileImage() {
Image img = testCanvas.createVolatileImage(TESTWIDTH, TESTHEIGHT);
test(img, "Volatile");
}
public static class ImageCanvas extends Canvas {
BufferedImage bimg;
public ImageCanvas(BufferedImage bimg) {
this.bimg = bimg;
}
public Dimension getPreferredSize() {
return new Dimension(bimg.getWidth(), bimg.getHeight());
}
public void paint(Graphics g) {
g.drawImage(bimg, 0, 0, null);
}
}
public static class TestCanvas extends Canvas {
BufferedImage bimg;
public Dimension getPreferredSize() {
return new Dimension(TESTWIDTH, TESTHEIGHT);
}
public void paint(Graphics g) {
if (bimg != null ||
getWidth() < TESTWIDTH ||
getHeight() < TESTHEIGHT)
{
return;
}
render((Graphics2D) g);
Toolkit.getDefaultToolkit().sync();
Point p = getLocationOnScreen();
Rectangle r = new Rectangle(p.x, p.y, TESTWIDTH, TESTHEIGHT);
try {
bimg = new Robot().createScreenCapture(r);
} catch (AWTException e) {
e.printStackTrace();
}
synchronized (this) {
notifyAll();
}
}
public synchronized BufferedImage getImage() {
while (bimg == null) {
try {
wait();
} catch (InterruptedException e) {
return null;
}
}
return bimg;
}
}
}

View file

@ -0,0 +1,104 @@
/*
* 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 4652373
* @summary verify that SunGraphics2D survives surface revalidation
* @library /java/awt/regtesthelpers
* @build PassFailJFrame
* @run main/manual RevalidateBug
* @requires (os.family == "windows")
*/
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GradientPaint;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Insets;
import java.awt.Rectangle;
import javax.swing.JComponent;
import javax.swing.JFrame;
public class RevalidateBug {
private static final String INSTRUCTIONS = """
This bug only reproduces on Windows systems with a task manager that can lock the computer.
This test draws a grayscale gradient in a window.
After the gradient becomes visible above, use ctrl-alt-del to bring up
the task manager and lock the computer.
Then unlock the computer and the gradient should be repainted to pass.
If the gradient does not appear after unlocking (or if the test gets
an error on its own after unlocking the computer) then it fails.
""";
public static void main(String[] argv) throws Exception {
PassFailJFrame.builder()
.title("RevalidateBug")
.instructions(INSTRUCTIONS)
.testTimeOut(5)
.rows(12)
.columns(50)
.testUI(RevalidateBug::createUI)
.build()
.awaitAndCheck();
}
private static JFrame createUI() {
JComponent comp = new JComponent() {
protected void paintComponent(Graphics g) {
super.paintComponent(g);
System.out.println("paintComponent");
Graphics2D g2d = (Graphics2D) g;
Insets insets = getInsets();
Rectangle rect =
new Rectangle(insets.left, insets.top,
getWidth() - insets.right - insets.left,
getHeight() - insets.top - insets.bottom);
g2d.setPaint(new GradientPaint(rect.x, rect.y, Color.white,
rect.x + rect.width, rect.y, Color.black));
System.out.println(rect + " w:" + getWidth() + " h:"+getHeight());
g2d.fillRect(0, 0, getWidth(), getHeight());
}
public Dimension getPreferredSize() {
return new Dimension(500, 500);
}
};
JFrame f = new JFrame("RevalidateTest");
f.add(comp);
f.pack();
return f;
}
}

View file

@ -0,0 +1,95 @@
/*
* Copyright (c) 2001, 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 4516037
* @summary verify that scaled Polygons honor the transform
*/
import java.awt.Color;
import static java.awt.Color.*;
import java.awt.Graphics2D;
import java.awt.Polygon;
import java.awt.image.BufferedImage;
public class ScaledPolyTest {
public static void main(String[] args) {
Polygon poly = new Polygon();
poly.addPoint(20, 10);
poly.addPoint(30, 30);
poly.addPoint(10, 30);
poly.addPoint(20, 10);
int height = 300;
int width = 300;
BufferedImage bi = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
Graphics2D g2d = bi.createGraphics();
g2d.setColor(Color.white);
g2d.fillRect(0, 0, bi.getWidth(), bi.getHeight());
g2d.translate(10, 10);
g2d.scale(2, 2);
g2d.setColor(Color.yellow);
g2d.fill(poly);
g2d.setColor(Color.blue);
g2d.draw(poly);
/*
* Examine each row of the image.
* If the stroked polygon is correctly aligned on the filled polygon,
* if there is anything except white on the line,
* the transition will always be white+->blue+->yellow*->blue*->white+
*/
int bluePix = blue.getRGB();
int yellowPix = yellow.getRGB();
int whitePix = white.getRGB();
for (int y = 0; y < height; y++ ) {
int x = 0;
int pix = whitePix;
while (pix == whitePix && x < width) pix = bi.getRGB(x++, y);
if (pix == whitePix && x == width) continue; // all white row.
if (pix != bluePix) throw new RuntimeException("Expected blue");
while (pix == bluePix) pix = bi.getRGB(x++, y);
if (pix == yellowPix) {
while (pix == yellowPix) pix = bi.getRGB(x++, y);
if (pix != bluePix) throw new RuntimeException("Expected blue");
while (pix == bluePix) pix = bi.getRGB(x++, y);
if (pix != whitePix) throw new RuntimeException("Expected white");
}
while (pix == whitePix && x < width) pix = bi.getRGB(x++, y);
if (pix == whitePix && x == width) {
continue;
} else {
throw new RuntimeException("Expected white to finish the row");
}
}
}
}

View file

@ -0,0 +1,281 @@
/*
* Copyright (c) 2005, 2018, 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
* @key headful
* @bug 4832224 6322584 6328478 6328481 6322580 6588884 6587863 8198613
* @summary Verifies that the pixelization of simple primitives (drawLine,
* fillRect, drawRect, fill, draw) with the OGL pipeline enabled
* matches that produced by our software loops. (The primitives tested here
* are simple enough that the OGL results should match the software results
* exactly.) There is some overlap with PolyVertTest as we test both
* solid and XOR rendering here, but this testcase is a bit simpler and
* more appropriate for quick OGL testing. This test is also useful for
* comparing quality between our X11/GDI and software pipelines.
* @run main/othervm SimplePrimQuality
* @author campbelc
*/
import java.awt.*;
import java.awt.geom.*;
import java.awt.image.*;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
public class SimplePrimQuality extends Canvas {
private static final int SIZE = 300;
private static boolean done;
private static boolean testVI;
private static volatile BufferedImage capture;
private static void doCapture(Component test) {
// Grab the screen region
try {
Robot robot = new Robot();
Point pt1 = test.getLocationOnScreen();
Rectangle rect =
new Rectangle(pt1.x, pt1.y, test.getWidth(), test.getHeight());
capture = robot.createScreenCapture(rect);
} catch (Exception e) {
e.printStackTrace();
}
}
private static final int[][] rpts = {
{2, 0, 0, 0},
{12, 0, 1, 0},
{22, 0, 0, 1},
{32, 0, 1, 1},
{42, 0, 2, 1},
{52, 0, 1, 2},
{62, 0, 2, 2},
{72, 0, 5, 5},
{82, 0, 10, 10},
{97, 0, 15, 15},
};
private void drawLine(Graphics2D g, int x, int y, int dx, int dy) {
g.drawLine(x, y, x + dx, y + dy);
}
private void drawLines(Graphics2D g, int s) {
drawLine(g, 2, 0, 0, 0);
drawLine(g, 12, 0, 0, s);
drawLine(g, 22, 0, s, 0);
drawLine(g, 32, 0, s, s);
drawLine(g, 42, 0, 0, -s);
drawLine(g, 52, 0, -s, 0);
drawLine(g, 62, 0, -s, -s);
drawLine(g, 72, 0, -s, s);
drawLine(g, 82, 0, s, -s);
}
private void fillRects(Graphics2D g) {
for (int i = 0; i < rpts.length; i++) {
g.fillRect(rpts[i][0], rpts[i][1], rpts[i][2], rpts[i][3]);
}
}
private void drawRects(Graphics2D g) {
for (int i = 0; i < rpts.length; i++) {
g.drawRect(rpts[i][0], rpts[i][1], rpts[i][2], rpts[i][3]);
}
}
private void fillOvals(Graphics2D g) {
for (int i = 0; i < rpts.length; i++) {
// use fill() instead of fillOval(), since the former is more
// likely to be consistent with our software loops when the
// OGL pipeline cannot be enabled
g.fill(new Ellipse2D.Float(rpts[i][0], rpts[i][1],
rpts[i][2], rpts[i][3]));
}
}
private void drawOvals(Graphics2D g) {
for (int i = 0; i < rpts.length; i++) {
// use draw() instead of drawOval(), since the former is more
// likely to be consistent with our software loops when the
// OGL pipeline cannot be enabled
g.draw(new Ellipse2D.Float(rpts[i][0], rpts[i][1],
rpts[i][2], rpts[i][3]));
}
}
private void renderShapes(Graphics2D g) {
// drawLine tests...
g.translate(0, 5);
drawLines(g, 1);
g.translate(0, 10);
drawLines(g, 4);
// fillRect tests...
g.translate(0, 10);
fillRects(g);
// drawRect tests...
g.translate(0, 20);
drawRects(g);
// fillOval tests...
g.translate(0, 20);
fillOvals(g);
// drawOval tests...
g.translate(0, 20);
drawOvals(g);
}
private void renderTest(Graphics2D g, int w, int h) {
// on the left side, render the shapes in solid mode
g.setColor(Color.black);
g.fillRect(0, 0, w, h);
g.setColor(Color.green);
renderShapes(g);
// on the right side, render the shapes in XOR mode
g.setTransform(AffineTransform.getTranslateInstance(SIZE/2, 0));
g.setXORMode(Color.black);
renderShapes(g);
g.setTransform(AffineTransform.getTranslateInstance(SIZE/2, 0));
renderShapes(g);
}
public void paint(Graphics g) {
Graphics2D g2d = (Graphics2D)g;
renderTest(g2d, SIZE, SIZE);
Toolkit.getDefaultToolkit().sync();
synchronized (this) {
if (!done) {
doCapture(this);
done = true;
}
notifyAll();
}
}
public Dimension getPreferredSize() {
return new Dimension(SIZE, SIZE);
}
public static void main(String[] args) {
boolean show = false;
for (String arg : args) {
if (arg.equals("-testvi")) {
System.out.println("Testing VolatileImage, not screen");
testVI = true;
} else if (arg.equals("-show")) {
show = true;
}
}
SimplePrimQuality test = new SimplePrimQuality();
Frame frame = new Frame();
frame.add(test);
frame.pack();
frame.setVisible(true);
// Wait until the component's been painted
synchronized (test) {
while (!done) {
try {
test.wait();
} catch (InterruptedException e) {
throw new RuntimeException("Failed: Interrupted");
}
}
}
// REMIND: We will allow this test to pass silently on Windows
// (when OGL is not enabled) until we fix the GDI pipeline so that
// its stroked/filled GeneralPaths match our software loops (see
// 6322554). This check should be removed when 6322554 is fixed.
GraphicsConfiguration gc = frame.getGraphicsConfiguration();
if (gc.getClass().getSimpleName().startsWith("Win")) {
System.out.println("GDI pipeline detected: " +
"test considered PASSED");
frame.dispose();
return;
}
if (testVI) {
// render to a VI instead of the screen
VolatileImage vi = frame.createVolatileImage(SIZE, SIZE);
do {
vi.validate(frame.getGraphicsConfiguration());
Graphics2D g1 = vi.createGraphics();
test.renderTest(g1, SIZE, SIZE);
g1.dispose();
capture = vi.getSnapshot();
} while (vi.contentsLost());
frame.dispose();
}
if (!show) {
frame.dispose();
}
if (capture == null) {
throw new RuntimeException("Error capturing the rendering");
}
// Create reference image
int w = SIZE, h = SIZE;
BufferedImage refimg = new BufferedImage(w, h,
BufferedImage.TYPE_INT_RGB);
Graphics2D g = refimg.createGraphics();
test.renderTest(g, w, h);
g.dispose();
// Test pixels
for (int y = 0; y < h; y++) {
for (int x = 0; x < w; x++) {
int actual = capture.getRGB(x, y);
int expected = refimg.getRGB(x, y);
if (actual != expected) {
String expectedName = "SimplePrimQuality_expected.png";
String actualName = "SimplePrimQuality_actual.png";
try {
System.out.println("Writing expected image to: "+
expectedName);
ImageIO.write(refimg, "png", new File(expectedName));
System.out.println("Writing actual image to: "+
actualName);
ImageIO.write(capture, "png", new File(actualName));
} catch (IOException ex) {}
throw new RuntimeException("Test failed at x="+x+" y="+y+
" (expected="+
Integer.toHexString(expected) +
" actual="+
Integer.toHexString(actual) +
")");
}
}
}
}
}

View file

@ -0,0 +1,299 @@
/*
* Copyright (c) 2005, 2010, 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
@key headful
@bug 6244574
@bug 6258142
@bug 6395165
@bug 6588884
@summary Tests that source is clipped correctly when blitting
different types of images to the screen
@author Dmitri.Trembovetski: area=Graphics2D
@run main SourceClippingBlitTest
*/
import java.awt.AWTException;
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.GraphicsConfiguration;
import java.awt.Image;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.Toolkit;
import java.awt.Transparency;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.image.BufferedImage;
import java.awt.image.VolatileImage;
public class SourceClippingBlitTest extends Canvas {
static final int TESTW = 300;
static final int TESTH = 300;
static final int IMAGEW = 50;
static final int IMAGEH = 50;
static final Rectangle IMAGE_BOUNDS = new Rectangle(0, 0, IMAGEW, IMAGEH);
static Robot robot;
static private boolean showErrors;
private static final Object lock = new Object();
private static volatile boolean done = false;
BufferedImage grabbedBI;
public static void main(String[] args) {
// allow user to override the properties if needed
if (System.getProperty("sun.java2d.pmoffscreen") == null) {
System.setProperty("sun.java2d.pmoffscreen", "true");
}
if (args.length > 0 && args[0].equals("-showerrors")) {
showErrors = true;
}
try {
robot = new Robot();
} catch (AWTException e) {
throw new RuntimeException(e);
}
Frame f = new Frame(SourceClippingBlitTest.class.getName());
final SourceClippingBlitTest test = new SourceClippingBlitTest();
f.add(test);
f.addWindowListener(new WindowAdapter() {
public void windowActivated(WindowEvent e) {
if (!done) {
test.runTests();
}
}
});
f.pack();
f.setLocation(100, 100);
f.setVisible(true);
synchronized (lock) {
while (!done) {
try {
lock.wait();
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
}
if (!showErrors) {
f.dispose();
}
}
public Dimension getPreferredSize() {
return new Dimension(TESTW, TESTH);
}
public void paint(Graphics g) {
if (showErrors && done && grabbedBI != null) {
g.drawImage(grabbedBI, 0, 0, null);
}
}
public void runTests() {
GraphicsConfiguration gc = getGraphicsConfiguration();
for (Image srcIm :
new Image[] {
getBufferedImage(gc, IMAGEW, IMAGEH,
BufferedImage.TYPE_INT_RGB, true),
getBufferedImage(gc, IMAGEW, IMAGEH,
BufferedImage.TYPE_INT_RGB, false),
// commented out due to 6593406
// getBMImage(gc, IMAGEW, IMAGEH),
// getBufferedImage(gc, IMAGEW, IMAGEH,
// BufferedImage.TYPE_INT_ARGB, true),
// getBufferedImage(gc, IMAGEW, IMAGEH,
// BufferedImage.TYPE_INT_ARGB, false),
getVImage(gc, IMAGEW, IMAGEH),
})
{
System.out.println("Testing source: " + srcIm);
// wiggle the source and dest rectangles
try {
for (int locationVar = -10; locationVar < 20; locationVar += 10)
{
for (int sizeVar = -10; sizeVar < 20; sizeVar += 10) {
Rectangle srcRect = (Rectangle)IMAGE_BOUNDS.clone();
srcRect.translate(locationVar, locationVar);
srcRect.grow(sizeVar, sizeVar);
Rectangle dstRect =
new Rectangle(sizeVar, sizeVar,
srcRect.width, srcRect.height);
System.out.println("testing blit rect src: " + srcRect);
System.out.println(" dst: " + dstRect);
render(getGraphics(), srcIm, srcRect, dstRect);
test(srcRect, dstRect);
}
}
System.out.println("Test passed.");
} finally {
synchronized (lock) {
done = true;
lock.notifyAll();
}
}
}
}
public void render(Graphics g, Image image,
Rectangle srcRect, Rectangle dstRect)
{
int w = getWidth();
int h = getHeight();
g.setColor(Color.green);
g.fillRect(0, 0, w, h);
int bltWidth = srcRect.width;
int bltHeight = srcRect.height;
VolatileImage vi = null;
if (image instanceof VolatileImage) {
vi = (VolatileImage)image;
}
do {
if (vi != null) {
GraphicsConfiguration gc = getGraphicsConfiguration();
if (vi.validate(gc) != VolatileImage.IMAGE_OK) {
initImage(gc, vi);
}
}
g.drawImage(image,
dstRect.x, dstRect.y,
dstRect.x + bltWidth, dstRect.y + bltHeight,
srcRect.x, srcRect.y,
srcRect.x + bltWidth, srcRect.y + bltHeight,
Color.red,
null);
} while (vi != null && vi.contentsLost());
}
public void test(Rectangle srcRect, Rectangle dstRect) {
int w = getWidth();
int h = getHeight();
Toolkit.getDefaultToolkit().sync();
try {
Thread.sleep(2000);
} catch (InterruptedException ex) {}
Point p = getLocationOnScreen();
grabbedBI = robot.createScreenCapture(new Rectangle(p.x, p.y, w, h));
// calculate the destination rectangle
Rectangle srcBounds = srcRect.intersection(IMAGE_BOUNDS);
int trX = dstRect.x - srcRect.x;
int trY = dstRect.y - srcRect.y;
Rectangle newDstRect = (Rectangle)dstRect.clone();
newDstRect.translate(-trX, -trY);
Rectangle.intersect(newDstRect, srcBounds, newDstRect);
newDstRect.translate(trX, trY);
Rectangle.intersect(newDstRect, new Rectangle(0, 0, w, h), newDstRect);
System.out.println("calculated dest rect:" + newDstRect);
// we do implicit clipping of the destination surface
// by only checking pixels within its bounds
for (int y = 0; y < h; y++) {
for (int x = 0; x < w; x++) {
int rgb = 0;
if (newDstRect.contains(x, y)) {
rgb = Color.red.getRGB();
} else {
rgb = Color.green.getRGB();
}
if (grabbedBI.getRGB(x, y) != rgb) {
String msg1 = "Test failed at x="+x+" y="+y;
System.out.println(msg1);
System.out.println(" expected: "+Integer.toHexString(rgb)+
" got:"+Integer.toHexString(grabbedBI.getRGB(x, y)));
throw new RuntimeException(msg1);
}
}
}
System.out.println("subtest passed");
}
static VolatileImage dstImage;
static void initImage(GraphicsConfiguration gc, Image image) {
Graphics g = image.getGraphics();
g.setColor(Color.RED);
int w = image.getWidth(null);
int h = image.getHeight(null);
g.fillRect(0, 0, w, h);
g.dispose();
// need to 'accelerate' the image
if (dstImage == null) {
dstImage =
gc.createCompatibleVolatileImage(TESTW, TESTH,
Transparency.OPAQUE);
}
dstImage.validate(gc);
g = dstImage.getGraphics();
g.drawImage(image, 0, 0, null);
g.drawImage(image, 0, 0, null);
g.drawImage(image, 0, 0, null);
}
static VolatileImage getVImage(GraphicsConfiguration gc,
int w, int h)
{
VolatileImage image =
gc.createCompatibleVolatileImage(w, h, Transparency.OPAQUE);
image.validate(gc);
initImage(gc, image);
return image;
}
static Image getBMImage(GraphicsConfiguration gc,
int w, int h)
{
Image image =
gc.createCompatibleImage(w, h, Transparency.BITMASK);
initImage(gc, image);
return image;
}
static Image getBufferedImage(GraphicsConfiguration gc,
int w, int h, int type, boolean acceleratable)
{
BufferedImage image = new BufferedImage(w, h, type);
if (!acceleratable) {
image.setAccelerationPriority(0.0f);
}
initImage(gc, image);
return image;
}
}

View file

@ -0,0 +1,85 @@
/*
* Copyright (c) 2015, 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.
*/
import java.awt.Component;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.Image;
import java.awt.Window;
import java.awt.image.BufferedImage;
import sun.java2d.SunGraphics2D;
import static java.awt.GraphicsEnvironment.getLocalGraphicsEnvironment;
import static java.awt.Transparency.BITMASK;
import static java.awt.Transparency.OPAQUE;
import static java.awt.Transparency.TRANSLUCENT;
import static java.awt.image.BufferedImage.TYPE_INT_ARGB;
/**
* @test
* @key headful
* @bug 8134603
* @modules java.desktop/sun.java2d
* @run main/othervm SurfaceDestination
*/
public final class SurfaceDestination {
public static void main(final String[] args) {
final GraphicsEnvironment lge = getLocalGraphicsEnvironment();
final GraphicsDevice dev = lge.getDefaultScreenDevice();
final GraphicsConfiguration config = dev.getDefaultConfiguration();
test(config.createCompatibleImage(10, 10).getGraphics());
test(config.createCompatibleImage(10, 10, OPAQUE).getGraphics());
test(config.createCompatibleImage(10, 10, BITMASK).getGraphics());
test(config.createCompatibleImage(10, 10, TRANSLUCENT).getGraphics());
test(new BufferedImage(10, 10, TYPE_INT_ARGB).getGraphics());
final Window frame = new Frame();
frame.pack();
try {
test(frame.getGraphics());
test(frame.createImage(10, 10).getGraphics());
} finally {
frame.dispose();
}
}
private static void test(final Graphics graphics) {
try {
if (graphics instanceof SunGraphics2D) {
final Object dst = ((SunGraphics2D) graphics).getDestination();
if (!(dst instanceof Image) && !(dst instanceof Component)) {
throw new RuntimeException("Wrong type:" + dst);
}
}
} finally {
graphics.dispose();
}
}
}

View file

@ -0,0 +1,100 @@
/*
* Copyright (c) 2011, 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 7032930
*
* @summary verify the existence of the method
* SunGraphicsEnvironment.useAlternateFontforJALocales
*
* @modules java.desktop/sun.java2d
* @run main/othervm TestSGEuseAlternateFontforJALocales
* @run main/othervm -Dfile.encoding=windows-31j -Duser.language=ja -Duser.country=JA TestSGEuseAlternateFontforJALocales
*
*/
import java.lang.reflect.Method;
import java.nio.charset.Charset;
import java.util.Locale;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics2D;
import java.awt.GraphicsEnvironment;
import java.awt.image.BufferedImage;
public class TestSGEuseAlternateFontforJALocales {
public static void main(String args[]) throws Exception {
System.out.println("Default Charset = "
+ Charset.defaultCharset().name());
System.out.println("Locale = " + Locale.getDefault());
String os = System.getProperty("os.name");
String encoding = System.getProperty("file.encoding");
/* Want to test the JA locale uses alternate font for DialogInput. */
boolean jaTest = encoding.equalsIgnoreCase("windows-31j");
if (!os.startsWith("Win") && jaTest) {
System.out.println("Skipping Windows only test");
return;
}
String className = "sun.java2d.SunGraphicsEnvironment";
String methodName = "useAlternateFontforJALocales";
Class sge = Class.forName(className);
Method uafMethod = sge.getMethod(methodName, (Class[])null);
Object ret = uafMethod.invoke(null);
GraphicsEnvironment ge =
GraphicsEnvironment.getLocalGraphicsEnvironment();
ge.preferLocaleFonts();
ge.preferProportionalFonts();
if (jaTest) {
Font msMincho = new Font("MS Mincho", Font.PLAIN, 12);
if (!msMincho.getFamily(Locale.ENGLISH).equals("MS Mincho")) {
System.out.println("MS Mincho not installed. Skipping test");
return;
}
Font dialogInput = new Font("DialogInput", Font.PLAIN, 12);
Font courierNew = new Font("Courier New", Font.PLAIN, 12);
Font msGothic = new Font("MS Gothic", Font.PLAIN, 12);
BufferedImage bi = new BufferedImage(1,1,1);
Graphics2D g2d = bi.createGraphics();
FontMetrics cnMetrics = g2d.getFontMetrics(courierNew);
FontMetrics diMetrics = g2d.getFontMetrics(dialogInput);
FontMetrics mmMetrics = g2d.getFontMetrics(msMincho);
FontMetrics mgMetrics = g2d.getFontMetrics(msGothic);
// This tests to make sure we at least have applied
// "preferLocaleFonts for Japanese
if (cnMetrics.charWidth('A') == diMetrics.charWidth('A')) {
throw new RuntimeException
("Courier New should not be used for DialogInput");
}
// This is supposed to make sure we are using MS Mincho instead
// of MS Gothic. However they are metrics identical so its
// not definite proof.
if (diMetrics.charWidth('A') != mmMetrics.charWidth('A')) {
throw new RuntimeException
("MS Mincho should be used for DialogInput");
}
}
}
}

View file

@ -0,0 +1,2 @@
modules=java.desktop

View file

@ -0,0 +1,110 @@
/*
* Copyright (c) 2007, 2016, 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
* @key headful
* @bug 6603887
* @summary Verifies that drawImage with bg color works correctly for ICM image
* @run main/othervm DrawImageBgTest
* @run main/othervm -Dsun.java2d.pmoffscreen=true DrawImageBgTest
*/
import java.awt.Color;
import java.awt.Graphics;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsEnvironment;
import java.awt.image.BufferedImage;
import java.awt.image.IndexColorModel;
import java.awt.image.VolatileImage;
import java.awt.image.WritableRaster;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
public class DrawImageBgTest {
public static void main(String[] args) {
GraphicsConfiguration gc =
GraphicsEnvironment.getLocalGraphicsEnvironment().
getDefaultScreenDevice().getDefaultConfiguration();
if (gc.getColorModel().getPixelSize() <= 8) {
System.out.println("8-bit color model, test considered passed");
return;
}
/*
* Set up images:
* 1.) VolatileImge for rendering to,
* 2.) BufferedImage for reading back the contents of the VI
* 3.) The image triggering the problem
*/
VolatileImage vImg = null;
BufferedImage readBackBImg;
// create a BITMASK ICM such that the transparent color is
// tr. black (and it's the first in the color map so a buffered image
// created with this ICM is transparent
byte r[] = { 0x00, (byte)0xff};
byte g[] = { 0x00, (byte)0xff};
byte b[] = { 0x00, (byte)0xff};
IndexColorModel icm = new IndexColorModel(8, 2, r, g, b, 0);
WritableRaster wr = icm.createCompatibleWritableRaster(25, 25);
BufferedImage tImg = new BufferedImage(icm, wr, false, null);
do {
if (vImg == null ||
vImg.validate(gc) == VolatileImage.IMAGE_INCOMPATIBLE)
{
vImg = gc.createCompatibleVolatileImage(tImg.getWidth(),
tImg.getHeight());
}
Graphics viG = vImg.getGraphics();
viG.setColor(Color.red);
viG.fillRect(0, 0, vImg.getWidth(), vImg.getHeight());
viG.drawImage(tImg, 0, 0, Color.green, null);
viG.fillRect(0, 0, vImg.getWidth(), vImg.getHeight());
viG.drawImage(tImg, 0, 0, Color.white, null);
readBackBImg = vImg.getSnapshot();
} while (vImg.contentsLost());
for (int x = 0; x < readBackBImg.getWidth(); x++) {
for (int y = 0; y < readBackBImg.getHeight(); y++) {
int currPixel = readBackBImg.getRGB(x, y);
if (currPixel != Color.white.getRGB()) {
String fileName = "DrawImageBgTest.png";
try {
ImageIO.write(readBackBImg, "png", new File(fileName));
System.err.println("Dumped image to " + fileName);
} catch (IOException ex) {}
throw new
RuntimeException("Test Failed: found wrong color: 0x"+
Integer.toHexString(currPixel));
}
}
}
System.out.println("Test Passed.");
}
}

View file

@ -0,0 +1,149 @@
/*
* Copyright (c) 2005, 2025, 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.
*/
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;
import java.awt.image.VolatileImage;
/*
*
*
* Tests that the use of shared memory pixmaps isn't broken:
* create a VolatileImage, fill it with red color, copy it to the screen
* make sure the pixels on the screen are red.
*
* Note that we force the use of shared memory pixmaps in the shell script.
*/
public class SharedMemoryPixmapsTest {
static final int IMAGE_SIZE = 200;
static volatile boolean show = false;
static volatile Frame testFrame;
static volatile TestComponent testComponent;
static void createUI() {
testFrame = new Frame("SharedMemoryPixmapsTest");
testComponent = new TestComponent();
testFrame.add(testComponent);
testFrame.setUndecorated(true);
testFrame.setResizable(false);
testFrame.pack();
testFrame.setLocationRelativeTo(null);
testFrame.setVisible(true);
testFrame.toFront();
}
public static void main(String[] args) throws Exception {
for (String s : args) {
if ("-show".equals(s)) {
show = true;
} else {
System.err.println("Usage: SharedMemoryPixmapsTest [-show]");
}
}
EventQueue.invokeAndWait(SharedMemoryPixmapsTest::createUI);
if (testRendering()) {
System.err.println("Test Passed");
} else {
System.err.println("Test Failed");
}
if (!show && testFrame != null) {
EventQueue.invokeAndWait(testFrame::dispose);
}
}
static boolean testRendering() throws Exception {
Robot r = new Robot();
r.waitForIdle();
r.delay(2000);
Point p = testComponent.getLocationOnScreen();
BufferedImage b =
r.createScreenCapture(new Rectangle(p, testComponent.getPreferredSize()));
for (int y = 20; y < b.getHeight() - 40; y++) {
for (int x = 20; x < b.getWidth() - 40; x++) {
if (b.getRGB(x, y) != Color.red.getRGB()) {
System.err.println("Incorrect pixel at "
+ x + "x" + y + " : " +
Integer.toHexString(b.getRGB(x, y)));
if (show) {
return false;
}
System.err.println("Test Failed");
System.exit(1);
}
}
}
return true;
}
static class TestComponent extends Component {
VolatileImage vi = null;
void initVI() {
int res;
if (vi == null) {
res = VolatileImage.IMAGE_INCOMPATIBLE;
} else {
res = vi.validate(getGraphicsConfiguration());
}
if (res == VolatileImage.IMAGE_INCOMPATIBLE) {
if (vi != null) vi.flush();
vi = createVolatileImage(IMAGE_SIZE, IMAGE_SIZE);
vi.validate(getGraphicsConfiguration());
res = VolatileImage.IMAGE_RESTORED;
}
if (res == VolatileImage.IMAGE_RESTORED) {
Graphics vig = vi.getGraphics();
vig.setColor(Color.red);
vig.fillRect(0, 0, vi.getWidth(), vi.getHeight());
vig.dispose();
}
}
@Override
public synchronized void paint(Graphics g) {
do {
g.setColor(Color.green);
g.fillRect(0, 0, getWidth(), getHeight());
vi = null;
initVI();
g.drawImage(vi, 0, 0, null);
} while (vi.contentsLost());
}
@Override
public Dimension getPreferredSize() {
return new Dimension(IMAGE_SIZE, IMAGE_SIZE);
}
}
}

View file

@ -0,0 +1,50 @@
#!/bin/sh
#
# Copyright (c) 2005, 2025, 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
# @key headful
# @bug 6363434 6588884
# @summary Verify that shared memory pixmaps are not broken
# by filling a VolatileImage with red color and copying it
# to the screen.
# Note that we force the use of shared memory pixmaps.
echo "TESTJAVA=${TESTJAVA}"
echo "TESTSRC=${TESTSRC}"
echo "TESTCLASSES=${TESTCLASSES}"
cd ${TESTSRC}
${TESTJAVA}/bin/javac -d ${TESTCLASSES} SharedMemoryPixmapsTest.java
cd ${TESTCLASSES}
J2D_PIXMAPS=shared
export J2D_PIXMAPS
${TESTJAVA}/bin/java ${TESTVMOPTS} SharedMemoryPixmapsTest
if [ $? -ne 0 ]; then
echo "Test failed!"
exit 1
fi
exit 0

View file

@ -0,0 +1,100 @@
/*
* Copyright (c) 2015, 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.
*/
import java.awt.Color;
import java.awt.FlowLayout;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
import java.awt.Component;
import javax.swing.JOptionPane;
/**
* @test
* @bug 8039345
* @author Prasanta Sadhukhan
* @run main/manual ComponentResizeTest
* @summary Resizes JFrame so that component drawn inside it gets repainted
* without leaving any trails
*/
public class ComponentResizeTest {
private static JFrame demoFrame;
public static void testresize() throws Exception {
Thread.sleep(5000);
for (int i = 0; i < 20; i++) {
SwingUtilities.invokeLater(() -> {
demoFrame.setSize(demoFrame.getWidth() + 5, demoFrame.getHeight() + 5);
});
Thread.sleep(1000);
}
}
public static void main(String[] args) throws Exception {
SwingUtilities.invokeAndWait(() -> {
JOptionPane.showMessageDialog(
(Component) null,
"The test creates a transparent JFrame and resizes the JFrame. Please verify JFrame is transparent and components (like JButton, checkbox) move without leaving any trails",
"information", JOptionPane.INFORMATION_MESSAGE);
createAndShowGUI();
});
try {
testresize();
} finally {
SwingUtilities.invokeLater(() -> {
demoFrame.dispose();
});
}
SwingUtilities.invokeAndWait(() -> {
int confirm = JOptionPane.showConfirmDialog(
(Component) null,
"Did the component resize work without leaving any trails?",
"alert", JOptionPane.YES_NO_OPTION);
if (confirm == JOptionPane.YES_OPTION) {
System.out.println("Test passed");
} else {
System.out.println("Test failed");
throw new RuntimeException("Component resize leaves trail");
}
});
}
private static void createAndShowGUI() {
demoFrame = new JFrame();
demoFrame.setSize(300, 300);
demoFrame.setLayout(new FlowLayout());
demoFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
demoFrame.setUndecorated(true);
demoFrame.setBackground(new Color(0f, 0, 0, 0.1f));
JCheckBox b = new JCheckBox("Whatever");
demoFrame.paintAll(null);
b.setOpaque(true);
demoFrame.add(b);
demoFrame.add(new JButton());
demoFrame.setVisible(true);
}
}

View file

@ -0,0 +1,95 @@
/*
* Copyright (c) 2011, 2016, 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
* @key headful
* @bug 6985593
* @summary Test verifies that rendering standard images to screen does
* not caiuse a crash in case of XRender.
* @run main/othervm -Dsun.java2d.xrender=True XRenderBlitsTest
*/
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.concurrent.CountDownLatch;
public class XRenderBlitsTest {
private static final int w = 10;
private static final int h = 10;
public static void main(String[] args) {
final CountDownLatch done = new CountDownLatch(1);
final ArrayList<BufferedImage> images = new ArrayList<BufferedImage>();
int type = BufferedImage.TYPE_INT_RGB;
do {
BufferedImage img = new BufferedImage(w, h, type++);
Graphics2D g2d = img.createGraphics();
g2d.setColor(Color.pink);
g2d.fillRect(0, 0, w, h);
g2d.dispose();
images.add(img);
} while (type <= BufferedImage.TYPE_BYTE_INDEXED);
Frame f = new Frame("Draw images");
Component c = new Component() {
@Override
public Dimension getPreferredSize() {
return new Dimension(w * images.size(), h);
}
@Override
public void paint(Graphics g) {
int x = 0;
for (BufferedImage img : images) {
System.out.println("Draw image " + img.getType());
g.drawImage(img, x, 0, this);
x += w;
}
done.countDown();
}
};
f.add("Center", c);
f.pack();
f.setVisible(true);
// now wait for test results
try {
done.await();
} catch (InterruptedException e) {
}
System.out.println("Test passed");
f.dispose();
}
}

View file

@ -0,0 +1,99 @@
/*
* Copyright (c) 2013, 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 8005930
* @summary Thest verifies that color conversion does not distort
* alpha channel in the destination image.
*
* @run main AlphaTest
*/
import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.color.ColorSpace;
import java.awt.image.BufferedImage;
import java.awt.image.ColorConvertOp;
public class AlphaTest {
public static void main(String[] args) {
ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_GRAY);
ColorConvertOp op = new ColorConvertOp(cs, null);
// create source image filled with an opaque color
BufferedImage src = createSrc();
int srcAlpha = getAlpha(src);
System.out.printf("Src alpha: 0x%02x\n", srcAlpha);
// create clear (transparent black) destination image
BufferedImage dst = createDst();
int dstAlpha = getAlpha(dst);
System.out.printf("Dst alpha: 0x%02x\n", dstAlpha);
dst = op.filter(src, dst);
dstAlpha = getAlpha(dst);
// we expect that destination image is opaque
// i.e. alpha is transferred from source to
// the destination
System.out.printf("Result alpha: 0x%02x\n", dstAlpha);
if (srcAlpha != dstAlpha) {
throw new RuntimeException("Test failed!");
}
System.out.println("Test passed");
}
private static BufferedImage createSrc() {
BufferedImage img = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
Graphics2D g = img.createGraphics();
g.setColor(Color.red);
g.fillRect(0, 0, w, h);
g.dispose();
return img;
}
private static BufferedImage createDst() {
BufferedImage img = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
Graphics2D g = img.createGraphics();
g.setComposite(AlphaComposite.Clear);
g.fillRect(0, 0, w, h);
g.dispose();
return img;
}
private static int getAlpha(BufferedImage img) {
int argb = img.getRGB(w / 2, h / 2);
return 0xff & (argb >> 24);
}
private static final int w = 100;
private static final int h = 100;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

View file

@ -0,0 +1,167 @@
/*
* Copyright (c) 2007, 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 6476665 7033534 6830714 8052162 8196572 8326661
* @summary Verifies color conversion of Component Color Model based images
* @run main ColConvCCMTest
*/
import java.awt.color.ColorSpace;
import java.awt.image.BufferedImage;
import java.awt.image.ColorConvertOp;
import java.awt.image.DataBuffer;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
public class ColConvCCMTest extends ColConvTest {
final static int [] dataTypes = {
DataBuffer.TYPE_BYTE,
DataBuffer.TYPE_DOUBLE,
DataBuffer.TYPE_FLOAT,
DataBuffer.TYPE_INT,
DataBuffer.TYPE_SHORT,
DataBuffer.TYPE_USHORT
};
final static int [] cSpaces = {
ColorSpace.CS_sRGB,
ColorSpace.CS_LINEAR_RGB,
ColorSpace.CS_GRAY,
ColorSpace.CS_PYCC,
ColorSpace.CS_CIEXYZ
};
final static double [] ACCURACY = {
// Accuracy for color conversions
2.5, // sRGB
(isOpenProfile() ? 45.0 : 10.1), // LINEAR_RGB
10.5, // GRAY
(isOpenProfile() ? 215.0 : 64.5), // PYCC
(isOpenProfile() ? 56.0 : 55.5) // CIEXYZ
};
final static String [] gldImgNames = {
"SRGB.png", "LRGB.png", "GRAY.png", "PYCC.png", "CIEXYZ.png"
};
static BufferedImage [] gldImages = null;
static boolean testImage(int dataType, int rBits, int gBits, int bBits,
int cs, BufferedImage gldImage,
double accuracy)
{
BufferedImage src = ImageFactory.createCCMImage(cs, dataType);
BufferedImage dst = ImageFactory.createDstImage(
BufferedImage.TYPE_INT_RGB);
ColorConvertOp op = new ColorConvertOp(null);
op.filter(src, dst);
ImageComparator cmp = new ImageComparator(accuracy, rBits, gBits,
bBits);
boolean result = cmp.compare(gldImage, dst);
if (!result) {
System.err.println(cmp.getStat());
}
return result;
}
static boolean testSubImage(int x0, int y0, int dx, int dy,
int dataType, int rBits, int gBits,
int bBits, int cs, BufferedImage gldImage,
double accuracy)
{
BufferedImage src = ImageFactory.createCCMImage(cs, dataType);
BufferedImage subSrc = src.getSubimage(x0, y0, dx, dy);
BufferedImage dst = ImageFactory.createDstImage(
BufferedImage.TYPE_INT_RGB);
BufferedImage subDst = dst.getSubimage(x0, y0, dx, dy);
ColorConvertOp op = new ColorConvertOp(null);
op.filter(subSrc, subDst);
ImageComparator cmp = new ImageComparator(accuracy, rBits, gBits,
bBits);
boolean result = cmp.compare(subDst, gldImage, x0, y0, dx, dy);
if (!result) {
System.err.println(cmp.getStat());
}
return result;
}
synchronized public static void initGoldenImages() {
if (gldImages == null) {
gldImages = new BufferedImage[gldImgNames.length];
for (int i = 0; i < gldImgNames.length; i++) {
try {
File gldFile = new File(System.getProperty("test.src", "."),
gldImgNames[i]);
gldImages[i] = ImageIO.read(gldFile);
} catch (IOException e) {
throw new RuntimeException("Cannot initialize golden " +
"image: " + gldImgNames[i]);
}
}
}
}
public void init() {
initGoldenImages();
}
public void runTest() {
for (int i = 0; i < cSpaces.length; i++) {
BufferedImage gldImage = gldImages[i];
for (int j = 0; j < dataTypes.length; j++) {
if (!testImage(dataTypes[j], 8, 8, 8, cSpaces[i], gldImage,
ACCURACY[i]))
{
throw new RuntimeException(
"Invalid result of the ColorConvertOp for " +
"ColorSpace:" + getCSName(cSpaces[i]) +
" Data type:" +
getDTName(dataTypes[j]) + ". Golden image:" +
gldImages[i]);
}
if (!testSubImage(SI_X, SI_Y, SI_W, SI_H, dataTypes[j],
8, 8, 8, cSpaces[i], gldImage, ACCURACY[i]))
{
throw new RuntimeException(
"Invalid result of the ColorConvertOp for " +
"ColorSpace:" + getCSName(cSpaces[i]) +
" Data type:" +
getDTName(dataTypes[j]) + ". Golden image:" +
gldImages[i]);
}
}
}
}
public static void main(String [] args) throws Exception {
ColConvCCMTest test = new ColConvCCMTest();
test.init();
test.run();
}
}

View file

@ -0,0 +1,179 @@
/*
* Copyright (c) 2007, 2013, 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 6476665
* @summary Verifies color conversion of Direct Color Model based images
* @run main ColConvDCMTest
*/
import java.awt.color.ColorSpace;
import java.awt.image.BufferedImage;
import java.awt.image.ColorConvertOp;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
public class ColConvDCMTest extends ColConvTest {
/*
* Test case descriptors: <imgType> <rBits> <gBits> <bBits> <csNum> <gldNum>
*/
final static int [][] imgTypes = {
{BufferedImage.TYPE_INT_ARGB, 8, 8, 8, 0, 0},
{BufferedImage.TYPE_INT_ARGB, 8, 8, 8, 1, 3},
{BufferedImage.TYPE_INT_RGB, 8, 8, 8, 0, 0},
{BufferedImage.TYPE_INT_RGB, 8, 8, 8, 1, 3},
{BufferedImage.TYPE_INT_BGR, 8, 8, 8, 0, 0},
{BufferedImage.TYPE_INT_BGR, 8, 8, 8, 1, 3},
{BufferedImage.TYPE_USHORT_555_RGB, 5, 5, 5, 0, 1},
{BufferedImage.TYPE_USHORT_555_RGB, 5, 5, 5, 1, 4},
{BufferedImage.TYPE_USHORT_565_RGB, 5, 6, 5, 0, 2},
{BufferedImage.TYPE_USHORT_565_RGB, 5, 6, 5, 1, 5}
};
final static int [] cSpaces = {
ColorSpace.CS_sRGB,
ColorSpace.CS_LINEAR_RGB,
};
final static double [] ACCURACY = {
// Accuracy for color conversions
2.5, // sRGB
(isOpenProfile() ? 45.0 : 2.5), // LINEAR_RGB
};
final static String [] gldImgNames = {
"SRGB.png", "SRGB555.png", "SRGB565.png", "LRGB.png", "LRGB555.png",
"LRGB565.png"
};
static BufferedImage [] gldImages = null;
static boolean testImage(int type, int rBits, int gBits, int bBits,
int cs, BufferedImage gldImage,
double accuracy)
{
BufferedImage src = ImageFactory.createDCMImage(type, cs);
BufferedImage dst = ImageFactory.createDstImage(
BufferedImage.TYPE_INT_RGB);
ColorConvertOp op = new ColorConvertOp(null);
op.filter(src, dst);
ImageComparator cmp = new ImageComparator(accuracy, rBits, gBits,
bBits);
boolean result = cmp.compare(gldImage, dst);
if (!result) {
System.err.println(cmp.getStat());
}
return result;
}
static boolean testSubImage(int x0, int y0, int dx, int dy, int type,
int rBits, int gBits, int bBits,
int cs, BufferedImage gldImage,
double accuracy)
{
BufferedImage src = ImageFactory.createDCMImage(type, cs);
BufferedImage subSrc = src.getSubimage(x0, y0, dx, dy);
BufferedImage dst = ImageFactory.createDstImage(
BufferedImage.TYPE_INT_RGB);
BufferedImage subDst = dst.getSubimage(x0, y0, dx, dy);
ColorConvertOp op = new ColorConvertOp(null);
op.filter(subSrc, subDst);
ImageComparator cmp = new ImageComparator(accuracy, rBits, gBits,
bBits);
boolean result = cmp.compare(subDst, gldImage, x0, y0, dx, dy);
if (!result) {
System.err.println(cmp.getStat());
}
return result;
}
synchronized public static void initGoldenImages() {
if (gldImages == null) {
gldImages = new BufferedImage[gldImgNames.length];
for (int i = 0; i < gldImgNames.length; i++) {
try {
File gldFile = new File(System.getProperty("test.src", "."),
gldImgNames[i]);
gldImages[i] = ImageIO.read(gldFile);
} catch (IOException e) {
throw new RuntimeException("Cannot initialize golden " +
"image: " + gldImgNames[i]);
}
}
}
}
public void init() {
initGoldenImages();
}
public void runTest() {
for (int i = 0; i < imgTypes.length; i++) {
BufferedImage gldImage = gldImages[imgTypes[i][5]];
if (!testImage(imgTypes[i][0], imgTypes[i][1], imgTypes[i][2],
imgTypes[i][3], cSpaces[imgTypes[i][4]], gldImage,
ACCURACY[imgTypes[i][4]]))
{
throw new RuntimeException(
"Invalid result of the ColorConvertOp for " +
"ColorSpace:" + getCSName(cSpaces[imgTypes[i][4]]) +
" Image type:" +
getImageTypeName(imgTypes[i][0]) + ". Golden image:" +
gldImgNames[imgTypes[i][5]]);
}
if (!testSubImage(SI_X, SI_Y, SI_W, SI_H, imgTypes[i][0],
imgTypes[i][1], imgTypes[i][2], imgTypes[i][3],
cSpaces[imgTypes[i][4]], gldImage,
ACCURACY[imgTypes[i][4]]))
{
throw new RuntimeException(
"Invalid result of the ColorConvertOp for " +
"ColorSpace:" + getCSName(cSpaces[imgTypes[i][4]]) +
" Image type:" +
getImageTypeName(imgTypes[i][0]) + ". Golden image:" +
gldImgNames[imgTypes[i][5]]);
}
}
}
public static void main(String [] args) throws Exception {
ColConvDCMTest test = new ColConvDCMTest();
test.init();
test.run();
}
}

View file

@ -0,0 +1,159 @@
/*
* Copyright (c) 2007, 2013, 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.
*/
import java.awt.color.ColorSpace;
import java.awt.color.ICC_Profile;
import java.awt.image.BufferedImage;
import java.awt.image.DataBuffer;
public abstract class ColConvTest implements Runnable {
/* Parameters of the testing subimage */
static final int SI_X = 10;
static final int SI_Y = 10;
static final int SI_W = 100;
static final int SI_H = 100;
private boolean passed = false;
static String getCSName(int cs) {
switch(cs) {
case ColorSpace.CS_GRAY:
return "CS_GRAY";
case ColorSpace.CS_CIEXYZ:
return "CS_CIEXYZ";
case ColorSpace.CS_LINEAR_RGB:
return "CS_LINEAR_RGB";
case ColorSpace.CS_PYCC:
return "CS_PYCC";
case ColorSpace.CS_sRGB:
return "CS_sRGB";
}
return "UNKNOWN";
}
static String getDTName(int dType) {
switch(dType) {
case DataBuffer.TYPE_BYTE:
return "TYPE_BYTE";
case DataBuffer.TYPE_DOUBLE:
return "TYPE_DOUBLE";
case DataBuffer.TYPE_FLOAT:
return "TYPE_FLOAT";
case DataBuffer.TYPE_INT:
return "TYPE_INT";
case DataBuffer.TYPE_SHORT:
return "TYPE_SHORT";
case DataBuffer.TYPE_USHORT:
return "TYPE_USHORT";
case DataBuffer.TYPE_UNDEFINED:
return "TYPE_UNDEFINED";
}
return "UNKNOWN";
}
static String getImageTypeName(int type) {
switch(type) {
case BufferedImage.TYPE_INT_ARGB:
return "TYPE_INT_ARGB";
case BufferedImage.TYPE_INT_RGB:
return "TYPE_INT_RGB";
case BufferedImage.TYPE_INT_BGR:
return "TYPE_INT_BGR";
case BufferedImage.TYPE_INT_ARGB_PRE:
return "TYPE_INT_ARGB_PRE";
case BufferedImage.TYPE_3BYTE_BGR:
return "TYPE_3BYTE_BGR";
case BufferedImage.TYPE_4BYTE_ABGR:
return "TYPE_4BYTE_ABGR";
case BufferedImage.TYPE_4BYTE_ABGR_PRE:
return "TYPE_4BYTE_ABGR_PRE";
case BufferedImage.TYPE_BYTE_BINARY:
return "TYPE_BYTE_BINARY";
case BufferedImage.TYPE_BYTE_GRAY:
return "TYPE_BYTE_GRAY";
case BufferedImage.TYPE_BYTE_INDEXED:
return "TYPE_BYTE_INDEXED";
case BufferedImage.TYPE_USHORT_555_RGB:
return "TYPE_USHORT_555_RGB";
case BufferedImage.TYPE_USHORT_565_RGB:
return "TYPE_USHORT_565_RGB";
case BufferedImage.TYPE_USHORT_GRAY:
return "TYPE_USHORT_GRAY";
}
return "UNKNOWN";
}
/* Actual tests should override this method and put initialization logic
* into it
*/
public abstract void init();
/* Actual tests should override this method and put test logic into it */
public abstract void runTest();
public final void run() {
try {
runTest();
passed = true;
} catch (Throwable ex) {
ex.printStackTrace();
passed = false;
throw new RuntimeException(ex);
}
}
/* returns result of the test */
public boolean isPassed() {
return passed;
}
private static Boolean isOpenProfile = null;
public static boolean isOpenProfile() {
if (isOpenProfile == null) {
ICC_Profile p = ICC_Profile.getInstance(ColorSpace.CS_sRGB);
byte[] h = p.getData(ICC_Profile.icSigHead);
if (h == null || h.length < 128) {
throw new RuntimeException("Test failed: invalid sRGB header");
}
final byte[] lcmsID = new byte[] {
(byte)0x6c, // l
(byte)0x63, // c
(byte)0x6d, // m
(byte)0x73, // s
};
int off = ICC_Profile.icHdrCmmId;
isOpenProfile = ((h[off + 0] == lcmsID[0])
&& (h[off + 1] == lcmsID[1])
&& (h[off + 2] == lcmsID[2])
&& (h[off + 3] == lcmsID[3]));
}
return isOpenProfile;
}
}

View file

@ -0,0 +1,87 @@
/*
* Copyright (c) 2001, 2021, 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 4405224 8012229
* @summary Test color conversion for images with alpha
*/
import java.awt.Color;
import java.awt.Transparency;
import java.awt.Point;
import java.awt.image.BufferedImage;
import java.awt.image.ColorConvertOp;
import java.awt.image.ColorModel;
import java.awt.image.ComponentColorModel;
import java.awt.image.SampleModel;
import java.awt.image.Raster;
import java.awt.image.WritableRaster;
import java.awt.image.PixelInterleavedSampleModel;
import java.awt.image.DataBuffer;
import java.awt.color.ColorSpace;
public class ColCvtAlpha {
public static void main(String args[]) {
BufferedImage src
= new BufferedImage(1, 10, BufferedImage.TYPE_INT_ARGB);
// Set src pixel values
Color pelColor = new Color(100, 100, 100, 128);
for (int i = 0; i < 10; i++) {
src.setRGB(0, i, pelColor.getRGB());
}
ColorModel cm = new ComponentColorModel
(ColorSpace.getInstance(ColorSpace.CS_GRAY),
new int [] {8,8}, true,
src.getColorModel().isAlphaPremultiplied(),
Transparency.TRANSLUCENT,
DataBuffer.TYPE_BYTE);
SampleModel sm = new PixelInterleavedSampleModel
(DataBuffer.TYPE_BYTE, 100, 100, 2, 200,
new int [] { 0, 1 });
WritableRaster wr = Raster.createWritableRaster(sm, new Point(0,0));
BufferedImage dst =
new BufferedImage(cm, wr, cm.isAlphaPremultiplied(), null);
dst = dst.getSubimage(0, 0, 1, 10);
ColorConvertOp op = new ColorConvertOp(null);
op.filter(src, dst);
for (int i = 0; i < 10; i++) {
int rgb = (dst.getRGB(0, i) >> 24) & 0xff;
if (rgb != 128) {
throw new RuntimeException(
"Incorrect destination alpha value: " + rgb);
}
}
}
}

View file

@ -0,0 +1,343 @@
/*
* Copyright (c) 2021, 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.
*/
import java.awt.AlphaComposite;
import java.awt.Graphics2D;
import java.awt.Transparency;
import java.awt.color.ColorSpace;
import java.awt.color.ICC_ColorSpace;
import java.awt.color.ICC_Profile;
import java.awt.image.BufferedImage;
import java.awt.image.ColorConvertOp;
import java.awt.image.ColorModel;
import java.awt.image.ComponentColorModel;
import java.awt.image.DataBuffer;
import java.awt.image.DirectColorModel;
import java.awt.image.Raster;
import java.awt.image.WritableRaster;
import static java.awt.image.BufferedImage.TYPE_3BYTE_BGR;
import static java.awt.image.BufferedImage.TYPE_4BYTE_ABGR;
import static java.awt.image.BufferedImage.TYPE_4BYTE_ABGR_PRE;
import static java.awt.image.BufferedImage.TYPE_BYTE_BINARY;
import static java.awt.image.BufferedImage.TYPE_BYTE_GRAY;
import static java.awt.image.BufferedImage.TYPE_BYTE_INDEXED;
import static java.awt.image.BufferedImage.TYPE_INT_ARGB;
import static java.awt.image.BufferedImage.TYPE_INT_ARGB_PRE;
import static java.awt.image.BufferedImage.TYPE_INT_BGR;
import static java.awt.image.BufferedImage.TYPE_INT_RGB;
import static java.awt.image.BufferedImage.TYPE_USHORT_555_RGB;
import static java.awt.image.BufferedImage.TYPE_USHORT_565_RGB;
import static java.awt.image.BufferedImage.TYPE_USHORT_GRAY;
/*
* @test
* @bug 8012229 8300725 8279216 8323210
* @summary one more test to check the alpha channel
*/
public final class ColCvtAlphaDifferentSrcDst {
private static final int WIDTH = 256;
private static final int HEIGHT = 256;
private static final int TYPE_CUSTOM_4BYTE_ABGR_PRE = -1;
private static final int TYPE_CUSTOM_4BYTE_ARGB_PRE = -2;
private static final int TYPE_CUSTOM_4BYTE_RGBA_PRE = -3;
private static final int TYPE_CUSTOM_4BYTE_GABR_PRE = -4;
private static final int TYPE_CUSTOM_INT_ARGB_PRE = -5;
private static final int TYPE_CUSTOM_INT_GABR_PRE = -6;
public static void main(String[] args) throws Exception {
differentToOpaqueDst();
differentToTransparentDst(TYPE_INT_ARGB);
differentToTransparentDst(TYPE_4BYTE_ABGR);
differentToTransparentDst(TYPE_INT_ARGB_PRE);
differentToTransparentDst(TYPE_4BYTE_ABGR_PRE);
differentToNullDst();
}
/**
* Various types of source images transform to the null destination.
*/
private static void differentToNullDst() {
nullDst(TYPE_INT_RGB);
nullDst(TYPE_INT_ARGB);
// TODO DirectColorModel and ComponentColorModel have different precision for pre
// nullDst(TYPE_INT_ARGB_PRE);
nullDst(TYPE_INT_BGR);
nullDst(TYPE_3BYTE_BGR);
nullDst(TYPE_4BYTE_ABGR);
// TODO DirectColorModel and ComponentColorModel have different precision for pre
// nullDst(TYPE_4BYTE_ABGR_PRE);
// Default destination for null is always 8 bit per component
// nullDst(TYPE_USHORT_565_RGB);
// nullDst(TYPE_USHORT_555_RGB);
nullDst(TYPE_BYTE_GRAY);
// Default destination for null is always 8 bit per component
// nullDst(TYPE_USHORT_GRAY);
nullDst(TYPE_BYTE_BINARY);
// Default destination for null is always 8 bit per component
// nullDst(TYPE_BYTE_INDEXED);
}
/**
* Various types of source images transform to the opaque destination, the
* result should be the same.
*/
private static void differentToOpaqueDst() {
opaqueDst(TYPE_INT_ARGB, TYPE_INT_RGB);
opaqueDst(TYPE_INT_ARGB, TYPE_INT_BGR);
opaqueDst(TYPE_4BYTE_ABGR, TYPE_INT_BGR);
// compare the "fast" and "slow" paths
opaqueDst(TYPE_4BYTE_ABGR_PRE, TYPE_CUSTOM_4BYTE_ABGR_PRE);
opaqueDst(TYPE_4BYTE_ABGR_PRE, TYPE_CUSTOM_4BYTE_ARGB_PRE);
opaqueDst(TYPE_4BYTE_ABGR_PRE, TYPE_CUSTOM_4BYTE_RGBA_PRE);
opaqueDst(TYPE_4BYTE_ABGR_PRE, TYPE_CUSTOM_4BYTE_GABR_PRE);
opaqueDst(TYPE_INT_ARGB_PRE, TYPE_CUSTOM_INT_ARGB_PRE);
opaqueDst(TYPE_INT_ARGB_PRE, TYPE_CUSTOM_INT_GABR_PRE);
// It is unclear how to handle pre colors in the opaque DST
//opaqueDst(TYPE_INT_ARGB_PRE, TYPE_4BYTE_ABGR_PRE);
//opaqueDst(TYPE_4BYTE_ABGR_PRE, TYPE_INT_BGR);
}
/**
* Transparent types of source images transform to the transparent
* destination, the alpha channel should be the same in src/dst.
*/
private static void differentToTransparentDst(int typeDst) {
transparentDst(TYPE_INT_RGB, typeDst);
transparentDst(TYPE_INT_ARGB, typeDst);
transparentDst(TYPE_INT_ARGB_PRE, typeDst);
transparentDst(TYPE_INT_BGR, typeDst);
transparentDst(TYPE_3BYTE_BGR, typeDst);
transparentDst(TYPE_4BYTE_ABGR, typeDst);
transparentDst(TYPE_4BYTE_ABGR_PRE, typeDst);
transparentDst(TYPE_USHORT_565_RGB, typeDst);
transparentDst(TYPE_USHORT_555_RGB, typeDst);
transparentDst(TYPE_BYTE_GRAY, typeDst);
transparentDst(TYPE_USHORT_GRAY, typeDst);
transparentDst(TYPE_BYTE_BINARY, typeDst);
transparentDst(TYPE_BYTE_INDEXED, typeDst);
}
/**
* Compares the rendering to the default destination created by the
* ColorConvertOp and the destination format equal to the source.
*/
private static void nullDst(int typeSrc) {
BufferedImage src = createSrc(typeSrc);
BufferedImage gold = createDst(typeSrc);
// just a round trip from src to src color space
ICC_Profile[] profs = {
((ICC_ColorSpace) (src.getColorModel().getColorSpace())).getProfile(),
ICC_Profile.getInstance(ColorSpace.CS_LINEAR_RGB),
ICC_Profile.getInstance(ColorSpace.CS_GRAY),
ICC_Profile.getInstance(ColorSpace.CS_LINEAR_RGB),
((ICC_ColorSpace) (src.getColorModel().getColorSpace())).getProfile(),
};
ColorConvertOp op = new ColorConvertOp(profs, null);
op.filter(src, gold);
BufferedImage dst = op.filter(src, null);
validate(gold, dst, false);
}
private static void opaqueDst(int transparent, int opaque) {
ColorSpace to = ColorSpace.getInstance(ColorSpace.CS_LINEAR_RGB);
ColorSpace from = ColorSpace.getInstance(ColorSpace.CS_sRGB);
ColorConvertOp op = new ColorConvertOp(from, to, null);
// Source data
BufferedImage timgSrc = createSrc(transparent);
BufferedImage oimgSrc = createSrc(opaque);
// Destination data
BufferedImage timgDst = createDst(TYPE_INT_RGB);
BufferedImage oimgDst = createDst(TYPE_INT_RGB);
op.filter(timgSrc, timgDst);
op.filter(oimgSrc, oimgDst);
validate(timgDst, oimgDst, false);
}
private static void transparentDst(int typeSrc, int typeDst) {
ColorSpace to = ColorSpace.getInstance(ColorSpace.CS_CIEXYZ);
ColorSpace from = ColorSpace.getInstance(ColorSpace.CS_sRGB);
ColorConvertOp op = new ColorConvertOp(from, to, null);
BufferedImage src = createSrc(typeSrc);
BufferedImage dst = createDst(typeDst);
op.filter(src, dst);
validate(src, dst, true);
}
private static void validate(BufferedImage img1, BufferedImage img2,
boolean alphaOnly) {
for (int i = 0; i < WIDTH; i++) {
for (int j = 0; j < HEIGHT; j++) {
int rgb1 = img1.getRGB(i, j);
int rgb2 = img2.getRGB(i, j);
if (alphaOnly) {
rgb1 |= 0x00FFFFFF;
rgb2 |= 0x00FFFFFF;
}
if (rgb1 != rgb2) {
System.err.println("rgb1 = " + Integer.toHexString(rgb1));
System.err.println("rgb2 = " + Integer.toHexString(rgb2));
throw new RuntimeException();
}
}
}
}
private static BufferedImage createSrc(int type) {
BufferedImage img = switch (type) {
case TYPE_CUSTOM_4BYTE_ABGR_PRE -> TYPE_4BYTE_ABGR_PRE();
case TYPE_CUSTOM_4BYTE_ARGB_PRE -> TYPE_4BYTE_ARGB_PRE();
case TYPE_CUSTOM_4BYTE_RGBA_PRE -> TYPE_4BYTE_RGBA_PRE();
case TYPE_CUSTOM_4BYTE_GABR_PRE -> TYPE_4BYTE_GABR_PRE();
case TYPE_CUSTOM_INT_ARGB_PRE -> TYPE_INT_ARGB_PRE();
case TYPE_CUSTOM_INT_GABR_PRE -> TYPE_INT_GABR_PRE();
default -> new BufferedImage(WIDTH, HEIGHT, type);
};
fill(img);
return img;
}
private static BufferedImage createDst(int type) {
BufferedImage img = new BufferedImage(WIDTH, HEIGHT, type);
Graphics2D g = img.createGraphics();
g.setComposite(AlphaComposite.Clear);
g.fillRect(0, 0, WIDTH, HEIGHT);
g.dispose();
return img;
}
private static void fill(BufferedImage image) {
for (int i = 0; i < WIDTH; i++) {
for (int j = 0; j < HEIGHT; j++) {
image.setRGB(i, j,
(i << 24) | (i << 16) | (j << 8) | ((i + j) >> 1));
}
}
}
private static BufferedImage TYPE_4BYTE_RGBA_PRE() {
ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_sRGB);
int[] nBits = {8, 8, 8, 8};
int[] bOffs = {0, 1, 2, 3};
ColorModel colorModel = new ComponentColorModel(cs, nBits, true, true,
Transparency.TRANSLUCENT,
DataBuffer.TYPE_BYTE);
WritableRaster raster = Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE,
WIDTH, HEIGHT,
WIDTH * 4, 4,
bOffs, null);
return new BufferedImage(colorModel, raster, true, null);
}
private static BufferedImage TYPE_4BYTE_ABGR_PRE() {
ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_sRGB);
int[] nBits = {8, 8, 8, 8};
int[] bOffs = {3, 2, 1, 0};
ColorModel colorModel = new ComponentColorModel(cs, nBits, true, true,
Transparency.TRANSLUCENT,
DataBuffer.TYPE_BYTE);
WritableRaster raster = Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE,
WIDTH, HEIGHT,
WIDTH * 4, 4,
bOffs, null);
return new BufferedImage(colorModel, raster, true, null);
}
private static BufferedImage TYPE_4BYTE_ARGB_PRE() {
ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_sRGB);
int[] nBits = {8, 8, 8, 8};
int[] bOffs = {1, 2, 3, 0};
ColorModel colorModel = new ComponentColorModel(cs, nBits, true, true,
Transparency.TRANSLUCENT,
DataBuffer.TYPE_BYTE);
WritableRaster raster = Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE,
WIDTH, HEIGHT,
WIDTH * 4, 4,
bOffs, null);
return new BufferedImage(colorModel, raster, true, null);
}
private static BufferedImage TYPE_4BYTE_GABR_PRE() {
ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_sRGB);
int[] nBits = {8, 8, 8, 8};
int[] bOffs = {3, 0, 2, 1};
ColorModel colorModel = new ComponentColorModel(cs, nBits, true, false,
Transparency.TRANSLUCENT,
DataBuffer.TYPE_BYTE);
WritableRaster raster = Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE,
WIDTH, HEIGHT,
WIDTH * 4, 4,
bOffs, null);
return new BufferedImage(colorModel, raster, true, null);
}
private static BufferedImage TYPE_INT_ARGB_PRE() {
ColorModel colorModel = new DirectColorModel(
ColorSpace.getInstance(ColorSpace.CS_sRGB),
32,
0x00ff0000, // Red
0x0000ff00, // Green
0x000000ff, // Blue
0xff000000, // Alpha
true, // Alpha Premultiplied
DataBuffer.TYPE_INT
);
WritableRaster raster = colorModel.createCompatibleWritableRaster(WIDTH,
HEIGHT);
return new BufferedImage(colorModel, raster, true, null);
}
private static BufferedImage TYPE_INT_GABR_PRE() {
ColorModel colorModel = new DirectColorModel(
ColorSpace.getInstance(ColorSpace.CS_sRGB),
32,
0x000000ff, // Red
0xff000000, // Green
0x0000ff00, // Blue
0x00ff0000, // Alpha
true, // Alpha Premultiplied
DataBuffer.TYPE_INT
);
WritableRaster raster = colorModel.createCompatibleWritableRaster(WIDTH,
HEIGHT);
return new BufferedImage(colorModel, raster, true, null);
}
}

View file

@ -0,0 +1,72 @@
/*
* Copyright (c) 2001, 2007, 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 4425837
* @summary Test color conversion for TYPE_INT_ARGB images
*/
import java.awt.Color;
import java.awt.image.BufferedImage;
import java.awt.image.ColorConvertOp;
public class ColCvtIntARGB {
public static void main(String args[]) {
//
// Build a 1 pixel ARGB, non-premultiplied image
//
BufferedImage src
= new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB);
// Set src pixel value
Color pelColor = new Color(100, 100, 100, 128);
src.setRGB(0, 0, pelColor.getRGB());
//
// ColorConvertOp filter
//
ColorConvertOp op = new ColorConvertOp(null);
//
// Test ARGB -> ARGB_PRE
//
BufferedImage dst
= new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB_PRE);
op.filter(src, dst);
if (((dst.getRGB(0, 0) >> 24) & 0xff) != 128) {
throw new RuntimeException("Incorrect destination alpha value.");
}
//
// Test ARGB -> ARGB
//
dst = new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB);
op.filter(src, dst);
if (((dst.getRGB(0, 0) >> 24) & 0xff) != 128) {
throw new RuntimeException("Incorrect destination alpha value.");
}
}
}

View file

@ -0,0 +1,50 @@
/*
* Copyright (c) 2006, 2007, 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 6396875
* @summary Checking that color conversion with CMM doesn't crash or throw ProfileDataException
* @run main ColorConvertTest
*/
import java.awt.color.*;
import java.awt.image.*;
public class ColorConvertTest {
public static void main(String[] args) {
ColorSpace rgbCS = ColorSpace.getInstance(ColorSpace.CS_sRGB);
ColorSpace grayCS = ColorSpace.getInstance(ColorSpace.CS_GRAY);
ColorConvertOp op = new ColorConvertOp(rgbCS, grayCS, null);
BufferedImage src = new BufferedImage(100, 100,
BufferedImage.TYPE_INT_RGB);
BufferedImage dst = new BufferedImage(100, 100,
BufferedImage.TYPE_BYTE_GRAY);
try {
op.filter(src, dst);
} catch (ProfileDataException ex) {
throw new RuntimeException("Test Failed", ex);
}
}
}

View file

@ -0,0 +1,49 @@
/*
* Copyright (c) 2003, 2007, 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 4907226
@summary Tests that cmm code doesn't crash
@author
@run main ColorSpaceCvtCrashTest
*/
import java.awt.image.*;
import java.awt.color.*;
/* Note that this bug is reproducible only on systems with more than 4 cpus. */
public class ColorSpaceCvtCrashTest {
public static void main(String argv[]) {
ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_GRAY);
ColorConvertOp theOp = new ColorConvertOp(cs, null);
BufferedImage srcImg =
new BufferedImage(100, 100, BufferedImage.TYPE_INT_RGB);
BufferedImage dstImg =
new BufferedImage(100, 100, BufferedImage.TYPE_INT_RGB);
theOp.filter(srcImg, dstImg);
System.err.println("Test passed");
}
}

View file

@ -0,0 +1,61 @@
/*
* Copyright Amazon.com Inc. 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.
*/
import java.awt.color.ColorSpace;
import java.awt.image.BufferedImage;
import java.awt.image.ColorConvertOp;
/**
* @test
* @bug 8312191
* @summary Standard color spaces should be reused for CompatibleDestImage
*/
public final class CompatibleColorSpace {
private static final int[] spaces = {
ColorSpace.CS_CIEXYZ, ColorSpace.CS_GRAY, ColorSpace.CS_LINEAR_RGB,
ColorSpace.CS_PYCC, ColorSpace.CS_sRGB
};
public static void main(String[] args) {
for (int from : spaces) {
for (int to : spaces) {
test(from, to);
}
}
}
private static void test(int from, int to) {
ColorSpace srcCS = ColorSpace.getInstance(from);
ColorSpace dstCS = ColorSpace.getInstance(to);
ColorConvertOp op = new ColorConvertOp(srcCS, dstCS, null);
BufferedImage src = new BufferedImage(10, 10,
BufferedImage.TYPE_INT_ARGB);
BufferedImage dst = op.filter(src, null);
// dst image is not set and will be created automatically, the dstCS
// should be reused
if (dst.getColorModel().getColorSpace() != dstCS) {
throw new RuntimeException("Wrong color space");
}
}
}

View file

@ -0,0 +1,61 @@
/*
* Copyright (c) 2000, 2018, 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 4185854
@summary Checks that constructors do not accept nulls and throw NPE
@run main ConstructorsNullTest
*/
import java.awt.RenderingHints;
import java.awt.color.ColorSpace;
import java.awt.color.ICC_Profile;
import java.awt.image.ColorConvertOp;
public class ConstructorsNullTest {
public static void main(final String[] args) {
ColorConvertOp gp;
boolean passed = false;
try {
gp = new ColorConvertOp((ColorSpace)null, (RenderingHints)null);
} catch (NullPointerException e) {
try {
gp = new ColorConvertOp((ColorSpace)null, null, null);
} catch (NullPointerException e1) {
try {
gp = new ColorConvertOp((ICC_Profile[])null, null);
} catch (NullPointerException e2) {
passed = true;
}
}
}
if (!passed) {
System.out.println("Test FAILED: one of constructors didn't throw NullPointerException.");
throw new RuntimeException("Test FAILED: one of constructors didn't throw NullPointerException.");
}
System.out.println("Test PASSED: all constructors threw NullPointerException.");
}
}// class ConstructorsNullTest

View file

@ -0,0 +1,200 @@
/*
* Copyright Amazon.com Inc. or its affiliates. All Rights Reserved.
* Copyright (c) 2014, 2019, 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.
*/
import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Transparency;
import java.awt.color.ColorSpace;
import java.awt.image.BufferedImage;
import java.awt.image.ColorConvertOp;
import java.awt.image.ColorModel;
import java.awt.image.ComponentColorModel;
import java.awt.image.DataBuffer;
import java.awt.image.Raster;
import java.awt.image.WritableRaster;
import java.io.File;
import javax.imageio.ImageIO;
import static java.awt.image.BufferedImage.TYPE_3BYTE_BGR;
import static java.awt.image.BufferedImage.TYPE_4BYTE_ABGR;
import static java.awt.image.BufferedImage.TYPE_4BYTE_ABGR_PRE;
import static java.awt.image.BufferedImage.TYPE_BYTE_BINARY;
import static java.awt.image.BufferedImage.TYPE_BYTE_GRAY;
import static java.awt.image.BufferedImage.TYPE_BYTE_INDEXED;
import static java.awt.image.BufferedImage.TYPE_INT_ARGB;
import static java.awt.image.BufferedImage.TYPE_INT_ARGB_PRE;
import static java.awt.image.BufferedImage.TYPE_INT_BGR;
import static java.awt.image.BufferedImage.TYPE_INT_RGB;
import static java.awt.image.BufferedImage.TYPE_USHORT_555_RGB;
import static java.awt.image.BufferedImage.TYPE_USHORT_565_RGB;
import static java.awt.image.BufferedImage.TYPE_USHORT_GRAY;
/**
* @test
* @bug 8295430
* @summary Tests various conversions from/to custom 3BYTE_BGR image
*/
public final class FilterImageLineGap {
private static final int[] TYPES = {
TYPE_INT_RGB, TYPE_INT_ARGB, TYPE_INT_ARGB_PRE, TYPE_INT_BGR,
TYPE_3BYTE_BGR, TYPE_4BYTE_ABGR, TYPE_4BYTE_ABGR_PRE,
TYPE_USHORT_565_RGB, TYPE_USHORT_555_RGB, TYPE_BYTE_GRAY,
TYPE_USHORT_GRAY, TYPE_BYTE_BINARY, TYPE_BYTE_INDEXED
};
private static final int[] CSS = {
ColorSpace.CS_CIEXYZ, ColorSpace.CS_GRAY, ColorSpace.CS_LINEAR_RGB,
ColorSpace.CS_PYCC, ColorSpace.CS_sRGB
};
private static final int W = 511;
private static final int H = 255;
public static void main(String[] args) throws Exception {
for (int fromIndex : CSS) {
for (int toIndex : CSS) {
customToCustom(fromIndex, toIndex);
customToAny(fromIndex, toIndex);
anytoCustom(fromIndex, toIndex);
}
}
}
private static void customToCustom(int fromIndex, int toIndex)
throws Exception
{
ColorSpace toCS = ColorSpace.getInstance(fromIndex);
ColorSpace fromCS = ColorSpace.getInstance(toIndex);
ColorConvertOp op = new ColorConvertOp(fromCS, toCS, null);
BufferedImage src = makeCustom3BYTE_BGR();
BufferedImage dst = makeCustom3BYTE_BGR();
BufferedImage srcGold = new BufferedImage(W, H, TYPE_3BYTE_BGR);
BufferedImage dstGold = new BufferedImage(W, H, TYPE_3BYTE_BGR);
fill(src);
fill(srcGold);
op.filter(src, dst);
op.filter(srcGold, dstGold);
// validate images
for (int x = 0; x < W; ++x) {
for (int y = 0; y < H; ++y) {
if (dst.getRGB(x, y) != dstGold.getRGB(x, y)) {
ImageIO.write(dst, "png", new File("custom.png"));
ImageIO.write(dstGold, "png", new File("gold.png"));
throw new RuntimeException("Test failed.");
}
}
}
}
private static void customToAny(int fromIndex, int toIndex) throws Exception
{
ColorSpace toCS = ColorSpace.getInstance(fromIndex);
ColorSpace fromCS = ColorSpace.getInstance(toIndex);
ColorConvertOp op = new ColorConvertOp(fromCS, toCS, null);
for (int type : TYPES) {
BufferedImage src = makeCustom3BYTE_BGR();
BufferedImage dst = new BufferedImage(W, H, type);
BufferedImage srcGold = new BufferedImage(W, H, TYPE_3BYTE_BGR);
BufferedImage dstGold = new BufferedImage(W, H, type);
fill(src);
fill(srcGold);
op.filter(src, dst);
op.filter(srcGold, dstGold);
// validate images
for (int x = 0; x < W; ++x) {
for (int y = 0; y < H; ++y) {
if (dst.getRGB(x, y) != dstGold.getRGB(x, y)) {
ImageIO.write(dst, "png", new File("custom.png"));
ImageIO.write(dstGold, "png", new File("gold.png"));
throw new RuntimeException("Test failed.");
}
}
}
}
}
private static void anytoCustom(int fromIndex, int toIndex) throws Exception
{
ColorSpace toCS = ColorSpace.getInstance(fromIndex);
ColorSpace fromCS = ColorSpace.getInstance(toIndex);
ColorConvertOp op = new ColorConvertOp(fromCS, toCS, null);
for (int type : TYPES) {
BufferedImage src = new BufferedImage(W, H, type);
BufferedImage dst = makeCustom3BYTE_BGR();
BufferedImage srcGold = new BufferedImage(W, H, type);
BufferedImage dstGold = new BufferedImage(W, H, TYPE_3BYTE_BGR);
fill(src);
fill(srcGold);
op.filter(src, dst);
op.filter(srcGold, dstGold);
// validate images
for (int x = 0; x < W; ++x) {
for (int y = 0; y < H; ++y) {
if (dst.getRGB(x, y) != dstGold.getRGB(x, y)) {
ImageIO.write(dst, "png", new File("custom.png"));
ImageIO.write(dstGold, "png", new File("gold.png"));
throw new RuntimeException("Test failed.");
}
}
}
}
}
/**
* Returns the custom buffered image, which mostly identical to
* BufferedImage.(w,h,TYPE_3BYTE_BGR), but uses the bigger scanlineStride.
* This means that the raster will have gaps, between the rows.
*/
private static BufferedImage makeCustom3BYTE_BGR() {
ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_sRGB);
int[] nBits = {8, 8, 8};
int[] bOffs = {2, 1, 0};
ColorModel colorModel = new ComponentColorModel(cs, nBits, false, false,
Transparency.OPAQUE,
DataBuffer.TYPE_BYTE);
WritableRaster raster = Raster.createInterleavedRaster(
DataBuffer.TYPE_BYTE, W, H, W * 3 + 2, 3, bOffs, null);
return new BufferedImage(colorModel, raster, true, null);
}
private static void fill(Image image) {
Graphics2D graphics = (Graphics2D) image.getGraphics();
graphics.setComposite(AlphaComposite.Src);
for (int i = 0; i < image.getHeight(null); ++i) {
graphics.setColor(new Color(i, 0, 255 - i));
graphics.fillRect(0, i, image.getWidth(null), 1);
}
graphics.dispose();
}
}

View file

@ -0,0 +1,162 @@
/*
* Copyright Amazon.com Inc. 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.
*/
import java.awt.Color;
import java.awt.Point;
import java.awt.color.ColorSpace;
import java.awt.image.BufferedImage;
import java.awt.image.ColorConvertOp;
import java.awt.image.ColorModel;
import java.awt.image.SampleModel;
import java.awt.image.WritableRaster;
import java.io.File;
import javax.imageio.ImageIO;
import static java.awt.image.BufferedImage.TYPE_3BYTE_BGR;
import static java.awt.image.BufferedImage.TYPE_4BYTE_ABGR;
import static java.awt.image.BufferedImage.TYPE_4BYTE_ABGR_PRE;
import static java.awt.image.BufferedImage.TYPE_INT_ARGB;
import static java.awt.image.BufferedImage.TYPE_INT_ARGB_PRE;
import static java.awt.image.BufferedImage.TYPE_INT_BGR;
import static java.awt.image.BufferedImage.TYPE_INT_RGB;
import static java.awt.image.BufferedImage.TYPE_USHORT_GRAY;
/**
* @test
* @bug 8366208
* @summary Verifies ColorConvertOp works correctly with BufferedImage and
* semi-custom raster
*/
public final class FilterSemiCustomImages {
private static final int W = 144;
private static final int H = 123;
private static final int[] TYPES = {
TYPE_INT_RGB, TYPE_INT_ARGB, TYPE_INT_ARGB_PRE, TYPE_INT_BGR,
TYPE_3BYTE_BGR, TYPE_4BYTE_ABGR, TYPE_4BYTE_ABGR_PRE,
TYPE_USHORT_GRAY
};
private static final int[] CSS = {
ColorSpace.CS_CIEXYZ, ColorSpace.CS_GRAY, ColorSpace.CS_LINEAR_RGB,
ColorSpace.CS_PYCC, ColorSpace.CS_sRGB
};
private static final class CustomRaster extends WritableRaster {
CustomRaster(SampleModel sampleModel, Point origin) {
super(sampleModel, origin);
}
}
public static void main(String[] args) throws Exception {
for (int fromIndex : CSS) {
for (int toIndex : CSS) {
if (fromIndex != toIndex) {
for (int type : TYPES) {
test(fromIndex, toIndex, type);
}
}
}
}
}
private static void test(int fromIndex, int toIndex, int type)
throws Exception
{
ColorSpace fromCS = ColorSpace.getInstance(fromIndex);
ColorSpace toCS = ColorSpace.getInstance(toIndex);
ColorConvertOp op = new ColorConvertOp(fromCS, toCS, null);
// standard source -> standard dst
BufferedImage srcGold = new BufferedImage(W, H, type);
fill(srcGold);
BufferedImage dstGold = new BufferedImage(W, H, type);
op.filter(srcGold, dstGold);
// custom source -> standard dst
BufferedImage srcCustom = makeCustomBI(srcGold);
fill(srcCustom);
BufferedImage dst = new BufferedImage(W, H, type);
op.filter(srcCustom, dst);
verify(dstGold, dst);
// standard source -> custom dst
BufferedImage src = new BufferedImage(W, H, type);
fill(src);
BufferedImage dstCustom = makeCustomBI(dstGold);
op.filter(src, dstCustom);
verify(dstGold, dstCustom);
// custom source -> custom dst
srcCustom = makeCustomBI(srcGold);
fill(srcCustom);
dstCustom = makeCustomBI(dstGold);
op.filter(srcCustom, dstCustom);
verify(dstGold, dstCustom);
}
private static BufferedImage makeCustomBI(BufferedImage bi) {
ColorModel cm = bi.getColorModel();
SampleModel sm = bi.getSampleModel();
CustomRaster cr = new CustomRaster(sm, new Point());
return new BufferedImage(cm, cr, bi.isAlphaPremultiplied(), null) {
@Override
public int getType() {
return bi.getType();
}
};
}
private static void fill(BufferedImage image) {
int width = image.getWidth();
int height = image.getHeight();
for (int x = 0; x < width; ++x) {
for (int y = 0; y < height; ++y) {
// alpha channel may be calculated slightly differently on
// different code paths, so only check fully transparent and
// fully opaque pixels
Color c = new Color(y * 255 / (height - 1),
x * 255 / (width - 1),
x % 255,
(x % 2 == 0) ? 0 : 255);
image.setRGB(x, y, c.getRGB());
}
}
}
private static void verify(BufferedImage dstGold, BufferedImage dst)
throws Exception
{
for (int x = 0; x < W; ++x) {
for (int y = 0; y < H; ++y) {
if (dst.getRGB(x, y) != dstGold.getRGB(x, y)) {
ImageIO.write(dst, "png", new File("custom.png"));
ImageIO.write(dstGold, "png", new File("gold.png"));
throw new RuntimeException("Test failed.");
}
}
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

View file

@ -0,0 +1,102 @@
/*
* Copyright (c) 2012, 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 7124245
* @summary Test verifies that color conversion does not distort
* colors in destination image of standard type.
*
* @run main GrayTest
*/
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.color.ColorSpace;
import java.awt.image.BufferedImage;
import java.awt.image.ColorConvertOp;
public class GrayTest {
public static void main(String[] args) {
GrayTest t = new GrayTest();
t.doTest(BufferedImage.TYPE_INT_RGB);
t.doTest(BufferedImage.TYPE_INT_BGR);
t.doTest(BufferedImage.TYPE_INT_ARGB);
t.doTest(BufferedImage.TYPE_3BYTE_BGR);
t.doTest(BufferedImage.TYPE_4BYTE_ABGR);
System.out.println("Test passed.");
}
private static final int w = 3;
private static final int h = 3;
private BufferedImage src;
private BufferedImage dst;
private ColorConvertOp op;
public GrayTest() {
ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_GRAY);
op = new ColorConvertOp(cs, null);
}
private void render(Graphics2D g) {
g.setColor(Color.red);
g.fillRect(0, 0, w, h);
}
private BufferedImage initImage(int type) {
BufferedImage img = new BufferedImage(w, h, type);
Graphics2D g = img.createGraphics();
render(g);
g.dispose();
return img;
}
public void doTest(int type) {
System.out.println("Test for type: " + type);
src = initImage(type);
dst = initImage(type);
dst = op.filter(src, dst);
int pixel = dst.getRGB(1, 1);
int r = 0xff & (pixel >> 16);
int g = 0xff & (pixel >> 8);
int b = 0xff & (pixel );
System.out.printf("dst: r:%02x, g: %02x, %02x\n",
r, g, b);
if (r != g || r != b) {
String msg = String.format("Invalid pixel: %08x", pixel);
throw new RuntimeException(msg);
}
System.out.println("Done.");
}
}

View file

@ -0,0 +1,139 @@
/*
* Copyright (c) 2007, 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.
*/
import java.awt.Color;
import java.awt.image.BufferedImage;
public class ImageComparator {
double accuracy;
int errorCounter = 0;
double maxError = 0f;
int rMask = 0x00FF0000;
int gMask = 0x0000FF00;
int bMask = 0x000000FF;
int rShift = 16;
int gShift = 8;
int bShift = 0;
public ImageComparator() {
accuracy = 0;
}
public ImageComparator(double accuracy) {
this.accuracy = accuracy;
}
public ImageComparator(double accuracy, int rBits, int gBits, int bBits) {
this.accuracy = accuracy;
rShift += (8 - rBits);
gShift += (8 - gBits);
bShift += (8 - bBits);
}
public boolean compare(int c1, int c2) {
int d1 = Math.abs(((c1&bMask)>>bShift) - ((c2&bMask)>>bShift));
int d2 = Math.abs(((c1&gMask)>>gShift) - ((c2&gMask)>>gShift));
int d3 = Math.abs(((c1&rMask)>>rShift) - ((c2&rMask)>>rShift));
if (d1 < d2) d1 = d2;
if (d1 < d3) d1 = d3;
if (d1 >= accuracy) {
errorCounter++;
if (d1 > maxError) maxError = d1;
return false;
}
return true;
}
public boolean compare(double r1, double g1, double b1,
double r2, double g2, double b2)
{
double d1 = Math.abs(r1 - r2);
double d2 = Math.abs(g1 - g2);
double d3 = Math.abs(b1 - b2);
if (d1 < d2) d1 = d2;
if (d1 < d3) d1 = d3;
if (d1 >= accuracy) {
errorCounter++;
if (d1 > maxError) maxError = d1;
return false;
}
return true;
}
public boolean compare(Color c1, Color c2) {
return compare(c1.getRed(), c1.getGreen(), c1.getBlue(),
c2.getRed(), c2.getGreen(), c2.getBlue());
}
public boolean compare(BufferedImage img1, BufferedImage img2) {
boolean result = true;
if (img1.getWidth() != img2.getWidth() ||
img1.getHeight() != img2.getHeight()) {
throw new IllegalArgumentException(
"Images have different width or height");
}
for (int i = 0; i < img1.getWidth(); i++) {
for (int j = 0; j < img1.getHeight(); j++) {
boolean cmp = compare(img1.getRGB(i,j), img2.getRGB(i,j));
result = cmp && result;
}
}
return result;
}
public void resetStat() {
errorCounter = 0;
maxError = 0;
}
public String getStat() {
return "Accuracy " + accuracy + ". Errors " + errorCounter +
". Max error " + maxError;
}
boolean compare(BufferedImage dst, BufferedImage gldImage, int x0, int y0,
int dx, int dy)
{
int width = gldImage.getWidth();
int height = gldImage.getHeight();
if (x0 < 0) x0 = 0;
if (x0 > width - dx) x0 = width - dx;
if (y0 < 0) y0 = 0;
if (y0 > height - dy) y0 = height - dy;
int c = 0;
boolean result = true;
for (int i = x0; i < x0 + dx; i++) {
for (int j = y0; j < y0 + dy; j++) {
boolean cmp = compare(dst.getRGB(i-x0,j-y0),
gldImage.getRGB(i,j));
result = cmp && result;
}
}
return result;
}
}

View file

@ -0,0 +1,305 @@
/*
* Copyright (c) 2007, 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.
*/
import java.awt.Color;
import java.awt.Transparency;
import java.awt.color.ColorSpace;
import java.awt.image.BufferedImage;
import java.awt.image.ColorConvertOp;
import java.awt.image.ColorModel;
import java.awt.image.ComponentColorModel;
import java.awt.image.DataBuffer;
import java.awt.image.DirectColorModel;
import java.awt.image.IndexColorModel;
import java.awt.image.SampleModel;
import java.awt.image.WritableRaster;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
public class ImageFactory {
public static int WIDTH = 256;
public static int HEIGHT = 256;
final static int aMask = 0xFF000000;
final static int rMask = 0x00FF0000;
final static int gMask = 0x0000FF00;
final static int bMask = 0x000000FF;
final static int r555Mask = 0x7c00;
final static int g555Mask = 0x3e0;
final static int b555Mask = 0x1f;
final static int r565Mask = 0xf800;
final static int g565Mask = 0x7e0;
final static int b565Mask = 0x1f;
final static int rShift = 16;
final static int gShift = 8;
final static int bShift = 0;
public static BufferedImage createCCMImage(int cs, int dataType)
{
ColorSpace cSpace = ColorSpace.getInstance(cs);
ComponentColorModel ccm = null;
if (dataType == DataBuffer.TYPE_INT)
{
ccm = new ComponentColorModel(cSpace,
((cs == ColorSpace.CS_GRAY)?
new int[] {8}: new int[] {8,8,8}),
false, false, Transparency.OPAQUE, dataType);
} else {
ccm = new ComponentColorModel(
cSpace, false, false, Transparency.OPAQUE, dataType);
}
SampleModel sm = ccm.createCompatibleSampleModel(WIDTH, HEIGHT);
WritableRaster raster = ccm.createCompatibleWritableRaster(WIDTH,
HEIGHT);
DataBuffer data = raster.getDataBuffer();
fillCCM(data, sm, cSpace);
return new BufferedImage(ccm, raster, false, null);
}
public static BufferedImage createDCMImage(int type, int cs) {
if (type == BufferedImage.TYPE_INT_RGB && cs == ColorSpace.CS_sRGB) {
BufferedImage image = new BufferedImage(WIDTH, HEIGHT,
BufferedImage.TYPE_INT_RGB);
DataBuffer data = image.getData().getDataBuffer();
fill(image);
return image;
}
ColorSpace cSpace = ColorSpace.getInstance(cs);
DirectColorModel dcm = null;
switch(type) {
case BufferedImage.TYPE_INT_ARGB:
dcm = new DirectColorModel(cSpace, 32, rMask, gMask,
bMask, aMask, false,
DataBuffer.TYPE_INT);
break;
case BufferedImage.TYPE_INT_RGB:
dcm = new DirectColorModel(cSpace, 24, rMask, gMask,
bMask, 0, false,
DataBuffer.TYPE_INT);
break;
case BufferedImage.TYPE_INT_BGR:
dcm = new DirectColorModel(cSpace, 24, rMask, gMask,
bMask, 0, false,
DataBuffer.TYPE_INT);
break;
case BufferedImage.TYPE_USHORT_555_RGB:
dcm = new DirectColorModel(cSpace, 15, r555Mask, g555Mask,
b555Mask, 0, false,
DataBuffer.TYPE_USHORT);
break;
case BufferedImage.TYPE_USHORT_565_RGB:
dcm = new DirectColorModel(cSpace, 16, r565Mask, g565Mask,
b565Mask, 0, false,
DataBuffer.TYPE_USHORT);
break;
}
SampleModel sm = dcm.createCompatibleSampleModel(WIDTH, HEIGHT);
WritableRaster raster = dcm.createCompatibleWritableRaster(WIDTH,
HEIGHT);
switch(type) {
case BufferedImage.TYPE_INT_ARGB:
fillDCM(raster.getDataBuffer(), sm, cSpace.getType());
break;
case BufferedImage.TYPE_INT_RGB:
fillDCM(raster.getDataBuffer(), sm, cSpace.getType());
break;
case BufferedImage.TYPE_INT_BGR:
fillDCM(raster.getDataBuffer(), sm, cSpace.getType());
break;
case BufferedImage.TYPE_USHORT_555_RGB:
fillDCM(raster.getDataBuffer(), sm, cSpace.getType(), 5, 5, 5);
break;
case BufferedImage.TYPE_USHORT_565_RGB:
fillDCM(raster.getDataBuffer(), sm, cSpace.getType(), 5, 6, 5);
break;
}
return new BufferedImage(dcm, raster, false, null);
}
public static void fill(BufferedImage image) {
for (int i = 0; i < WIDTH; i++) {
for (int j = 0; j < HEIGHT; j++) {
image.setRGB(i,j,0xFF000000 | (i << 16) | (j << 8) |
((i + j)>>1));
}
}
}
public static void fillCCM(DataBuffer data, SampleModel sm, ColorSpace cs) {
switch (cs.getType()) {
case ColorSpace.TYPE_RGB:
case ColorSpace.TYPE_XYZ:
case ColorSpace.TYPE_3CLR:
if (data.getDataType() == DataBuffer.TYPE_BYTE ||
data.getDataType() == DataBuffer.TYPE_INT)
{
int [] pixel = new int[3];
for (int i = 0; i < WIDTH; i++) {
for (int j = 0; j < HEIGHT; j++) {
pixel[0] = i;
pixel[1] = j;
pixel[2] = ((i + j)>>1);
sm.setPixel(i, j, pixel, data);
}
}
} else if (data.getDataType() == DataBuffer.TYPE_SHORT) {
int [] pixel = new int[3];
for (int i = 0; i < WIDTH; i++) {
for (int j = 0; j < HEIGHT; j++) {
pixel[0] = (i<<7);
pixel[1] = (j<<7);
pixel[2] = ((i + j)<<6);
sm.setPixel(i, j, pixel, data);
}
}
} else if (data.getDataType() == DataBuffer.TYPE_USHORT) {
int [] pixel = new int[3];
for (int i = 0; i < WIDTH; i++) {
for (int j = 0; j < HEIGHT; j++) {
pixel[0] = (i<<8);
pixel[1] = (j<<8);
pixel[2] = ((i + j)<<7);
sm.setPixel(i, j, pixel, data);
}
}
} else if (data.getDataType() == DataBuffer.TYPE_DOUBLE) {
double [] pixel = new double [3];
for (int i = 0; i < WIDTH; i++) {
for (int j = 0; j < HEIGHT; j++) {
pixel[0] = (i/255.0)*(cs.getMaxValue(0) -
cs.getMinValue(0)) +
cs.getMinValue(0);
pixel[1] = (j/255.0)*(cs.getMaxValue(1) -
cs.getMinValue(1)) +
cs.getMinValue(1);
pixel[2] = (((i + j)>>1)/255.0)*(cs.getMaxValue(2) -
cs.getMinValue(2))+
cs.getMinValue(2);
sm.setPixel(i, j, pixel, data);
}
}
} else if (data.getDataType() == DataBuffer.TYPE_FLOAT) {
float [] pixel = new float [3];
for (int i = 0; i < WIDTH; i++) {
for (int j = 0; j < HEIGHT; j++) {
pixel[0] = (i/255.0f)*(cs.getMaxValue(0) -
cs.getMinValue(0)) +
cs.getMinValue(0);
pixel[1] = (j/255.0f)*(cs.getMaxValue(1) -
cs.getMinValue(1)) +
cs.getMinValue(1);
pixel[2] = (((i + j)>>1)/255.0f)*(cs.getMaxValue(2)-
cs.getMinValue(2))
+ cs.getMinValue(2);
sm.setPixel(i, j, pixel, data);
}
}
} else {
throw new RuntimeException("Unsupported DataBuffer type");
}
break;
case ColorSpace.TYPE_GRAY:
if (data.getDataType() == DataBuffer.TYPE_BYTE ||
data.getDataType() == DataBuffer.TYPE_INT) {
int [] pixel = new int[1];
for (int i = 0; i < WIDTH; i++) {
for (int j = 0; j < HEIGHT; j++) {
pixel[0] = i;
sm.setPixel(i, j, pixel, data);
}
}
} else if (data.getDataType() == DataBuffer.TYPE_SHORT) {
int [] pixel = new int[1];
for (int i = 0; i < WIDTH; i++) {
for (int j = 0; j < HEIGHT; j++) {
pixel[0] = i << 7;
sm.setPixel(i, j, pixel, data);
}
}
} else if (data.getDataType() == DataBuffer.TYPE_USHORT) {
int [] pixel = new int[1];
for (int i = 0; i < WIDTH; i++) {
for (int j = 0; j < HEIGHT; j++) {
pixel[0] = i << 8;
sm.setPixel(i, j, pixel, data);
}
}
} else if (data.getDataType() == DataBuffer.TYPE_DOUBLE) {
double [] pixel = new double[1];
for (int i = 0; i < WIDTH; i++) {
for (int j = 0; j < HEIGHT; j++) {
pixel[0] = (i/255.0)*(cs.getMaxValue(0) -
cs.getMinValue(0)) +
cs.getMinValue(0);
sm.setPixel(i, j, pixel, data);
}
}
} else if (data.getDataType() == DataBuffer.TYPE_FLOAT) {
float [] pixel = new float[1];
for (int i = 0; i < WIDTH; i++) {
for (int j = 0; j < HEIGHT; j++) {
pixel[0] = (i/255.0f)*(cs.getMaxValue(0) -
cs.getMinValue(0)) +
cs.getMinValue(0);
sm.setPixel(i, j, pixel, data);
}
}
} else {
throw new RuntimeException("Unsupported DataBuffer type");
}
break;
}
}
public static void fillDCM(DataBuffer data, SampleModel sm, int csType,
int c1Bits, int c2Bits, int c3Bits)
{
int [] pixel;
pixel = new int[4];
for (int i = 0; i < WIDTH; i++) {
for (int j = 0; j < HEIGHT; j++) {
pixel[0] = i >> (8 - c1Bits);
pixel[1] = j >> (8 - c2Bits);
pixel[2] = ((i + j)>>1) >> (8 - c3Bits);
pixel[3] = 0xFF;
sm.setPixel(i, j, pixel, data);
}
}
}
public static void fillDCM(DataBuffer data, SampleModel sm, int csType) {
fillDCM(data, sm, csType, 8, 8, 8);
}
public static BufferedImage createDstImage(int type) {
return new BufferedImage(WIDTH, HEIGHT, type);
}
}

View file

@ -0,0 +1,77 @@
/*
* Copyright (c) 2011, 2012, 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 7064516
* @summary Test verifies that incorrect profile rendering intent
* does not cause an failure of color conversion op.
* @run main InvalidRenderIntentTest
*/
import java.awt.color.CMMException;
import java.awt.color.ColorSpace;
import java.awt.color.ICC_ColorSpace;
import java.awt.color.ICC_Profile;
import java.awt.image.ColorConvertOp;
import java.awt.image.BufferedImage;
import static java.awt.color.ColorSpace.CS_sRGB;
import static java.awt.image.BufferedImage.TYPE_3BYTE_BGR;
public class InvalidRenderIntentTest {
public static void main(String[] args) {
ICC_Profile pSRGB = ICC_Profile.getInstance(CS_sRGB);
byte[] raw_data = pSRGB.getData();
setRenderingIntent(0x1000000, raw_data);
ICC_Profile p = ICC_Profile.getInstance(raw_data);
ICC_ColorSpace cs = new ICC_ColorSpace(p);
// perfrom test color conversion
ColorConvertOp op = new ColorConvertOp(cs,
ColorSpace.getInstance(CS_sRGB), null);
BufferedImage src = new BufferedImage(1, 1, TYPE_3BYTE_BGR);
BufferedImage dst = new BufferedImage(1, 1, TYPE_3BYTE_BGR);
try {
op.filter(src.getRaster(), dst.getRaster());
} catch (CMMException e) {
throw new RuntimeException("Test failed.", e);
}
System.out.println("Test passed.");
}
private static void setRenderingIntent(int intent, byte[] data) {
final int pos = ICC_Profile.icHdrRenderingIntent;
data[pos + 0] = (byte) (0xff & (intent >> 24));
data[pos + 1] = (byte) (0xff & (intent >> 16));
data[pos + 2] = (byte) (0xff & (intent >> 8));
data[pos + 3] = (byte) (0xff & (intent));
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 106 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

View file

@ -0,0 +1,58 @@
/*
* Copyright (c) 2007, 2011, 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 6476665 7033534
* @summary Verifies MT safety of color conversion of Component and Direct Color Model based images
* @run main MTColConvTest
*/
public class MTColConvTest {
public final static int THREAD_COUNT = 10;
public static void main(String [] args) throws InterruptedException {
Thread [] threads = new Thread[THREAD_COUNT];
ColConvTest [] tests = new ColConvTest[THREAD_COUNT];
for (int i = 0; i < threads.length; i+=2) {
tests[i]= new ColConvDCMTest();
tests[i].init();
threads[i] = new Thread(tests[i]);
tests[i+1] = new ColConvCCMTest();
tests[i+1].init();
threads[i+1] = new Thread(tests[i+1]);
}
for (int i = 0; i < threads.length; i++) {
threads[i].start();
}
boolean isPassed = true;
for (int i = 0; i < threads.length; i++) {
threads[i].join();
isPassed = isPassed && tests[i].isPassed();
}
if (!isPassed) {
throw new RuntimeException("MT Color Conversion error");
}
}
}

View file

@ -0,0 +1,146 @@
/*
* Copyright Amazon.com Inc. 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.
*/
import java.awt.color.ColorSpace;
import java.awt.image.BufferedImage;
import java.awt.image.ColorConvertOp;
/**
* @test
* @bug 8273972
* @summary Verifies that ColorConvertOp works fine if shared between threads
* @run main/othervm/timeout=600 MTPerLineTransformValidation
*/
public final class MTPerLineTransformValidation {
private volatile static BufferedImage[] lines;
public static final int SIZE = 255;
private static volatile boolean failed = false;
private static final int[] spaces = {
ColorSpace.CS_CIEXYZ, ColorSpace.CS_GRAY, ColorSpace.CS_LINEAR_RGB,
ColorSpace.CS_PYCC, ColorSpace.CS_sRGB
};
private static final int[] types = new int[]{
BufferedImage.TYPE_INT_RGB, BufferedImage.TYPE_INT_ARGB,
BufferedImage.TYPE_INT_ARGB_PRE, BufferedImage.TYPE_INT_BGR,
BufferedImage.TYPE_3BYTE_BGR, BufferedImage.TYPE_4BYTE_ABGR,
BufferedImage.TYPE_4BYTE_ABGR_PRE,
BufferedImage.TYPE_USHORT_565_RGB,
BufferedImage.TYPE_USHORT_555_RGB, BufferedImage.TYPE_BYTE_GRAY,
BufferedImage.TYPE_USHORT_GRAY, BufferedImage.TYPE_BYTE_BINARY,
BufferedImage.TYPE_BYTE_INDEXED
};
/**
* For all possible combinations of color spaces and image types, convert
* the source image using one shared ColorConvertOp per line on the
* different threads. The result is validated against images converted on
* one thread only.
*/
public static void main(String[] args) throws Exception {
for (int srcCS : spaces) {
for (int dstCS : spaces) {
if(srcCS != dstCS) {
for (int type : types) {
checkTypes(ColorSpace.getInstance(srcCS),
ColorSpace.getInstance(dstCS), type);
}
}
}
}
}
private static void checkTypes(ColorSpace srcCS, ColorSpace dstCS, int type)
throws Exception {
lines = new BufferedImage[SIZE];
ColorConvertOp goldOp = new ColorConvertOp(srcCS, dstCS, null);
BufferedImage src = createSrc(type);
BufferedImage gold = goldOp.filter(src, null);
// we do not share the goldOp since it is already initialized and used
// for the whole image, instead we will create a separate sharedOp and
// use it for each line of a different threads
ColorConvertOp sharedOp = new ColorConvertOp(srcCS, dstCS, null);
Thread[] threads = new Thread[SIZE];
for (int y = 0; y < SIZE; ++y) {
BufferedImage line = src.getSubimage(0, y, SIZE, 1);
threads[y] = test(sharedOp, line, y);
}
for (Thread t: threads) {
t.start();
}
for (Thread t: threads) {
t.join();
}
for (int y = 0; y < SIZE; ++y) {
validate(gold, lines[y], y);
}
if (failed) {
throw new RuntimeException("Unexpected exception");
}
}
private static Thread test(ColorConvertOp sharedOp,
BufferedImage line, int y){
return new Thread(() -> {
try {
BufferedImage image = sharedOp.filter(line, null);
lines[y] = image;
} catch (Throwable t) {
t.printStackTrace();
failed = true;
}
});
}
private static BufferedImage createSrc(int type) {
BufferedImage img = new BufferedImage(SIZE, SIZE, type);
fill(img);
return img;
}
private static void fill(BufferedImage image) {
for (int i = 0; i < SIZE; i++) {
for (int j = 0; j < SIZE; j++) {
image.setRGB(i, j,
(i << 24) | (i << 16) | (j << 8) | ((i + j) >> 1));
}
}
}
private static void validate(BufferedImage full, BufferedImage line, int y) {
for (int i = 0; i < SIZE; i++) {
int rgb1 = full.getRGB(i, y);
int rgb2 = line.getRGB(i, 0);
if (rgb1 != rgb2) {
System.err.println("rgb1 = " + Integer.toHexString(rgb1));
System.err.println("rgb2 = " + Integer.toHexString(rgb2));
throw new RuntimeException();
}
}
}
}

View file

@ -0,0 +1,141 @@
/*
* Copyright (c) 2007, 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 6476665
* @summary Verifies MT safety of color conversions
* @run main MTSafetyTest
*/
import java.util.Vector;
import java.awt.*;
import java.awt.color.*;
import java.awt.image.*;
public class MTSafetyTest {
static boolean failed = false;
static int[] colorSpaceType = {
ColorSpace.CS_CIEXYZ,
ColorSpace.CS_GRAY,
ColorSpace.CS_LINEAR_RGB,
ColorSpace.CS_PYCC,
ColorSpace.CS_sRGB
};
static private final int[] imageTypes = new int[] {
BufferedImage.TYPE_INT_RGB,
BufferedImage.TYPE_INT_ARGB,
BufferedImage.TYPE_INT_ARGB_PRE,
BufferedImage.TYPE_INT_BGR,
BufferedImage.TYPE_3BYTE_BGR,
BufferedImage.TYPE_4BYTE_ABGR,
BufferedImage.TYPE_4BYTE_ABGR_PRE,
BufferedImage.TYPE_USHORT_565_RGB,
BufferedImage.TYPE_USHORT_555_RGB,
BufferedImage.TYPE_BYTE_GRAY,
BufferedImage.TYPE_USHORT_GRAY,
BufferedImage.TYPE_BYTE_BINARY,
BufferedImage.TYPE_BYTE_INDEXED
};
public static void main(String[] args) {
int nImgTypes = imageTypes.length;
int nCSTypes = colorSpaceType.length;
Vector<Thread> threads =
new Vector<Thread>(nImgTypes*nCSTypes*nCSTypes);
for (int i = 0; i < nImgTypes; i++) {
BufferedImage origImage =
new BufferedImage(300, 300, imageTypes[i]);
for (int j = 0; j < nCSTypes; j++) {
for (int k = 0; k < nCSTypes; k++) {
Graphics2D g2 = (Graphics2D) origImage.getGraphics();
g2.fillRect(0, 0, 300, 150);
ColorConvertOp colorOp = getColorConvertOp(j,k);
ColorConvert cc = new ColorConvert(origImage, colorOp);
Thread colorThread = new Thread(cc);
threads.add(colorThread);
colorThread.start();
}
}
}
try {
for (Thread thread : threads) {
thread.join();
}
} catch (InterruptedException e) {
throw new RuntimeException("Unexpected exception" + e);
}
if (failed) {
throw new RuntimeException("Unexpected exception");
}
}
private static ColorConvertOp getColorConvertOp(int srcIndex,
int destIndex)
{
ColorSpace srcColorSpace = ColorSpace.getInstance(
colorSpaceType[srcIndex]);
ColorSpace destColorSpace = ColorSpace.getInstance(
colorSpaceType[destIndex]);
return new ColorConvertOp(srcColorSpace, destColorSpace, null);
}
static class ColorConvert implements Runnable {
BufferedImage original = null;
ColorConvertOp colorOp = null;
public ColorConvert(BufferedImage orig, ColorConvertOp ccOp) {
original = orig;
colorOp = ccOp;
}
public void run() {
try {
colorOp.filter(original, null);
} catch (OutOfMemoryError e) {
/* Skipping OOM exception. We cannot just enlarge stack and heap
* because it causes problem to disappear
*/
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
failed = true;
}
}
}
}

View file

@ -0,0 +1,143 @@
/*
* Copyright Amazon.com Inc. 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.
*/
import java.awt.color.ColorSpace;
import java.awt.image.BufferedImage;
import java.awt.image.ColorConvertOp;
import java.util.concurrent.CountDownLatch;
/**
* @test
* @bug 8273972
* @summary Verifies that ColorConvertOp works fine if shared between threads
* @run main/othervm/timeout=600 MTTransformValidation
*/
public final class MTTransformValidation {
public static final int SIZE = 255;
private static volatile boolean failed = false;
private static final int[] spaces = {
ColorSpace.CS_CIEXYZ, ColorSpace.CS_GRAY, ColorSpace.CS_LINEAR_RGB,
ColorSpace.CS_PYCC, ColorSpace.CS_sRGB
};
private static final int[] types = new int[]{
BufferedImage.TYPE_INT_RGB, BufferedImage.TYPE_INT_ARGB,
BufferedImage.TYPE_INT_ARGB_PRE, BufferedImage.TYPE_INT_BGR,
BufferedImage.TYPE_3BYTE_BGR, BufferedImage.TYPE_4BYTE_ABGR,
BufferedImage.TYPE_4BYTE_ABGR_PRE,
BufferedImage.TYPE_USHORT_565_RGB,
BufferedImage.TYPE_USHORT_555_RGB, BufferedImage.TYPE_BYTE_GRAY,
BufferedImage.TYPE_USHORT_GRAY, BufferedImage.TYPE_BYTE_BINARY,
BufferedImage.TYPE_BYTE_INDEXED
};
/**
* For all possible combinations of color spaces and image types, convert
* the source image using one shared ColorConvertOp. The result is validated
* against images converted on one thread only.
*/
public static void main(String[] args) throws Exception {
for (int srcCS : spaces) {
for (int dstCS : spaces) {
if(srcCS != dstCS) {
for (int type : types) {
checkTypes(ColorSpace.getInstance(srcCS),
ColorSpace.getInstance(dstCS), type);
}
}
}
}
}
private static void checkTypes(ColorSpace srcCS, ColorSpace dstCS, int type)
throws Exception {
ColorConvertOp goldOp = new ColorConvertOp(srcCS, dstCS, null);
BufferedImage gold = goldOp.filter(createSrc(type), null);
// we do not share the goldOp since it is already initialized, but
// instead we will trigger initialization/usage of the new sharedOp on
// different threads at once
ColorConvertOp sharedOp = new ColorConvertOp(srcCS, dstCS, null);
test(gold, sharedOp, type);
if (failed) {
throw new RuntimeException("Unexpected exception");
}
}
private static void test(BufferedImage gold, ColorConvertOp sharedOp,
int type) throws Exception {
Thread[] ts = new Thread[7];
CountDownLatch latch = new CountDownLatch(ts.length);
for (int i = 0; i < ts.length; i++) {
ts[i] = new Thread(() -> {
BufferedImage local = createSrc(type);
latch.countDown();
try {
latch.await();
BufferedImage image = sharedOp.filter(local, null);
validate(image, gold);
} catch (Throwable t) {
t.printStackTrace();
failed = true;
}
});
}
for (Thread t : ts) {
t.start();
}
for (Thread t : ts) {
t.join();
}
}
private static BufferedImage createSrc(int type) {
BufferedImage img = new BufferedImage(SIZE, SIZE, type);
fill(img);
return img;
}
private static void fill(BufferedImage image) {
for (int i = 0; i < SIZE; i++) {
for (int j = 0; j < SIZE; j++) {
image.setRGB(i, j,
(i << 24) | (i << 16) | (j << 8) | ((i + j) >> 1));
}
}
}
private static void validate(BufferedImage img1, BufferedImage img2) {
for (int i = 0; i < SIZE; i++) {
for (int j = 0; j < SIZE; j++) {
int rgb1 = img1.getRGB(i, j);
int rgb2 = img2.getRGB(i, j);
if (rgb1 != rgb2) {
System.err.println("rgb1 = " + Integer.toHexString(rgb1));
System.err.println("rgb2 = " + Integer.toHexString(rgb2));
throw new RuntimeException();
}
}
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 83 KiB

View file

@ -0,0 +1,264 @@
/*
* Copyright Amazon.com Inc. 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.
*/
import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Transparency;
import java.awt.color.ColorSpace;
import java.awt.image.BufferedImage;
import java.awt.image.ColorConvertOp;
import java.awt.image.ColorModel;
import java.awt.image.ComponentColorModel;
import java.awt.image.DataBuffer;
import java.awt.image.DirectColorModel;
import java.awt.image.Raster;
import java.awt.image.WritableRaster;
import java.util.Arrays;
import static java.awt.image.BufferedImage.TYPE_4BYTE_ABGR_PRE;
import static java.awt.image.BufferedImage.TYPE_INT_ARGB_PRE;
/**
* @test
* @bug 8279216
* @summary Verifies implementation of premultiplied alpha
*/
public final class PremultipliedAlpha {
private static final int SIZE = 256;
private static final int COLOR_TOLERANCE = 2;
private enum Type {
TYPE_ARGB_PRE,
TYPE_4BYTE_ABGR_PRE,
TYPE_CUSTOM_ARGB_PRE,
TYPE_CUSTOM_GABR_PRE,
TYPE_CUSTOM_4BYTE_ABGR_PRE,
TYPE_CUSTOM_4BYTE_ARGB_PRE,
TYPE_CUSTOM_4BYTE_RGBA_PRE,
TYPE_CUSTOM_4BYTE_GABR_PRE,
TYPE_CUSTOM_4USHORT_8bit_ARGB_PRE,
TYPE_CUSTOM_4INT_8bit_ARGB_PRE,
}
private static final ColorSpace[] CSs = {
ColorSpace.getInstance(ColorSpace.CS_CIEXYZ),
ColorSpace.getInstance(ColorSpace.CS_GRAY),
ColorSpace.getInstance(ColorSpace.CS_LINEAR_RGB),
ColorSpace.getInstance(ColorSpace.CS_PYCC),
ColorSpace.getInstance(ColorSpace.CS_sRGB)
};
public static void main(String[] args) {
for (ColorSpace cs : CSs) {
for (Type dst : Type.values()) {
BufferedImage gold = null;
for (Type src : Type.values()) {
BufferedImage from = createSrc(src);
BufferedImage to = createDst(dst);
ColorConvertOp op = new ColorConvertOp(cs, null);
op.filter(from, to);
if (gold == null) {
gold = to;
} else {
validate(gold, to);
}
}
}
}
}
private static void validate(BufferedImage img1, BufferedImage img2) {
for (int a = 0; a < SIZE; a++) {
for (int c = 0; c < SIZE; c++) {
int[] pixel1 = img1.getRaster().getPixel(c, a, (int[]) null);
int[] pixel2 = img2.getRaster().getPixel(c, a, (int[]) null);
if (pixel1.length != pixel2.length) {
throw new RuntimeException();
}
for (int i = 0 ; i < pixel1.length; ++i) {
if (Math.abs(pixel1[i] - pixel2[i]) >= COLOR_TOLERANCE) {
System.out.println("c = " + c);
System.out.println("a = " + a);
System.err.println("rgb1 = " + Arrays.toString(pixel1));
System.err.println("rgb2 = " + Arrays.toString(pixel2));
throw new RuntimeException();
}
}
}
}
}
private static BufferedImage createDst(Type type) {
BufferedImage img = createSrc(type);
Graphics2D g = img.createGraphics();
g.setComposite(AlphaComposite.Clear);
g.fillRect(0, 0, SIZE, SIZE);
g.dispose();
return img;
}
private static BufferedImage createSrc(Type type) {
BufferedImage bi = switch (type) {
case TYPE_ARGB_PRE -> new BufferedImage(SIZE, SIZE, TYPE_INT_ARGB_PRE);
case TYPE_CUSTOM_ARGB_PRE -> TYPE_ARGB_PRE();
case TYPE_CUSTOM_GABR_PRE -> TYPE_GABR_PRE();
case TYPE_4BYTE_ABGR_PRE -> new BufferedImage(SIZE, SIZE, TYPE_4BYTE_ABGR_PRE);
case TYPE_CUSTOM_4BYTE_ARGB_PRE -> TYPE_4BYTE_ARGB_PRE();
case TYPE_CUSTOM_4BYTE_ABGR_PRE -> TYPE_4BYTE_ABGR_PRE();
case TYPE_CUSTOM_4BYTE_RGBA_PRE -> TYPE_4BYTE_RGBA_PRE();
case TYPE_CUSTOM_4BYTE_GABR_PRE -> TYPE_4BYTE_GABR_PRE();
case TYPE_CUSTOM_4USHORT_8bit_ARGB_PRE -> TYPE_4USHORT_ARGB_8bit_PRE();
case TYPE_CUSTOM_4INT_8bit_ARGB_PRE -> TYPE_4INT_ARGB_8bit_PRE();
};
fill(bi);
return bi;
}
private static BufferedImage TYPE_ARGB_PRE() {
ColorModel colorModel = new DirectColorModel(
ColorSpace.getInstance(ColorSpace.CS_sRGB),
32,
0x00ff0000, // Red
0x0000ff00, // Green
0x000000ff, // Blue
0xff000000, // Alpha
true, // Alpha Premultiplied
DataBuffer.TYPE_INT
);
WritableRaster raster = colorModel.createCompatibleWritableRaster(SIZE,
SIZE);
return new BufferedImage(colorModel, raster, true, null);
}
private static BufferedImage TYPE_GABR_PRE() {
ColorModel colorModel = new DirectColorModel(
ColorSpace.getInstance(ColorSpace.CS_sRGB),
32,
0x000000ff, // Red
0xff000000, // Green
0x0000ff00, // Blue
0x00ff0000, // Alpha
true, // Alpha Premultiplied
DataBuffer.TYPE_INT
);
WritableRaster raster = colorModel.createCompatibleWritableRaster(SIZE,
SIZE);
return new BufferedImage(colorModel, raster, true, null);
}
private static BufferedImage TYPE_4BYTE_RGBA_PRE() {
ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_sRGB);
int[] nBits = {8, 8, 8, 8};
int[] bOffs = {0, 1, 2, 3};
ColorModel colorModel = new ComponentColorModel(cs, nBits, true, true,
Transparency.TRANSLUCENT,
DataBuffer.TYPE_BYTE);
WritableRaster raster = Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE,
SIZE, SIZE,
SIZE * 4, 4,
bOffs, null);
return new BufferedImage(colorModel, raster, true, null);
}
private static BufferedImage TYPE_4BYTE_ABGR_PRE() {
ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_sRGB);
int[] nBits = {8, 8, 8, 8};
int[] bOffs = {3, 2, 1, 0};
ColorModel colorModel = new ComponentColorModel(cs, nBits, true, true,
Transparency.TRANSLUCENT,
DataBuffer.TYPE_BYTE);
WritableRaster raster = Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE,
SIZE, SIZE,
SIZE * 4, 4,
bOffs, null);
return new BufferedImage(colorModel, raster, true, null);
}
private static BufferedImage TYPE_4BYTE_ARGB_PRE() {
ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_sRGB);
int[] nBits = {8, 8, 8, 8};
int[] bOffs = {1, 2, 3, 0};
ColorModel colorModel = new ComponentColorModel(cs, nBits, true, true,
Transparency.TRANSLUCENT,
DataBuffer.TYPE_BYTE);
WritableRaster raster = Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE,
SIZE, SIZE,
SIZE * 4, 4,
bOffs, null);
return new BufferedImage(colorModel, raster, true, null);
}
private static BufferedImage TYPE_4BYTE_GABR_PRE() {
ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_sRGB);
int[] nBits = {8, 8, 8, 8};
int[] bOffs = {3, 0, 2, 1};
ColorModel colorModel = new ComponentColorModel(cs, nBits, true, false,
Transparency.TRANSLUCENT,
DataBuffer.TYPE_BYTE);
WritableRaster raster = Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE,
SIZE, SIZE,
SIZE * 4, 4,
bOffs, null);
return new BufferedImage(colorModel, raster, true, null);
}
private static BufferedImage TYPE_4INT_ARGB_8bit_PRE() {
ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_sRGB);
int[] nBits = {8, 8, 8, 8};
ColorModel colorModel = new ComponentColorModel(cs, nBits, true, true,
Transparency.TRANSLUCENT,
DataBuffer.TYPE_INT);
WritableRaster raster = colorModel.createCompatibleWritableRaster(SIZE,
SIZE);
return new BufferedImage(colorModel, raster, true, null);
}
private static BufferedImage TYPE_4USHORT_ARGB_8bit_PRE() {
ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_sRGB);
int[] nBits = {8, 8, 8, 8};
ColorModel colorModel = new ComponentColorModel(cs, nBits, true, true,
Transparency.TRANSLUCENT,
DataBuffer.TYPE_USHORT);
WritableRaster raster = colorModel.createCompatibleWritableRaster(SIZE,
SIZE);
return new BufferedImage(colorModel, raster, true, null);
}
private static void fill(BufferedImage image) {
// Graphics2D g = image.createGraphics();
// g.setComposite(AlphaComposite.Src);
for (int a = 0; a < SIZE; ++a) {
for (int c = 0; c < SIZE; ++c) {
Color c1 = new Color(a, c, c, a);
// g.setColor(c1);
//TODO CANNOT USE fillrect, does not work for custom types!
// g.fillRect(c, a, 1, 1);
image.setRGB(c,a , c1.getRGB());
}
}
// g.dispose();
}
}

View file

@ -0,0 +1,74 @@
/*
* Copyright (c) 2006, 2007, 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 6279846
* @summary Verifies that transform between the same ICC color spaces does not
* change pixels
*/
import java.awt.image.*;
import java.awt.color.ColorSpace;
public class RGBColorConvertTest {
public static void main(String [] args) {
BufferedImage src =
new BufferedImage(256,3,BufferedImage.TYPE_INT_RGB);
BufferedImage dst =
new BufferedImage(256,3,BufferedImage.TYPE_INT_RGB);
for (int i = 0; i < 256; i++) {
src.setRGB(i,0,i);
src.setRGB(i,1,i << 8);
src.setRGB(i,2,i << 16);
}
ColorSpace srcColorSpace = src.getColorModel().getColorSpace();
ColorConvertOp op = new ColorConvertOp(srcColorSpace, srcColorSpace,
null);
op.filter(src, dst);
int errCount = 0;
for (int i = 0; i < src.getWidth(); i++) {
for (int j = 0; j < src.getHeight(); j++) {
int scol = src.getRGB(i,j);
int dcol = dst.getRGB(i,j);
if (scol != dcol) {
System.err.println("(" + i + "," + j + ") : " +
Integer.toHexString(scol) + "!=" +
Integer.toHexString(dcol));
errCount++;
}
}
}
if (errCount > 0) {
throw new RuntimeException(errCount + " pixels are changed by " +
"transform between the same ICC color " +
"spaces");
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 177 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

View file

@ -0,0 +1,83 @@
/*
* Copyright Amazon.com Inc. 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.
*/
import java.awt.color.ColorSpace;
import java.awt.image.BufferedImage;
import java.awt.image.ColorConvertOp;
import java.awt.image.SampleModel;
/**
* @test
* @bug 8279216
* @summary behavior checked by this test is not specified, this test just
* defends against accidental changes
*/
public final class SkipSampleModel {
private static int[] TYPES = {
BufferedImage.TYPE_INT_RGB,
BufferedImage.TYPE_INT_ARGB,
BufferedImage.TYPE_INT_ARGB_PRE,
BufferedImage.TYPE_INT_BGR,
BufferedImage.TYPE_3BYTE_BGR,
BufferedImage.TYPE_4BYTE_ABGR,
BufferedImage.TYPE_4BYTE_ABGR_PRE,
BufferedImage.TYPE_USHORT_565_RGB,
BufferedImage.TYPE_USHORT_555_RGB,
BufferedImage.TYPE_BYTE_GRAY,
BufferedImage.TYPE_USHORT_GRAY,
BufferedImage.TYPE_BYTE_BINARY,
BufferedImage.TYPE_BYTE_INDEXED
};
private static final ColorSpace[] CSs = {
ColorSpace.getInstance(ColorSpace.CS_CIEXYZ),
ColorSpace.getInstance(ColorSpace.CS_GRAY),
ColorSpace.getInstance(ColorSpace.CS_LINEAR_RGB),
ColorSpace.getInstance(ColorSpace.CS_PYCC),
ColorSpace.getInstance(ColorSpace.CS_sRGB)
};
public static void main(String[] args) {
for (ColorSpace cs : CSs) {
ColorConvertOp op = new ColorConvertOp(cs, null);
for (int srcType : TYPES) {
for (int dstType : TYPES) {
BufferedImage src = new BufferedImage(1, 1, srcType) {
@Override
public SampleModel getSampleModel() {
throw new AssertionError();
}
};
BufferedImage dst = new BufferedImage(1, 1, dstType) {
@Override
public SampleModel getSampleModel() {
throw new AssertionError();
}
};
op.filter(src, dst);
}
}
}
}
}

View file

@ -0,0 +1,169 @@
/*
* Copyright Amazon.com Inc. 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.
*/
import java.awt.color.ColorSpace;
import java.awt.image.BufferedImage;
import java.awt.image.ColorConvertOp;
import java.util.concurrent.atomic.AtomicInteger;
import static java.awt.image.BufferedImage.TYPE_3BYTE_BGR;
import static java.awt.image.BufferedImage.TYPE_4BYTE_ABGR;
import static java.awt.image.BufferedImage.TYPE_4BYTE_ABGR_PRE;
import static java.awt.image.BufferedImage.TYPE_BYTE_BINARY;
import static java.awt.image.BufferedImage.TYPE_BYTE_GRAY;
import static java.awt.image.BufferedImage.TYPE_BYTE_INDEXED;
import static java.awt.image.BufferedImage.TYPE_INT_ARGB;
import static java.awt.image.BufferedImage.TYPE_INT_ARGB_PRE;
import static java.awt.image.BufferedImage.TYPE_INT_BGR;
import static java.awt.image.BufferedImage.TYPE_INT_RGB;
import static java.awt.image.BufferedImage.TYPE_USHORT_555_RGB;
import static java.awt.image.BufferedImage.TYPE_USHORT_565_RGB;
import static java.awt.image.BufferedImage.TYPE_USHORT_GRAY;
/**
* @test
* @bug 8264666
* @summary No exception or errors should occur in ColorConvertOp.filter().
* @run main/othervm/timeout=600 UnexpectedSourceImageSize
*/
public final class UnexpectedSourceImageSize {
private static final int SIZE = 100;
private static final int[] TYPES = {
TYPE_INT_RGB, TYPE_INT_ARGB, TYPE_INT_ARGB_PRE, TYPE_INT_BGR,
TYPE_3BYTE_BGR, TYPE_4BYTE_ABGR, TYPE_4BYTE_ABGR_PRE,
TYPE_USHORT_565_RGB, TYPE_USHORT_555_RGB, TYPE_BYTE_GRAY,
TYPE_USHORT_GRAY, TYPE_BYTE_BINARY, TYPE_BYTE_INDEXED
};
private static final int[] INTERESTING_POINTS = new int[]{
Integer.MIN_VALUE / SIZE - 1,
-SIZE, -3, -1, 0, 1, 3,
Integer.MAX_VALUE / SIZE + 1,
};
private static final int[] CSs = new int[]{
ColorSpace.CS_sRGB, ColorSpace.CS_LINEAR_RGB, ColorSpace.CS_CIEXYZ,
ColorSpace.CS_PYCC, ColorSpace.CS_GRAY
};
public static void main(String[] args) throws Exception {
Thread[] threads = new Thread[CSs.length];
for (int i = 0; i < threads.length; i++) {
ColorSpace cs = ColorSpace.getInstance(CSs[i]);
threads[i] = new Thread(() -> {
for (final int type : TYPES) {
test(cs, type);
}
});
threads[i].start();
}
for (int i = 0; i < CSs.length; i++) {
threads[i].join();
}
}
/**
* 1. Checks how many times the width/height are requested during filter()
* 2. Repeats step1, but returns some random data for each request
*/
private static void test(ColorSpace cs, int type) {
AtomicInteger srcCountW = new AtomicInteger();
AtomicInteger srcCountH = new AtomicInteger();
AtomicInteger dstCountW = new AtomicInteger();
AtomicInteger dstCountH = new AtomicInteger();
BufferedImage dstBI = new BufferedImage(SIZE, SIZE, type) {
public int getWidth() {
dstCountW.incrementAndGet();
return super.getWidth();
}
public int getHeight() {
dstCountH.incrementAndGet();
return super.getHeight();
}
};
BufferedImage srcBI = new BufferedImage(SIZE, SIZE, type) {
public int getWidth() {
srcCountW.incrementAndGet();
return super.getWidth();
}
public int getHeight() {
srcCountH.incrementAndGet();
return super.getHeight();
}
};
filter(srcBI, cs, dstBI);
if (dstCountW.get() == 0 && dstCountH.get() == 0
&& srcCountW.get() == 0 && srcCountH.get() == 0) {
// getWidth/getHeight are never called
return;
}
for (int brokenH : INTERESTING_POINTS) {
for (int brokenW : INTERESTING_POINTS) {
for (int srcW = 0; srcW <= srcCountW.get(); ++srcW) {
for (int srcH = 0; srcH <= srcCountH.get(); ++srcH) {
srcBI = makeBI(type, brokenH, brokenW, srcW, srcH);
for (int dstW = 0; dstW <= dstCountW.get(); ++dstW) {
for (int dstH = 0; dstH <= dstCountH.get(); ++dstH) {
try {
dstBI = makeBI(type, brokenH, brokenW, dstW, dstH);
filter(srcBI, cs, dstBI);
} catch (Exception | OutOfMemoryError ignore) {
}
}
}
}
}
}
}
}
private static BufferedImage makeBI(int biType, int brokenH, int brokenW,
int breakStepW, int breakStepH) {
return new BufferedImage(SIZE, SIZE, biType) {
private int stepW = 0;
private int stepH = 0;
public int getWidth() {
if (stepW == breakStepW) {
return brokenW;
}
stepW++;
return super.getWidth();
}
public int getHeight() {
if (stepH == breakStepH) {
return brokenH;
}
stepH++;
return super.getHeight();
}
};
}
private static void filter(BufferedImage src, ColorSpace to,
BufferedImage dest) {
ColorConvertOp op = new ColorConvertOp(to, null);
op.filter(src, dest);
}
}

View file

@ -0,0 +1,140 @@
/*
* Copyright Amazon.com Inc. or its affiliates. All Rights Reserved.
* Copyright (c) 2014, 2019, 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.
*/
import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Transparency;
import java.awt.color.ColorSpace;
import java.awt.color.ICC_ColorSpace;
import java.awt.color.ICC_Profile;
import java.awt.image.BufferedImage;
import java.awt.image.ColorConvertOp;
import java.awt.image.ColorModel;
import java.awt.image.ComponentColorModel;
import java.awt.image.DataBuffer;
import java.awt.image.Raster;
import java.awt.image.WritableRaster;
import java.io.File;
import javax.imageio.ImageIO;
import static java.awt.image.BufferedImage.TYPE_3BYTE_BGR;
import static java.awt.image.BufferedImage.TYPE_4BYTE_ABGR;
import static java.awt.image.BufferedImage.TYPE_4BYTE_ABGR_PRE;
import static java.awt.image.BufferedImage.TYPE_BYTE_BINARY;
import static java.awt.image.BufferedImage.TYPE_BYTE_GRAY;
import static java.awt.image.BufferedImage.TYPE_BYTE_INDEXED;
import static java.awt.image.BufferedImage.TYPE_CUSTOM;
import static java.awt.image.BufferedImage.TYPE_INT_ARGB;
import static java.awt.image.BufferedImage.TYPE_INT_ARGB_PRE;
import static java.awt.image.BufferedImage.TYPE_INT_BGR;
import static java.awt.image.BufferedImage.TYPE_INT_RGB;
import static java.awt.image.BufferedImage.TYPE_USHORT_555_RGB;
import static java.awt.image.BufferedImage.TYPE_USHORT_565_RGB;
import static java.awt.image.BufferedImage.TYPE_USHORT_GRAY;
/**
* @test
* @bug 8295430
* @summary Compare the SRGB->SRGB and SRGB->CUSTOM conversions when CUSTOM=SRGB
*/
public final class ValidateNoopFilter {
private static final int[] TYPES = {
TYPE_INT_RGB, TYPE_INT_ARGB, TYPE_INT_ARGB_PRE, TYPE_INT_BGR,
TYPE_3BYTE_BGR, TYPE_4BYTE_ABGR, TYPE_4BYTE_ABGR_PRE,
TYPE_USHORT_565_RGB, TYPE_USHORT_555_RGB, TYPE_BYTE_GRAY,
TYPE_USHORT_GRAY, TYPE_BYTE_BINARY, TYPE_BYTE_INDEXED, TYPE_CUSTOM
};
private static final int W = 511;
private static final int H = 255;
public static void main(String[] args) throws Exception {
byte[] data = ICC_Profile.getInstance(ColorSpace.CS_sRGB).getData();
ColorSpace custom = new ICC_ColorSpace(ICC_Profile.getInstance(data));
ColorSpace srgb = ColorSpace.getInstance(ColorSpace.CS_sRGB);
ColorConvertOp opCustom = new ColorConvertOp(srgb, custom, null);
ColorConvertOp opGold = new ColorConvertOp(srgb, srgb, null);
for (int type : TYPES) {
BufferedImage src = makeBi(type);
BufferedImage dst = makeBi(type);
BufferedImage dstGold = makeBi(type);
fill(src);
opCustom.filter(src, dst);
opGold.filter(src, dstGold);
// validate images
for (int x = 0; x < W; ++x) {
for (int y = 0; y < H; ++y) {
if (dst.getRGB(x, y) != dstGold.getRGB(x, y)) {
ImageIO.write(dst, "png", new File("custom.png"));
ImageIO.write(dstGold, "png", new File("gold.png"));
throw new RuntimeException("Test failed.");
}
}
}
}
}
private static BufferedImage makeBi(int type) {
if (type == TYPE_CUSTOM) {
return makeCustom3BYTE_BGR();
} else {
return new BufferedImage(W, H, type);
}
}
/**
* Returns the custom buffered image, which mostly identical to
* BufferedImage.(w,h,TYPE_3BYTE_BGR), but uses the bigger scanlineStride.
* This means that the raster will have gaps, between the rows.
*/
private static BufferedImage makeCustom3BYTE_BGR() {
ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_sRGB);
int[] nBits = {8, 8, 8};
int[] bOffs = {2, 1, 0};
ColorModel colorModel = new ComponentColorModel(cs, nBits, false, false,
Transparency.OPAQUE,
DataBuffer.TYPE_BYTE);
WritableRaster raster = Raster.createInterleavedRaster(
DataBuffer.TYPE_BYTE, W, H, W * 3 + 2, 3, bOffs, null);
return new BufferedImage(colorModel, raster, true, null);
}
private static void fill(Image image) {
Graphics2D graphics = (Graphics2D) image.getGraphics();
graphics.setComposite(AlphaComposite.Src);
for (int i = 0; i < image.getHeight(null); ++i) {
graphics.setColor(new Color(i, 0, 255 - i));
graphics.fillRect(0, i, image.getWidth(null), 1);
}
graphics.dispose();
}
}

View file

@ -0,0 +1,83 @@
/*
* Copyright (c) 2013, 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 8024511
* @summary Verifies that instances of color profiles are destroyed correctly.
* A crash during profile destruction indicates failure.
*
* @run main DisposalCrashTest
*/
import static java.awt.color.ColorSpace.*;
import java.awt.color.ICC_Profile;
import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.WeakReference;
import java.util.Vector;
public class DisposalCrashTest {
static final ReferenceQueue<ICC_Profile> queue = new ReferenceQueue<>();
static final Vector<Reference<? extends ICC_Profile>> v = new Vector<>();
public static void main(String[] args) {
int[] ids = new int[]{
CS_sRGB, CS_CIEXYZ, CS_GRAY, CS_LINEAR_RGB, CS_PYCC
};
for (int id : ids) {
ICC_Profile p = getCopyOf(id);
}
while (!v.isEmpty()) {
System.gc();
System.out.println(".");
try {
Thread.sleep(500);
} catch (InterruptedException e) {};
final Reference<? extends ICC_Profile> ref = queue.poll();
System.out.println("Got reference: " + ref);
v.remove(ref);
}
System.out.println("Test PASSED.");
}
private static ICC_Profile getCopyOf(int id) {
ICC_Profile std = ICC_Profile.getInstance(id);
byte[] data = std.getData();
ICC_Profile p = ICC_Profile.getInstance(data);
WeakReference<ICC_Profile> ref = new WeakReference<>(p, queue);
v.add(ref);
return p;
}
}

View file

@ -0,0 +1,52 @@
/*
* Copyright (c) 2007, 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 6476665
* @summary Verifies MT safety of reading profiles of the standard color spaces
* @run main MTReadProfileTest
*/
public class MTReadProfileTest {
public final static int THREAD_COUNT = 30;
public static void main(String [] args) throws InterruptedException {
Thread [] threads = new Thread[THREAD_COUNT];
ReadProfileTest [] tests = new ReadProfileTest[THREAD_COUNT];
for (int i = 0; i < THREAD_COUNT; i++) {
tests[i] = new ReadProfileTest();
threads[i] = new Thread(tests[i]);
}
for (int i = 0; i < threads.length; i++) {
threads[i].start();
}
for (int i = 0; i < threads.length; i++) {
threads[i].join();
if (!tests[i].getStatus()) {
throw new RuntimeException("Error in MT reading of the ICC " +
"profiles");
}
}
}
}

View file

@ -0,0 +1,127 @@
/*
* Copyright (c) 2007, 2008, 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 6476665 6523403
* @summary Verifies reading profiles of the standard color spaces
* @run main ReadProfileTest
*/
import java.awt.color.ColorSpace;
import java.awt.color.ICC_Profile;
import java.util.*;
import java.nio.*;
import java.util.Hashtable;
public class ReadProfileTest implements Runnable {
/* Location of the tag sig counter in 4-byte words */
final static int TAG_COUNT_OFFSET = 32;
/* Location of the tag sig table in 4-byte words */
final static int TAG_ELEM_OFFSET = 33;
static byte[][] profiles;
static int [][] tagSigs;
static Hashtable [] tags;
boolean status;
static int [] cspaces = {ColorSpace.CS_sRGB, ColorSpace.CS_PYCC,
ColorSpace.CS_LINEAR_RGB, ColorSpace.CS_CIEXYZ,
ColorSpace.CS_GRAY};
static String [] csNames = {"sRGB", "PYCC", "LINEAR_RGB", "CIEXYZ", "GRAY"};
static void getProfileTags(byte [] data, Hashtable tags) {
ByteBuffer byteBuf = ByteBuffer.wrap(data);
IntBuffer intBuf = byteBuf.asIntBuffer();
int tagCount = intBuf.get(TAG_COUNT_OFFSET);
intBuf.position(TAG_ELEM_OFFSET);
for (int i = 0; i < tagCount; i++) {
int tagSig = intBuf.get();
int tagDataOff = intBuf.get();
int tagSize = intBuf.get();
byte [] tagData = new byte[tagSize];
byteBuf.position(tagDataOff);
byteBuf.get(tagData);
tags.put(tagSig, tagData);
}
}
static {
profiles = new byte[cspaces.length][];
tags = new Hashtable[cspaces.length];
for (int i = 0; i < cspaces.length; i++) {
ICC_Profile pf = ICC_Profile.getInstance(cspaces[i]);
profiles[i] = pf.getData();
tags[i] = new Hashtable();
getProfileTags(profiles[i], tags[i]);
}
}
public ReadProfileTest() {
status = true;
}
public void run() {
for (int i = 0; i < cspaces.length; i++) {
ICC_Profile pf = ICC_Profile.getInstance(cspaces[i]);
byte [] data = pf.getData();
if (!Arrays.equals(data, profiles[i])) {
status = false;
System.err.println("Incorrect result of getData() " + "with " +
csNames[i] + " profile");
throw new RuntimeException("Incorrect result of getData()");
}
Iterator<Integer> iter = tags[i].keySet().iterator();
while(iter.hasNext()) {
int tagSig = iter.next();
byte [] tagData = pf.getData(tagSig);
if (!Arrays.equals(tagData,
(byte[]) tags[i].get(tagSig)))
{
status = false;
System.err.println("Incorrect result of getData(int) with" +
" tag " +
Integer.toHexString(tagSig) +
" of " + csNames[i] + " profile");
throw new RuntimeException("Incorrect result of " +
"getData(int)");
}
}
}
}
public boolean getStatus() {
return status;
}
public static void main(String [] args) {
ReadProfileTest test = new ReadProfileTest();
test.run();
}
}

View file

@ -0,0 +1,155 @@
/*
* Copyright (c) 2007, 2013, 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 6476665 6523403 6733501 7042594 7043064
* @summary Verifies reading and writing profiles and tags of the standard color
* spaces
* @run main ReadWriteProfileTest
*/
import java.awt.color.ColorSpace;
import java.awt.color.ICC_Profile;
import java.util.*;
import java.nio.*;
import java.util.Hashtable;
public class ReadWriteProfileTest implements Runnable {
/* Location of the tag sig counter in 4-byte words */
final static int TAG_COUNT_OFFSET = 32;
/* Location of the tag sig table in 4-byte words */
final static int TAG_ELEM_OFFSET = 33;
static byte[][] profiles;
static int [][] tagSigs;
static Hashtable<Integer,byte[]> [] tags;
static int [] cspaces = {ColorSpace.CS_sRGB, ColorSpace.CS_PYCC,
ColorSpace.CS_LINEAR_RGB, ColorSpace.CS_CIEXYZ,
ColorSpace.CS_GRAY};
static String [] csNames = {"sRGB", "PYCC", "LINEAR_RGB", "CIEXYZ", "GRAY"};
static void getProfileTags(byte [] data, Hashtable tags) {
ByteBuffer byteBuf = ByteBuffer.wrap(data);
IntBuffer intBuf = byteBuf.asIntBuffer();
int tagCount = intBuf.get(TAG_COUNT_OFFSET);
intBuf.position(TAG_ELEM_OFFSET);
for (int i = 0; i < tagCount; i++) {
int tagSig = intBuf.get();
int tagDataOff = intBuf.get();
int tagSize = intBuf.get();
byte [] tagData = new byte[tagSize];
byteBuf.position(tagDataOff);
byteBuf.get(tagData);
tags.put(tagSig, tagData);
}
}
static {
profiles = new byte[cspaces.length][];
tags = new Hashtable[cspaces.length];
for (int i = 0; i < cspaces.length; i++) {
ICC_Profile pf = ICC_Profile.getInstance(cspaces[i]);
profiles[i] = pf.getData();
tags[i] = new Hashtable();
getProfileTags(profiles[i], tags[i]);
}
}
public void run() {
for (int i = 0; i < cspaces.length; i++) {
System.out.println("Profile: " + csNames[i]);
ICC_Profile pf = ICC_Profile.getInstance(cspaces[i]);
byte [] data = pf.getData();
pf = ICC_Profile.getInstance(data);
if (!Arrays.equals(data, profiles[i])) {
System.err.println("Incorrect result of getData() " + "with " +
csNames[i] + " profile");
throw new RuntimeException("Incorrect result of getData()");
}
for (int tagSig : tags[i].keySet()) {
String signature = SigToString(tagSig);
System.out.printf("Tag: %s\n", signature);
System.out.flush();
byte [] tagData = pf.getData(tagSig);
byte [] empty = new byte[tagData.length];
boolean emptyDataRejected = false;
try {
pf.setData(tagSig, empty);
} catch (IllegalArgumentException e) {
emptyDataRejected = true;
}
if (!emptyDataRejected) {
throw new
RuntimeException("Test failed: empty tag data was not rejected.");
}
try {
pf.setData(tagSig, tagData);
} catch (IllegalArgumentException e) {
// let's ignore this exception for Kodak proprietary tags
if (isKodakExtention(signature)) {
System.out.println("Ignore Kodak tag: " + signature);
} else {
throw new RuntimeException("Test failed!", e);
}
}
byte [] tagData1 = pf.getData(tagSig);
if (!Arrays.equals(tagData1, tags[i].get(tagSig)))
{
System.err.println("Incorrect result of getData(int) with" +
" tag " +
SigToString(tagSig) +
" of " + csNames[i] + " profile");
throw new RuntimeException("Incorrect result of " +
"getData(int)");
}
}
}
}
private static boolean isKodakExtention(String signature) {
return signature.matches("K\\d\\d\\d");
}
private static String SigToString(int tagSig ) {
return String.format("%c%c%c%c",
(char)(0xff & (tagSig >> 24)),
(char)(0xff & (tagSig >> 16)),
(char)(0xff & (tagSig >> 8)),
(char)(0xff & (tagSig)));
}
public static void main(String [] args) {
ReadWriteProfileTest test = new ReadWriteProfileTest();
test.run();
}
}

View file

@ -0,0 +1,143 @@
/*
* Copyright (c) 2011, 2025, 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 7042594 8028206
* @summary Test verifies that ICC_Profile.setData() conforms the spec.
*
* @run main SetDataTest
*/
import java.util.ArrayList;
import java.util.List;
import java.awt.color.ICC_Profile;
import static java.awt.color.ICC_ColorSpace.CS_GRAY;
import static java.awt.color.ICC_Profile.icSigGrayTRCTag;
import static java.awt.color.ICC_Profile.icSigRedTRCTag;
import static java.awt.color.ICC_Profile.icSigGreenTRCTag;
public class SetDataTest {
static class TestCase {
static ICC_Profile profile;
static byte[] validTRCdata;
static byte[] invalidTRCData;
static {
ICC_Profile builtInProfile = ICC_Profile.getInstance(CS_GRAY);
profile = ICC_Profile.getInstance(builtInProfile.getData());
validTRCdata = profile.getData(icSigGrayTRCTag);
invalidTRCData = new byte[]{0x42, 0x42, 0x42, 0x42, 1, 3, 4, 6,};
}
String desciption;
int signature;
boolean useValidData;
Throwable err;
boolean isIAEexpected;
public TestCase(String descr, int sig,
boolean useValidData,
boolean isIAEexpected) {
this.desciption = descr;
this.signature = sig;
this.useValidData = useValidData;
this.isIAEexpected = isIAEexpected;
}
public void doTest() {
System.out.println(desciption);
byte[] data = useValidData
? validTRCdata : invalidTRCData;
err = null;
try {
profile.setData(signature, data);
} catch (Throwable e) {
err = e;
System.out.println("Got exception: " +
e.getClass().getName() + ": " +
e.getMessage());
}
if (isIAEexpected) {
if (err == null) {
throw new RuntimeException(
"Test failed: expected exception was not thrown");
}
if (!(err instanceof IllegalArgumentException)) {
throw new RuntimeException(
"Unexpected exception was thrown: " +
err.getMessage(), err);
}
} else {
if (err != null) {
throw new RuntimeException(
"Unexpected exception was thrown: " +
err.getMessage(), err);
}
}
System.out.println("Testcase PASSED");
}
}
public static void main(String[] args) {
List<TestCase> tests = new ArrayList<TestCase>();
TestCase selfupdate = new TestCase(
"Selfupdate: update grayTRC with the same data.",
icSigGrayTRCTag, true, false);
tests.add(selfupdate);
TestCase newValdTag = new TestCase(
"Insert new valid tag",
icSigRedTRCTag,
true, false);
tests.add(newValdTag);
TestCase newInvalidTag = new TestCase(
"Insert new tag with invalid contet",
icSigGreenTRCTag,
false, true);
tests.add(newInvalidTag);
TestCase newUnknowInvalidTag = new TestCase(
"Insert new tag with invalid data and unknown signature",
0x41414141,
false, true);
tests.add(newUnknowInvalidTag);
TestCase newUnknownValidTag = new TestCase(
"Insert new tag with valid data and unknown signatiure",
0x41414141,
true, true);
tests.add(newUnknownValidTag);
for (TestCase t: tests) {
t.doTest();
}
System.out.println("Test passed!.");
}
}

View file

@ -0,0 +1,57 @@
/*
* 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 4238978
* @summary This test verifies that the correct blitting loop is being used.
* The correct output should have a yellow border on the top and
* left sides of a red box. The incorrect output would have only
* a red box -- no yellow border."
*/
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
public class ARGBBgToRGB {
public static void main(String[] argv) {
BufferedImage bi = new BufferedImage(256, 256, BufferedImage.TYPE_INT_ARGB);
Graphics2D big = bi.createGraphics();
big.setColor(Color.red);
big.fillRect(30, 30, 150, 150);
BufferedImage bi2 = new BufferedImage(100, 100, BufferedImage.TYPE_INT_ARGB);
Graphics2D big2 = bi2.createGraphics();
big2.drawImage(bi, 0, 0, Color.yellow, null);
int expectYellowPix = bi2.getRGB(0, 0);
int expectRedPix = bi2.getRGB(50, 50);
if ((expectYellowPix != Color.yellow.getRGB()) ||
(expectRedPix != Color.red.getRGB()))
{
throw new RuntimeException("Unexpected colors " + expectYellowPix + " " + expectRedPix);
}
}
}

View file

@ -0,0 +1,77 @@
/*
* Copyright 2011 Red Hat, Inc. All Rights Reserved.
* Copyright (c) 2011, 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 7049339
@summary Copying images with a non-rectangular clip and a custom composite
fails
@author Denis Lila <dlila@redhat.com>
@run main Bug7049339
*/
import java.awt.Composite;
import java.awt.CompositeContext;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.geom.Ellipse2D;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.awt.image.Raster;
import java.awt.image.WritableRaster;
public class Bug7049339 {
public static void main(String[] argv) {
int x = 100, y = 100;
BufferedImage src = new BufferedImage(x, y, BufferedImage.TYPE_INT_ARGB);
BufferedImage dst = new BufferedImage(x, y, BufferedImage.TYPE_3BYTE_BGR);
Graphics2D dstg2d = dst.createGraphics();
dstg2d.setComposite(new Composite() {
@Override
public CompositeContext createContext(
ColorModel srcColorModel,
ColorModel dstColorModel,
RenderingHints hints)
{
return new CompositeContext() {
@Override
public void compose(Raster src, Raster dstIn,
WritableRaster dstOut)
{
// do nothing
}
@Override
public void dispose() {
}
};
}
});
Shape clip = new Ellipse2D.Double(x/4, y/4, x/2, y/2);
dstg2d.setClip(clip);
// This will throw a RasterFormatException if the bug is present.
dstg2d.drawImage(src, 0, 0, null);
}
}

View file

@ -0,0 +1,122 @@
/*
* Copyright (c) 2016, 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 7116979
* @summary Test verifies whether BufferedImage with primary colors are
* stored properly when we draw into ByteIndexed BufferedImage.
* @run main ConvertToByteIndexedTest
*/
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.util.HashMap;
public class ConvertToByteIndexedTest {
static final int[] SRC_TYPES = new int[] {
BufferedImage.TYPE_INT_RGB,
BufferedImage.TYPE_INT_ARGB,
BufferedImage.TYPE_INT_ARGB_PRE,
BufferedImage.TYPE_INT_BGR,
BufferedImage.TYPE_3BYTE_BGR,
BufferedImage.TYPE_4BYTE_ABGR,
BufferedImage.TYPE_4BYTE_ABGR_PRE,
BufferedImage.TYPE_USHORT_565_RGB,
BufferedImage.TYPE_USHORT_555_RGB,
BufferedImage.TYPE_BYTE_INDEXED};
static final String[] TYPE_NAME = new String[] {
"INT_RGB",
"INT_ARGB",
"INT_ARGB_PRE",
"INT_BGR",
"3BYTE_BGR",
"4BYTE_ABGR",
"4BYTE_ABGR_PRE",
"USHORT_565_RGB",
"USHORT_555_RGB",
"BYTE_INDEXED"};
static final Color[] COLORS = new Color[] {
//Color.WHITE,
Color.BLACK,
Color.RED,
Color.YELLOW,
Color.GREEN,
Color.MAGENTA,
Color.CYAN,
Color.BLUE};
static final HashMap<Integer,String> TYPE_TABLE =
new HashMap<Integer,String>();
static {
for (int i = 0; i < SRC_TYPES.length; i++) {
TYPE_TABLE.put(new Integer(SRC_TYPES[i]), TYPE_NAME[i]);
}
}
static int width = 50;
static int height = 50;
public static void ConvertToByteIndexed(Color color, int srcType) {
// setup source image and graphics for conversion.
BufferedImage srcImage = new BufferedImage(width, height, srcType);
Graphics2D srcG2D = srcImage.createGraphics();
srcG2D.setColor(color);
srcG2D.fillRect(0, 0, width, height);
// setup destination image and graphics for conversion.
int dstType = BufferedImage.TYPE_BYTE_INDEXED;
BufferedImage dstImage = new BufferedImage(width, height, dstType);
Graphics2D dstG2D = (Graphics2D)dstImage.getGraphics();
// draw source image into Byte Indexed destination
dstG2D.drawImage(srcImage, 0, 0, null);
// draw into ARGB image to verify individual pixel value.
BufferedImage argbImage = new BufferedImage(width, height,
BufferedImage.TYPE_INT_ARGB);
Graphics2D argbG2D = (Graphics2D)argbImage.getGraphics();
argbG2D.drawImage(dstImage, 0, 0, null);
for (int i = 0; i < width; i++) {
for (int j = 0; j < height; j++) {
if (color.getRGB() != argbImage.getRGB(i, j)) {
throw new RuntimeException("Conversion from " +
TYPE_TABLE.get(srcType) + " to BYTE_INDEXED is not"
+ " done properly for " + color);
}
}
}
}
public static void main(String args[]) {
for (int srcType : SRC_TYPES) {
for (Color color : COLORS) {
ConvertToByteIndexed(color, srcType);
}
}
}
}

View file

@ -0,0 +1,143 @@
/*
* Copyright (c) 2015, 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.
*/
import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Rectangle;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import java.util.Date;
/*
* @test
* @bug 4189070
* @summary This test prints out the time it takes for a certain amount of
* copyArea calls to be completed. Because the performance measurement is
* relative, this code only provides a benchmark to run with different releases
* to compare the outcomes.
* @library /java/awt/regtesthelpers
* @build PassFailJFrame
* @run main/manual CopyAreaSpeed
*/
public class CopyAreaSpeed {
public static void main(String args[]) throws Exception {
String instructions = """
This test prints out the time it takes for a certain amount
of copyArea calls to be completed. Because the performance
measurement is relative, this code only provides a benchmark
to run with different releases to compare the outcomes.
""";
PassFailJFrame.builder()
.title("Test Instructions")
.instructions(instructions)
.rows(5)
.columns(35)
.testUI(CopyAreaSpeed::initialize)
.build()
.awaitAndCheck();
}
public static JFrame initialize() {
JFrame frame = new JFrame("Copy Area Test");
frame.add(new CopyAreaSpeedTest());
frame.setSize(300, 320);
frame.setVisible(true);
return frame;
}
}
class CopyAreaSpeedTest extends Container implements Runnable {
int top = 0;
public static String result;
public CopyAreaSpeedTest() {
super();
(new Thread(this)).start();
}
public void update(Graphics g) {
paint(g);
}
public void paint(Graphics g) {
synchronized (this) {
Rectangle rct = g.getClipBounds();
g.setColor(Color.white);
g.fillRect(rct.x, rct.y, rct.width, rct.height);
g.setFont(getFont());
g.setColor(Color.black);
Dimension dm = getSize();
for (int y = 0; y <= (dm.height + 10); y += 20) {
if (y > rct.y) {
int z = y / 20 + top;
g.drawString("" + z, 10, y);
}
}
}
}
static long millsec(Date s, Date e) {
long ts = s.getTime();
long te = e.getTime();
return te - ts;
}
public void run() {
int count = 1000;
int loops = count;
Date start;
Date end;
start = new Date();
while (count-- > 0) {
Dimension dm = getSize();
if (dm != null && dm.width != 0 && dm.height != 0) {
synchronized (this) {
top++;
Graphics g = getGraphics();
g.copyArea(0, 20, dm.width, dm.height - 20, 0, -20);
g.setClip(0, dm.height - 20, dm.width, 20);
paint(g);
g.dispose();
}
}
try {
Thread.sleep(1);
} catch (Exception ex) {
ex.printStackTrace();
}
}
end = new Date();
Graphics g = getGraphics();
g.setFont(getFont());
g.setColor(Color.black);
result = "copyArea X " + loops + " = " + millsec(start, end) + " msec";
JOptionPane.showMessageDialog(null, result);
}
}

View file

@ -0,0 +1,103 @@
/*
* 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 4188744
* @summary This test verifies that copyArea performs correctly for negative offset values.
* The correct output shows that the text area is moved to the left and down,
* leaving some garbage on the right and the top.
* The incorrect copy would show the text area garbled and no text is legible.
* @library /java/awt/regtesthelpers
* @build PassFailJFrame
* @run main/manual CopyNegative
*/
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Panel;
public class CopyNegative extends Panel {
private static final String INSTRUCTIONS = """
This test verifies that copyArea performs correctly for negative offset values.
The test draws text in an image, then copies the contents repeatedly.
The correct output shows that the text is moved to the left and down,
leaving some garbage on the top / right and some legible text at the bottom left.
The incorrect copy would show the whole text area garbled and no text is legible.
""";
public static void main(String[] argv) throws Exception {
PassFailJFrame.builder()
.title("CopyNegativeTest")
.instructions(INSTRUCTIONS)
.testUI(CopyNegative::createUI)
.testTimeOut(5)
.rows(10)
.columns(50)
.build()
.awaitAndCheck();
}
Image img;
static final int W = 200, H = 200;
static Frame createUI() {
Frame f = new Frame("CopyNegative");
f.add(new CopyNegative());
f.pack();
return f;
}
public Dimension getPreferredSize() {
return new Dimension(W, H);
}
private void doCopy() {
Graphics g = img.getGraphics();
g.setColor(Color.white);
g.fillRect(0, 0, W, H);
g.setColor(Color.black);
String text = "Some Text To Display, it is long enough to fill the entire display line.";
StringBuffer sb = new StringBuffer(text);
for (int i = 1; i < 50; i++) {
g.drawString(sb.toString(), 5,20 * i - 10);
sb.insert(0, Integer.toString(i));
}
for (int i = 0 ; i < 20 ; i++ ) {
g.copyArea(0, 0, W, H, -3, 3);
}
}
public void paint(Graphics g) {
img = createImage(W, H);
doCopy();
g.drawImage(img, 0, 0, this);
}
}

View file

@ -0,0 +1,73 @@
/*
* 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 4181172
* @summary Confirm that solid white fill is not dithered on an 8-bit indexed surface.
* The test draws two areas filled with white solid color.
* The upper left square is filled in aliasing mode and
* the lower right square is filled in anti-aliasing mode.
*/
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
public class DitheredSolidFill {
public static void main(String args[]) {
BufferedImage bi = new BufferedImage(120, 120, BufferedImage.TYPE_BYTE_INDEXED);
Graphics2D g2D = bi.createGraphics();
g2D.setColor(Color.black);
g2D.fillRect(0, 0, 100, 100);
g2D.setColor(Color.white);
g2D.fillRect(5, 5, 40, 40);
checkPixels(bi, 5, 5, 40, 40);
g2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2D.fillRect(55, 55, 40, 40);
checkPixels(bi, 55, 55, 40, 40);
}
static void checkPixels(BufferedImage bi, int x, int y, int w, int h) {
// pixel can be off white, but must be the same in all cases.
int expectedPix = bi.getRGB(x, y);
for (int x0 = x; x0 < x + w; x0++) {
for (int y0 = y; y0 < y + h; y0++) {
if (bi.getRGB(x0, y0) != expectedPix) {
try {
javax.imageio.ImageIO.write(bi, "png", new java.io.File("failed.png"));
} catch (Exception e) {
}
throw new RuntimeException("Not expected pix : " +
Integer.toHexString(bi.getRGB(x0, y0)) +
" at " + x0 + "," + y0);
}
}
}
}
}

View file

@ -0,0 +1,68 @@
/*
* Copyright (c) 2023, Azul Systems, Inc. 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.
*/
import java.util.concurrent.CountDownLatch;
/**
* @test
* @bug 6995195
* @summary Verify that concurrent classloading of GraphicsPrimitiveMgr
* and Blit doesn't deadlock
* @run main/othervm/timeout=20 GraphicsPrimitiveMgrTest
*/
public class GraphicsPrimitiveMgrTest {
private static volatile CountDownLatch latch;
private static final String C1 = "sun.java2d.loops.GraphicsPrimitiveMgr";
private static final String C2 = "sun.java2d.loops.Blit";
public static void main(final String[] args)
throws ClassNotFoundException, InterruptedException
{
// force loading awt library
Class.forName("java.awt.Toolkit");
latch = new CountDownLatch(2);
Thread t1 = new Thread(() -> loadClass(C1));
Thread t2 = new Thread(() -> loadClass(C2));
t1.start();
t2.start();
t1.join();
t2.join();
}
private static void loadClass(String className) {
System.out.println(Thread.currentThread().getName() + " loading " + className);
try {
latch.countDown();
latch.await();
Class.forName(className);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}

View file

@ -0,0 +1,68 @@
/*
* 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 4236576
@summary tests that a BufferedImage in TYPE_3BYTE_BGR format is correctly
drawn when there is an offset between the Graphics clip bounds
and the clip box of the underlying device context.
@run main OffsetCalculationTest
*/
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.image.BufferedImage;
import java.awt.image.DataBuffer;
public class OffsetCalculationTest {
public static void main(String[] args) {
BufferedImage srcImage = new BufferedImage(500, 500, BufferedImage.TYPE_3BYTE_BGR);
DataBuffer buffer = srcImage.getRaster().getDataBuffer();
for (int i = 2; i < buffer.getSize(); i+=3) {
// setting each pixel to blue via the data buffer elements.
buffer.setElem(i - 2, 0xff);
buffer.setElem(i - 1, 0);
buffer.setElem(i, 0);
}
int w = 200, h = 200;
BufferedImage destImage = new BufferedImage(w, h, BufferedImage.TYPE_3BYTE_BGR);
Graphics2D g = destImage.createGraphics();
Rectangle r = new Rectangle(0, 0, w, h);
g.setClip(r.x - 1, r.y, r.width + 1, r.height);
g.drawImage(srcImage, 0, 0, null);
int bluepix = Color.blue.getRGB();
for (int y = 0; y < w; y++) {
for (int x = 0; x < h; x++) {
if (destImage.getRGB(x, y) != bluepix) {
throw new RuntimeException("Not Blue");
}
}
}
}
}

Some files were not shown because too many files have changed in this diff Show more