1 /*
   2  * Copyright (c) 2012, 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 package j2dbench.tests.cmm;
  41 
  42 import java.awt.AlphaComposite;
  43 import java.awt.Color;
  44 import java.awt.Graphics2D;
  45 import java.awt.Image;
  46 import java.awt.color.ColorSpace;
  47 import java.awt.image.BufferedImage;
  48 import java.awt.image.ColorConvertOp;
  49 import java.awt.image.Raster;
  50 import java.awt.image.WritableRaster;
  51 
  52 import javax.imageio.ImageIO;
  53 
  54 import j2dbench.Group;
  55 import j2dbench.Option;
  56 import j2dbench.Result;
  57 import j2dbench.TestEnvironment;
  58 import j2dbench.tests.iio.IIOTests;
  59 
  60 public class ColorConvertOpTests extends ColorConversionTests {
  61 
  62     private static class ImageContent {
  63         static ImageContent BLANK = new ImageContent("blank", "Blank (opaque black)");
  64         static ImageContent RANDOM = new ImageContent("random", "Random");
  65         static ImageContent VECTOR = new ImageContent("vector", "Vector Art");
  66         static ImageContent PHOTO= new ImageContent("photo", "Photograph");
  67 
  68         public final String name;
  69         public final String descr;
  70 
  71         private ImageContent(String name, String descr) {
  72             this.name = name;
  73             this.descr = descr;
  74         }
  75 
  76         public static ImageContent[] values() {
  77             return new ImageContent[]{BLANK, RANDOM, VECTOR, PHOTO};
  78         }
  79     }
  80 
  81     private static class ImageType {
  82         static ImageType INT_ARGB = new ImageType(BufferedImage.TYPE_INT_ARGB, "INT_ARGB", "TYPE_INT_ARGB");
  83         static ImageType INT_RGB = new ImageType(BufferedImage.TYPE_INT_RGB, "INT_RGB", "TYPE_INT_RGB");
  84         static ImageType INT_BGR = new ImageType(BufferedImage.TYPE_INT_BGR, "INT_BGR", "TYPE_INT_BGR");
  85         static ImageType BYTE_3BYTE_BGR = new ImageType(BufferedImage.TYPE_3BYTE_BGR, "3BYTE_BGR", "TYPE_3BYTE_BGR");
  86         static ImageType BYTE_4BYTE_ABGR = new ImageType(BufferedImage.TYPE_4BYTE_ABGR, "4BYTE_ABGR", "TYPE_4BYTE_ABGR");
  87         static ImageType COMPATIBLE_DST = new ImageType(0, "Compatible", "Compatible destination");
  88 
  89         private ImageType(int type, String abbr, String descr) {
  90             this.type = type;
  91             this.abbrev = abbr;
  92             this.descr = descr;
  93         }
  94 
  95         public final int type;
  96         public final String abbrev;
  97         public final String descr;
  98 
  99         public static ImageType[] values() {
 100             return new ImageType[]{INT_ARGB, INT_RGB, INT_BGR,
 101                     BYTE_3BYTE_BGR, BYTE_4BYTE_ABGR, COMPATIBLE_DST};
 102         }
 103     }
 104 
 105     private static class ListType {
 106         static ListType SRC = new ListType("srcType", "Source Images");
 107         static ListType DST = new ListType("dstType", "Destination Images");
 108 
 109         private ListType(String name, String description) {
 110             this.name = name;
 111             this.description = description;
 112         }
 113         public final String name;
 114         public final String description;
 115     }
 116 
 117     public static Option createImageTypeList(ListType listType) {
 118 
 119         ImageType[] allTypes = ImageType.values();
 120 
 121         int num = allTypes.length;
 122         if (listType == ListType.SRC) {
 123             num -= 1; // exclude compatible destination
 124         }
 125 
 126         ImageType[] t = new ImageType[num];
 127         String[] names = new String[num];
 128         String[] abbrev = new String[num];
 129         String[] descr = new String[num];
 130 
 131         for (int i = 0; i < num; i++) {
 132             t[i] = allTypes[i];
 133             names[i] = t[i].abbrev;
 134             abbrev[i] = t[i].abbrev;
 135             descr[i] = t[i].descr;
 136         }
 137 
 138         Option list = new Option.ObjectList(opOptionsRoot,
 139                 listType.name, listType.description,
 140                 names, t, abbrev, descr, 1);
 141         return list;
 142     }
 143 
 144     protected static Group opConvRoot;
 145 
 146     protected static Group opOptionsRoot;
 147     protected static Option sizeList;
 148     protected static Option contentList;
 149 
 150     protected static Option sourceType;
 151 
 152     protected static Option destinationType;
 153 
 154     public static void init() {
 155         opConvRoot = new Group(colorConvRoot, "ccop", "ColorConvertOp Tests");
 156 
 157         opOptionsRoot = new Group(opConvRoot, "ccopOptions", "Options");
 158 
 159         // size list
 160         int[] sizes = new int[] {1, 20, 250, 1000, 4000};
 161         String[] sizeStrs = new String[] {
 162             "1x1", "20x20", "250x250", "1000x1000", "4000x4000"
 163         };
 164         String[] sizeDescs = new String[] {
 165             "Tiny Images (1x1)",
 166             "Small Images (20x20)",
 167             "Medium Images (250x250)",
 168             "Large Images (1000x1000)",
 169             "Huge Images (4000x4000)",
 170         };
 171         sizeList = new Option.IntList(opOptionsRoot,
 172                                       "size", "Image Size",
 173                                       sizes, sizeStrs, sizeDescs, 0x4);
 174         ((Option.ObjectList) sizeList).setNumRows(5);
 175 
 176         // image content
 177         ImageContent[] c = ImageContent.values();
 178 
 179         String[] contentStrs = new String[c.length];
 180         String[] contentDescs = new String[c.length];
 181 
 182         for (int i = 0; i < c.length; i++) {
 183             contentStrs[i] = c[i].name;
 184             contentDescs[i] = c[i].descr;
 185         };
 186 
 187         contentList = new Option.ObjectList(opOptionsRoot,
 188                                             "content", "Image Content",
 189                                             contentStrs, c,
 190                                             contentStrs, contentDescs,
 191                                             0x8);
 192 
 193         sourceType = createImageTypeList(ListType.SRC);
 194 
 195         destinationType = createImageTypeList(ListType.DST);
 196 
 197         new ConvertImageTest();
 198         new ConvertRasterTest();
 199         new DrawImageTest();
 200     }
 201 
 202     public ColorConvertOpTests(Group parent, String nodeName, String description) {
 203         super(parent, nodeName, description);
 204         addDependencies(opOptionsRoot, true);
 205     }
 206 
 207     public Object initTest(TestEnvironment env, Result res) {
 208         return new Context(env, res);
 209     }
 210 
 211     public void cleanupTest(TestEnvironment env, Object o) {
 212         Context ctx = (Context)o;
 213         ctx.cs = null;
 214         ctx.op_img = null;
 215         ctx.op_rst = null;
 216         ctx.dst = null;
 217         ctx.src = null;
 218         ctx.graphics = null;
 219     }
 220 
 221     private static class Context {
 222         ColorSpace cs;
 223         Graphics2D graphics;
 224         ColorConvertOp op_img;
 225         ColorConvertOp op_rst;
 226 
 227         BufferedImage src;
 228         BufferedImage dst;
 229 
 230         WritableRaster rsrc;
 231         WritableRaster rdst;
 232 
 233         public Context(TestEnvironment env, Result res) {
 234 
 235             graphics = (Graphics2D)env.getGraphics();
 236             cs = getColorSpace(env);
 237 
 238             // TODO: provide rendering hints
 239             op_img = new ColorConvertOp(cs, null);
 240             ColorSpace sRGB = ColorSpace.getInstance(ColorSpace.CS_sRGB);
 241             op_rst = new ColorConvertOp(sRGB, cs, null);
 242 
 243             int size = env.getIntValue(sizeList);
 244 
 245             ImageContent content = (ImageContent)env.getModifier(contentList);
 246             ImageType srcType = (ImageType)env.getModifier(sourceType);
 247 
 248             src = createBufferedImage(size, size, content, srcType.type);
 249             rsrc = src.getRaster();
 250 
 251             ImageType dstType = (ImageType)env.getModifier(destinationType);
 252             if (dstType == ImageType.COMPATIBLE_DST) {
 253                 dst = op_img.createCompatibleDestImage(src, null);
 254             } else {
 255                 dst = createBufferedImage(size, size, content, dstType.type);
 256             }
 257             // raster always has to be comatible
 258             rdst = op_rst.createCompatibleDestRaster(rsrc);
 259         }
 260     }
 261 
 262     private static class ConvertImageTest extends ColorConvertOpTests {
 263         public ConvertImageTest() {
 264             super(opConvRoot, "op_img", "op.filetr(BufferedImage)");
 265         }
 266 
 267         public void runTest(Object octx, int numReps) {
 268             final Context ctx = (Context)octx;
 269             final ColorConvertOp op = ctx.op_img;
 270 
 271             final BufferedImage src = ctx.src;
 272             BufferedImage dst = ctx.dst;
 273             do {
 274                 try {
 275                     dst = op.filter(src, dst);
 276                 } catch (Exception e) {
 277                     e.printStackTrace();
 278                 }
 279             } while (--numReps >= 0);
 280         }
 281     }
 282 
 283     private static class ConvertRasterTest extends ColorConvertOpTests {
 284         public ConvertRasterTest() {
 285             super(opConvRoot, "op_rst", "op.filetr(Raster)");
 286         }
 287 
 288         public void runTest(Object octx, int numReps) {
 289             final Context ctx = (Context)octx;
 290             final ColorConvertOp op = ctx.op_rst;
 291 
 292             final Raster src = ctx.rsrc;
 293             WritableRaster dst = ctx.rdst;
 294             do {
 295                 try {
 296                     dst = op.filter(src, dst);
 297                 } catch (Exception e) {
 298                     e.printStackTrace();
 299                 }
 300             } while (--numReps >= 0);
 301         }
 302     }
 303 
 304     private static class DrawImageTest extends ColorConvertOpTests {
 305         public DrawImageTest() {
 306             super(opConvRoot, "op_draw", "drawImage(ColorConvertOp)");
 307         }
 308 
 309         public void runTest(Object octx, int numReps) {
 310             final Context ctx = (Context)octx;
 311             final ColorConvertOp op = ctx.op_img;
 312 
 313             final Graphics2D g = ctx.graphics;
 314 
 315             final BufferedImage src = ctx.src;
 316 
 317             do {
 318                 g.drawImage(src, op, 0, 0);
 319             } while (--numReps >= 0);
 320         }
 321     }
 322 
 323     /**************************************************************************
 324      ******                    Helper routines
 325      *************************************************************************/
 326     protected static BufferedImage createBufferedImage(int width,
 327                                                        int height,
 328                                                        ImageContent contentType,
 329                                                        int type)
 330     {
 331         BufferedImage image;
 332         image = new BufferedImage(width, height, type);
 333         boolean hasAlpha = image.getColorModel().hasAlpha();
 334         if (contentType == ImageContent.RANDOM) {
 335             for (int y = 0; y < height; y++) {
 336                 for (int x = 0; x < width; x++) {
 337                     int rgb = (int) (Math.random() * 0xffffff);
 338                     if (hasAlpha) {
 339                         rgb |= 0x7f000000;
 340                     }
 341                     image.setRGB(x, y, rgb);
 342                 }
 343             }
 344         }
 345         if (contentType == ImageContent.VECTOR) {
 346             Graphics2D g = image.createGraphics();
 347             if (hasAlpha) {
 348                 // fill background with a translucent color
 349                 g.setComposite(AlphaComposite.getInstance(
 350                                    AlphaComposite.SRC, 0.5f));
 351             }
 352             g.setColor(Color.blue);
 353             g.fillRect(0, 0, width, height);
 354             g.setComposite(AlphaComposite.Src);
 355             g.setColor(Color.yellow);
 356             g.fillOval(2, 2, width-4, height-4);
 357             g.setColor(Color.red);
 358             g.fillOval(4, 4, width-8, height-8);
 359             g.setColor(Color.green);
 360             g.fillRect(8, 8, width-16, height-16);
 361             g.setColor(Color.white);
 362             g.drawLine(0, 0, width, height);
 363             g.drawLine(0, height, width, 0);
 364             g.dispose();
 365         }
 366         if (contentType == ImageContent.PHOTO) {
 367             Image photo = null;
 368             try {
 369                 photo = ImageIO.read(
 370                     IIOTests.class.getResourceAsStream("images/photo.jpg"));
 371             } catch (Exception e) {
 372                 System.err.println("error loading photo");
 373                 e.printStackTrace();
 374             }
 375             Graphics2D g = image.createGraphics();
 376             if (hasAlpha) {
 377                 g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC,
 378                                                           0.5f));
 379             }
 380             g.drawImage(photo, 0, 0, width, height, null);
 381             g.dispose();
 382         }
 383         return image;
 384     }
 385 }