1 16 17 package imageinfo; 18 import java.io.DataInput ; 19 import java.io.FileInputStream ; 20 import java.io.InputStream ; 21 import java.io.IOException ; 22 import java.net.*; 23 import java.util.Vector ; 24 25 114 public class ImageInfo { 115 121 public static final int FORMAT_JPEG = 0; 122 123 131 public static final int FORMAT_GIF = 1; 132 133 139 public static final int FORMAT_PNG = 2; 140 141 152 public static final int FORMAT_BMP = 3; 153 154 159 public static final int FORMAT_PCX = 4; 160 161 164 public static final int FORMAT_IFF = 5; 165 166 171 public static final int FORMAT_RAS = 6; 172 173 174 public static final int FORMAT_PBM = 7; 175 176 177 public static final int FORMAT_PGM = 8; 178 179 180 public static final int FORMAT_PPM = 9; 181 182 183 public static final int FORMAT_PSD = 10; 184 185 186 public static final int FORMAT_SWF = 11; 187 188 public static final int COLOR_TYPE_UNKNOWN = -1; 189 public static final int COLOR_TYPE_TRUECOLOR_RGB = 0; 190 public static final int COLOR_TYPE_PALETTED = 1; 191 public static final int COLOR_TYPE_GRAYSCALE= 2; 192 public static final int COLOR_TYPE_BLACK_AND_WHITE = 3; 193 194 199 private static final String [] FORMAT_NAMES = 200 {"JPEG", "GIF", "PNG", "BMP", "PCX", 201 "IFF", "RAS", "PBM", "PGM", "PPM", 202 "PSD", "SWF"}; 203 204 209 private static final String [] MIME_TYPE_STRINGS = 210 {"image/jpeg", "image/gif", "image/png", "image/bmp", "image/pcx", 211 "image/iff", "image/ras", "image/x-portable-bitmap", "image/x-portable-graymap", "image/x-portable-pixmap", 212 "image/psd", "application/x-shockwave-flash"}; 213 214 private int width; 215 private int height; 216 private int bitsPerPixel; 217 private int colorType = COLOR_TYPE_UNKNOWN; 218 private int format; 219 private InputStream in; 220 private DataInput din; 221 private boolean collectComments = true; 222 private Vector comments; 223 private boolean determineNumberOfImages; 224 private int numberOfImages; 225 private int physicalHeightDpi; 226 private int physicalWidthDpi; 227 private int bitBuf; 228 private int bitPos; 229 230 private void addComment(String s) { 231 if (comments == null) { 232 comments = new Vector (); 233 } 234 comments.addElement(s); 235 } 236 237 244 public boolean check() { 245 format = -1; 246 width = -1; 247 height = -1; 248 bitsPerPixel = -1; 249 numberOfImages = 1; 250 physicalHeightDpi = -1; 251 physicalWidthDpi = -1; 252 comments = null; 253 try { 254 int b1 = read() & 0xff; 255 int b2 = read() & 0xff; 256 if (b1 == 0x47 && b2 == 0x49) { 257 return checkGif(); 258 } 259 else 260 if (b1 == 0x89 && b2 == 0x50) { 261 return checkPng(); 262 } 263 else 264 if (b1 == 0xff && b2 == 0xd8) { 265 return checkJpeg(); 266 } 267 else 268 if (b1 == 0x42 && b2 == 0x4d) { 269 return checkBmp(); 270 } 271 else 272 if (b1 == 0x0a && b2 < 0x06) { 273 return checkPcx(); 274 } 275 else 276 if (b1 == 0x46 && b2 == 0x4f) { 277 return checkIff(); 278 } 279 else 280 if (b1 == 0x59 && b2 == 0xa6) { 281 return checkRas(); 282 } 283 else 284 if (b1 == 0x50 && b2 >= 0x31 && b2 <= 0x36) { 285 return checkPnm(b2 - '0'); 286 } 287 else 288 if (b1 == 0x38 && b2 == 0x42) { 289 return checkPsd(); 290 } 291 else 292 if (b1 == 0x46 && b2 == 0x57) { 293 return checkSwf(); 294 } 295 else { 296 return false; 297 } 298 } catch (IOException ioe) { 299 return false; 300 } 301 } 302 303 private boolean checkBmp() throws IOException { 304 byte[] a = new byte[44]; 305 if (read(a) != a.length) { 306 return false; 307 } 308 width = getIntLittleEndian(a, 16); 309 height = getIntLittleEndian(a, 20); 310 if (width < 1 || height < 1) { 311 return false; 312 } 313 bitsPerPixel = getShortLittleEndian(a, 26); 314 if (bitsPerPixel != 1 && bitsPerPixel != 4 && 315 bitsPerPixel != 8 && bitsPerPixel != 16 && 316 bitsPerPixel != 24 && bitsPerPixel != 32) { 317 return false; 318 } 319 int x = getIntLittleEndian(a, 36); 320 if (x > 0) { 321 setPhysicalWidthDpi(x); 322 } 323 int y = getIntLittleEndian(a, 40); 324 if (y > 0) { 325 setPhysicalHeightDpi(y); 326 } 327 format = FORMAT_BMP; 328 return true; 329 } 330 331 private boolean checkGif() throws IOException { 332 final byte[] GIF_MAGIC_87A = {0x46, 0x38, 0x37, 0x61}; 333 final byte[] GIF_MAGIC_89A = {0x46, 0x38, 0x39, 0x61}; 334 byte[] a = new byte[11]; if (read(a) != 11) { 336 return false; 337 } 338 if ((!equals(a, 0, GIF_MAGIC_89A, 0, 4)) && 339 (!equals(a, 0, GIF_MAGIC_87A, 0, 4))) { 340 return false; 341 } 342 format = FORMAT_GIF; 343 width = getShortLittleEndian(a, 4); 344 height = getShortLittleEndian(a, 6); 345 int flags = a[8] & 0xff; 346 bitsPerPixel = ((flags >> 4) & 0x07) + 1; 347 if (!determineNumberOfImages) { 348 return true; 349 } 350 if ((flags & 0x80) != 0) { 352 int tableSize = (1 << ((flags & 7) + 1)) * 3; 353 skip(tableSize); 354 } 355 numberOfImages = 0; 356 int blockType; 357 do 358 { 359 blockType = read(); 360 switch(blockType) 361 { 362 case(0x2c): { 364 if (read(a, 0, 9) != 9) { 365 return false; 366 } 367 flags = a[8] & 0xff; 368 int localBitsPerPixel = (flags & 0x07) + 1; 369 if (localBitsPerPixel > bitsPerPixel) { 370 bitsPerPixel = localBitsPerPixel; 371 } 372 if ((flags & 0x80) != 0) { 373 skip((1 << localBitsPerPixel) * 3); 374 } 375 skip(1); int n; 377 do 378 { 379 n = read(); 380 if (n > 0) { 381 skip(n); 382 } 383 else 384 if (n == -1) { 385 return false; 386 } 387 } 388 while (n > 0); 389 numberOfImages++; 390 break; 391 } 392 case(0x21): { 394 int extensionType = read(); 395 if (collectComments && extensionType == 0xfe) { 396 StringBuffer sb = new StringBuffer (); 397 int n; 398 do 399 { 400 n = read(); 401 if (n == -1) { 402 return false; 403 } 404 if (n > 0) { 405 for (int i = 0; i < n; i++) { 406 int ch = read(); 407 if (ch == -1) { 408 return false; 409 } 410 sb.append((char)ch); 411 } 412 } 413 } 414 while (n > 0); 415 } else { 416 int n; 417 do 418 { 419 n = read(); 420 if (n > 0) { 421 skip(n); 422 } 423 else 424 if (n == -1) { 425 return false; 426 } 427 } 428 while (n > 0); 429 } 430 break; 431 } 432 case(0x3b): { 434 break; 435 } 436 default: 437 { 438 return false; 439 } 440 } 441 } 442 while (blockType != 0x3b); 443 return true; 444 } 445 446 private boolean checkIff() throws IOException { 447 byte[] a = new byte[10]; 448 if (read(a, 0, 10) != 10) { 451 return false; 452 } 453 final byte[] IFF_RM = {0x52, 0x4d}; 454 if (!equals(a, 0, IFF_RM, 0, 2)) { 455 return false; 456 } 457 int type = getIntBigEndian(a, 6); 458 if (type != 0x494c424d && type != 0x50424d20) { return false; 461 } 462 do { 464 if (read(a, 0, 8) != 8) { 465 return false; 466 } 467 int chunkId = getIntBigEndian(a, 0); 468 int size = getIntBigEndian(a, 4); 469 if ((size & 1) == 1) { 470 size++; 471 } 472 if (chunkId == 0x424d4844) { if (read(a, 0, 9) != 9) { 474 return false; 475 } 476 format = FORMAT_IFF; 477 width = getShortBigEndian(a, 0); 478 height = getShortBigEndian(a, 2); 479 bitsPerPixel = a[8] & 0xff; 480 return (width > 0 && height > 0 && bitsPerPixel > 0 && bitsPerPixel < 33); 481 } else { 482 skip(size); 483 } 484 } while (true); 485 } 486 487 private boolean checkJpeg() throws IOException { 488 byte[] data = new byte[12]; 489 while (true) { 490 if (read(data, 0, 4) != 4) { 491 return false; 492 } 493 int marker = getShortBigEndian(data, 0); 494 int size = getShortBigEndian(data, 2); 495 if ((marker & 0xff00) != 0xff00) { 496 return false; } 498 if (marker == 0xffe0) { if (size < 14) { 500 return false; } 502 if (read(data, 0, 12) != 12) { 503 return false; 504 } 505 final byte[] APP0_ID = {0x4a, 0x46, 0x49, 0x46, 0x00}; 506 if (equals(APP0_ID, 0, data, 0, 5)) { 507 if (data[7] == 1) { 509 setPhysicalWidthDpi(getShortBigEndian(data, 8)); 510 setPhysicalHeightDpi(getShortBigEndian(data, 10)); 511 } 512 else 513 if (data[7] == 2) { 514 int x = getShortBigEndian(data, 8); 515 int y = getShortBigEndian(data, 10); 516 setPhysicalWidthDpi((int)(x * 2.54f)); 517 setPhysicalHeightDpi((int)(y * 2.54f)); 518 } 519 } 520 skip(size - 14); 521 } 522 else 523 if (collectComments && size > 2 && marker == 0xfffe) { size -= 2; 525 byte[] chars = new byte[size]; 526 if (read(chars, 0, size) != size) { 527 return false; 528 } 529 String comment = new String (chars, "iso-8859-1"); 530 comment = comment.trim(); 531 addComment(comment); 533 } 534 else 535 if (marker >= 0xffc0 && marker <= 0xffcf && marker != 0xffc4 && marker != 0xffc8) { 536 if (read(data, 0, 6) != 6) { 537 return false; 538 } 539 format = FORMAT_JPEG; 540 bitsPerPixel = (data[0] & 0xff) * (data[5] & 0xff); 541 width = getShortBigEndian(data, 3); 542 height = getShortBigEndian(data, 1); 543 return true; 544 } else { 545 skip(size - 2); 546 } 547 } 548 } 549 550 private boolean checkPcx() throws IOException { 551 byte[] a = new byte[64]; 552 if (read(a) != a.length) { 553 return false; 554 } 555 if (a[0] != 1) { return false; 557 } 558 int x1 = getShortLittleEndian(a, 2); 560 int y1 = getShortLittleEndian(a, 4); 561 int x2 = getShortLittleEndian(a, 6); 562 int y2 = getShortLittleEndian(a, 8); 563 if (x1 < 0 || x2 < x1 || y1 < 0 || y2 < y1) { 564 return false; 565 } 566 width = x2 - x1 + 1; 567 height = y2 - y1 + 1; 568 int bits = a[1]; 570 int planes = a[63]; 571 if (planes == 1 && 572 (bits == 1 || bits == 2 || bits == 4 || bits == 8)) { 573 bitsPerPixel = bits; 575 } else 576 if (planes == 3 && bits == 8) { 577 bitsPerPixel = 24; 579 } else { 580 return false; 581 } 582 setPhysicalWidthDpi(getShortLittleEndian(a, 10)); 583 setPhysicalHeightDpi(getShortLittleEndian(a, 10)); 584 format = FORMAT_PCX; 585 return true; 586 } 587 588 private boolean checkPng() throws IOException { 589 final byte[] PNG_MAGIC = {0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a}; 590 byte[] a = new byte[24]; 591 if (read(a) != 24) { 592 return false; 593 } 594 if (!equals(a, 0, PNG_MAGIC, 0, 6)) { 595 return false; 596 } 597 format = FORMAT_PNG; 598 width = getIntBigEndian(a, 14); 599 height = getIntBigEndian(a, 18); 600 bitsPerPixel = a[22] & 0xff; 601 int colorType = a[23] & 0xff; 602 if (colorType == 2 || colorType == 6) { 603 bitsPerPixel *= 3; 604 } 605 return true; 606 } 607 608 private boolean checkPnm(int id) throws IOException { 609 if (id < 1 || id > 6) { 610 return false; 611 } 612 final int[] PNM_FORMATS = {FORMAT_PBM, FORMAT_PGM, FORMAT_PPM}; 613 format = PNM_FORMATS[(id - 1) % 3]; 614 boolean hasPixelResolution = false; 615 String s; 616 while (true) 617 { 618 s = readLine(); 619 if (s != null) { 620 s = s.trim(); 621 } 622 if (s == null || s.length() < 1) { 623 continue; 624 } 625 if (s.charAt(0) == '#') { if (collectComments && s.length() > 1) { 627 addComment(s.substring(1)); 628 } 629 continue; 630 } 631 if (!hasPixelResolution) { int spaceIndex = s.indexOf(' '); 633 if (spaceIndex == -1) { 634 return false; 635 } 636 String widthString = s.substring(0, spaceIndex); 637 spaceIndex = s.lastIndexOf(' '); 638 if (spaceIndex == -1) { 639 return false; 640 } 641 String heightString = s.substring(spaceIndex + 1); 642 try { 643 width = Integer.parseInt(widthString); 644 height = Integer.parseInt(heightString); 645 } catch (NumberFormatException nfe) { 646 return false; 647 } 648 if (width < 1 || height < 1) { 649 return false; 650 } 651 if (format == FORMAT_PBM) { 652 bitsPerPixel = 1; 653 return true; 654 } 655 hasPixelResolution = true; 656 } 657 else 658 { 659 int maxSample; 660 try { 661 maxSample = Integer.parseInt(s); 662 } catch (NumberFormatException nfe) { 663 return false; 664 } 665 if (maxSample < 0) { 666 return false; 667 } 668 for (int i = 0; i < 25; i++) { 669 if (maxSample < (1 << (i + 1))) { 670 bitsPerPixel = i + 1; 671 if (format == FORMAT_PPM) { 672 bitsPerPixel *= 3; 673 } 674 return true; 675 } 676 } 677 return false; 678 } 679 } 680 } 681 682 private boolean checkPsd() throws IOException { 683 byte[] a = new byte[24]; 684 if (read(a) != a.length) { 685 return false; 686 } 687 final byte[] PSD_MAGIC = {0x50, 0x53}; 688 if (!equals(a, 0, PSD_MAGIC, 0, 2)) { 689 return false; 690 } 691 format = FORMAT_PSD; 692 width = getIntBigEndian(a, 16); 693 height = getIntBigEndian(a, 12); 694 int channels = getShortBigEndian(a, 10); 695 int depth = getShortBigEndian(a, 20); 696 bitsPerPixel = channels * depth; 697 return (width > 0 && height > 0 && bitsPerPixel > 0 && bitsPerPixel <= 64); 698 } 699 700 private boolean checkRas() throws IOException { 701 byte[] a = new byte[14]; 702 if (read(a) != a.length) { 703 return false; 704 } 705 final byte[] RAS_MAGIC = {0x6a, (byte)0x95}; 706 if (!equals(a, 0, RAS_MAGIC, 0, 2)) { 707 return false; 708 } 709 format = FORMAT_RAS; 710 width = getIntBigEndian(a, 2); 711 height = getIntBigEndian(a, 6); 712 bitsPerPixel = getIntBigEndian(a, 10); 713 return (width > 0 && height > 0 && bitsPerPixel > 0 && bitsPerPixel <= 24); 714 } 715 716 private boolean checkSwf() throws IOException { 718 byte[] a = new byte[6]; 720 if (read(a) != a.length) { 721 return false; 722 } 723 format = FORMAT_SWF; 724 int bitSize = (int)readUBits( 5 ); 725 int minX = (int)readSBits( bitSize ); 726 int maxX = (int)readSBits( bitSize ); 727 int minY = (int)readSBits( bitSize ); 728 int maxY = (int)readSBits( bitSize ); 729 width = maxX/20; height = maxY/20; setPhysicalWidthDpi(72); 732 setPhysicalHeightDpi(72); 733 return (width > 0 && height > 0); 734 } 735 736 740 private static boolean determineVerbosity(String [] args) { 741 if (args != null && args.length > 0) { 742 for (int i = 0; i < args.length; i++) { 743 if ("-c".equals(args[i])) { 744 return false; 745 } 746 } 747 } 748 return true; 749 } 750 751 private boolean equals(byte[] a1, int offs1, byte[] a2, int offs2, int num) { 752 while (num-- > 0) { 753 if (a1[offs1++] != a2[offs2++]) { 754 return false; 755 } 756 } 757 return true; 758 } 759 760 765 public int getBitsPerPixel() { 766 return bitsPerPixel; 767 } 768 769 775 public String getComment(int index) { 776 if (comments == null || index < 0 || index >= comments.size()) { 777 throw new IllegalArgumentException ("Not a valid comment index: " + index); 778 } 779 return (String )comments.elementAt(index); 780 } 781 782 788 public int getFormat() { 789 return format; 790 } 791 792 797 public String getFormatName() { 798 if (format >= 0 && format < FORMAT_NAMES.length) { 799 return FORMAT_NAMES[format]; 800 } else { 801 return "?"; 802 } 803 } 804 805 810 public int getHeight() { 811 return height; 812 } 813 814 private int getIntBigEndian(byte[] a, int offs) { 815 return 816 (a[offs] & 0xff) << 24 | 817 (a[offs + 1] & 0xff) << 16 | 818 (a[offs + 2] & 0xff) << 8 | 819 a[offs + 3] & 0xff; 820 } 821 822 private int getIntLittleEndian(byte[] a, int offs) { 823 return 824 (a[offs + 3] & 0xff) << 24 | 825 (a[offs + 2] & 0xff) << 16 | 826 (a[offs + 1] & 0xff) << 8 | 827 a[offs] & 0xff; 828 } 829 830 835 public String getMimeType() { 836 if (format >= 0 && format < MIME_TYPE_STRINGS.length) { 837 return MIME_TYPE_STRINGS[format]; 838 } else { 839 return null; 840 } 841 } 842 843 851 public int getNumberOfComments() 852 { 853 if (comments == null) { 854 return 0; 855 } else { 856 return comments.size(); 857 } 858 } 859 860 867 public int getNumberOfImages() 868 { 869 return numberOfImages; 870 } 871 872 880 public int getPhysicalHeightDpi() { 881 return physicalHeightDpi; 882 } 883 884 892 public float getPhysicalHeightInch() { 893 int h = getHeight(); 894 int ph = getPhysicalHeightDpi(); 895 if (h > 0 && ph > 0) { 896 return ((float)h) / ((float)ph); 897 } else { 898 return -1.0f; 899 } 900 } 901 902 910 public int getPhysicalWidthDpi() { 911 return physicalWidthDpi; 912 } 913 914 922 public float getPhysicalWidthInch() { 923 int w = getWidth(); 924 int pw = getPhysicalWidthDpi(); 925 if (w > 0 && pw > 0) { 926 return ((float)w) / ((float)pw); 927 } else { 928 return -1.0f; 929 } 930 } 931 932 private int getShortBigEndian(byte[] a, int offs) { 933 return 934 (a[offs] & 0xff) << 8 | 935 (a[offs + 1] & 0xff); 936 } 937 938 private int getShortLittleEndian(byte[] a, int offs) { 939 return (a[offs] & 0xff) | (a[offs + 1] & 0xff) << 8; 940 } 941 942 947 public int getWidth() { 948 return width; 949 } 950 951 959 public static void main(String [] args) { 960 ImageInfo imageInfo = new ImageInfo(); 961 imageInfo.setDetermineImageNumber(true); 962 boolean verbose = determineVerbosity(args); 963 if (args.length == 0) { 964 run(null, System.in, imageInfo, verbose); 965 } else { 966 int index = 0; 967 while (index < args.length) { 968 InputStream in = null; 969 try { 970 String name = args[index++]; 971 System.out.print(name + ";"); 972 if (name.startsWith("http://")) { 973 in = new URL(name).openConnection().getInputStream(); 974 } else { 975 in = new FileInputStream (name); 976 } 977 run(name, in, imageInfo, verbose); 978 in.close(); 979 } catch (Exception e) { 980 System.out.println(e); 981 try { 982 in.close(); 983 } catch (Exception ee) { 984 } 985 } 986 } 987 } 988 } 989 990 private static void print(String sourceName, ImageInfo ii, boolean verbose) { 991 if (verbose) { 992 printVerbose(sourceName, ii); 993 } else { 994 printCompact(sourceName, ii); 995 } 996 } 997 998 private static void printCompact(String sourceName, ImageInfo imageInfo) { 999 System.out.println( 1000 imageInfo.getFormatName() + ";" + 1001 imageInfo.getMimeType() + ";" + 1002 imageInfo.getWidth() + ";" + 1003 imageInfo.getHeight() + ";" + 1004 imageInfo.getBitsPerPixel() + ";" + 1005 imageInfo.getNumberOfImages() + ";" + 1006 imageInfo.getPhysicalWidthDpi() + ";" + 1007 imageInfo.getPhysicalHeightDpi() + ";" + 1008 imageInfo.getPhysicalWidthInch() + ";" + 1009 imageInfo.getPhysicalHeightInch() 1010 ); 1011 } 1012 1013 private static void printLine(int indentLevels, String text, float value, float minValidValue) { 1014 if (value < minValidValue) { 1015 return; 1016 } 1017 printLine(indentLevels, text, Float.toString(value)); 1018 } 1019 1020 private static void printLine(int indentLevels, String text, int value, int minValidValue) { 1021 if (value >= minValidValue) { 1022 printLine(indentLevels, text, Integer.toString(value)); 1023 } 1024 } 1025 1026 private static void printLine(int indentLevels, String text, String value) { 1027 if (value == null || value.length() == 0) { 1028 return; 1029 } 1030 while (indentLevels-- > 0) { 1031 System.out.print("\t"); 1032 } 1033 if (text != null && text.length() > 0) { 1034 System.out.print(text); 1035 System.out.print(" "); 1036 } 1037 System.out.println(value); 1038 } 1039 1040 private static void printVerbose(String sourceName, ImageInfo ii) { 1041 printLine(0, null, sourceName); 1042 printLine(1, "File format: ", ii.getFormatName()); 1043 printLine(1, "MIME type: ", ii.getMimeType()); 1044 printLine(1, "Width (pixels): ", ii.getWidth(), 1); 1045 printLine(1, "Height (pixels): ", ii.getHeight(), 1); 1046 printLine(1, "Bits per pixel: ", ii.getBitsPerPixel(), 1); 1047 printLine(1, "Number of images: ", ii.getNumberOfImages(), 1); 1048 printLine(1, "Physical width (dpi): ", ii.getPhysicalWidthDpi(), 1); 1049 printLine(1, "Physical height (dpi): ", ii.getPhysicalHeightDpi(), 1); 1050 printLine(1, "Physical width (inches): ", ii.getPhysicalWidthInch(), 1.0f); 1051 printLine(1, "Physical height (inches): ", ii.getPhysicalHeightInch(), 1.0f); 1052 int numComments = ii.getNumberOfComments(); 1053 printLine(1, "Number of textual comments: ", numComments, 1); 1054 if (numComments > 0) { 1055 for (int i = 0; i < numComments; i++) { 1056 printLine(2, null, ii.getComment(i)); 1057 } 1058 } 1059 } 1060 1061 private int read() throws IOException { 1062 if (in != null) { 1063 return in.read(); 1064 } else { 1065 return din.readByte(); 1066 } 1067 } 1068 1069 private int read(byte[] a) throws IOException { 1070 if (in != null) { 1071 return in.read(a); 1072 } else { 1073 din.readFully(a); 1074 return a.length; 1075 } 1076 } 1077 1078 private int read(byte[] a, int offset, int num) throws IOException { 1079 if (in != null) { 1080 return in.read(a, offset, num); 1081 } else { 1082 din.readFully(a, offset, num); 1083 return num; 1084 } 1085 } 1086 1087 private String readLine() throws IOException { 1088 return readLine(new StringBuffer ()); 1089 } 1090 1091 private String readLine(StringBuffer sb) throws IOException { 1092 boolean finished; 1093 do { 1094 int value = read(); 1095 finished = (value == -1 || value == 10); 1096 if (!finished) { 1097 sb.append((char)value); 1098 } 1099 } while (!finished); 1100 return sb.toString(); 1101 } 1102 1103 1106 public long readUBits( int numBits ) throws IOException 1107 { 1108 if (numBits == 0) { 1109 return 0; 1110 } 1111 int bitsLeft = numBits; 1112 long result = 0; 1113 if (bitPos == 0) { if (in != null) { 1115 bitBuf = in.read(); 1116 } else { 1117 bitBuf = din.readByte(); 1118 } 1119 bitPos = 8; 1120 } 1121 1122 while( true ) 1123 { 1124 int shift = bitsLeft - bitPos; 1125 if( shift > 0 ) 1126 { 1127 result |= bitBuf << shift; 1129 bitsLeft -= bitPos; 1130 1131 if (in != null) { 1133 bitBuf = in.read(); 1134 } else { 1135 bitBuf = din.readByte(); 1136 } 1137 bitPos = 8; 1138 } 1139 else 1140 { 1141 result |= bitBuf >> -shift; 1143 bitPos -= bitsLeft; 1144 bitBuf &= 0xff >> (8 - bitPos); 1146 return result; 1147 } 1148 } 1149 } 1150 1151 1154 private int readSBits( int numBits ) throws IOException 1155 { 1156 long uBits = readUBits( numBits ); 1158 1159 if( ( uBits & (1L << (numBits - 1))) != 0 ) 1161 { 1162 uBits |= -1L << numBits; 1164 } 1165 1166 return (int)uBits; 1167 } 1168 1169 1172 public void synchBits() 1173 { 1174 bitBuf = 0; 1175 bitPos = 0; 1176 } 1177 1178 private String readLine(int firstChar) throws IOException { 1179 StringBuffer result = new StringBuffer (); 1180 result.append((char)firstChar); 1181 return readLine(result); 1182 } 1183 1184 private static void run(String sourceName, InputStream in, ImageInfo imageInfo, boolean verbose) { 1185 imageInfo.setInput(in); 1186 imageInfo.setDetermineImageNumber(false); 1187 imageInfo.setCollectComments(verbose); 1188 if (imageInfo.check()) { 1189 print(sourceName, imageInfo, verbose); 1190 } 1191 } 1192 1193 1201 public void setCollectComments(boolean newValue) 1202 { 1203 collectComments = newValue; 1204 } 1205 1206 1220 public void setDetermineImageNumber(boolean newValue) 1221 { 1222 determineNumberOfImages = newValue; 1223 } 1224 1225 1231 public void setInput(DataInput dataInput) { 1232 din = dataInput; 1233 in = null; 1234 } 1235 1236 1240 public void setInput(InputStream inputStream) { 1241 in = inputStream; 1242 din = null; 1243 } 1244 1245 private void setPhysicalHeightDpi(int newValue) { 1246 physicalWidthDpi = newValue; 1247 } 1248 1249 private void setPhysicalWidthDpi(int newValue) { 1250 physicalHeightDpi = newValue; 1251 } 1252 1253 private void skip(int num) throws IOException { 1254 while (num > 0) { 1255 long result; 1256 if (in != null) { 1257 result = in.skip(num); 1258 } else { 1259 result = din.skipBytes(num); 1260 } 1261 if (result > 0) { 1262 num -= result; 1263 } 1264 } 1265 } 1266} 1267 | Popular Tags |