KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > javax > imageio > stream > ImageOutputStreamImpl


1 /*
2  * @(#)ImageOutputStreamImpl.java 1.24 03/12/19
3  *
4  * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
5  * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
6  */

7
8 package javax.imageio.stream;
9
10 import java.io.File JavaDoc;
11 import java.io.IOException JavaDoc;
12 import java.io.UTFDataFormatException JavaDoc;
13 import java.nio.ByteOrder JavaDoc;
14
15 /**
16  * An abstract class implementing the <code>ImageOutputStream</code> interface.
17  * This class is designed to reduce the number of methods that must
18  * be implemented by subclasses.
19  *
20  * @version 0.5
21  */

22 public abstract class ImageOutputStreamImpl
23     extends ImageInputStreamImpl JavaDoc
24     implements ImageOutputStream JavaDoc {
25     
26     /**
27      * Constructs an <code>ImageOutputStreamImpl</code>.
28      */

29     public ImageOutputStreamImpl() {
30     }
31
32     public abstract void write(int b) throws IOException JavaDoc;
33
34     public void write(byte b[]) throws IOException JavaDoc {
35         write(b, 0, b.length);
36     }
37
38     public abstract void write(byte b[], int off, int len) throws IOException JavaDoc;
39
40     public void writeBoolean(boolean v) throws IOException JavaDoc {
41     write(v ? 1 : 0);
42     }
43
44     public void writeByte(int v) throws IOException JavaDoc {
45     write(v);
46     }
47
48     public void writeShort(int v) throws IOException JavaDoc {
49         if (byteOrder == ByteOrder.BIG_ENDIAN) {
50             write((v >>> 8) & 0xFF);
51             write((v >>> 0) & 0xFF);
52         } else {
53             write((v >>> 0) & 0xFF);
54             write((v >>> 8) & 0xFF);
55         }
56     }
57
58     public void writeChar(int v) throws IOException JavaDoc {
59         writeShort(v);
60     }
61
62     public void writeInt(int v) throws IOException JavaDoc {
63         if (byteOrder == ByteOrder.BIG_ENDIAN) {
64             write((v >>> 24) & 0xFF);
65             write((v >>> 16) & 0xFF);
66             write((v >>> 8) & 0xFF);
67             write((v >>> 0) & 0xFF);
68         } else {
69             write((v >>> 0) & 0xFF);
70             write((v >>> 8) & 0xFF);
71             write((v >>> 16) & 0xFF);
72             write((v >>> 24) & 0xFF);
73         }
74     }
75
76     public void writeLong(long v) throws IOException JavaDoc {
77         if (byteOrder == ByteOrder.BIG_ENDIAN) {
78             write((int)(v >>> 56) & 0xFF);
79             write((int)(v >>> 48) & 0xFF);
80             write((int)(v >>> 40) & 0xFF);
81             write((int)(v >>> 32) & 0xFF);
82             write((int)(v >>> 24) & 0xFF);
83             write((int)(v >>> 16) & 0xFF);
84             write((int)(v >>> 8) & 0xFF);
85             write((int)(v >>> 0) & 0xFF);
86         } else {
87             write((int)(v >>> 0) & 0xFF);
88             write((int)(v >>> 8) & 0xFF);
89             write((int)(v >>> 16) & 0xFF);
90             write((int)(v >>> 24) & 0xFF);
91             write((int)(v >>> 32) & 0xFF);
92             write((int)(v >>> 40) & 0xFF);
93             write((int)(v >>> 48) & 0xFF);
94             write((int)(v >>> 56) & 0xFF);
95         }
96     }
97
98     public void writeFloat(float v) throws IOException JavaDoc {
99         writeInt(Float.floatToIntBits(v));
100     }
101
102     public void writeDouble(double v) throws IOException JavaDoc {
103         writeLong(Double.doubleToLongBits(v));
104     }
105
106     public void writeBytes(String JavaDoc s) throws IOException JavaDoc {
107     int len = s.length();
108     for (int i = 0 ; i < len ; i++) {
109         write((byte)s.charAt(i));
110     }
111     }
112
113     public void writeChars(String JavaDoc s) throws IOException JavaDoc {
114     int len = s.length();
115
116         byte[] b = new byte[len*2];
117         int boff = 0;
118         if (byteOrder == ByteOrder.BIG_ENDIAN) {
119             for (int i = 0; i < len ; i++) {
120                 int v = s.charAt(i);
121                 b[boff++] = (byte)(v >>> 8);
122                 b[boff++] = (byte)(v >>> 0);
123             }
124         } else {
125             for (int i = 0; i < len ; i++) {
126                 int v = s.charAt(i);
127                 b[boff++] = (byte)(v >>> 0);
128                 b[boff++] = (byte)(v >>> 8);
129             }
130         }
131
132         write(b, 0, len*2);
133     }
134
135     public void writeUTF(String JavaDoc s) throws IOException JavaDoc {
136     int strlen = s.length();
137     int utflen = 0;
138     char[] charr = new char[strlen];
139     int c, boff = 0;
140
141     s.getChars(0, strlen, charr, 0);
142  
143     for (int i = 0; i < strlen; i++) {
144         c = charr[i];
145         if ((c >= 0x0001) && (c <= 0x007F)) {
146         utflen++;
147         } else if (c > 0x07FF) {
148         utflen += 3;
149         } else {
150         utflen += 2;
151         }
152     }
153
154     if (utflen > 65535) {
155         throw new UTFDataFormatException JavaDoc("utflen > 65536!");
156         }
157
158     byte[] b = new byte[utflen+2];
159     b[boff++] = (byte) ((utflen >>> 8) & 0xFF);
160     b[boff++] = (byte) ((utflen >>> 0) & 0xFF);
161     for (int i = 0; i < strlen; i++) {
162         c = charr[i];
163         if ((c >= 0x0001) && (c <= 0x007F)) {
164         b[boff++] = (byte) c;
165         } else if (c > 0x07FF) {
166         b[boff++] = (byte) (0xE0 | ((c >> 12) & 0x0F));
167         b[boff++] = (byte) (0x80 | ((c >> 6) & 0x3F));
168         b[boff++] = (byte) (0x80 | ((c >> 0) & 0x3F));
169         } else {
170         b[boff++] = (byte) (0xC0 | ((c >> 6) & 0x1F));
171         b[boff++] = (byte) (0x80 | ((c >> 0) & 0x3F));
172         }
173     }
174         write(b, 0, utflen + 2);
175     }
176
177     public void writeShorts(short[] s, int off, int len) throws IOException JavaDoc {
178         // Fix 4430357 - if off + len < 0, overflow occurred
179
if (off < 0 || len < 0 || off + len > s.length || off + len < 0) {
180             throw new IndexOutOfBoundsException JavaDoc
181                 ("off < 0 || len < 0 || off + len > s.length!");
182         }
183
184         byte[] b = new byte[len*2];
185         int boff = 0;
186         if (byteOrder == ByteOrder.BIG_ENDIAN) {
187             for (int i = 0; i < len; i++) {
188                 short v = s[off + i];
189                 b[boff++] = (byte)(v >>> 8);
190                 b[boff++] = (byte)(v >>> 0);
191             }
192         } else {
193             for (int i = 0; i < len; i++) {
194                 short v = s[off + i];
195                 b[boff++] = (byte)(v >>> 0);
196                 b[boff++] = (byte)(v >>> 8);
197             }
198         }
199         
200         write(b, 0, len*2);
201     }
202
203     public void writeChars(char[] c, int off, int len) throws IOException JavaDoc {
204         // Fix 4430357 - if off + len < 0, overflow occurred
205
if (off < 0 || len < 0 || off + len > c.length || off + len < 0) {
206             throw new IndexOutOfBoundsException JavaDoc
207                 ("off < 0 || len < 0 || off + len > c.length!");
208         }
209
210         byte[] b = new byte[len*2];
211         int boff = 0;
212         if (byteOrder == ByteOrder.BIG_ENDIAN) {
213             for (int i = 0; i < len; i++) {
214                 char v = c[off + i];
215                 b[boff++] = (byte)(v >>> 8);
216                 b[boff++] = (byte)(v >>> 0);
217             }
218         } else {
219             for (int i = 0; i < len; i++) {
220                 char v = c[off + i];
221                 b[boff++] = (byte)(v >>> 0);
222                 b[boff++] = (byte)(v >>> 8);
223             }
224         }
225         
226         write(b, 0, len*2);
227     }
228
229     public void writeInts(int[] i, int off, int len) throws IOException JavaDoc {
230         // Fix 4430357 - if off + len < 0, overflow occurred
231
if (off < 0 || len < 0 || off + len > i.length || off + len < 0) {
232             throw new IndexOutOfBoundsException JavaDoc
233                 ("off < 0 || len < 0 || off + len > i.length!");
234         }
235
236         byte[] b = new byte[len*4];
237         int boff = 0;
238         if (byteOrder == ByteOrder.BIG_ENDIAN) {
239             for (int j = 0; j < len; j++) {
240                 int v = i[off + j];
241                 b[boff++] = (byte)(v >>> 24);
242                 b[boff++] = (byte)(v >>> 16);
243                 b[boff++] = (byte)(v >>> 8);
244                 b[boff++] = (byte)(v >>> 0);
245             }
246         } else {
247             for (int j = 0; j < len; j++) {
248                 int v = i[off + j];
249                 b[boff++] = (byte)(v >>> 0);
250                 b[boff++] = (byte)(v >>> 8);
251                 b[boff++] = (byte)(v >>> 16);
252                 b[boff++] = (byte)(v >>> 24);
253             }
254         }
255         
256         write(b, 0, len*4);
257     }
258
259     public void writeLongs(long[] l, int off, int len) throws IOException JavaDoc {
260         // Fix 4430357 - if off + len < 0, overflow occurred
261
if (off < 0 || len < 0 || off + len > l.length || off + len < 0) {
262             throw new IndexOutOfBoundsException JavaDoc
263                 ("off < 0 || len < 0 || off + len > l.length!");
264         }
265
266         byte[] b = new byte[len*8];
267         int boff = 0;
268         if (byteOrder == ByteOrder.BIG_ENDIAN) {
269             for (int i = 0; i < len; i++) {
270                 long v = l[off + i];
271                 b[boff++] = (byte)(v >>> 56);
272                 b[boff++] = (byte)(v >>> 48);
273                 b[boff++] = (byte)(v >>> 40);
274                 b[boff++] = (byte)(v >>> 32);
275                 b[boff++] = (byte)(v >>> 24);
276                 b[boff++] = (byte)(v >>> 16);
277                 b[boff++] = (byte)(v >>> 8);
278                 b[boff++] = (byte)(v >>> 0);
279             }
280         } else {
281             for (int i = 0; i < len; i++) {
282                 long v = l[off + i];
283                 b[boff++] = (byte)(v >>> 0);
284                 b[boff++] = (byte)(v >>> 8);
285                 b[boff++] = (byte)(v >>> 16);
286                 b[boff++] = (byte)(v >>> 24);
287                 b[boff++] = (byte)(v >>> 32);
288                 b[boff++] = (byte)(v >>> 40);
289                 b[boff++] = (byte)(v >>> 48);
290                 b[boff++] = (byte)(v >>> 56);
291             }
292         }
293         
294         write(b, 0, len*8);
295     }
296
297     public void writeFloats(float[] f, int off, int len) throws IOException JavaDoc {
298         // Fix 4430357 - if off + len < 0, overflow occurred
299
if (off < 0 || len < 0 || off + len > f.length || off + len < 0) {
300             throw new IndexOutOfBoundsException JavaDoc
301                 ("off < 0 || len < 0 || off + len > f.length!");
302         }
303
304         byte[] b = new byte[len*4];
305         int boff = 0;
306         if (byteOrder == ByteOrder.BIG_ENDIAN) {
307             for (int i = 0; i < len; i++) {
308                 int v = Float.floatToIntBits(f[off + i]);
309                 b[boff++] = (byte)(v >>> 24);
310                 b[boff++] = (byte)(v >>> 16);
311                 b[boff++] = (byte)(v >>> 8);
312                 b[boff++] = (byte)(v >>> 0);
313             }
314         } else {
315             for (int i = 0; i < len; i++) {
316                 int v = Float.floatToIntBits(f[off + i]);
317                 b[boff++] = (byte)(v >>> 0);
318                 b[boff++] = (byte)(v >>> 8);
319                 b[boff++] = (byte)(v >>> 16);
320                 b[boff++] = (byte)(v >>> 24);
321             }
322         }
323
324         write(b, 0, len*4);
325     }
326
327     public void writeDoubles(double[] d, int off, int len) throws IOException JavaDoc {
328         // Fix 4430357 - if off + len < 0, overflow occurred
329
if (off < 0 || len < 0 || off + len > d.length || off + len < 0) {
330             throw new IndexOutOfBoundsException JavaDoc
331                 ("off < 0 || len < 0 || off + len > d.length!");
332         }
333
334         byte[] b = new byte[len*8];
335         int boff = 0;
336         if (byteOrder == ByteOrder.BIG_ENDIAN) {
337             for (int i = 0; i < len; i++) {
338                 long v = Double.doubleToLongBits(d[off + i]);
339                 b[boff++] = (byte)(v >>> 56);
340                 b[boff++] = (byte)(v >>> 48);
341                 b[boff++] = (byte)(v >>> 40);
342                 b[boff++] = (byte)(v >>> 32);
343                 b[boff++] = (byte)(v >>> 24);
344                 b[boff++] = (byte)(v >>> 16);
345                 b[boff++] = (byte)(v >>> 8);
346                 b[boff++] = (byte)(v >>> 0);
347             }
348         } else {
349             for (int i = 0; i < len; i++) {
350                 long v = Double.doubleToLongBits(d[off + i]);
351                 b[boff++] = (byte)(v >>> 0);
352                 b[boff++] = (byte)(v >>> 8);
353                 b[boff++] = (byte)(v >>> 16);
354                 b[boff++] = (byte)(v >>> 24);
355                 b[boff++] = (byte)(v >>> 32);
356                 b[boff++] = (byte)(v >>> 40);
357                 b[boff++] = (byte)(v >>> 48);
358                 b[boff++] = (byte)(v >>> 56);
359             }
360         }
361         
362         write(b, 0, len*8);
363     }
364
365     public void writeBit(int bit) throws IOException JavaDoc {
366         writeBits((1L & bit), 1);
367     }
368
369     public void writeBits(long bits, int numBits) throws IOException JavaDoc {
370         checkClosed();
371
372         if (numBits < 0 || numBits > 64) {
373             throw new IllegalArgumentException JavaDoc("Bad value for numBits!");
374         }
375         if (numBits == 0) {
376             return;
377         }
378
379         // Prologue: deal with pre-existing bits
380

381         // Bug 4499158, 4507868 - if we're at the beginning of the stream
382
// and the bit offset is 0, there can't be any pre-existing bits
383
if ((getStreamPosition() > 0) || (bitOffset > 0)) {
384             int offset = bitOffset; // read() will reset bitOffset
385
int partialByte = read();
386             if (partialByte != -1) {
387                 seek(getStreamPosition() - 1);
388             } else {
389                 partialByte = 0;
390             }
391             
392             if (numBits + offset < 8) {
393                 // Notch out the partial byte and drop in the new bits
394
int shift = 8 - (offset+numBits);
395                 int mask = -1 >>> (32 - numBits);
396                 partialByte &= ~(mask << shift); // Clear out old bits
397
partialByte |= ((bits & mask) << shift); // Or in new ones
398
write(partialByte);
399                 seek(getStreamPosition() - 1);
400                 bitOffset = offset + numBits;
401                 numBits = 0; // Signal that we are done
402
} else {
403                 // Fill out the partial byte and reduce numBits
404
int num = 8 - offset;
405                 int mask = -1 >>> (32 - num);
406                 partialByte &= ~mask; // Clear out bits
407
partialByte |= ((bits >> (numBits - num)) & mask);
408                 // Note that bitOffset is already 0, so there is no risk
409
// of this advancing to the next byte
410
write(partialByte);
411                 numBits -= num;
412             }
413         }
414
415         // Now write any whole bytes
416
if (numBits > 7) {
417             int extra = numBits % 8;
418             for (int numBytes = numBits / 8; numBytes > 0; numBytes--) {
419                 int shift = (numBytes-1)*8+extra;
420                 int value = (int) ((shift == 0)
421                                    ? bits & 0xFF
422                                    : (bits>>shift) & 0xFF);
423                 write(value);
424             }
425             numBits = extra;
426         }
427
428         // Epilogue: write out remaining partial byte, if any
429
// Note that we may be at EOF, in which case we pad with 0,
430
// or not, in which case we must preserve the existing bits
431
if (numBits != 0) {
432             // If we are not at the end of the file, read the current byte
433
// If we are at the end of the file, initialize our byte to 0.
434
int partialByte = 0;
435             partialByte = read();
436             if (partialByte != -1) {
437                 seek(getStreamPosition() - 1);
438             }
439             // Fix 4494976: writeBit(int) does not pad the remainder
440
// of the current byte with 0s
441
else { // EOF
442
partialByte = 0;
443             }
444             
445             int shift = 8 - numBits;
446             int mask = -1 >>> (32 - numBits);
447             partialByte &= ~(mask << shift);
448             partialByte |= (bits & mask) << shift;
449             // bitOffset is always already 0 when we get here.
450
write(partialByte);
451             seek(getStreamPosition() - 1);
452             bitOffset = numBits;
453         }
454     }
455
456     /**
457      * If the bit offset is non-zero, forces the remaining bits
458      * in the current byte to 0 and advances the stream position
459      * by one. This method should be called by subclasses at the
460      * beginning of the <code>write(int)</code> and
461      * <code>write(byte[], int, int)</code> methods.
462      *
463      * @exception IOException if an I/O error occurs.
464      */

465     protected final void flushBits() throws IOException JavaDoc {
466         checkClosed();
467         if (bitOffset != 0) {
468             int offset = bitOffset;
469             int partialByte = read(); // Sets bitOffset to 0
470
if (partialByte < 0) {
471                 // Fix 4465683: When bitOffset is set
472
// to something non-zero beyond EOF,
473
// we should set that whole byte to
474
// zero and write it to stream.
475
partialByte = 0;
476                 bitOffset = 0;
477             }
478             else {
479                 seek(getStreamPosition() - 1);
480                 partialByte &= -1 << (8 - offset);
481             }
482             write(partialByte);
483         }
484     }
485
486 }
487
Popular Tags