1/*
2 * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23
24/**
25 * @test
26 * @library /test/lib
27 *
28 * @bug     8145776
29 * @author  a.stepanov
30 * @summary A simple write-read test for the multi-page tiff.
31 *          Create the file programmaticaly, then do some simple checks
32 *          (number of pages, sizes, colors). Use -Dseed=X to set
33 *          the random generator seed.
34 *
35 * @build   jdk.test.lib.RandomFactory
36 * @run     main MultiPageTest
37 * @key     randomness
38 */
39
40
41import java.awt.*;
42import java.awt.image.*;
43import java.io.*;
44
45import java.util.*;
46
47import javax.imageio.*;
48import javax.imageio.stream.*;
49
50import jdk.test.lib.RandomFactory;
51
52
53public class MultiPageTest {
54
55    private final String fileName;
56
57    private final int NUM_IMAGES = 51;
58
59    private final static Random rnd = RandomFactory.getRandom();
60
61    private final int w[], h[];
62    private final Color colors[];
63    private final int BLACK_SIZE = 100;
64
65    private final int imageType;
66
67
68    public MultiPageTest(int type, String tName) {
69
70        imageType = type;
71        fileName  = "test__" + tName + ".tif";
72
73        w = new int[NUM_IMAGES + 4];
74        h = new int[NUM_IMAGES + 4];
75
76        for (int i = 2; i < NUM_IMAGES + 2; i++) {
77            w[i] = 10 + rnd.nextInt(21);
78            h[i] = 10 + rnd.nextInt(21);
79        }
80
81        w[0] = BLACK_SIZE;  h[0] = BLACK_SIZE;
82        w[1] = BLACK_SIZE;  h[1] = BLACK_SIZE;
83        w[NUM_IMAGES + 2] = BLACK_SIZE;  h[NUM_IMAGES + 2] = BLACK_SIZE;
84        w[NUM_IMAGES + 3] = BLACK_SIZE;  h[NUM_IMAGES + 3] = BLACK_SIZE;
85
86
87        colors = new Color[NUM_IMAGES + 4];
88        for (int i = 2; i < NUM_IMAGES + 2; ++i) {
89            colors[i] = new Color(
90                rnd.nextInt(256), rnd.nextInt(256), rnd.nextInt(256));
91        }
92
93        colors[0] = Color.black;
94        colors[1] = Color.black;
95        colors[NUM_IMAGES + 2] = Color.black;
96        colors[NUM_IMAGES + 3] = Color.black;
97    }
98
99
100    private ImageWriter getTIFFWriter() {
101
102        Iterator<ImageWriter> writers = ImageIO.getImageWritersByFormatName("TIFF");
103        if (!writers.hasNext()) {
104            throw new RuntimeException("No writers available for " + fileName);
105        }
106        return writers.next();
107    }
108
109    private ImageReader getTIFFReader() {
110
111        Iterator<ImageReader> readers = ImageIO.getImageReadersByFormatName("TIFF");
112        if (!readers.hasNext()) {
113            throw new RuntimeException("No readers available for " + fileName);
114        }
115        return readers.next();
116    }
117
118
119    private void createImage() throws Exception {
120
121        OutputStream s = new BufferedOutputStream(new FileOutputStream(fileName));
122        try (ImageOutputStream ios = ImageIO.createImageOutputStream(s)) {
123
124            ImageWriter writer = getTIFFWriter();
125            writer.setOutput(ios);
126
127            Graphics g;
128
129            BufferedImage blackImg =
130                new BufferedImage(BLACK_SIZE, BLACK_SIZE, imageType);
131            g = blackImg.getGraphics();
132            g.setColor(Color.black);
133            g.fillRect(0, 0, BLACK_SIZE, BLACK_SIZE);
134
135            writer.prepareWriteSequence(null);
136
137            for (int i = 2; i < NUM_IMAGES + 2; i++) {
138                BufferedImage img = new BufferedImage(w[i], h[i], imageType);
139
140                g = img.getGraphics();
141                g.setColor(colors[i]);
142                g.fillRect(0, 0, w[i], h[i]);
143
144                writer.writeToSequence(new IIOImage(img, null, null), null);
145            }
146
147            writer.endWriteSequence();
148
149            // check: insert to the beginning
150            writer.writeInsert(0, new IIOImage(blackImg, null, null), null);
151
152            // check: insert to non-zero position
153            writer.writeInsert(1, new IIOImage(blackImg, null, null), null);
154
155            // check: append to the end by index
156            writer.writeInsert(NUM_IMAGES + 2,
157                new IIOImage(blackImg, null, null), null);
158
159            // check: append to the end using index "-1"
160            writer.writeInsert(-1, new IIOImage(blackImg, null, null), null);
161
162            ios.flush();
163            writer.dispose();
164        }
165        s.close();
166    }
167
168
169
170    private void readAndCheckImage() throws Exception {
171
172        ImageReader reader = getTIFFReader();
173
174        ImageInputStream s = ImageIO.createImageInputStream(new File(fileName));
175        reader.setInput(s);
176
177
178        // check number of pages
179        if ((NUM_IMAGES + 4) != reader.getNumImages(true)) {
180            throw new RuntimeException("invalid number of images!");
181        }
182
183        // check colors / sizes
184        for (int i = 0; i < NUM_IMAGES + 4; i++) {
185
186            BufferedImage img = reader.read(i);
187
188            int imw = w[i], imh = h[i];
189
190            if ( (img.getWidth() != imw) || (img.getHeight() != imh) ) {
191                throw new RuntimeException("NOK: size(" + i + ")");
192            }
193
194            Color
195                    c1 = new Color(img.getRGB(0, 0)),
196                    c2 = new Color(img.getRGB(imw / 2, imh / 2)),
197                    c3 = new Color(img.getRGB(imw - 1, imh - 1));
198            if (! (c1.equals(colors[i]) && c1.equals(c2) && c1.equals(c3) ) ) {
199                throw new RuntimeException("NOK: color(" + i + ")");
200            }
201        }
202
203        reader.dispose();
204        s.close();
205    }
206
207    public void doTest() throws Exception {
208        createImage();
209        readAndCheckImage();
210    }
211
212    public static void main(String[] args) throws Exception {
213
214        int types[] = new int[]{
215            BufferedImage.TYPE_INT_RGB,
216            BufferedImage.TYPE_INT_ARGB,
217            BufferedImage.TYPE_INT_ARGB_PRE,
218            BufferedImage.TYPE_INT_BGR,
219            BufferedImage.TYPE_3BYTE_BGR,
220            BufferedImage.TYPE_4BYTE_ABGR,
221            BufferedImage.TYPE_4BYTE_ABGR_PRE
222        };
223
224        String names[] = new String[]{
225            "TYPE_INT_RGB",
226            "TYPE_INT_ARGB",
227            "TYPE_INT_ARGB_PRE",
228            "TYPE_INT_BGR",
229            "TYPE_3BYTE_BGR",
230            "TYPE_4BYTE_ABGR",
231            "TYPE_4BYTE_ABGR_PRE"
232        };
233
234        for (int i = 0; i < types.length; i++) {
235            System.out.println("image type: " + names[i]);
236            (new MultiPageTest(types[i], names[i])).doTest();
237        }
238    }
239}
240