1 7 8 package javax.imageio.stream; 9 10 import java.io.DataInput ; 11 import java.io.DataInputStream ; 12 import java.io.EOFException ; 13 import java.io.File ; 14 import java.io.FileNotFoundException ; 15 import java.io.IOException ; 16 import java.io.RandomAccessFile ; 17 import java.nio.ByteOrder ; 18 import java.util.Stack ; 19 import javax.imageio.IIOException ; 20 21 30 public abstract class ImageInputStreamImpl implements ImageInputStream { 31 32 private Stack markByteStack = new Stack (); 33 34 private Stack markBitStack = new Stack (); 35 36 private boolean isClosed = false; 37 38 private static final int BYTE_BUF_LENGTH = 8192; 40 41 private byte[] byteBuf = new byte[BYTE_BUF_LENGTH]; 43 44 52 protected ByteOrder byteOrder = ByteOrder.BIG_ENDIAN; 53 54 59 protected long streamPos; 60 61 66 protected int bitOffset; 67 68 73 protected long flushedPos = 0; 74 75 78 public ImageInputStreamImpl() { 79 } 80 81 88 protected final void checkClosed() throws IOException { 89 if (isClosed) { 90 throw new IOException ("closed"); 91 } 92 } 93 94 public void setByteOrder(ByteOrder byteOrder) { 95 this.byteOrder = byteOrder; 96 } 97 98 public ByteOrder getByteOrder() { 99 return byteOrder; 100 } 101 102 119 public abstract int read() throws IOException ; 120 121 134 public int read(byte[] b) throws IOException { 135 return read(b, 0, b.length); 136 } 137 138 165 public abstract int read(byte[] b, int off, int len) throws IOException ; 166 167 public void readBytes(IIOByteBuffer buf, int len) throws IOException { 168 if (len < 0) { 169 throw new IndexOutOfBoundsException ("len < 0!"); 170 } 171 if (buf == null) { 172 throw new NullPointerException ("buf == null!"); 173 } 174 175 byte[] data = new byte[len]; 176 len = read(data, 0, len); 177 178 buf.setData(data); 179 buf.setOffset(0); 180 buf.setLength(len); 181 } 182 183 public boolean readBoolean() throws IOException { 184 int ch = this.read(); 185 if (ch < 0) { 186 throw new EOFException (); 187 } 188 return (ch != 0); 189 } 190 191 public byte readByte() throws IOException { 192 int ch = this.read(); 193 if (ch < 0) { 194 throw new EOFException (); 195 } 196 return (byte)ch; 197 } 198 199 public int readUnsignedByte() throws IOException { 200 int ch = this.read(); 201 if (ch < 0) { 202 throw new EOFException (); 203 } 204 return ch; 205 } 206 207 public short readShort() throws IOException { 208 int ch1 = this.read(); 209 int ch2 = this.read(); 210 if ((ch1 | ch2) < 0) { 211 throw new EOFException (); 212 } 213 214 if (byteOrder == ByteOrder.BIG_ENDIAN) { 215 return (short)((ch1 << 8) + (ch2 << 0)); 216 } else { 217 return (short)((ch2 << 8) + (ch1 << 0)); 218 } 219 } 220 221 public int readUnsignedShort() throws IOException { 222 return ((int)readShort()) & 0xffff; 223 } 224 225 public char readChar() throws IOException { 226 return (char)readShort(); 227 } 228 229 public int readInt() throws IOException { 230 int ch1 = this.read(); 231 int ch2 = this.read(); 232 int ch3 = this.read(); 233 int ch4 = this.read(); 234 if ((ch1 | ch2 | ch3 | ch4) < 0) { 235 throw new EOFException (); 236 } 237 238 if (byteOrder == ByteOrder.BIG_ENDIAN) { 239 return ((ch1 << 24) + (ch2 << 16) + (ch3 << 8) + (ch4 << 0)); 240 } else { 241 return ((ch4 << 24) + (ch3 << 16) + (ch2 << 8) + (ch1 << 0)); 242 } 243 } 244 245 public long readUnsignedInt() throws IOException { 246 return ((long)readInt()) & 0xffffffffL; 247 } 248 249 public long readLong() throws IOException { 250 int i1 = readInt(); 251 int i2 = readInt(); 252 253 if (byteOrder == ByteOrder.BIG_ENDIAN) { 254 return ((long)i1 << 32) + (i2 & 0xFFFFFFFFL); 255 } else { 256 return ((long)i2 << 32) + (i1 & 0xFFFFFFFFL); 257 } 258 } 259 260 public float readFloat() throws IOException { 261 return Float.intBitsToFloat(readInt()); 262 } 263 264 public double readDouble() throws IOException { 265 return Double.longBitsToDouble(readLong()); 266 } 267 268 public String readLine() throws IOException { 269 StringBuffer input = new StringBuffer (); 270 int c = -1; 271 boolean eol = false; 272 273 while (!eol) { 274 switch (c = read()) { 275 case -1: 276 case '\n': 277 eol = true; 278 break; 279 case '\r': 280 eol = true; 281 long cur = getStreamPosition(); 282 if ((read()) != '\n') { 283 seek(cur); 284 } 285 break; 286 default: 287 input.append((char)c); 288 break; 289 } 290 } 291 292 if ((c == -1) && (input.length() == 0)) { 293 return null; 294 } 295 return input.toString(); 296 } 297 298 public String readUTF() throws IOException { 299 this.bitOffset = 0; 300 301 ByteOrder oldByteOrder = getByteOrder(); 305 setByteOrder(ByteOrder.BIG_ENDIAN); 306 307 String ret; 308 try { 309 ret = DataInputStream.readUTF(this); 310 } catch (IOException e) { 311 setByteOrder(oldByteOrder); 313 throw e; 314 } 315 316 setByteOrder(oldByteOrder); 317 return ret; 318 } 319 320 public void readFully(byte[] b, int off, int len) throws IOException { 321 if (off < 0 || len < 0 || off + len > b.length || off + len < 0) { 323 throw new IndexOutOfBoundsException 324 ("off < 0 || len < 0 || off + len > b.length!"); 325 } 326 327 while (len > 0) { 328 int nbytes = read(b, off, len); 329 if (nbytes == -1) { 330 throw new EOFException (); 331 } 332 off += nbytes; 333 len -= nbytes; 334 } 335 } 336 337 public void readFully(byte[] b) throws IOException { 338 readFully(b, 0, b.length); 339 } 340 341 public void readFully(short[] s, int off, int len) throws IOException { 342 if (off < 0 || len < 0 || off + len > s.length || off + len < 0) { 344 throw new IndexOutOfBoundsException 345 ("off < 0 || len < 0 || off + len > s.length!"); 346 } 347 348 while (len > 0) { 349 int nelts = Math.min(len, byteBuf.length/2); 350 readFully(byteBuf, 0, nelts*2); 351 toShorts(byteBuf, s, off, nelts); 352 off += nelts; 353 len -= nelts; 354 } 355 } 356 357 public void readFully(char[] c, int off, int len) throws IOException { 358 if (off < 0 || len < 0 || off + len > c.length || off + len < 0) { 360 throw new IndexOutOfBoundsException 361 ("off < 0 || len < 0 || off + len > c.length!"); 362 } 363 364 while (len > 0) { 365 int nelts = Math.min(len, byteBuf.length/2); 366 readFully(byteBuf, 0, nelts*2); 367 toChars(byteBuf, c, off, nelts); 368 off += nelts; 369 len -= nelts; 370 } 371 } 372 373 public void readFully(int[] i, int off, int len) throws IOException { 374 if (off < 0 || len < 0 || off + len > i.length || off + len < 0) { 376 throw new IndexOutOfBoundsException 377 ("off < 0 || len < 0 || off + len > i.length!"); 378 } 379 380 while (len > 0) { 381 int nelts = Math.min(len, byteBuf.length/4); 382 readFully(byteBuf, 0, nelts*4); 383 toInts(byteBuf, i, off, nelts); 384 off += nelts; 385 len -= nelts; 386 } 387 } 388 389 public void readFully(long[] l, int off, int len) throws IOException { 390 if (off < 0 || len < 0 || off + len > l.length || off + len < 0) { 392 throw new IndexOutOfBoundsException 393 ("off < 0 || len < 0 || off + len > l.length!"); 394 } 395 396 while (len > 0) { 397 int nelts = Math.min(len, byteBuf.length/8); 398 readFully(byteBuf, 0, nelts*8); 399 toLongs(byteBuf, l, off, nelts); 400 off += nelts; 401 len -= nelts; 402 } 403 } 404 405 public void readFully(float[] f, int off, int len) throws IOException { 406 if (off < 0 || len < 0 || off + len > f.length || off + len < 0) { 408 throw new IndexOutOfBoundsException 409 ("off < 0 || len < 0 || off + len > f.length!"); 410 } 411 412 while (len > 0) { 413 int nelts = Math.min(len, byteBuf.length/4); 414 readFully(byteBuf, 0, nelts*4); 415 toFloats(byteBuf, f, off, nelts); 416 off += nelts; 417 len -= nelts; 418 } 419 } 420 421 public void readFully(double[] d, int off, int len) throws IOException { 422 if (off < 0 || len < 0 || off + len > d.length || off + len < 0) { 424 throw new IndexOutOfBoundsException 425 ("off < 0 || len < 0 || off + len > d.length!"); 426 } 427 428 while (len > 0) { 429 int nelts = Math.min(len, byteBuf.length/8); 430 readFully(byteBuf, 0, nelts*8); 431 toDoubles(byteBuf, d, off, nelts); 432 off += nelts; 433 len -= nelts; 434 } 435 } 436 437 private void toShorts(byte[] b, short[] s, int off, int len) { 438 int boff = 0; 439 if (byteOrder == ByteOrder.BIG_ENDIAN) { 440 for (int j = 0; j < len; j++) { 441 int b0 = b[boff]; 442 int b1 = b[boff + 1] & 0xff; 443 s[off + j] = (short)((b0 << 8) | b1); 444 boff += 2; 445 } 446 } else { 447 for (int j = 0; j < len; j++) { 448 int b0 = b[boff + 1]; 449 int b1 = b[boff] & 0xff; 450 s[off + j] = (short)((b0 << 8) | b1); 451 boff += 2; 452 } 453 } 454 } 455 456 private void toChars(byte[] b, char[] c, int off, int len) { 457 int boff = 0; 458 if (byteOrder == ByteOrder.BIG_ENDIAN) { 459 for (int j = 0; j < len; j++) { 460 int b0 = b[boff]; 461 int b1 = b[boff + 1] & 0xff; 462 c[off + j] = (char)((b0 << 8) | b1); 463 boff += 2; 464 } 465 } else { 466 for (int j = 0; j < len; j++) { 467 int b0 = b[boff + 1]; 468 int b1 = b[boff] & 0xff; 469 c[off + j] = (char)((b0 << 8) | b1); 470 boff += 2; 471 } 472 } 473 } 474 475 private void toInts(byte[] b, int[] i, int off, int len) { 476 int boff = 0; 477 if (byteOrder == ByteOrder.BIG_ENDIAN) { 478 for (int j = 0; j < len; j++) { 479 int b0 = b[boff]; 480 int b1 = b[boff + 1] & 0xff; 481 int b2 = b[boff + 2] & 0xff; 482 int b3 = b[boff + 3] & 0xff; 483 i[off + j] = (b0 << 24) | (b1 << 16) | (b2 << 8) | b3; 484 boff += 4; 485 } 486 } else { 487 for (int j = 0; j < len; j++) { 488 int b0 = b[boff + 3]; 489 int b1 = b[boff + 2] & 0xff; 490 int b2 = b[boff + 1] & 0xff; 491 int b3 = b[boff] & 0xff; 492 i[off + j] = (b0 << 24) | (b1 << 16) | (b2 << 8) | b3; 493 boff += 4; 494 } 495 } 496 } 497 498 private void toLongs(byte[] b, long[] l, int off, int len) { 499 int boff = 0; 500 if (byteOrder == ByteOrder.BIG_ENDIAN) { 501 for (int j = 0; j < len; j++) { 502 int b0 = b[boff]; 503 int b1 = b[boff + 1] & 0xff; 504 int b2 = b[boff + 2] & 0xff; 505 int b3 = b[boff + 3] & 0xff; 506 int b4 = b[boff + 4]; 507 int b5 = b[boff + 5] & 0xff; 508 int b6 = b[boff + 6] & 0xff; 509 int b7 = b[boff + 7] & 0xff; 510 511 int i0 = (b0 << 24) | (b1 << 16) | (b2 << 8) | b3; 512 int i1 = (b4 << 24) | (b5 << 16) | (b6 << 8) | b7; 513 514 l[off + j] = ((long)i0 << 32) | (i1 & 0xffffffffL); 515 boff += 8; 516 } 517 } else { 518 for (int j = 0; j < len; j++) { 519 int b0 = b[boff + 7]; 520 int b1 = b[boff + 6] & 0xff; 521 int b2 = b[boff + 5] & 0xff; 522 int b3 = b[boff + 4] & 0xff; 523 int b4 = b[boff + 3]; 524 int b5 = b[boff + 2] & 0xff; 525 int b6 = b[boff + 1] & 0xff; 526 int b7 = b[boff] & 0xff; 527 528 int i0 = (b0 << 24) | (b1 << 16) | (b2 << 8) | b3; 529 int i1 = (b4 << 24) | (b5 << 16) | (b6 << 8) | b7; 530 531 l[off + j] = ((long)i0 << 32) | (i1 & 0xffffffffL); 532 boff += 8; 533 } 534 } 535 } 536 537 private void toFloats(byte[] b, float[] f, int off, int len) { 538 int boff = 0; 539 if (byteOrder == ByteOrder.BIG_ENDIAN) { 540 for (int j = 0; j < len; j++) { 541 int b0 = b[boff]; 542 int b1 = b[boff + 1] & 0xff; 543 int b2 = b[boff + 2] & 0xff; 544 int b3 = b[boff + 3] & 0xff; 545 int i = (b0 << 24) | (b1 << 16) | (b2 << 8) | b3; 546 f[off + j] = Float.intBitsToFloat(i); 547 boff += 4; 548 } 549 } else { 550 for (int j = 0; j < len; j++) { 551 int b0 = b[boff + 3]; 552 int b1 = b[boff + 2] & 0xff; 553 int b2 = b[boff + 1] & 0xff; 554 int b3 = b[boff + 0] & 0xff; 555 int i = (b0 << 24) | (b1 << 16) | (b2 << 8) | b3; 556 f[off + j] = Float.intBitsToFloat(i); 557 boff += 4; 558 } 559 } 560 } 561 562 private void toDoubles(byte[] b, double[] d, int off, int len) { 563 int boff = 0; 564 if (byteOrder == ByteOrder.BIG_ENDIAN) { 565 for (int j = 0; j < len; j++) { 566 int b0 = b[boff]; 567 int b1 = b[boff + 1] & 0xff; 568 int b2 = b[boff + 2] & 0xff; 569 int b3 = b[boff + 3] & 0xff; 570 int b4 = b[boff + 4]; 571 int b5 = b[boff + 5] & 0xff; 572 int b6 = b[boff + 6] & 0xff; 573 int b7 = b[boff + 7] & 0xff; 574 575 int i0 = (b0 << 24) | (b1 << 16) | (b2 << 8) | b3; 576 int i1 = (b4 << 24) | (b5 << 16) | (b6 << 8) | b7; 577 long l = ((long)i0 << 32) | (i1 & 0xffffffffL); 578 579 d[off + j] = Double.longBitsToDouble(l); 580 boff += 8; 581 } 582 } else { 583 for (int j = 0; j < len; j++) { 584 int b0 = b[boff + 7]; 585 int b1 = b[boff + 6] & 0xff; 586 int b2 = b[boff + 5] & 0xff; 587 int b3 = b[boff + 4] & 0xff; 588 int b4 = b[boff + 3]; 589 int b5 = b[boff + 2] & 0xff; 590 int b6 = b[boff + 1] & 0xff; 591 int b7 = b[boff] & 0xff; 592 593 int i0 = (b0 << 24) | (b1 << 16) | (b2 << 8) | b3; 594 int i1 = (b4 << 24) | (b5 << 16) | (b6 << 8) | b7; 595 long l = ((long)i0 << 32) | (i1 & 0xffffffffL); 596 597 d[off + j] = Double.longBitsToDouble(l); 598 boff += 8; 599 } 600 } 601 } 602 603 public long getStreamPosition() throws IOException { 604 checkClosed(); 605 return streamPos; 606 } 607 608 public int getBitOffset() throws IOException { 609 checkClosed(); 610 return bitOffset; 611 } 612 613 public void setBitOffset(int bitOffset) throws IOException { 614 checkClosed(); 615 if (bitOffset < 0 || bitOffset > 7) { 616 throw new IllegalArgumentException ("bitOffset must be betwwen 0 and 7!"); 617 } 618 this.bitOffset = bitOffset; 619 } 620 621 public int readBit() throws IOException { 622 checkClosed(); 623 624 int newBitOffset = (this.bitOffset + 1) & 0x7; 626 627 int val = read(); 628 if (val == -1) { 629 throw new EOFException (); 630 } 631 632 if (newBitOffset != 0) { 633 seek(getStreamPosition() - 1); 635 val >>= 8 - newBitOffset; 637 } 638 this.bitOffset = newBitOffset; 639 640 return val & 0x1; 641 } 642 643 public long readBits(int numBits) throws IOException { 644 checkClosed(); 645 646 if (numBits < 0 || numBits > 64) { 647 throw new IllegalArgumentException (); 648 } 649 if (numBits == 0) { 650 return 0L; 651 } 652 653 int bitsToRead = numBits + bitOffset; 655 656 int newBitOffset = (this.bitOffset + numBits) & 0x7; 658 659 long accum = 0L; 661 while (bitsToRead > 0) { 662 int val = read(); 663 if (val == -1) { 664 throw new EOFException (); 665 } 666 667 accum <<= 8; 668 accum |= val; 669 bitsToRead -= 8; 670 } 671 672 if (newBitOffset != 0) { 674 seek(getStreamPosition() - 1); 675 } 676 this.bitOffset = newBitOffset; 677 678 accum >>>= (-bitsToRead); 681 accum &= (-1L >>> (64 - numBits)); 683 684 return accum; 685 } 686 687 694 public long length() { 695 return -1L; 696 } 697 698 713 public int skipBytes(int n) throws IOException { 714 long pos = getStreamPosition(); 715 seek(pos + n); 716 return (int)(getStreamPosition() - pos); 717 } 718 719 734 public long skipBytes(long n) throws IOException { 735 long pos = getStreamPosition(); 736 seek(pos + n); 737 return getStreamPosition() - pos; 738 } 739 740 public void seek(long pos) throws IOException { 741 checkClosed(); 742 743 if (pos < flushedPos) { 745 throw new IndexOutOfBoundsException ("pos < flushedPos!"); 746 } 747 748 this.streamPos = pos; 749 this.bitOffset = 0; 750 } 751 752 756 public void mark() { 757 try { 758 markByteStack.push(new Long (getStreamPosition())); 759 markBitStack.push(new Integer (getBitOffset())); 760 } catch (IOException e) { 761 } 762 } 763 764 773 public void reset() throws IOException { 774 if (markByteStack.empty()) { 775 return; 776 } 777 778 long pos = ((Long )markByteStack.pop()).longValue(); 779 if (pos < flushedPos) { 780 throw new IIOException 781 ("Previous marked position has been discarded!"); 782 } 783 seek(pos); 784 785 int offset = ((Integer )markBitStack.pop()).intValue(); 786 setBitOffset(offset); 787 } 788 789 public void flushBefore(long pos) throws IOException { 790 if (pos < flushedPos) { 791 throw new IndexOutOfBoundsException ("pos < flushedPos!"); 792 } 793 if (pos > getStreamPosition()) { 794 throw new IndexOutOfBoundsException ("pos > getStreamPosition()!"); 795 } 796 flushedPos = pos; 798 } 799 800 public void flush() throws IOException { 801 flushBefore(getStreamPosition()); 802 } 803 804 public long getFlushedPosition() { 805 return flushedPos; 806 } 807 808 812 public boolean isCached() { 813 return false; 814 } 815 816 820 public boolean isCachedMemory() { 821 return false; 822 } 823 824 828 public boolean isCachedFile() { 829 return false; 830 } 831 832 public void close() throws IOException { 833 checkClosed(); 834 835 isClosed = true; 836 } 837 838 847 protected void finalize() throws Throwable { 848 if (!isClosed) { 849 try { 850 close(); 851 } catch (IOException e) { 852 } 853 } 854 super.finalize(); 855 } 856 } 857 | Popular Tags |