History

My first initial commit with all of mine experimental changes.

Dmitry Kabak (userdima committed 13 years ago

Commit d37b88d1 parent 3f5b46618352 files · +2598093 −-8690Browse files

Showing the changes to java/pkg/javax/imageio/stream/ImageOutputStreamImpl.java (1 of 18352 files). Show all

Unified · Split

java/pkg/javax/imageio/stream/ImageOutputStreamImpl.java+510−0
@@ -0,0 +1,510 @@
1+/*
2+ * Copyright (c) 2000, 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. 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</code> 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</code>.
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)</code> and
485+ * <code>write(byte[], int, int)</code> 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+}