Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/test/jdk/javax/imageio/plugins/tiff/WriteToSequenceAfterAbort.java
41153 views
1
/*
2
* Copyright (c) 2015, 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
import java.awt.Color;
25
import java.awt.Graphics2D;
26
import java.awt.Rectangle;
27
import java.awt.image.BufferedImage;
28
import java.io.File;
29
import java.io.FileNotFoundException;
30
import java.io.FileOutputStream;
31
import java.io.IOException;
32
33
import javax.imageio.ImageIO;
34
import javax.imageio.ImageWriter;
35
import javax.imageio.event.IIOWriteProgressListener;
36
import javax.imageio.stream.ImageOutputStream;
37
38
import static java.awt.image.BufferedImage.TYPE_BYTE_BINARY;
39
import java.awt.image.ColorModel;
40
import java.awt.image.Raster;
41
import java.awt.image.RenderedImage;
42
import java.awt.image.SampleModel;
43
import java.awt.image.WritableRaster;
44
import java.util.Vector;
45
import javax.imageio.IIOImage;
46
import javax.imageio.ImageReader;
47
import javax.imageio.stream.ImageInputStream;
48
49
/**
50
* @test
51
* @bug 8144245
52
* @summary Ensure aborting write works properly for a TIFF sequence.
53
*/
54
public final class WriteToSequenceAfterAbort implements IIOWriteProgressListener {
55
56
private volatile boolean abortFlag = true;
57
private volatile boolean isAbortCalled;
58
private volatile boolean isCompleteCalled;
59
private volatile boolean isProgressCalled;
60
private volatile boolean isStartedCalled;
61
private static final int WIDTH = 100;
62
private static final int HEIGHT = 100;
63
private static final int NUM_TILES_XY = 3;
64
65
private class TiledImage implements RenderedImage {
66
private final BufferedImage tile;
67
private final BufferedImage image;
68
private final int numXTiles, numYTiles;
69
private boolean isImageInitialized = false;
70
71
TiledImage(BufferedImage tile, int numXTiles, int numYTiles) {
72
this.tile = tile;
73
this.numXTiles = numXTiles;
74
this.numYTiles = numYTiles;
75
image = new BufferedImage(getWidth(), getHeight(), tile.getType());
76
}
77
78
@Override
79
public Vector<RenderedImage> getSources() {
80
return null;
81
}
82
83
@Override
84
public Object getProperty(String string) {
85
return java.awt.Image.UndefinedProperty;
86
}
87
88
@Override
89
public String[] getPropertyNames() {
90
return new String[0];
91
}
92
93
@Override
94
public ColorModel getColorModel() {
95
return tile.getColorModel();
96
}
97
98
@Override
99
public SampleModel getSampleModel() {
100
return tile.getSampleModel();
101
}
102
103
@Override
104
public int getWidth() {
105
return numXTiles*tile.getWidth();
106
}
107
108
@Override
109
public int getHeight() {
110
return numYTiles*tile.getHeight();
111
}
112
113
@Override
114
public int getMinX() {
115
return 0;
116
}
117
118
@Override
119
public int getMinY() {
120
return 0;
121
}
122
123
@Override
124
public int getNumXTiles() {
125
return numXTiles;
126
}
127
128
@Override
129
public int getNumYTiles() {
130
return numYTiles;
131
}
132
133
@Override
134
public int getMinTileX() {
135
return 0;
136
}
137
138
@Override
139
public int getMinTileY() {
140
return 0;
141
}
142
143
@Override
144
public int getTileWidth() {
145
return tile.getWidth();
146
}
147
148
@Override
149
public int getTileHeight() {
150
return tile.getHeight();
151
}
152
153
@Override
154
public int getTileGridXOffset() {
155
return 0;
156
}
157
158
@Override
159
public int getTileGridYOffset() {
160
return 0;
161
}
162
163
@Override
164
public Raster getTile(int x, int y) {
165
WritableRaster r = tile.getRaster();
166
return r.createWritableTranslatedChild(x*tile.getWidth(),
167
y*tile.getHeight());
168
}
169
170
@Override
171
public Raster getData() {
172
return getAsBufferedImage().getData();
173
}
174
175
@Override
176
public Raster getData(Rectangle r) {
177
return getAsBufferedImage().getData(r);
178
}
179
180
@Override
181
public WritableRaster copyData(WritableRaster wr) {
182
return getAsBufferedImage().copyData(wr);
183
}
184
185
public BufferedImage getAsBufferedImage() {
186
synchronized (image) {
187
if (!isImageInitialized) {
188
int tx0 = getMinTileX(), ty0 = getMinTileY();
189
int txN = tx0 + getNumXTiles(), tyN = ty0 + getNumYTiles();
190
for (int j = ty0; j < tyN; j++) {
191
for (int i = tx0; i < txN; i++) {
192
image.setData(getTile(i, j));
193
}
194
}
195
}
196
isImageInitialized = true;
197
}
198
return image;
199
}
200
}
201
202
private void test(final ImageWriter writer) throws IOException {
203
String suffix = writer.getOriginatingProvider().getFileSuffixes()[0];
204
205
// Image initialization
206
BufferedImage imageUpperLeft =
207
new BufferedImage(WIDTH, HEIGHT, TYPE_BYTE_BINARY);
208
Graphics2D g = imageUpperLeft.createGraphics();
209
g.setColor(Color.WHITE);
210
g.fillRect(0, 0, WIDTH/2, HEIGHT/2);
211
g.dispose();
212
BufferedImage imageLowerRight =
213
new BufferedImage(WIDTH, HEIGHT, TYPE_BYTE_BINARY);
214
g = imageLowerRight.createGraphics();
215
g.setColor(Color.WHITE);
216
g.fillRect(WIDTH/2, HEIGHT/2, WIDTH/2, HEIGHT/2);
217
g.dispose();
218
TiledImage[] images = new TiledImage[] {
219
new TiledImage(imageUpperLeft, NUM_TILES_XY, NUM_TILES_XY),
220
new TiledImage(imageUpperLeft, NUM_TILES_XY, NUM_TILES_XY),
221
new TiledImage(imageLowerRight, NUM_TILES_XY, NUM_TILES_XY),
222
new TiledImage(imageLowerRight, NUM_TILES_XY, NUM_TILES_XY)
223
};
224
225
// File initialization
226
File file = File.createTempFile("temp", "." + suffix);
227
file.deleteOnExit();
228
FileOutputStream fos = new SkipWriteOnAbortOutputStream(file);
229
ImageOutputStream ios = ImageIO.createImageOutputStream(fos);
230
writer.setOutput(ios);
231
writer.addIIOWriteProgressListener(this);
232
233
writer.prepareWriteSequence(null);
234
boolean[] abortions = new boolean[] {true, false, true, false};
235
for (int i = 0; i < 4; i++) {
236
abortFlag = abortions[i];
237
isAbortCalled = false;
238
isCompleteCalled = false;
239
isProgressCalled = false;
240
isStartedCalled = false;
241
242
TiledImage image = images[i];
243
if (abortFlag) {
244
// This write will be aborted, and file will not be touched
245
writer.writeToSequence(new IIOImage(image, null, null), null);
246
if (!isStartedCalled) {
247
throw new RuntimeException("Started should be called");
248
}
249
if (!isProgressCalled) {
250
throw new RuntimeException("Progress should be called");
251
}
252
if (!isAbortCalled) {
253
throw new RuntimeException("Abort should be called");
254
}
255
if (isCompleteCalled) {
256
throw new RuntimeException("Complete should not be called");
257
}
258
} else {
259
// This write should be completed successfully and the file should
260
// contain correct image data.
261
writer.writeToSequence(new IIOImage(image, null, null), null);
262
if (!isStartedCalled) {
263
throw new RuntimeException("Started should be called");
264
}
265
if (!isProgressCalled) {
266
throw new RuntimeException("Progress should be called");
267
}
268
if (isAbortCalled) {
269
throw new RuntimeException("Abort should not be called");
270
}
271
if (!isCompleteCalled) {
272
throw new RuntimeException("Complete should be called");
273
}
274
}
275
}
276
277
writer.endWriteSequence();
278
writer.dispose();
279
ios.close();
280
281
// Validates content of the file.
282
ImageReader reader = ImageIO.getImageReader(writer);
283
ImageInputStream iis = ImageIO.createImageInputStream(file);
284
reader.setInput(iis);
285
for (int i = 0; i < 2; i++) {
286
System.out.println("Testing image " + i);
287
BufferedImage imageRead = reader.read(i);
288
BufferedImage imageWrite = images[2 * i].getAsBufferedImage();
289
for (int x = 0; x < WIDTH; ++x) {
290
for (int y = 0; y < HEIGHT; ++y) {
291
if (imageRead.getRGB(x, y) != imageWrite.getRGB(x, y)) {
292
throw new RuntimeException("Test failed for image " + i);
293
}
294
}
295
}
296
}
297
}
298
299
public static void main(final String[] args) throws IOException {
300
WriteToSequenceAfterAbort writeAfterAbort = new WriteToSequenceAfterAbort();
301
ImageWriter writer = ImageIO.getImageWritersByFormatName("TIFF").next();
302
writeAfterAbort.test(writer);
303
System.out.println("Test passed.");
304
}
305
306
// Callbacks
307
308
@Override
309
public void imageComplete(ImageWriter source) {
310
isCompleteCalled = true;
311
}
312
313
@Override
314
public void imageProgress(ImageWriter source, float percentageDone) {
315
isProgressCalled = true;
316
if (percentageDone > 50 && abortFlag) {
317
source.abort();
318
}
319
}
320
321
@Override
322
public void imageStarted(ImageWriter source, int imageIndex) {
323
isStartedCalled = true;
324
}
325
326
@Override
327
public void writeAborted(final ImageWriter source) {
328
isAbortCalled = true;
329
}
330
331
@Override
332
public void thumbnailComplete(ImageWriter source) {
333
}
334
335
@Override
336
public void thumbnailProgress(ImageWriter source, float percentageDone) {
337
}
338
339
@Override
340
public void thumbnailStarted(ImageWriter source, int imageIndex,
341
int thumbnailIndex) {
342
}
343
344
/**
345
* We need to skip writes on abort, because content of the file after abort
346
* is undefined.
347
*/
348
private class SkipWriteOnAbortOutputStream extends FileOutputStream {
349
350
SkipWriteOnAbortOutputStream(File file) throws FileNotFoundException {
351
super(file);
352
}
353
354
@Override
355
public void write(int b) throws IOException {
356
if (!abortFlag) {
357
super.write(b);
358
}
359
}
360
361
@Override
362
public void write(byte[] b) throws IOException {
363
if (!abortFlag) {
364
super.write(b);
365
}
366
}
367
368
@Override
369
public void write(byte[] b, int off, int len) throws IOException {
370
if (!abortFlag) {
371
super.write(b, off, len);
372
}
373
}
374
}
375
}
376
377
378