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