1 /* 2 * Copyright (c) 2002, 2020, Oracle and/or its affiliates. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 8 * - Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 11 * - Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * - Neither the name of Oracle nor the names of its 16 * contributors may be used to endorse or promote products derived 17 * from this software without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 20 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 21 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 23 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 24 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 25 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 26 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 27 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 28 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 29 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 /* 33 * This source code is provided to illustrate the usage of a given feature 34 * or technique and has been deliberately simplified. Additional steps 35 * required for a production-quality application, such as security checks, 36 * input validation and proper error handling, might not be present in 37 * this sample code. 38 */ 39 40 41 package j2dbench.tests; 42 43 import j2dbench.Destinations; 44 import j2dbench.Group; 45 import j2dbench.Modifier; 46 import j2dbench.Option; 47 import j2dbench.TestEnvironment; 48 import java.awt.Graphics; 49 import java.awt.Graphics2D; 50 import java.awt.Color; 51 import java.awt.Image; 52 import java.awt.Canvas; 53 import java.awt.AlphaComposite; 54 import java.awt.Dimension; 55 import java.awt.GraphicsConfiguration; 56 import java.awt.Rectangle; 57 import java.awt.RenderingHints; 58 import java.awt.Window; 59 import java.awt.image.BufferedImage; 60 import java.awt.image.BufferedImageOp; 61 import java.awt.image.ByteLookupTable; 62 import java.awt.image.ConvolveOp; 63 import java.awt.image.DataBuffer; 64 import java.awt.image.IndexColorModel; 65 import java.awt.image.Kernel; 66 import java.awt.image.LookupOp; 67 import java.awt.image.Raster; 68 import java.awt.image.RasterOp; 69 import java.awt.image.RescaleOp; 70 import java.awt.image.ShortLookupTable; 71 import java.awt.image.VolatileImage; 72 import java.awt.image.WritableRaster; 73 import java.awt.Transparency; 74 import java.awt.geom.AffineTransform; 75 import java.awt.image.DataBufferByte; 76 import java.awt.image.DataBufferInt; 77 import java.awt.image.DataBufferShort; 78 import java.util.ArrayList; 79 import javax.swing.JComponent; 80 81 public abstract class ImageTests extends GraphicsTests { 82 public static boolean hasVolatileImage; 83 public static boolean hasTransparentVolatileImage; 84 public static boolean hasShapedWindow; 85 public static boolean hasOpacityWindow; 86 public static boolean hasCompatImage; 87 88 static { 89 try { 90 hasVolatileImage = (VolatileImage.class != null); 91 } catch (NoClassDefFoundError e) { 92 } 93 try { 94 new Canvas().getGraphicsConfiguration(); 95 hasCompatImage = true; 96 } catch (NoSuchMethodError e) { 97 } 98 try { 99 new Canvas().getMousePosition(); 100 hasTransparentVolatileImage = true; 101 } catch (NoSuchMethodError e) { 102 } 103 try { 104 new Window(null).setShape(new Rectangle()); 105 hasShapedWindow = true; 106 } catch (Exception e) { 107 } 108 try { 109 new Window(null).setOpacity(0.5f); 110 hasOpacityWindow = true; 111 } catch (Exception e) { 112 } 113 } 114 115 static Group imageroot; 116 static Group.EnableSet imgsrcroot; 117 static Group.EnableSet bufimgsrcroot; 118 119 static Group imgbenchroot; 120 static Group imgtestroot; 121 static Group imgtestOptRoot; 122 123 static Group imageOpRoot; 124 static Group imageOpOptRoot; 125 static Group imageOpTestRoot; 126 static Group graphicsTestRoot; 127 static Group bufImgOpTestRoot; 128 static Group rasterOpTestRoot; 129 static Option opList; 130 static Option doTouchSrc; 131 static Option interpolation; 132 133 static String[] transNodeNames = { 134 null, "opaque", "bitmask", "translucent", 135 }; 136 137 static String[] transDescriptions = { 138 null, "Opaque", "Bitmask", "Translucent", 139 }; 140 141 public static void init() { 142 imageroot = new Group(graphicsroot, "imaging", 143 "Imaging Benchmarks"); 144 imageroot.setTabbed(); 145 146 imgsrcroot = new Group.EnableSet(imageroot, "src", 147 "Image Rendering Sources"); 148 imgbenchroot = new Group(imageroot, "benchmarks", 149 "Image Rendering Benchmarks"); 150 imgtestOptRoot = new Group(imgbenchroot, "opts", "Options"); 151 152 new OffScreen(); 153 154 if (hasGraphics2D) { 155 if (hasCompatImage) { 156 new CompatImg(Transparency.OPAQUE); 157 new CompatImg(Transparency.BITMASK); 158 new CompatImg(Transparency.TRANSLUCENT); 159 } 160 if (hasVolatileImage) { 161 if (hasTransparentVolatileImage) { 162 new VolatileImg(Transparency.OPAQUE); 163 new VolatileImg(Transparency.BITMASK); 164 new VolatileImg(Transparency.TRANSLUCENT); 165 } else { 166 new VolatileImg(); 167 } 168 } 169 170 bufimgsrcroot = 171 new Group.EnableSet(imgsrcroot, "bufimg", 172 "BufferedImage Rendering Sources"); 173 new BufImg(BufferedImage.TYPE_INT_RGB); 174 new BufImg(BufferedImage.TYPE_INT_ARGB); 175 new BufImg(BufferedImage.TYPE_INT_ARGB_PRE); 176 new BufImg(BufferedImage.TYPE_BYTE_GRAY); 177 new BufImg(BufferedImage.TYPE_3BYTE_BGR); 178 new BufImg(BufferedImage.TYPE_4BYTE_ABGR); 179 new BufImg(BufferedImage.TYPE_4BYTE_ABGR_PRE); 180 new BmByteIndexBufImg(); 181 new BufImg(BufferedImage.TYPE_INT_RGB, true); 182 new BufImg(BufferedImage.TYPE_INT_ARGB, true); 183 new BufImg(BufferedImage.TYPE_INT_ARGB_PRE, true); 184 new BufImg(BufferedImage.TYPE_3BYTE_BGR, true); 185 186 imageOpRoot = new Group(imageroot, "imageops", 187 "Image Op Benchmarks"); 188 imageOpOptRoot = new Group(imageOpRoot, "opts", "Options"); 189 imageOpTestRoot = new Group(imageOpRoot, "tests", "Tests"); 190 graphicsTestRoot = new Group(imageOpTestRoot, "graphics2d", 191 "Graphics2D Tests"); 192 bufImgOpTestRoot = new Group(imageOpTestRoot, "bufimgop", 193 "BufferedImageOp Tests"); 194 rasterOpTestRoot = new Group(imageOpTestRoot, "rasterop", 195 "RasterOp Tests"); 196 197 ArrayList opStrs = new ArrayList(); 198 ArrayList opDescs = new ArrayList(); 199 opStrs.add("convolve3x3zero"); 200 opDescs.add("ConvolveOp (3x3 blur, zero)"); 201 opStrs.add("convolve3x3noop"); 202 opDescs.add("ConvolveOp (3x3 blur, noop)"); 203 opStrs.add("convolve5x5zero"); 204 opDescs.add("ConvolveOp (5x5 edge, zero)"); 205 opStrs.add("convolve5x5noop"); 206 opDescs.add("ConvolveOp (5x5 edge, noop)"); 207 opStrs.add("lookup1byte"); 208 opDescs.add("LookupOp (1 band, byte)"); 209 opStrs.add("lookup1short"); 210 opDescs.add("LookupOp (1 band, short)"); 211 opStrs.add("lookup3byte"); 212 opDescs.add("LookupOp (3 band, byte)"); 213 opStrs.add("lookup3short"); 214 opDescs.add("LookupOp (3 band, short)"); 215 opStrs.add("rescale1band"); 216 opDescs.add("RescaleOp (1 band)"); 217 opStrs.add("rescale3band"); 218 opDescs.add("RescaleOp (3 band)"); 219 String[] opStrArr = new String[opStrs.size()]; 220 opStrArr = (String[])opStrs.toArray(opStrArr); 221 String[] opDescArr = new String[opDescs.size()]; 222 opDescArr = (String[])opDescs.toArray(opDescArr); 223 opList = 224 new Option.ObjectList(imageOpOptRoot, 225 "op", "Operation", 226 opStrArr, opStrArr, 227 opStrArr, opDescArr, 228 0x1); 229 ((Option.ObjectList) opList).setNumRows(4); 230 231 new DrawImageOp(); 232 new BufImgOpFilter(false); 233 new BufImgOpFilter(true); 234 new RasterOpFilter(false); 235 new RasterOpFilter(true); 236 237 String[] interpolationnames = {"Nearest neighbor", "Bilinear", 238 "Bicubic",}; 239 interpolation = 240 new ObjectList(imgtestOptRoot, "interpolation", 241 "Interpolation", 242 interpolationnames, new Object[] { 243 RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR, 244 RenderingHints.VALUE_INTERPOLATION_BILINEAR, 245 RenderingHints.VALUE_INTERPOLATION_BICUBIC, 246 }, interpolationnames, interpolationnames, 1); 247 } 248 249 doTouchSrc = 250 new Option.Toggle(imgtestOptRoot, "touchsrc", 251 "Touch source image before every operation", 252 Option.Toggle.Off); 253 254 imgtestroot = new Group(imgbenchroot, "tests", "Image Rendering Tests"); 255 256 new DrawImage(); 257 new DrawImageBg(); 258 new DrawImageScale("up", 1.5f); 259 new DrawImageScale("down", .75f); 260 new DrawImageScale("split", .5f); 261 new DrawImageTransform(); 262 } 263 264 public static class Context extends GraphicsTests.Context { 265 boolean touchSrc; 266 Image src; 267 AffineTransform tx; 268 } 269 270 public ImageTests(Group parent, String nodeName, String description) { 271 this(parent, nodeName, description, null); 272 } 273 274 public ImageTests(Group parent, String nodeName, String description, 275 Modifier.Filter srcFilter) 276 { 277 super(parent, nodeName, description); 278 addDependency(imgsrcroot, srcFilter); 279 addDependency(doTouchSrc); 280 addDependency(interpolation); 281 } 282 283 public GraphicsTests.Context createContext() { 284 return new ImageTests.Context(); 285 } 286 287 public void initContext(TestEnvironment env, GraphicsTests.Context ctx) { 288 super.initContext(env, ctx); 289 ImageTests.Context ictx = (ImageTests.Context) ctx; 290 291 ictx.src = env.getSrcImage(); 292 ictx.touchSrc = env.isEnabled(doTouchSrc); 293 if (hasGraphics2D) { 294 Graphics2D g2d = (Graphics2D) ctx.graphics; 295 final Object modifier = env.getModifier(interpolation); 296 g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, modifier); 297 } 298 } 299 300 public abstract static class TriStateImageType extends Group { 301 Image theImage; 302 303 public TriStateImageType(Group parent, String nodename, String desc, 304 int transparency) 305 { 306 super(parent, nodename, desc); 307 setHorizontal(); 308 new DrawableImage(this, Transparency.OPAQUE, true); 309 new DrawableImage(this, Transparency.BITMASK, 310 (transparency != Transparency.OPAQUE)); 311 new DrawableImage(this, Transparency.TRANSLUCENT, 312 (transparency == Transparency.TRANSLUCENT)); 313 } 314 315 public Image getImage(TestEnvironment env, int w, int h) { 316 if (theImage == null || 317 theImage.getWidth(null) != w || 318 theImage.getHeight(null) != h) 319 { 320 theImage = makeImage(env, w, h); 321 } 322 return theImage; 323 } 324 325 public abstract Image makeImage(TestEnvironment env, int w, int h); 326 } 327 328 public static class OffScreen extends TriStateImageType { 329 public OffScreen() { 330 super(imgsrcroot, "offscr", "Offscreen Image", Transparency.OPAQUE); 331 } 332 333 public Image makeImage(TestEnvironment env, int w, int h) { 334 Canvas c = env.getCanvas(); 335 return c.createImage(w, h); 336 } 337 } 338 339 public static class VolatileImg extends TriStateImageType { 340 private final int transparency; 341 342 public VolatileImg() { 343 this(0); 344 } 345 346 public VolatileImg(int transparency) { 347 super(imgsrcroot, Destinations.VolatileImg.ShortNames[transparency], 348 Destinations.VolatileImg.LongDescriptions[transparency], 349 transparency); 350 this.transparency = transparency; 351 } 352 353 public Image makeImage(TestEnvironment env, int w, int h) { 354 Canvas c = env.getCanvas(); 355 GraphicsConfiguration gc = c.getGraphicsConfiguration(); 356 if (transparency == 0) { 357 return gc.createCompatibleVolatileImage(w, h); 358 } else { 359 return gc.createCompatibleVolatileImage(w, h, transparency); 360 } 361 } 362 } 363 364 public static class CompatImg extends TriStateImageType { 365 int transparency; 366 367 public CompatImg(int transparency) { 368 super(imgsrcroot, 369 Destinations.CompatImg.ShortNames[transparency], 370 Destinations.CompatImg.LongDescriptions[transparency], 371 transparency); 372 this.transparency = transparency; 373 } 374 375 public Image makeImage(TestEnvironment env, int w, int h) { 376 Canvas c = env.getCanvas(); 377 GraphicsConfiguration gc = c.getGraphicsConfiguration(); 378 return gc.createCompatibleImage(w, h, transparency); 379 } 380 } 381 382 public static class BufImg extends TriStateImageType { 383 int type; 384 boolean unmanaged; 385 386 static int[] Transparencies = { 387 Transparency.TRANSLUCENT, // "custom", 388 Transparency.OPAQUE, // "IntXrgb", 389 Transparency.TRANSLUCENT, // "IntArgb", 390 Transparency.TRANSLUCENT, // "IntArgbPre", 391 Transparency.OPAQUE, // "IntXbgr", 392 Transparency.OPAQUE, // "3ByteBgr", 393 Transparency.TRANSLUCENT, // "4ByteAbgr", 394 Transparency.TRANSLUCENT, // "4ByteAbgrPre", 395 Transparency.OPAQUE, // "Short565", 396 Transparency.OPAQUE, // "Short555", 397 Transparency.OPAQUE, // "ByteGray", 398 Transparency.OPAQUE, // "ShortGray", 399 Transparency.OPAQUE, // "ByteBinary", 400 Transparency.OPAQUE, // "ByteIndexed", 401 }; 402 403 public BufImg(int type) { 404 this(type, false); 405 } 406 407 public BufImg(int type, boolean unmanaged) { 408 super(bufimgsrcroot, 409 (unmanaged ? "unmanaged" : "") + 410 Destinations.BufImg.ShortNames[type], 411 (unmanaged ? "Unmanaged " : "") + 412 Destinations.BufImg.Descriptions[type], 413 Transparencies[type]); 414 this.type = type; 415 this.unmanaged = unmanaged; 416 } 417 418 public Image makeImage(TestEnvironment env, int w, int h) { 419 BufferedImage img = new BufferedImage(w, h, type); 420 if (unmanaged) { 421 DataBuffer db = img.getRaster().getDataBuffer(); 422 if (db instanceof DataBufferInt) { 423 ((DataBufferInt)db).getData(); 424 } else if (db instanceof DataBufferShort) { 425 ((DataBufferShort)db).getData(); 426 } else if (db instanceof DataBufferByte) { 427 ((DataBufferByte)db).getData(); 428 } else { 429 try { 430 img.setAccelerationPriority(0.0f); 431 } catch (Throwable e) {} 432 } 433 } 434 return img; 435 } 436 } 437 438 public static class BmByteIndexBufImg extends TriStateImageType { 439 static IndexColorModel icm; 440 441 public BmByteIndexBufImg() { 442 super(bufimgsrcroot, 443 "ByteIndexedBm", 444 "8-bit Transparent Indexed Image", 445 Transparency.BITMASK); 446 } 447 448 public Image makeImage(TestEnvironment env, int w, int h) { 449 if (icm == null) { 450 int[] cmap = new int[256]; 451 // Workaround for transparency rendering bug in earlier VMs 452 // Can only render transparency if first cmap entry is 0x0 453 // This bug is fixed in 1.4.2 (Mantis) 454 int i = 1; 455 for (int r = 0; r < 256; r += 51) { 456 for (int g = 0; g < 256; g += 51) { 457 for (int b = 0; b < 256; b += 51) { 458 cmap[i++] = (0xff<<24)|(r<<16)|(g<<8)|b; 459 } 460 } 461 } 462 463 // Leave the rest of the colormap transparent 464 465 icm = new IndexColorModel(8, 256, cmap, 0, true, 255, 466 DataBuffer.TYPE_BYTE); 467 } 468 return new BufferedImage(w, h, BufferedImage.TYPE_BYTE_INDEXED, 469 icm); 470 } 471 } 472 473 public static class DrawableImage extends Option.Enable { 474 static Color transparentBlack = makeAlphaColor(Color.black, 0); 475 static Color translucentRed = makeAlphaColor(Color.red, 192); 476 static Color translucentGreen = makeAlphaColor(Color.green, 128); 477 static Color translucentYellow = makeAlphaColor(Color.yellow, 64); 478 479 static Color[][] colorsets = new Color[][] { 480 null, 481 { 482 Color.blue, Color.red, 483 Color.green, Color.yellow, 484 Color.blue, 485 }, 486 { 487 transparentBlack, Color.red, 488 Color.green, transparentBlack, 489 transparentBlack, 490 }, 491 { 492 Color.blue, translucentRed, 493 translucentGreen, translucentYellow, 494 translucentRed, 495 }, 496 }; 497 498 TriStateImageType tsit; 499 int transparency; 500 boolean possible; 501 502 public DrawableImage(TriStateImageType parent, int transparency, 503 boolean possible) 504 { 505 super(parent, 506 transNodeNames[transparency], 507 transDescriptions[transparency], 508 false); 509 this.tsit = parent; 510 this.transparency = transparency; 511 this.possible = possible; 512 } 513 514 public int getTransparency() { 515 return transparency; 516 } 517 518 public JComponent getJComponent() { 519 JComponent comp = super.getJComponent(); 520 comp.setEnabled(possible); 521 return comp; 522 } 523 524 public String setValueFromString(String value) { 525 if (!possible && !value.equalsIgnoreCase("disabled")) { 526 return "Bad Value"; 527 } 528 return super.setValueFromString(value); 529 } 530 531 public void modifyTest(TestEnvironment env) { 532 int size = env.getIntValue(sizeList); 533 Image src = tsit.getImage(env, size, size); 534 Graphics g = src.getGraphics(); 535 if (hasGraphics2D) { 536 ((Graphics2D) g).setComposite(AlphaComposite.Src); 537 } 538 if (size == 1) { 539 g.setColor(colorsets[transparency][4]); 540 g.fillRect(0, 0, 1, 1); 541 } else { 542 int mid = size/2; 543 g.setColor(colorsets[transparency][0]); 544 g.fillRect(0, 0, mid, mid); 545 g.setColor(colorsets[transparency][1]); 546 g.fillRect(mid, 0, size-mid, mid); 547 g.setColor(colorsets[transparency][2]); 548 g.fillRect(0, mid, mid, size-mid); 549 g.setColor(colorsets[transparency][3]); 550 g.fillRect(mid, mid, size-mid, size-mid); 551 } 552 g.dispose(); 553 env.setSrcImage(src); 554 } 555 556 public void restoreTest(TestEnvironment env) { 557 env.setSrcImage(null); 558 } 559 560 public String getAbbreviatedModifierDescription(Object value) { 561 return "from "+getModifierValueName(value); 562 } 563 564 public String getModifierValueName(Object val) { 565 return getParent().getNodeName()+" "+getNodeName(); 566 } 567 } 568 569 public static class DrawImage extends ImageTests { 570 public DrawImage() { 571 super(imgtestroot, "drawimage", "drawImage(img, x, y, obs);"); 572 } 573 574 public void runTest(Object ctx, int numReps) { 575 ImageTests.Context ictx = (ImageTests.Context) ctx; 576 int x = ictx.initX; 577 int y = ictx.initY; 578 Graphics g = ictx.graphics; 579 g.translate(ictx.orgX, ictx.orgY); 580 Image src = ictx.src; 581 if (ictx.animate) { 582 if (ictx.touchSrc) { 583 Graphics srcG = src.getGraphics(); 584 do { 585 srcG.fillRect(0, 0, 1, 1); 586 g.drawImage(src, x, y, null); 587 if ((x -= 3) < 0) x += ictx.maxX; 588 if ((y -= 1) < 0) y += ictx.maxY; 589 } while (--numReps > 0); 590 } else { 591 do { 592 g.drawImage(src, x, y, null); 593 if ((x -= 3) < 0) x += ictx.maxX; 594 if ((y -= 1) < 0) y += ictx.maxY; 595 } while (--numReps > 0); 596 } 597 } else { 598 if (ictx.touchSrc) { 599 Graphics srcG = src.getGraphics(); 600 do { 601 srcG.fillRect(0, 0, 1, 1); 602 g.drawImage(src, x, y, null); 603 } while (--numReps > 0); 604 } else { 605 do { 606 g.drawImage(src, x, y, null); 607 } while (--numReps > 0); 608 } 609 } 610 g.translate(-ictx.orgX, -ictx.orgY); 611 } 612 } 613 614 public static class DrawImageBg extends ImageTests { 615 public DrawImageBg() { 616 super(imgtestroot, "drawimagebg", "drawImage(img, x, y, bg, obs);", 617 new Modifier.Filter() { 618 public boolean isCompatible(Object val) { 619 DrawableImage di = (DrawableImage) val; 620 return (di.getTransparency() != Transparency.OPAQUE); 621 } 622 }); 623 } 624 625 public void runTest(Object ctx, int numReps) { 626 ImageTests.Context ictx = (ImageTests.Context) ctx; 627 int x = ictx.initX; 628 int y = ictx.initY; 629 Graphics g = ictx.graphics; 630 g.translate(ictx.orgX, ictx.orgY); 631 Image src = ictx.src; 632 Color bg = Color.orange; 633 if (ictx.animate) { 634 if (ictx.touchSrc) { 635 Graphics srcG = src.getGraphics(); 636 do { 637 srcG.fillRect(0, 0, 1, 1); 638 g.drawImage(src, x, y, bg, null); 639 if ((x -= 3) < 0) x += ictx.maxX; 640 if ((y -= 1) < 0) y += ictx.maxY; 641 } while (--numReps > 0); 642 } else { 643 do { 644 g.drawImage(src, x, y, bg, null); 645 if ((x -= 3) < 0) x += ictx.maxX; 646 if ((y -= 1) < 0) y += ictx.maxY; 647 } while (--numReps > 0); 648 } 649 } else { 650 if (ictx.touchSrc) { 651 Graphics srcG = src.getGraphics(); 652 do { 653 srcG.fillRect(0, 0, 1, 1); 654 g.drawImage(src, x, y, bg, null); 655 } while (--numReps > 0); 656 } else { 657 do { 658 g.drawImage(src, x, y, bg, null); 659 } while (--numReps > 0); 660 } 661 } 662 g.translate(-ictx.orgX, -ictx.orgY); 663 } 664 } 665 666 public static class DrawImageScale extends ImageTests { 667 float scale; 668 669 public DrawImageScale(String dir, float scale) { 670 super(imgtestroot, "drawimagescale"+dir, 671 "drawImage(img, x, y, w*"+scale+", h*"+scale+", obs);"); 672 this.scale = scale; 673 } 674 675 public Dimension getOutputSize(int w, int h) { 676 int neww = (int) (w * scale); 677 int newh = (int) (h * scale); 678 if (neww == w && scale > 1f) neww = w+1; 679 if (newh == h && scale > 1f) newh = h+1; 680 return new Dimension(neww, newh); 681 } 682 683 public void runTest(Object ctx, int numReps) { 684 ImageTests.Context ictx = (ImageTests.Context) ctx; 685 int x = ictx.initX; 686 int y = ictx.initY; 687 int w = ictx.outdim.width; 688 int h = ictx.outdim.height; 689 Graphics g = ictx.graphics; 690 g.translate(ictx.orgX, ictx.orgY); 691 Image src = ictx.src; 692 if (ictx.animate) { 693 if (ictx.touchSrc) { 694 Graphics srcG = src.getGraphics(); 695 do { 696 srcG.fillRect(0, 0, 1, 1); 697 g.drawImage(src, x, y, w, h, null); 698 if ((x -= 3) < 0) x += ictx.maxX; 699 if ((y -= 1) < 0) y += ictx.maxY; 700 } while (--numReps > 0); 701 } else { 702 do { 703 g.drawImage(src, x, y, w, h, null); 704 if ((x -= 3) < 0) x += ictx.maxX; 705 if ((y -= 1) < 0) y += ictx.maxY; 706 } while (--numReps > 0); 707 } 708 } else { 709 Graphics srcG = src.getGraphics(); 710 if (ictx.touchSrc) { 711 do { 712 srcG.fillRect(0, 0, 1, 1); 713 g.drawImage(src, x, y, w, h, null); 714 } while (--numReps > 0); 715 } else { 716 do { 717 g.drawImage(src, x, y, w, h, null); 718 } while (--numReps > 0); 719 } 720 } 721 g.translate(-ictx.orgX, -ictx.orgY); 722 } 723 } 724 725 public static class DrawImageTransform extends ImageTests { 726 public DrawImageTransform() { 727 super(imgtestroot, "drawimagetxform", "drawImage(img, tx, obs);"); 728 } 729 730 public Dimension getOutputSize(int w, int h) { 731 int neww = (int) Math.ceil(w * 1.1); 732 int newh = (int) Math.ceil(h * 1.1); 733 return new Dimension(neww, newh); 734 } 735 736 public void initContext(TestEnvironment env, GraphicsTests.Context ctx) 737 { 738 super.initContext(env, ctx); 739 ImageTests.Context ictx = (ImageTests.Context) ctx; 740 741 ictx.tx = new AffineTransform(); 742 } 743 744 public void runTest(Object ctx, int numReps) { 745 ImageTests.Context ictx = (ImageTests.Context) ctx; 746 int x = ictx.initX; 747 int y = ictx.initY; 748 Graphics2D g = (Graphics2D) ictx.graphics; 749 g.translate(ictx.orgX, ictx.orgY); 750 Image src = ictx.src; 751 AffineTransform tx = ictx.tx; 752 if (ictx.animate) { 753 if (ictx.touchSrc) { 754 Graphics srcG = src.getGraphics(); 755 do { 756 tx.setTransform(1.0, 0.1, 0.1, 1.0, x, y); 757 srcG.fillRect(0, 0, 1, 1); 758 g.drawImage(src, tx, null); 759 if ((x -= 3) < 0) x += ictx.maxX; 760 if ((y -= 1) < 0) y += ictx.maxY; 761 } while (--numReps > 0); 762 } else { 763 do { 764 tx.setTransform(1.0, 0.1, 0.1, 1.0, x, y); 765 g.drawImage(src, tx, null); 766 if ((x -= 3) < 0) x += ictx.maxX; 767 if ((y -= 1) < 0) y += ictx.maxY; 768 } while (--numReps > 0); 769 } 770 } else { 771 tx.setTransform(1.0, 0.1, 0.1, 1.0, x, y); 772 if (ictx.touchSrc) { 773 Graphics srcG = src.getGraphics(); 774 do { 775 srcG.fillRect(0, 0, 1, 1); 776 g.drawImage(src, tx, null); 777 } while (--numReps > 0); 778 } else { 779 do { 780 g.drawImage(src, tx, null); 781 } while (--numReps > 0); 782 } 783 } 784 g.translate(-ictx.orgX, -ictx.orgY); 785 } 786 } 787 788 private abstract static class ImageOpTests extends ImageTests { 789 ImageOpTests(Group parent, String nodeName, String desc) { 790 super(parent, nodeName, desc, 791 new Modifier.Filter() { 792 public boolean isCompatible(Object val) { 793 // Filter out all non-BufferedImage sources 794 DrawableImage di = (DrawableImage) val; 795 Group imgtype = di.getParent(); 796 return 797 !(imgtype instanceof VolatileImg) && 798 !(imgtype instanceof OffScreen); 799 } 800 }); 801 addDependencies(imageOpOptRoot, true); 802 } 803 804 private static class Context extends ImageTests.Context { 805 BufferedImageOp bufImgOp; 806 BufferedImage bufSrc; 807 BufferedImage bufDst; 808 809 RasterOp rasterOp; 810 Raster rasSrc; 811 WritableRaster rasDst; 812 } 813 814 public GraphicsTests.Context createContext() { 815 return new ImageOpTests.Context(); 816 } 817 818 public void initContext(TestEnvironment env, 819 GraphicsTests.Context ctx) 820 { 821 super.initContext(env, ctx); 822 ImageOpTests.Context ictx = (ImageOpTests.Context)ctx; 823 824 // Note: We filter out all non-BufferedImage sources in the 825 // ImageOpTests constructor above, so the following is safe... 826 ictx.bufSrc = (BufferedImage)ictx.src; 827 828 String op = (String)env.getModifier(opList); 829 if (op.startsWith("convolve")) { 830 Kernel kernel; 831 if (op.startsWith("convolve3x3")) { 832 // 3x3 blur 833 float[] data = { 834 0.1f, 0.1f, 0.1f, 835 0.1f, 0.2f, 0.1f, 836 0.1f, 0.1f, 0.1f, 837 }; 838 kernel = new Kernel(3, 3, data); 839 } else { // (op.startsWith("convolve5x5")) 840 // 5x5 edge 841 float[] data = { 842 -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 843 -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 844 -1.0f, -1.0f, 24.0f, -1.0f, -1.0f, 845 -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 846 -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 847 }; 848 kernel = new Kernel(5, 5, data); 849 } 850 int edge = op.endsWith("zero") ? 851 ConvolveOp.EDGE_ZERO_FILL : ConvolveOp.EDGE_NO_OP; 852 ictx.bufImgOp = new ConvolveOp(kernel, edge, null); 853 } else if (op.startsWith("lookup")) { 854 if (op.endsWith("byte")) { 855 byte[] invert = new byte[256]; 856 byte[] ordered = new byte[256]; 857 for (int j = 0; j < 256 ; j++) { 858 invert[j] = (byte)(255-j); 859 ordered[j] = (byte)j; 860 } 861 if (op.equals("lookup1byte")) { 862 ictx.bufImgOp = 863 new LookupOp(new ByteLookupTable(0, invert), 864 null); 865 } else { // (op.equals("lookup3byte")) 866 byte[][] yellowInvert = 867 new byte[][] { invert, invert, ordered }; 868 ictx.bufImgOp = 869 new LookupOp(new ByteLookupTable(0, yellowInvert), 870 null); 871 } 872 } else { // (op.endsWith("short")) 873 short[] invert = new short[256]; 874 short[] ordered = new short[256]; 875 for (int j = 0; j < 256 ; j++) { 876 invert[j] = (short)((255-j) * 255); 877 ordered[j] = (short)(j * 255); 878 } 879 if (op.equals("lookup1short")) { 880 ictx.bufImgOp = 881 new LookupOp(new ShortLookupTable(0, invert), 882 null); 883 } else { // (op.equals("lookup3short")) 884 short[][] yellowInvert = 885 new short[][] { invert, invert, ordered }; 886 ictx.bufImgOp = 887 new LookupOp(new ShortLookupTable(0, yellowInvert), 888 null); 889 } 890 } 891 } else if (op.equals("rescale1band")) { 892 ictx.bufImgOp = new RescaleOp(0.5f, 10.0f, null); 893 } else if (op.equals("rescale3band")) { 894 float[] scaleFactors = { 0.5f, 0.3f, 0.8f }; 895 float[] offsets = { 5.0f, -7.5f, 1.0f }; 896 ictx.bufImgOp = new RescaleOp(scaleFactors, offsets, null); 897 } else { 898 throw new InternalError("Invalid image op"); 899 } 900 901 ictx.rasterOp = (RasterOp)ictx.bufImgOp; 902 } 903 } 904 905 private static class DrawImageOp extends ImageOpTests { 906 DrawImageOp() { 907 super(graphicsTestRoot, "drawimageop", 908 "drawImage(srcBufImg, op, x, y);"); 909 } 910 911 public void runTest(Object ctx, int numReps) { 912 ImageOpTests.Context ictx = (ImageOpTests.Context)ctx; 913 int x = ictx.initX; 914 int y = ictx.initY; 915 BufferedImageOp op = ictx.bufImgOp; 916 BufferedImage src = ictx.bufSrc; 917 Graphics2D g2 = (Graphics2D)ictx.graphics; 918 g2.translate(ictx.orgX, ictx.orgY); 919 if (ictx.animate) { 920 if (ictx.touchSrc) { 921 Graphics gSrc = src.getGraphics(); 922 do { 923 gSrc.fillRect(0, 0, 1, 1); 924 g2.drawImage(src, op, x, y); 925 if ((x -= 3) < 0) x += ictx.maxX; 926 if ((y -= 1) < 0) y += ictx.maxY; 927 } while (--numReps > 0); 928 } else { 929 do { 930 g2.drawImage(src, op, x, y); 931 if ((x -= 3) < 0) x += ictx.maxX; 932 if ((y -= 1) < 0) y += ictx.maxY; 933 } while (--numReps > 0); 934 } 935 } else { 936 if (ictx.touchSrc) { 937 Graphics gSrc = src.getGraphics(); 938 do { 939 gSrc.fillRect(0, 0, 1, 1); 940 g2.drawImage(src, op, x, y); 941 } while (--numReps > 0); 942 } else { 943 do { 944 g2.drawImage(src, op, x, y); 945 } while (--numReps > 0); 946 } 947 } 948 g2.translate(-ictx.orgX, -ictx.orgY); 949 } 950 } 951 952 private static class BufImgOpFilter extends ImageOpTests { 953 private boolean cached; 954 955 BufImgOpFilter(boolean cached) { 956 super(bufImgOpTestRoot, 957 "filter" + (cached ? "cached" : "null"), 958 "op.filter(srcBufImg, " + 959 (cached ? "cachedCompatibleDestImg" : "null") + ");"); 960 this.cached = cached; 961 } 962 963 public void initContext(TestEnvironment env, 964 GraphicsTests.Context ctx) 965 { 966 super.initContext(env, ctx); 967 ImageOpTests.Context ictx = (ImageOpTests.Context)ctx; 968 969 if (cached) { 970 ictx.bufDst = 971 ictx.bufImgOp.createCompatibleDestImage(ictx.bufSrc, null); 972 } 973 } 974 975 public void runTest(Object ctx, int numReps) { 976 ImageOpTests.Context ictx = (ImageOpTests.Context)ctx; 977 BufferedImageOp op = ictx.bufImgOp; 978 BufferedImage src = ictx.bufSrc; 979 BufferedImage dst = ictx.bufDst; 980 if (ictx.touchSrc) { 981 Graphics gSrc = src.getGraphics(); 982 do { 983 gSrc.fillRect(0, 0, 1, 1); 984 op.filter(src, dst); 985 } while (--numReps > 0); 986 } else { 987 do { 988 op.filter(src, dst); 989 } while (--numReps > 0); 990 } 991 } 992 } 993 994 private static class RasterOpFilter extends ImageOpTests { 995 private boolean cached; 996 997 RasterOpFilter(boolean cached) { 998 super(rasterOpTestRoot, 999 "filter" + (cached ? "cached" : "null"), 1000 "op.filter(srcRaster, " + 1001 (cached ? "cachedCompatibleDestRaster" : "null") + ");"); 1002 this.cached = cached; 1003 } 1004 1005 public void initContext(TestEnvironment env, 1006 GraphicsTests.Context ctx) 1007 { 1008 super.initContext(env, ctx); 1009 ImageOpTests.Context ictx = (ImageOpTests.Context)ctx; 1010 1011 ictx.rasSrc = ictx.bufSrc.getRaster(); 1012 if (cached) { 1013 ictx.bufDst = 1014 ictx.bufImgOp.createCompatibleDestImage(ictx.bufSrc, null); 1015 ictx.rasDst = ictx.bufDst.getRaster(); 1016 } 1017 } 1018 1019 public void runTest(Object ctx, int numReps) { 1020 ImageOpTests.Context ictx = (ImageOpTests.Context)ctx; 1021 RasterOp op = ictx.rasterOp; 1022 Raster src = ictx.rasSrc; 1023 WritableRaster dst = ictx.rasDst; 1024 if (ictx.touchSrc) { 1025 Graphics gSrc = ictx.bufSrc.getGraphics(); 1026 do { 1027 gSrc.fillRect(0, 0, 1, 1); 1028 op.filter(src, dst); 1029 } while (--numReps > 0); 1030 } else { 1031 do { 1032 op.filter(src, dst); 1033 } while (--numReps > 0); 1034 } 1035 } 1036 } 1037 }