1 /*
2  * Copyright (c) 2007, 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  * @bug     6557086 6547241
27  * @summary Test verifies that invocation of reset/abort/dispose methods from
28  *          another thread does not cause crash in jpeg library.
29  * @run     main ReadingInterruptionTest
30  */
31 
32 import java.awt.Color;
33 import java.awt.Graphics2D;
34 import java.awt.RadialGradientPaint;
35 import java.awt.geom.Point2D;
36 import java.awt.image.BufferedImage;
37 import java.io.File;
38 import java.io.IOException;
39 import javax.imageio.ImageIO;
40 import javax.imageio.ImageReader;
41 import javax.imageio.ImageReadParam;
42 import javax.imageio.event.IIOReadProgressListener;
43 import javax.imageio.stream.ImageInputStream;
44 
45 
46 public class ReadingInterruptionTest implements IIOReadProgressListener {
47 
main(String[] args)48     public static void main(String[] args) {
49         createTestFile();
50 
51         System.out.println("Test abort()....");
52         ReadingInterruptionTest t = new ReadingInterruptionTest(new AbortAction());
53         t.doTest();
54 
55         System.out.println("Test reset()....");
56         t = new ReadingInterruptionTest(new ResetAction());
57         t.doTest();
58 
59         System.out.println("Test dispose()....");
60         t = new ReadingInterruptionTest(new DisposeAction());
61         t.doTest();
62      }
63 
64     protected abstract static class Action implements Runnable {
65         protected ImageReader target;
66 
setTarget(ImageReader target)67         public void setTarget(ImageReader target) {
68             this.target = target;
69         }
70 
run()71         public abstract void run();
72     }
73 
74     protected static class DisposeAction extends Action {
run()75         public void run() {
76             try {
77                 target.dispose();
78             } catch (IllegalStateException e) {
79                 System.out.println("Test PASSED: IllegalStateException was thrown.");
80             } catch (Throwable e) {
81                 throw new RuntimeException("Test FAILED.", e);
82             }
83         }
84     }
85 
86     protected static class AbortAction extends Action {
run()87         public void run() {
88             try {
89                 target.abort();
90             } catch (IllegalStateException e) {
91                 System.out.println("Test PASSED: IllegalStateException was thrown.");
92             } catch (Throwable e) {
93                 throw new RuntimeException("Test FAILED.", e);
94             }
95         }
96     }
97 
98     protected static class ResetAction extends Action {
run()99         public void run() {
100             try {
101                 target.reset();
102             } catch (IllegalStateException e) {
103                 System.out.println("Test PASSED: IllegalStateException was thrown.");
104             } catch (Throwable e) {
105                 throw new RuntimeException("Test FAILED.", e);
106             }
107         }
108     }
109 
110     static File file = new File("IMGP1001.JPG");
111 
112     Action action;
113     ImageInputStream iis;
114     ImageReader reader;
115 
ReadingInterruptionTest(Action action)116     protected ReadingInterruptionTest(Action action) {
117         this.action = action;
118 
119         reader = ImageIO.getImageReadersByFormatName("JPEG").next();
120 
121         this.action.setTarget(reader);
122     }
123 
doTest()124     public void doTest() {
125         try {
126             reader.addIIOReadProgressListener(this);
127             iis = ImageIO.createImageInputStream(file);
128             reader.setInput(iis);
129             ImageReadParam p = reader.getDefaultReadParam();
130             Thread.sleep(70);
131             BufferedImage res = reader.read(0, p);
132             Thread.sleep(70);
133         } catch (Exception e) {
134             /*
135              * we do expect that concurrent attempt to dispose this
136              * instance of image reader will be blocked. So, this image
137              * should be read sucessfuly. Otherwise, something went wrong
138              * and we need to report test failure.
139              */
140             throw new RuntimeException("Test FAILED", e);
141         } finally {
142             /*
143              * it would happen that concurrent invocation of dispose() method
144              * will be successful. Due to race condition it seems to be possible
145              * that dispose operation will be performed after than read() operation
146              * leaveled thread lock. In this case all subsequent calls for reader
147              * methods should results in IllegalStateException. So, we treat
148              * IllegalStateException as success. Everything else means test failure.
149              */
150             try {
151                 reader.reset();
152             } catch (IllegalStateException e) {
153                 System.out.println("Expected exception was caught: " + e);
154             } catch(Exception e) {
155                 throw new RuntimeException("Test FAILED.", e);
156             }
157         }
158         System.out.println("Test PASSED.");
159     }
160 
161     // listener medthods
imageStarted(ImageReader source, int imageIndex)162     public void imageStarted(ImageReader source,
163                                   int imageIndex) {} ;
164 
imageProgress(ImageReader source, float percentageDone)165     public void imageProgress(ImageReader source,
166                               float percentageDone)
167     {
168         if (20f < percentageDone && percentageDone < 80f) {
169             Thread t = new Thread(action);
170             t.start();
171         }
172     };
173 
imageComplete(ImageReader source)174     public void imageComplete(ImageReader source) {};
175 
176 
sequenceStarted(ImageReader source, int minIndex)177     public void sequenceStarted(ImageReader source,
178                                 int minIndex) {};
179 
sequenceComplete(ImageReader source)180     public void sequenceComplete(ImageReader source) {};
181 
thumbnailStarted(ImageReader source, int imageIndex, int thumbnailIndex)182     public void thumbnailStarted(ImageReader source,
183                                  int imageIndex,
184                                  int thumbnailIndex) {};
185 
thumbnailProgress(ImageReader source, float percentageDone)186     public void thumbnailProgress(ImageReader source,
187                                   float percentageDone) {};
188 
thumbnailComplete(ImageReader source)189     public void thumbnailComplete(ImageReader source) {};
190 
readAborted(ImageReader source)191     public void readAborted(ImageReader source) {};
192 
createTestFile()193     private static void createTestFile() {
194         int w = 1280;
195         int h = 1024;
196 
197         BufferedImage img = new
198             BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
199         Graphics2D g = img.createGraphics();
200         Color[] colors = { Color.red, Color.green, Color.blue };
201         float[] dist = {0.0f, 0.5f, 1.0f };
202         Point2D center = new Point2D.Float(0.5f * w, 0.5f * h);
203 
204         RadialGradientPaint p =
205             new RadialGradientPaint(center, 0.5f * w, dist, colors);
206         g.setPaint(p);
207         g.fillRect(0, 0, w, h);
208         g.dispose();
209 
210         try {
211             System.out.println("Create test image " + file.getAbsolutePath());
212             boolean b = ImageIO.write(img, "JPEG", file);
213             if (!b) {
214                 throw new RuntimeException("Failed to create test image.");
215             }
216         } catch (IOException e) {
217             throw new RuntimeException("Test failed", e);
218         }
219     }
220 }
221