1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package org.htmlunit.platform.image;
16
17 import java.io.IOException;
18 import java.io.InputStream;
19 import java.lang.ref.Cleaner;
20 import java.util.Iterator;
21
22 import javax.imageio.ImageIO;
23 import javax.imageio.ImageReader;
24 import javax.imageio.stream.ImageInputStream;
25
26 import org.htmlunit.WebClient;
27 import org.htmlunit.platform.geom.IntDimension2D;
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48 public class ImageIOImageData implements ImageData {
49
50
51
52 private IntDimension2D dim_;
53
54 private final ImageIOImageDataCleaningAction cleaningAction_;
55 private final Cleaner.Cleanable cleanable_;
56
57 private static final class ImageIOImageDataCleaningAction implements Runnable {
58 private ImageReader imageReader_;
59 private InputStream inputStream_;
60
61 ImageIOImageDataCleaningAction(final ImageReader imageReader, final InputStream inputStream) {
62 imageReader_ = imageReader;
63 inputStream_ = inputStream;
64 }
65
66 synchronized ImageReader getImageReader() {
67 if (imageReader_ == null) {
68 throw new IllegalStateException("ImageIOImageData is closed");
69 }
70 return imageReader_;
71 }
72
73 @Override
74 public synchronized void run() {
75 if (imageReader_ == null) {
76 return;
77 }
78
79 try (ImageInputStream stream = (ImageInputStream) imageReader_.getInput()) {
80
81 }
82 catch (final IOException e) {
83
84 }
85 finally {
86 imageReader_.setInput(null);
87 imageReader_.dispose();
88 imageReader_ = null;
89 }
90
91 try {
92 inputStream_.close();
93 }
94 catch (final IOException e) {
95
96 }
97 finally {
98 inputStream_ = null;
99 }
100 }
101 }
102
103
104
105
106
107
108 public ImageIOImageData(final InputStream inputStream) throws IOException {
109 final ImageInputStream iis = ImageIO.createImageInputStream(inputStream);
110 final Iterator<ImageReader> iter = ImageIO.getImageReaders(iis);
111 if (!iter.hasNext()) {
112 iis.close();
113 inputStream.close();
114 throw new IOException("No image detected in response");
115 }
116
117 final ImageReader imageReader = iter.next();
118 imageReader.setInput(iis);
119
120 cleaningAction_ = new ImageIOImageDataCleaningAction(imageReader, inputStream);
121 cleanable_ = WebClient.registerCleanerAction(this, cleaningAction_);
122
123
124 while (iter.hasNext()) {
125 iter.next().dispose();
126 }
127 }
128
129
130
131
132
133
134 public ImageReader getImageReader() {
135 return cleaningAction_.getImageReader();
136 }
137
138
139
140
141 @Override
142 public IntDimension2D getWidthHeight() throws IOException {
143 if (dim_ == null) {
144 final ImageReader imgReader = cleaningAction_.getImageReader();
145 dim_ = new IntDimension2D(imgReader.getWidth(0), imgReader.getHeight(0));
146 }
147 return dim_;
148 }
149
150
151
152
153 @Override
154 public void close() {
155 cleanable_.clean();
156 }
157 }