1 /* ImageInputStream.java --
2 Copyright (C) 2004 Free Software Foundation, Inc.
4 This file is part of GNU Classpath.
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING. If not, write to the
18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library. Thus, the terms and
23 conditions of the GNU General Public License cover the whole
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module. An independent module is a module which is not derived from
33 or based on this library. If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so. If you do not wish to do so, delete this
36 exception statement from your version. */
39 package javax
.imageio
.stream
;
41 import java
.io
.DataInputStream
;
42 import java
.io
.EOFException
;
43 import java
.io
.IOException
;
44 import java
.nio
.ByteOrder
;
45 import java
.util
.Stack
;
48 * @author Michael Koch (konqueror@gmx.de)
50 public abstract class ImageInputStreamImpl
implements ImageInputStream
52 private boolean closed
;
53 private Stack markStack
= new Stack();
55 byte[] buffer
= new byte[8];
57 protected int bitOffset
;
58 protected ByteOrder byteOrder
= ByteOrder
.BIG_ENDIAN
;
59 protected long flushedPos
;
60 protected long streamPos
;
62 public ImageInputStreamImpl()
67 protected final void checkClosed()
71 throw new IOException("stream closed");
81 protected void finalize()
90 flushBefore(getStreamPosition());
93 public void flushBefore(long position
)
96 if (position
< flushedPos
)
97 throw new IndexOutOfBoundsException();
99 if (position
> streamPos
)
100 throw new IndexOutOfBoundsException();
102 flushedPos
= position
;
105 public int getBitOffset()
112 public ByteOrder
getByteOrder()
117 public long getFlushedPosition()
122 public long getStreamPosition()
129 public boolean isCached()
134 public boolean isCachedFile()
139 public boolean isCachedMemory()
153 markStack
.push(new Long(getStreamPosition()));
155 catch (IOException e
)
161 public abstract int read()
164 public int read(byte[] data
)
167 return read(data
, 0, data
.length
);
170 public abstract int read(byte[] data
, int offset
, int len
)
178 // Calc new bit offset here, readByte resets it.
179 int newOffset
= (bitOffset
+ 1) & 0x7;
181 byte data
= readByte();
185 seek(getStreamPosition() - 1);
186 data
= (byte) (data
>> (8 - newOffset
));
189 bitOffset
= newOffset
;
193 public long readBits(int numBits
)
198 if (numBits
< 0 || numBits
> 64)
199 throw new IllegalArgumentException();
206 for (int i
= 0; i
< numBits
; i
++)
215 public boolean readBoolean()
218 byte data
= readByte();
222 public byte readByte()
228 throw new EOFException();
233 public void readBytes(IIOByteBuffer buffer
, int len
)
236 int result
= read(buffer
.getData(), buffer
.getOffset(), len
);
238 if (result
== -1 || result
< len
)
239 throw new EOFException();
241 buffer
.setLength(len
);
244 public char readChar()
247 return (char) readShort();
250 public double readDouble()
253 return (double) readLong();
256 public float readFloat()
259 return (float) readInt();
262 public void readFully(byte[] data
)
265 readFully(data
, 0, data
.length
);
268 public void readFully(byte[] data
, int offset
, int len
)
271 for (int i
= 0; i
< len
; ++i
)
272 data
[offset
+ i
] = readByte();
275 public void readFully(char[] data
, int offset
, int len
)
278 for (int i
= 0; i
< len
; ++i
)
279 data
[offset
+ i
] = readChar();
282 public void readFully(double[] data
, int offset
, int len
)
285 for (int i
= 0; i
< len
; ++i
)
286 data
[offset
+ i
] = readDouble();
289 public void readFully(float[] data
, int offset
, int len
)
292 for (int i
= 0; i
< len
; ++i
)
293 data
[offset
+ i
] = readFloat();
296 public void readFully(int[] data
, int offset
, int len
)
299 for (int i
= 0; i
< len
; ++i
)
300 data
[offset
+ i
] = readInt();
303 public void readFully(long[] data
, int offset
, int len
)
306 for (int i
= 0; i
< len
; ++i
)
307 data
[offset
+ i
] = readLong();
310 public void readFully(short[] data
, int offset
, int len
)
313 for (int i
= 0; i
< len
; ++i
)
314 data
[offset
+ i
] = readShort();
320 int result
= read(buffer
, 0, 4);
323 throw new EOFException();
325 if (getByteOrder() == ByteOrder
.LITTLE_ENDIAN
)
327 return ((buffer
[0] & 0xff)
330 + (buffer
[3] << 24));
333 return ((buffer
[4] << 24)
336 + (buffer
[1] & 0xff));
339 public String
readLine()
346 StringBuffer buffer
= new StringBuffer();
348 while (!eol
&& (c
= read()) != -1)
353 // Consume following \n'
354 long oldPosition
= getStreamPosition();
361 buffer
.append((char) c
);
366 if (c
== -1 && buffer
.length() == 0)
369 return buffer
.toString();
372 public long readLong()
375 int result
= read(buffer
, 0, 8);
378 throw new EOFException();
380 if (getByteOrder() == ByteOrder
.LITTLE_ENDIAN
)
382 return ((buffer
[0] & 0xff)
383 + (((buffer
[1] & 0xff)) << 8)
384 + (((buffer
[2] & 0xff)) << 16)
385 + (((buffer
[3] & 0xffL
)) << 24)
386 + (((buffer
[4] & 0xffL
)) << 32)
387 + (((buffer
[5] & 0xffL
)) << 40)
388 + (((buffer
[6] & 0xffL
)) << 48)
389 + (((long) buffer
[7]) << 56));
392 return ((((long) buffer
[7]) << 56)
393 + ((buffer
[6] & 0xffL
) << 48)
394 + ((buffer
[5] & 0xffL
) << 40)
395 + ((buffer
[4] & 0xffL
) << 32)
396 + ((buffer
[3] & 0xffL
) << 24)
397 + ((buffer
[2] & 0xff) << 16)
398 + ((buffer
[1] & 0xff) << 8)
399 + (buffer
[0] & 0xff));
402 public short readShort()
405 int result
= read(buffer
, 0, 2);
408 throw new EOFException();
410 if (getByteOrder() == ByteOrder
.LITTLE_ENDIAN
)
412 return (short) ((buffer
[0] & 0xff)
416 return (short) ((buffer
[0] << 8)
417 + (buffer
[1] & 0xff));
420 public int readUnsignedByte()
423 return readByte() & 0xff;
426 public long readUnsignedInt()
429 return readInt() & 0xffffffff;
432 public int readUnsignedShort()
435 return readShort() & 0xffff;
438 public String
readUTF()
444 ByteOrder old
= getByteOrder();
445 setByteOrder(ByteOrder
.BIG_ENDIAN
); // Strings are always big endian.
449 data
= DataInputStream
.readUTF(this);
464 long mark
= ((Long
) markStack
.pop()).longValue();
468 public void seek(long position
)
473 if (position
< getFlushedPosition())
474 throw new IndexOutOfBoundsException("position < flushed position");
476 streamPos
= position
;
480 public void setBitOffset (int bitOffset
)
485 if (bitOffset
< 0 || bitOffset
> 7)
486 throw new IllegalArgumentException();
488 this.bitOffset
= bitOffset
;
491 public void setByteOrder(ByteOrder byteOrder
)
493 this.byteOrder
= byteOrder
;
496 public int skipBytes(int num
)
501 seek(getStreamPosition() + num
);
506 public long skipBytes(long num
)
511 seek(getStreamPosition() + num
);