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