1:
37:
38:
39: package ;
40:
41: import ;
42: import ;
43: import ;
44: import ;
45: import ;
46:
47:
50: public abstract class ImageInputStreamImpl implements ImageInputStream
51: {
52: private boolean closed;
53: private Stack markStack = new Stack();
54:
55: byte[] buffer = new byte[8];
56:
57: protected int bitOffset;
58: protected ByteOrder byteOrder = ByteOrder.BIG_ENDIAN;
59: protected long flushedPos;
60: protected long streamPos;
61:
62: public ImageInputStreamImpl()
63: {
64:
65: }
66:
67: protected final void checkClosed()
68: throws IOException
69: {
70: if (closed)
71: throw new IOException("stream closed");
72: }
73:
74: public void close()
75: throws IOException
76: {
77: checkClosed();
78: closed = true;
79: }
80:
81: protected void finalize()
82: throws Throwable
83: {
84: if (!closed)
85: close();
86: }
87:
88: public void flush()
89: throws IOException
90: {
91: flushBefore(getStreamPosition());
92: }
93:
94: public void flushBefore(long position)
95: throws IOException
96: {
97: if (position < flushedPos)
98: throw new IndexOutOfBoundsException();
99:
100: if (position > streamPos)
101: throw new IndexOutOfBoundsException();
102:
103: flushedPos = position;
104: }
105:
106: public int getBitOffset()
107: throws IOException
108: {
109: checkClosed();
110: return bitOffset;
111: }
112:
113: public ByteOrder getByteOrder()
114: {
115: return byteOrder;
116: }
117:
118: public long getFlushedPosition()
119: {
120: return flushedPos;
121: }
122:
123: public long getStreamPosition()
124: throws IOException
125: {
126: checkClosed();
127: return streamPos;
128: }
129:
130: public boolean isCached()
131: {
132: return false;
133: }
134:
135: public boolean isCachedFile()
136: {
137: return false;
138: }
139:
140: public boolean isCachedMemory()
141: {
142: return false;
143: }
144:
145: public long length()
146: {
147: return -1L;
148: }
149:
150: public void mark()
151: {
152: try
153: {
154: markStack.push(new Long(getStreamPosition()));
155: }
156: catch (IOException e)
157: {
158: throw new RuntimeException(e);
159: }
160: }
161:
162: public abstract int read()
163: throws IOException;
164:
165: public abstract int read(byte[] data, int offset, int len)
166: throws IOException;
167:
168: public int read(byte[] data)
169: throws IOException
170: {
171: return read(data, 0, data.length);
172: }
173:
174: public int readBit()
175: throws IOException
176: {
177: checkClosed();
178:
179:
180: int newOffset = (bitOffset + 1) & 0x7;
181:
182:
183: byte data = readByte();
184:
185:
186:
187:
188:
189: if (newOffset != 0)
190: {
191: seek(getStreamPosition() - 1);
192: data = (byte) (data >> (8 - newOffset));
193: }
194:
195: bitOffset = newOffset;
196: return data & 0x1;
197: }
198:
199: public long readBits(int numBits)
200: throws IOException
201: {
202: checkClosed();
203:
204: if (numBits < 0 || numBits > 64)
205: throw new IllegalArgumentException();
206:
207: long bits = 0L;
208:
209: for (int i = 0; i < numBits; i++)
210: {
211: bits <<= 1;
212: bits |= readBit();
213: }
214: return bits;
215: }
216:
217: public boolean readBoolean()
218: throws IOException
219: {
220: byte data = readByte();
221:
222: return data != 0;
223: }
224:
225: public byte readByte()
226: throws IOException
227: {
228: checkClosed();
229:
230: int data = read();
231:
232: if (data == -1)
233: throw new EOFException();
234:
235: return (byte) data;
236: }
237:
238: public void readBytes(IIOByteBuffer buffer, int len)
239: throws IOException
240: {
241: readFullyPrivate(buffer.getData(), buffer.getOffset(), len);
242:
243: buffer.setLength(len);
244: }
245:
246: public char readChar()
247: throws IOException
248: {
249: return (char) readShort();
250: }
251:
252: public double readDouble()
253: throws IOException
254: {
255: return Double.longBitsToDouble(readLong());
256: }
257:
258: public float readFloat()
259: throws IOException
260: {
261: return Float.intBitsToFloat(readInt());
262: }
263:
264: public void readFully(byte[] data)
265: throws IOException
266: {
267: readFully(data, 0, data.length);
268: }
269:
270: public void readFully(byte[] data, int offset, int len)
271: throws IOException
272: {
273: readFullyPrivate(data, offset, len);
274: }
275:
276: public void readFully(char[] data, int offset, int len)
277: throws IOException
278: {
279: for (int i = 0; i < len; ++i)
280: data[offset + i] = readChar();
281: }
282:
283: public void readFully(double[] data, int offset, int len)
284: throws IOException
285: {
286: for (int i = 0; i < len; ++i)
287: data[offset + i] = readDouble();
288: }
289:
290: public void readFully(float[] data, int offset, int len)
291: throws IOException
292: {
293: for (int i = 0; i < len; ++i)
294: data[offset + i] = readFloat();
295: }
296:
297: public void readFully(int[] data, int offset, int len)
298: throws IOException
299: {
300: for (int i = 0; i < len; ++i)
301: data[offset + i] = readInt();
302: }
303:
304: public void readFully(long[] data, int offset, int len)
305: throws IOException
306: {
307: for (int i = 0; i < len; ++i)
308: data[offset + i] = readLong();
309: }
310:
311: public void readFully(short[] data, int offset, int len)
312: throws IOException
313: {
314: for (int i = 0; i < len; ++i)
315: data[offset + i] = readShort();
316: }
317:
318: public int readInt()
319: throws IOException
320: {
321: readFullyPrivate(buffer, 0, 4);
322:
323: if (getByteOrder() == ByteOrder.LITTLE_ENDIAN)
324: return (int)
325: (((int) (buffer[0] & 0xff) << 0)
326: | ((int) (buffer[1] & 0xff) << 8)
327: | ((int) (buffer[2] & 0xff) << 16)
328: | ((int) (buffer[3] & 0xff) << 24));
329:
330: return (int)
331: (((int) (buffer[0] & 0xff) << 24)
332: + ((int) (buffer[1] & 0xff) << 16)
333: + ((int) (buffer[2] & 0xff) << 8)
334: + ((int) (buffer[3] & 0xff) << 0));
335: }
336:
337: public String readLine()
338: throws IOException
339: {
340: checkClosed();
341:
342: int c = -1;
343: boolean eol = false;
344: StringBuffer buffer = new StringBuffer();
345:
346: c = read();
347: if (c == -1)
348: return null;
349:
350: while (!eol)
351: {
352: switch(c)
353: {
354: case '\r':
355:
356: long oldPosition = getStreamPosition();
357: c = read();
358: if (c == -1 || c == '\n')
359: eol = true;
360: else
361: {
362: seek(oldPosition);
363: eol = true;
364: }
365: continue;
366:
367: case '\n':
368: eol = true;
369: continue;
370:
371: default:
372: buffer.append((char) c);
373: break;
374: }
375: c = read();
376: if (c == -1)
377: eol = true;
378: }
379:
380: return buffer.toString();
381: }
382:
383: public long readLong()
384: throws IOException
385: {
386: readFullyPrivate(buffer, 0, 8);
387:
388: if (getByteOrder() == ByteOrder.LITTLE_ENDIAN)
389: return (long)
390: (((long) (buffer[0] & 0xff) << 0)
391: | ((long) (buffer[1] & 0xff) << 8)
392: | ((long) (buffer[2] & 0xff) << 16)
393: | ((long) (buffer[3] & 0xff) << 24)
394: | ((long) (buffer[4] & 0xff) << 32)
395: | ((long) (buffer[5] & 0xff) << 40)
396: | ((long) (buffer[6] & 0xff) << 48)
397: | ((long) (buffer[7] & 0xff) << 56));
398:
399: return (long)
400: (((long) (buffer[0] & 0xff) << 56)
401: | ((long) (buffer[1] & 0xff) << 48)
402: | ((long) (buffer[2] & 0xff) << 40)
403: | ((long) (buffer[3] & 0xff) << 32)
404: | ((long) (buffer[4] & 0xff) << 24)
405: | ((long) (buffer[5] & 0xff) << 16)
406: | ((long) (buffer[6] & 0xff) << 8)
407: | ((long) (buffer[7] & 0xff) << 0));
408: }
409:
410: public short readShort()
411: throws IOException
412: {
413: readFullyPrivate(buffer, 0, 2);
414:
415: if (getByteOrder() == ByteOrder.LITTLE_ENDIAN)
416: return (short)
417: (((short) (buffer[0] & 0xff) << 0)
418: | ((short) (buffer[1] & 0xff) << 8));
419:
420: return (short)
421: (((short) (buffer[0] & 0xff) << 8)
422: | ((short) (buffer[1] & 0xff) << 0));
423: }
424:
425: public int readUnsignedByte()
426: throws IOException
427: {
428: return (int) readByte() & 0xff;
429: }
430:
431: public long readUnsignedInt()
432: throws IOException
433: {
434: return (long) readInt() & 0xffffffffL;
435: }
436:
437: public int readUnsignedShort()
438: throws IOException
439: {
440: return (int) readShort() & 0xffff;
441: }
442:
443: public String readUTF()
444: throws IOException
445: {
446: checkClosed();
447:
448: String data;
449: ByteOrder old = getByteOrder();
450:
451: setByteOrder(ByteOrder.BIG_ENDIAN);
452:
453: try
454: {
455: data = DataInputStream.readUTF(this);
456: }
457: finally
458: {
459: setByteOrder(old);
460: }
461:
462: return data;
463: }
464:
465: public void reset()
466: throws IOException
467: {
468: checkClosed();
469:
470: long mark = ((Long) markStack.pop()).longValue();
471: seek(mark);
472: }
473:
474: public void seek(long position)
475: throws IOException
476: {
477: checkClosed();
478:
479: if (position < getFlushedPosition())
480: throw new IndexOutOfBoundsException("position < flushed position");
481:
482: streamPos = position;
483: bitOffset = 0;
484: }
485:
486: public void setBitOffset (int bitOffset)
487: throws IOException
488: {
489: checkClosed();
490:
491: if (bitOffset < 0 || bitOffset > 7)
492: throw new IllegalArgumentException("bitOffset not between 0 and 7 inclusive");
493:
494: this.bitOffset = bitOffset;
495: }
496:
497: public void setByteOrder(ByteOrder byteOrder)
498: {
499: this.byteOrder = byteOrder;
500: }
501:
502: public int skipBytes(int num)
503: throws IOException
504: {
505: checkClosed();
506:
507: seek(getStreamPosition() + num);
508: bitOffset = 0;
509: return num;
510: }
511:
512: public long skipBytes(long num)
513: throws IOException
514: {
515: checkClosed();
516:
517: seek(getStreamPosition() + num);
518: bitOffset = 0;
519: return num;
520: }
521:
522: private void readFullyPrivate (byte[] buf, int offset, int len) throws IOException
523: {
524: checkClosed();
525:
526: if (len < 0)
527: throw new IndexOutOfBoundsException("Negative length: " + len);
528:
529: while (len > 0)
530: {
531:
532: int numread = read (buf, offset, len);
533: if (numread < 0)
534: throw new EOFException ();
535: len -= numread;
536: offset += numread;
537: }
538: bitOffset = 0;
539: }
540: }