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
40package j2dbench.tests.cmm;
41
42import java.awt.AlphaComposite;
43import java.awt.Color;
44import java.awt.Graphics2D;
45import java.awt.Image;
46import java.awt.color.ColorSpace;
47import java.awt.image.BufferedImage;
48import java.awt.image.ColorConvertOp;
49import java.awt.image.Raster;
50import java.awt.image.WritableRaster;
51
52import javax.imageio.ImageIO;
53
54import j2dbench.Group;
55import j2dbench.Option;
56import j2dbench.Result;
57import j2dbench.TestEnvironment;
58import j2dbench.tests.iio.IIOTests;
59
60public 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}
386