Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/java.desktop/share/classes/javax/imageio/stream/ImageOutputStreamImpl.java
41153 views
1
/*
2
* Copyright (c) 2000, 2018, 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. Oracle designates this
8
* particular file as subject to the "Classpath" exception as provided
9
* by Oracle in the LICENSE file that accompanied this code.
10
*
11
* This code is distributed in the hope that it will be useful, but WITHOUT
12
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14
* version 2 for more details (a copy is included in the LICENSE file that
15
* accompanied this code).
16
*
17
* You should have received a copy of the GNU General Public License version
18
* 2 along with this work; if not, write to the Free Software Foundation,
19
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20
*
21
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22
* or visit www.oracle.com if you need additional information or have any
23
* questions.
24
*/
25
26
package javax.imageio.stream;
27
28
import java.io.IOException;
29
import java.io.UTFDataFormatException;
30
import java.nio.ByteOrder;
31
32
/**
33
* An abstract class implementing the {@code ImageOutputStream} interface.
34
* This class is designed to reduce the number of methods that must
35
* be implemented by subclasses.
36
*
37
*/
38
public abstract class ImageOutputStreamImpl
39
extends ImageInputStreamImpl
40
implements ImageOutputStream {
41
42
/**
43
* Constructs an {@code ImageOutputStreamImpl}.
44
*/
45
public ImageOutputStreamImpl() {
46
}
47
48
public abstract void write(int b) throws IOException;
49
50
public void write(byte[] b) throws IOException {
51
write(b, 0, b.length);
52
}
53
54
public abstract void write(byte[] b, int off, int len) throws IOException;
55
56
public void writeBoolean(boolean v) throws IOException {
57
write(v ? 1 : 0);
58
}
59
60
public void writeByte(int v) throws IOException {
61
write(v);
62
}
63
64
public void writeShort(int v) throws IOException {
65
if (byteOrder == ByteOrder.BIG_ENDIAN) {
66
byteBuf[0] = (byte)(v >>> 8);
67
byteBuf[1] = (byte)(v >>> 0);
68
} else {
69
byteBuf[0] = (byte)(v >>> 0);
70
byteBuf[1] = (byte)(v >>> 8);
71
}
72
write(byteBuf, 0, 2);
73
}
74
75
public void writeChar(int v) throws IOException {
76
writeShort(v);
77
}
78
79
public void writeInt(int v) throws IOException {
80
if (byteOrder == ByteOrder.BIG_ENDIAN) {
81
byteBuf[0] = (byte)(v >>> 24);
82
byteBuf[1] = (byte)(v >>> 16);
83
byteBuf[2] = (byte)(v >>> 8);
84
byteBuf[3] = (byte)(v >>> 0);
85
} else {
86
byteBuf[0] = (byte)(v >>> 0);
87
byteBuf[1] = (byte)(v >>> 8);
88
byteBuf[2] = (byte)(v >>> 16);
89
byteBuf[3] = (byte)(v >>> 24);
90
}
91
write(byteBuf, 0, 4);
92
}
93
94
public void writeLong(long v) throws IOException {
95
if (byteOrder == ByteOrder.BIG_ENDIAN) {
96
byteBuf[0] = (byte)(v >>> 56);
97
byteBuf[1] = (byte)(v >>> 48);
98
byteBuf[2] = (byte)(v >>> 40);
99
byteBuf[3] = (byte)(v >>> 32);
100
byteBuf[4] = (byte)(v >>> 24);
101
byteBuf[5] = (byte)(v >>> 16);
102
byteBuf[6] = (byte)(v >>> 8);
103
byteBuf[7] = (byte)(v >>> 0);
104
} else {
105
byteBuf[0] = (byte)(v >>> 0);
106
byteBuf[1] = (byte)(v >>> 8);
107
byteBuf[2] = (byte)(v >>> 16);
108
byteBuf[3] = (byte)(v >>> 24);
109
byteBuf[4] = (byte)(v >>> 32);
110
byteBuf[5] = (byte)(v >>> 40);
111
byteBuf[6] = (byte)(v >>> 48);
112
byteBuf[7] = (byte)(v >>> 56);
113
}
114
// REMIND: Once 6277756 is fixed, we should do a bulk write of all 8
115
// bytes here as we do in writeShort() and writeInt() for even better
116
// performance. For now, two bulk writes of 4 bytes each is still
117
// faster than 8 individual write() calls (see 6347575 for details).
118
write(byteBuf, 0, 4);
119
write(byteBuf, 4, 4);
120
}
121
122
public void writeFloat(float v) throws IOException {
123
writeInt(Float.floatToIntBits(v));
124
}
125
126
public void writeDouble(double v) throws IOException {
127
writeLong(Double.doubleToLongBits(v));
128
}
129
130
public void writeBytes(String s) throws IOException {
131
int len = s.length();
132
for (int i = 0 ; i < len ; i++) {
133
write((byte)s.charAt(i));
134
}
135
}
136
137
public void writeChars(String s) throws IOException {
138
int len = s.length();
139
140
byte[] b = new byte[len*2];
141
int boff = 0;
142
if (byteOrder == ByteOrder.BIG_ENDIAN) {
143
for (int i = 0; i < len ; i++) {
144
int v = s.charAt(i);
145
b[boff++] = (byte)(v >>> 8);
146
b[boff++] = (byte)(v >>> 0);
147
}
148
} else {
149
for (int i = 0; i < len ; i++) {
150
int v = s.charAt(i);
151
b[boff++] = (byte)(v >>> 0);
152
b[boff++] = (byte)(v >>> 8);
153
}
154
}
155
156
write(b, 0, len*2);
157
}
158
159
public void writeUTF(String s) throws IOException {
160
int strlen = s.length();
161
int utflen = 0;
162
char[] charr = new char[strlen];
163
int c, boff = 0;
164
165
s.getChars(0, strlen, charr, 0);
166
167
for (int i = 0; i < strlen; i++) {
168
c = charr[i];
169
if ((c >= 0x0001) && (c <= 0x007F)) {
170
utflen++;
171
} else if (c > 0x07FF) {
172
utflen += 3;
173
} else {
174
utflen += 2;
175
}
176
}
177
178
if (utflen > 65535) {
179
throw new UTFDataFormatException("utflen > 65536!");
180
}
181
182
byte[] b = new byte[utflen+2];
183
b[boff++] = (byte) ((utflen >>> 8) & 0xFF);
184
b[boff++] = (byte) ((utflen >>> 0) & 0xFF);
185
for (int i = 0; i < strlen; i++) {
186
c = charr[i];
187
if ((c >= 0x0001) && (c <= 0x007F)) {
188
b[boff++] = (byte) c;
189
} else if (c > 0x07FF) {
190
b[boff++] = (byte) (0xE0 | ((c >> 12) & 0x0F));
191
b[boff++] = (byte) (0x80 | ((c >> 6) & 0x3F));
192
b[boff++] = (byte) (0x80 | ((c >> 0) & 0x3F));
193
} else {
194
b[boff++] = (byte) (0xC0 | ((c >> 6) & 0x1F));
195
b[boff++] = (byte) (0x80 | ((c >> 0) & 0x3F));
196
}
197
}
198
write(b, 0, utflen + 2);
199
}
200
201
public void writeShorts(short[] s, int off, int len) throws IOException {
202
// Fix 4430357 - if off + len < 0, overflow occurred
203
if (off < 0 || len < 0 || off + len > s.length || off + len < 0) {
204
throw new IndexOutOfBoundsException
205
("off < 0 || len < 0 || off + len > s.length!");
206
}
207
208
byte[] b = new byte[len*2];
209
int boff = 0;
210
if (byteOrder == ByteOrder.BIG_ENDIAN) {
211
for (int i = 0; i < len; i++) {
212
short v = s[off + i];
213
b[boff++] = (byte)(v >>> 8);
214
b[boff++] = (byte)(v >>> 0);
215
}
216
} else {
217
for (int i = 0; i < len; i++) {
218
short v = s[off + i];
219
b[boff++] = (byte)(v >>> 0);
220
b[boff++] = (byte)(v >>> 8);
221
}
222
}
223
224
write(b, 0, len*2);
225
}
226
227
public void writeChars(char[] c, int off, int len) throws IOException {
228
// Fix 4430357 - if off + len < 0, overflow occurred
229
if (off < 0 || len < 0 || off + len > c.length || off + len < 0) {
230
throw new IndexOutOfBoundsException
231
("off < 0 || len < 0 || off + len > c.length!");
232
}
233
234
byte[] b = new byte[len*2];
235
int boff = 0;
236
if (byteOrder == ByteOrder.BIG_ENDIAN) {
237
for (int i = 0; i < len; i++) {
238
char v = c[off + i];
239
b[boff++] = (byte)(v >>> 8);
240
b[boff++] = (byte)(v >>> 0);
241
}
242
} else {
243
for (int i = 0; i < len; i++) {
244
char v = c[off + i];
245
b[boff++] = (byte)(v >>> 0);
246
b[boff++] = (byte)(v >>> 8);
247
}
248
}
249
250
write(b, 0, len*2);
251
}
252
253
public void writeInts(int[] i, int off, int len) throws IOException {
254
// Fix 4430357 - if off + len < 0, overflow occurred
255
if (off < 0 || len < 0 || off + len > i.length || off + len < 0) {
256
throw new IndexOutOfBoundsException
257
("off < 0 || len < 0 || off + len > i.length!");
258
}
259
260
byte[] b = new byte[len*4];
261
int boff = 0;
262
if (byteOrder == ByteOrder.BIG_ENDIAN) {
263
for (int j = 0; j < len; j++) {
264
int v = i[off + j];
265
b[boff++] = (byte)(v >>> 24);
266
b[boff++] = (byte)(v >>> 16);
267
b[boff++] = (byte)(v >>> 8);
268
b[boff++] = (byte)(v >>> 0);
269
}
270
} else {
271
for (int j = 0; j < len; j++) {
272
int v = i[off + j];
273
b[boff++] = (byte)(v >>> 0);
274
b[boff++] = (byte)(v >>> 8);
275
b[boff++] = (byte)(v >>> 16);
276
b[boff++] = (byte)(v >>> 24);
277
}
278
}
279
280
write(b, 0, len*4);
281
}
282
283
public void writeLongs(long[] l, int off, int len) throws IOException {
284
// Fix 4430357 - if off + len < 0, overflow occurred
285
if (off < 0 || len < 0 || off + len > l.length || off + len < 0) {
286
throw new IndexOutOfBoundsException
287
("off < 0 || len < 0 || off + len > l.length!");
288
}
289
290
byte[] b = new byte[len*8];
291
int boff = 0;
292
if (byteOrder == ByteOrder.BIG_ENDIAN) {
293
for (int i = 0; i < len; i++) {
294
long v = l[off + i];
295
b[boff++] = (byte)(v >>> 56);
296
b[boff++] = (byte)(v >>> 48);
297
b[boff++] = (byte)(v >>> 40);
298
b[boff++] = (byte)(v >>> 32);
299
b[boff++] = (byte)(v >>> 24);
300
b[boff++] = (byte)(v >>> 16);
301
b[boff++] = (byte)(v >>> 8);
302
b[boff++] = (byte)(v >>> 0);
303
}
304
} else {
305
for (int i = 0; i < len; i++) {
306
long v = l[off + i];
307
b[boff++] = (byte)(v >>> 0);
308
b[boff++] = (byte)(v >>> 8);
309
b[boff++] = (byte)(v >>> 16);
310
b[boff++] = (byte)(v >>> 24);
311
b[boff++] = (byte)(v >>> 32);
312
b[boff++] = (byte)(v >>> 40);
313
b[boff++] = (byte)(v >>> 48);
314
b[boff++] = (byte)(v >>> 56);
315
}
316
}
317
318
write(b, 0, len*8);
319
}
320
321
public void writeFloats(float[] f, int off, int len) throws IOException {
322
// Fix 4430357 - if off + len < 0, overflow occurred
323
if (off < 0 || len < 0 || off + len > f.length || off + len < 0) {
324
throw new IndexOutOfBoundsException
325
("off < 0 || len < 0 || off + len > f.length!");
326
}
327
328
byte[] b = new byte[len*4];
329
int boff = 0;
330
if (byteOrder == ByteOrder.BIG_ENDIAN) {
331
for (int i = 0; i < len; i++) {
332
int v = Float.floatToIntBits(f[off + i]);
333
b[boff++] = (byte)(v >>> 24);
334
b[boff++] = (byte)(v >>> 16);
335
b[boff++] = (byte)(v >>> 8);
336
b[boff++] = (byte)(v >>> 0);
337
}
338
} else {
339
for (int i = 0; i < len; i++) {
340
int v = Float.floatToIntBits(f[off + i]);
341
b[boff++] = (byte)(v >>> 0);
342
b[boff++] = (byte)(v >>> 8);
343
b[boff++] = (byte)(v >>> 16);
344
b[boff++] = (byte)(v >>> 24);
345
}
346
}
347
348
write(b, 0, len*4);
349
}
350
351
public void writeDoubles(double[] d, int off, int len) throws IOException {
352
// Fix 4430357 - if off + len < 0, overflow occurred
353
if (off < 0 || len < 0 || off + len > d.length || off + len < 0) {
354
throw new IndexOutOfBoundsException
355
("off < 0 || len < 0 || off + len > d.length!");
356
}
357
358
byte[] b = new byte[len*8];
359
int boff = 0;
360
if (byteOrder == ByteOrder.BIG_ENDIAN) {
361
for (int i = 0; i < len; i++) {
362
long v = Double.doubleToLongBits(d[off + i]);
363
b[boff++] = (byte)(v >>> 56);
364
b[boff++] = (byte)(v >>> 48);
365
b[boff++] = (byte)(v >>> 40);
366
b[boff++] = (byte)(v >>> 32);
367
b[boff++] = (byte)(v >>> 24);
368
b[boff++] = (byte)(v >>> 16);
369
b[boff++] = (byte)(v >>> 8);
370
b[boff++] = (byte)(v >>> 0);
371
}
372
} else {
373
for (int i = 0; i < len; i++) {
374
long v = Double.doubleToLongBits(d[off + i]);
375
b[boff++] = (byte)(v >>> 0);
376
b[boff++] = (byte)(v >>> 8);
377
b[boff++] = (byte)(v >>> 16);
378
b[boff++] = (byte)(v >>> 24);
379
b[boff++] = (byte)(v >>> 32);
380
b[boff++] = (byte)(v >>> 40);
381
b[boff++] = (byte)(v >>> 48);
382
b[boff++] = (byte)(v >>> 56);
383
}
384
}
385
386
write(b, 0, len*8);
387
}
388
389
public void writeBit(int bit) throws IOException {
390
writeBits((1L & bit), 1);
391
}
392
393
public void writeBits(long bits, int numBits) throws IOException {
394
checkClosed();
395
396
if (numBits < 0 || numBits > 64) {
397
throw new IllegalArgumentException("Bad value for numBits!");
398
}
399
if (numBits == 0) {
400
return;
401
}
402
403
// Prologue: deal with pre-existing bits
404
405
// Bug 4499158, 4507868 - if we're at the beginning of the stream
406
// and the bit offset is 0, there can't be any pre-existing bits
407
if ((getStreamPosition() > 0) || (bitOffset > 0)) {
408
int offset = bitOffset; // read() will reset bitOffset
409
int partialByte = read();
410
if (partialByte != -1) {
411
seek(getStreamPosition() - 1);
412
} else {
413
partialByte = 0;
414
}
415
416
if (numBits + offset < 8) {
417
// Notch out the partial byte and drop in the new bits
418
int shift = 8 - (offset+numBits);
419
int mask = -1 >>> (32 - numBits);
420
partialByte &= ~(mask << shift); // Clear out old bits
421
partialByte |= ((bits & mask) << shift); // Or in new ones
422
write(partialByte);
423
seek(getStreamPosition() - 1);
424
bitOffset = offset + numBits;
425
numBits = 0; // Signal that we are done
426
} else {
427
// Fill out the partial byte and reduce numBits
428
int num = 8 - offset;
429
int mask = -1 >>> (32 - num);
430
partialByte &= ~mask; // Clear out bits
431
partialByte |= ((bits >> (numBits - num)) & mask);
432
// Note that bitOffset is already 0, so there is no risk
433
// of this advancing to the next byte
434
write(partialByte);
435
numBits -= num;
436
}
437
}
438
439
// Now write any whole bytes
440
if (numBits > 7) {
441
int extra = numBits % 8;
442
for (int numBytes = numBits / 8; numBytes > 0; numBytes--) {
443
int shift = (numBytes-1)*8+extra;
444
int value = (int) ((shift == 0)
445
? bits & 0xFF
446
: (bits>>shift) & 0xFF);
447
write(value);
448
}
449
numBits = extra;
450
}
451
452
// Epilogue: write out remaining partial byte, if any
453
// Note that we may be at EOF, in which case we pad with 0,
454
// or not, in which case we must preserve the existing bits
455
if (numBits != 0) {
456
// If we are not at the end of the file, read the current byte
457
// If we are at the end of the file, initialize our byte to 0.
458
int partialByte = 0;
459
partialByte = read();
460
if (partialByte != -1) {
461
seek(getStreamPosition() - 1);
462
}
463
// Fix 4494976: writeBit(int) does not pad the remainder
464
// of the current byte with 0s
465
else { // EOF
466
partialByte = 0;
467
}
468
469
int shift = 8 - numBits;
470
int mask = -1 >>> (32 - numBits);
471
partialByte &= ~(mask << shift);
472
partialByte |= (bits & mask) << shift;
473
// bitOffset is always already 0 when we get here.
474
write(partialByte);
475
seek(getStreamPosition() - 1);
476
bitOffset = numBits;
477
}
478
}
479
480
/**
481
* If the bit offset is non-zero, forces the remaining bits
482
* in the current byte to 0 and advances the stream position
483
* by one. This method should be called by subclasses at the
484
* beginning of the {@code write(int)} and
485
* {@code write(byte[], int, int)} methods.
486
*
487
* @exception IOException if an I/O error occurs.
488
*/
489
protected final void flushBits() throws IOException {
490
checkClosed();
491
if (bitOffset != 0) {
492
int offset = bitOffset;
493
int partialByte = read(); // Sets bitOffset to 0
494
if (partialByte < 0) {
495
// Fix 4465683: When bitOffset is set
496
// to something non-zero beyond EOF,
497
// we should set that whole byte to
498
// zero and write it to stream.
499
partialByte = 0;
500
bitOffset = 0;
501
}
502
else {
503
seek(getStreamPosition() - 1);
504
partialByte &= -1 << (8 - offset);
505
}
506
write(partialByte);
507
}
508
}
509
510
}
511
512