1 16 17 30 package org.wings.util; 31 32 import java.io.DataInput ; 33 import java.io.FileInputStream ; 34 import java.io.IOException ; 35 import java.io.InputStream ; 36 import java.net.URL ; 37 import java.util.ArrayList ; 38 import java.util.List ; 39 40 136 public class ImageInfo { 137 145 public static final int FORMAT_JPEG = 0; 146 147 156 public static final int FORMAT_GIF = 1; 157 158 165 public static final int FORMAT_PNG = 2; 166 167 173 public static final int FORMAT_BMP = 3; 174 175 180 public static final int FORMAT_PCX = 4; 181 182 185 public static final int FORMAT_IFF = 5; 186 187 192 public static final int FORMAT_RAS = 6; 193 194 197 public static final int FORMAT_PBM = 7; 198 199 202 public static final int FORMAT_PGM = 8; 203 204 207 public static final int FORMAT_PPM = 9; 208 209 212 public static final int FORMAT_PSD = 10; 213 214 217 public static final int FORMAT_SWF = 11; 218 219 public static final int COLOR_TYPE_UNKNOWN = -1; 220 public static final int COLOR_TYPE_TRUECOLOR_RGB = 0; 221 public static final int COLOR_TYPE_PALETTED = 1; 222 public static final int COLOR_TYPE_GRAYSCALE = 2; 223 public static final int COLOR_TYPE_BLACK_AND_WHITE = 3; 224 225 230 public static final String [] FORMAT_NAMES = 231 {"JPEG", "GIF", "PNG", "BMP", "PCX", 232 "IFF", "RAS", "PBM", "PGM", "PPM", 233 "PSD", "SWF"}; 234 235 240 public static final String [] MIME_TYPE_STRINGS = 241 {"image/jpeg", "image/gif", "image/png", "image/bmp", "image/pcx", 242 "image/iff", "image/ras", "image/x-portable-bitmap", "image/x-portable-graymap", "image/x-portable-pixmap", 243 "image/psd", "application/x-shockwave-flash"}; 244 245 private int width; 246 private int height; 247 private int bitsPerPixel; 248 private int colorType = COLOR_TYPE_UNKNOWN; 249 private boolean progressive; 250 private int format; 251 private InputStream in; 252 private DataInput din; 253 private boolean collectComments = true; 254 private List comments; 255 private boolean determineNumberOfImages; 256 private int numberOfImages; 257 private int physicalHeightDpi; 258 private int physicalWidthDpi; 259 private int bitBuf; 260 private int bitPos; 261 262 private void addComment(String s) { 263 if (comments == null) { 264 comments = new ArrayList (); 265 } 266 comments.add(s); 267 } 268 269 277 public boolean check() { 278 format = -1; 279 width = -1; 280 height = -1; 281 bitsPerPixel = -1; 282 numberOfImages = 1; 283 physicalHeightDpi = -1; 284 physicalWidthDpi = -1; 285 comments = null; 286 try { 287 int b1 = read() & 0xff; 288 int b2 = read() & 0xff; 289 if (b1 == 0x47 && b2 == 0x49) { 290 return checkGif(); 291 } else if (b1 == 0x89 && b2 == 0x50) { 292 return checkPng(); 293 } else if (b1 == 0xff && b2 == 0xd8) { 294 return checkJpeg(); 295 } else if (b1 == 0x42 && b2 == 0x4d) { 296 return checkBmp(); 297 } else if (b1 == 0x0a && b2 < 0x06) { 298 return checkPcx(); 299 } else if (b1 == 0x46 && b2 == 0x4f) { 300 return checkIff(); 301 } else if (b1 == 0x59 && b2 == 0xa6) { 302 return checkRas(); 303 } else if (b1 == 0x50 && b2 >= 0x31 && b2 <= 0x36) { 304 return checkPnm(b2 - '0'); 305 } else if (b1 == 0x38 && b2 == 0x42) { 306 return checkPsd(); 307 } else if (b1 == 0x46 && b2 == 0x57) { 308 return checkSwf(); 309 } else { 310 return false; 311 } 312 } catch (IOException ioe) { 313 return false; 314 } 315 } 316 317 private boolean checkBmp() throws IOException { 318 byte[] a = new byte[44]; 319 if (read(a) != a.length) { 320 return false; 321 } 322 width = getIntLittleEndian(a, 16); 323 height = getIntLittleEndian(a, 20); 324 if (width < 1 || height < 1) { 325 return false; 326 } 327 bitsPerPixel = getShortLittleEndian(a, 26); 328 if (bitsPerPixel != 1 && bitsPerPixel != 4 && 329 bitsPerPixel != 8 && bitsPerPixel != 16 && 330 bitsPerPixel != 24 && bitsPerPixel != 32) { 331 return false; 332 } 333 int x = (int) (getIntLittleEndian(a, 36) * 0.0254); 334 if (x > 0) { 335 setPhysicalWidthDpi(x); 336 } 337 int y = (int) (getIntLittleEndian(a, 40) * 0.0254); 338 if (y > 0) { 339 setPhysicalHeightDpi(y); 340 } 341 format = FORMAT_BMP; 342 return true; 343 } 344 345 private boolean checkGif() throws IOException { 346 final byte[] GIF_MAGIC_87A = {0x46, 0x38, 0x37, 0x61}; 347 final byte[] GIF_MAGIC_89A = {0x46, 0x38, 0x39, 0x61}; 348 byte[] a = new byte[11]; if (read(a) != 11) { 350 return false; 351 } 352 if ((!equals(a, 0, GIF_MAGIC_89A, 0, 4)) && 353 (!equals(a, 0, GIF_MAGIC_87A, 0, 4))) { 354 return false; 355 } 356 format = FORMAT_GIF; 357 width = getShortLittleEndian(a, 4); 358 height = getShortLittleEndian(a, 6); 359 int flags = a[8] & 0xff; 360 bitsPerPixel = ((flags >> 4) & 0x07) + 1; 361 progressive = (flags & 0x02) != 0; 362 if (!determineNumberOfImages) { 363 return true; 364 } 365 if ((flags & 0x80) != 0) { 367 int tableSize = (1 << ((flags & 7) + 1)) * 3; 368 skip(tableSize); 369 } 370 numberOfImages = 0; 371 int blockType; 372 do { 373 blockType = read(); 374 switch (blockType) { 375 case (0x2c): { 377 if (read(a, 0, 9) != 9) { 378 return false; 379 } 380 flags = a[8] & 0xff; 381 int localBitsPerPixel = (flags & 0x07) + 1; 382 if (localBitsPerPixel > bitsPerPixel) { 383 bitsPerPixel = localBitsPerPixel; 384 } 385 if ((flags & 0x80) != 0) { 386 skip((1 << localBitsPerPixel) * 3); 387 } 388 skip(1); int n; 390 do { 391 n = read(); 392 if (n > 0) { 393 skip(n); 394 } else if (n == -1) { 395 return false; 396 } 397 } while (n > 0); 398 numberOfImages++; 399 break; 400 } 401 case (0x21): { 403 int extensionType = read(); 404 if (collectComments && extensionType == 0xfe) { 405 StringBuffer sb = new StringBuffer (); 406 int n; 407 do { 408 n = read(); 409 if (n == -1) { 410 return false; 411 } 412 if (n > 0) { 413 for (int i = 0; i < n; i++) { 414 int ch = read(); 415 if (ch == -1) { 416 return false; 417 } 418 sb.append((char) ch); 419 } 420 } 421 } while (n > 0); 422 } else { 423 int n; 424 do { 425 n = read(); 426 if (n > 0) { 427 skip(n); 428 } else if (n == -1) { 429 return false; 430 } 431 } while (n > 0); 432 } 433 break; 434 } 435 case (0x3b): { 437 break; 438 } 439 default: 440 { 441 return false; 442 } 443 } 444 } while (blockType != 0x3b); 445 return true; 446 } 447 448 private boolean checkIff() throws IOException { 449 byte[] a = new byte[10]; 450 if (read(a, 0, 10) != 10) { 453 return false; 454 } 455 final byte[] IFF_RM = {0x52, 0x4d}; 456 if (!equals(a, 0, IFF_RM, 0, 2)) { 457 return false; 458 } 459 int type = getIntBigEndian(a, 6); 460 if (type != 0x494c424d && type != 0x50424d20) { return false; 463 } 464 do { 466 if (read(a, 0, 8) != 8) { 467 return false; 468 } 469 int chunkId = getIntBigEndian(a, 0); 470 int size = getIntBigEndian(a, 4); 471 if ((size & 1) == 1) { 472 size++; 473 } 474 if (chunkId == 0x424d4844) { if (read(a, 0, 9) != 9) { 476 return false; 477 } 478 format = FORMAT_IFF; 479 width = getShortBigEndian(a, 0); 480 height = getShortBigEndian(a, 2); 481 bitsPerPixel = a[8] & 0xff; 482 return (width > 0 && height > 0 && bitsPerPixel > 0 && bitsPerPixel < 33); 483 } else { 484 skip(size); 485 } 486 } while (true); 487 } 488 489 private boolean checkJpeg() throws IOException { 490 byte[] data = new byte[12]; 491 while (true) { 492 if (read(data, 0, 4) != 4) { 493 return false; 494 } 495 int marker = getShortBigEndian(data, 0); 496 int size = getShortBigEndian(data, 2); 497 if ((marker & 0xff00) != 0xff00) { 498 return false; } 500 if (marker == 0xffe0) { if (size < 14) { 502 return false; } 504 if (read(data, 0, 12) != 12) { 505 return false; 506 } 507 final byte[] APP0_ID = {0x4a, 0x46, 0x49, 0x46, 0x00}; 508 if (equals(APP0_ID, 0, data, 0, 5)) { 509 if (data[7] == 1) { 511 setPhysicalWidthDpi(getShortBigEndian(data, 8)); 512 setPhysicalHeightDpi(getShortBigEndian(data, 10)); 513 } else 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 } else if (collectComments && size > 2 && marker == 0xfffe) { size -= 2; 523 byte[] chars = new byte[size]; 524 if (read(chars, 0, size) != size) { 525 return false; 526 } 527 String comment = new String (chars, "iso-8859-1"); 528 comment = comment.trim(); 529 addComment(comment); 530 } else if (marker >= 0xffc0 && marker <= 0xffcf && marker != 0xffc4 && marker != 0xffc8) { 531 if (read(data, 0, 6) != 6) { 532 return false; 533 } 534 format = FORMAT_JPEG; 535 bitsPerPixel = (data[0] & 0xff) * (data[5] & 0xff); 536 progressive = marker == 0xffc2 || marker == 0xffc6 || 537 marker == 0xffca || marker == 0xffce; 538 width = getShortBigEndian(data, 3); 539 height = getShortBigEndian(data, 1); 540 return true; 541 } else { 542 skip(size - 2); 543 } 544 } 545 } 546 547 private boolean checkPcx() throws IOException { 548 byte[] a = new byte[64]; 549 if (read(a) != a.length) { 550 return false; 551 } 552 if (a[0] != 1) { return false; 554 } 555 int x1 = getShortLittleEndian(a, 2); 557 int y1 = getShortLittleEndian(a, 4); 558 int x2 = getShortLittleEndian(a, 6); 559 int y2 = getShortLittleEndian(a, 8); 560 if (x1 < 0 || x2 < x1 || y1 < 0 || y2 < y1) { 561 return false; 562 } 563 width = x2 - x1 + 1; 564 height = y2 - y1 + 1; 565 int bits = a[1]; 567 int planes = a[63]; 568 if (planes == 1 && 569 (bits == 1 || bits == 2 || bits == 4 || bits == 8)) { 570 bitsPerPixel = bits; 572 } else if (planes == 3 && bits == 8) { 573 bitsPerPixel = 24; 575 } else { 576 return false; 577 } 578 setPhysicalWidthDpi(getShortLittleEndian(a, 10)); 579 setPhysicalHeightDpi(getShortLittleEndian(a, 10)); 580 format = FORMAT_PCX; 581 return true; 582 } 583 584 private boolean checkPng() throws IOException { 585 final byte[] PNG_MAGIC = {0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a}; 586 byte[] a = new byte[27]; 587 if (read(a) != 27) { 588 return false; 589 } 590 if (!equals(a, 0, PNG_MAGIC, 0, 6)) { 591 return false; 592 } 593 format = FORMAT_PNG; 594 width = getIntBigEndian(a, 14); 595 height = getIntBigEndian(a, 18); 596 bitsPerPixel = a[22] & 0xff; 597 colorType = a[23] & 0xff; 598 if (colorType == 2 || colorType == 6) { 599 bitsPerPixel *= 3; 600 } 601 progressive = (a[26] & 0xff) != 0; 602 return true; 603 } 604 605 private boolean checkPnm(int id) throws IOException { 606 if (id < 1 || id > 6) { 607 return false; 608 } 609 final int[] PNM_FORMATS = {FORMAT_PBM, FORMAT_PGM, FORMAT_PPM}; 610 format = PNM_FORMATS[(id - 1) % 3]; 611 boolean hasPixelResolution = false; 612 String s; 613 while (true) { 614 s = readLine(); 615 if (s != null) { 616 s = s.trim(); 617 } 618 if (s == null || s.length() < 1) { 619 continue; 620 } 621 if (s.charAt(0) == '#') { if (collectComments && s.length() > 1) { 623 addComment(s.substring(1)); 624 } 625 continue; 626 } 627 if (!hasPixelResolution) { int spaceIndex = s.indexOf(' '); 629 if (spaceIndex == -1) { 630 return false; 631 } 632 String widthString = s.substring(0, spaceIndex); 633 spaceIndex = s.lastIndexOf(' '); 634 if (spaceIndex == -1) { 635 return false; 636 } 637 String heightString = s.substring(spaceIndex + 1); 638 try { 639 width = Integer.parseInt(widthString); 640 height = Integer.parseInt(heightString); 641 } catch (NumberFormatException nfe) { 642 return false; 643 } 644 if (width < 1 || height < 1) { 645 return false; 646 } 647 if (format == FORMAT_PBM) { 648 bitsPerPixel = 1; 649 return true; 650 } 651 hasPixelResolution = true; 652 } else { 653 int maxSample; 654 try { 655 maxSample = Integer.parseInt(s); 656 } catch (NumberFormatException nfe) { 657 return false; 658 } 659 if (maxSample < 0) { 660 return false; 661 } 662 for (int i = 0; i < 25; i++) { 663 if (maxSample < (1 << (i + 1))) { 664 bitsPerPixel = i + 1; 665 if (format == FORMAT_PPM) { 666 bitsPerPixel *= 3; 667 } 668 return true; 669 } 670 } 671 return false; 672 } 673 } 674 } 675 676 private boolean checkPsd() throws IOException { 677 byte[] a = new byte[24]; 678 if (read(a) != a.length) { 679 return false; 680 } 681 final byte[] PSD_MAGIC = {0x50, 0x53}; 682 if (!equals(a, 0, PSD_MAGIC, 0, 2)) { 683 return false; 684 } 685 format = FORMAT_PSD; 686 width = getIntBigEndian(a, 16); 687 height = getIntBigEndian(a, 12); 688 int channels = getShortBigEndian(a, 10); 689 int depth = getShortBigEndian(a, 20); 690 bitsPerPixel = channels * depth; 691 return (width > 0 && height > 0 && bitsPerPixel > 0 && bitsPerPixel <= 64); 692 } 693 694 private boolean checkRas() throws IOException { 695 byte[] a = new byte[14]; 696 if (read(a) != a.length) { 697 return false; 698 } 699 final byte[] RAS_MAGIC = {0x6a, (byte) 0x95}; 700 if (!equals(a, 0, RAS_MAGIC, 0, 2)) { 701 return false; 702 } 703 format = FORMAT_RAS; 704 width = getIntBigEndian(a, 2); 705 height = getIntBigEndian(a, 6); 706 bitsPerPixel = getIntBigEndian(a, 10); 707 return (width > 0 && height > 0 && bitsPerPixel > 0 && bitsPerPixel <= 24); 708 } 709 710 private boolean checkSwf() throws IOException { 712 byte[] a = new byte[6]; 714 if (read(a) != a.length) { 715 return false; 716 } 717 format = FORMAT_SWF; 718 int bitSize = (int) readUBits(5); 719 int minX = (int) readSBits(bitSize); 720 int maxX = (int) readSBits(bitSize); 721 int minY = (int) readSBits(bitSize); 722 int maxY = (int) readSBits(bitSize); 723 width = maxX / 20; height = maxY / 20; setPhysicalWidthDpi(72); 726 setPhysicalHeightDpi(72); 727 return (width > 0 && height > 0); 728 } 729 730 734 private static boolean determineVerbosity(String [] args) { 735 if (args != null && args.length > 0) { 736 for (int i = 0; i < args.length; i++) { 737 if ("-c".equals(args[i])) { 738 return false; 739 } 740 } 741 } 742 return true; 743 } 744 745 private boolean equals(byte[] a1, int offs1, byte[] a2, int offs2, int num) { 746 while (num-- > 0) { 747 if (a1[offs1++] != a2[offs2++]) { 748 return false; 749 } 750 } 751 return true; 752 } 753 754 760 public int getBitsPerPixel() { 761 return bitsPerPixel; 762 } 763 764 772 public String getComment(int index) { 773 if (comments == null || index < 0 || index >= comments.size()) { 774 throw new IllegalArgumentException ("Not a valid comment index: " + index); 775 } 776 return (String ) comments.get(index); 777 } 778 779 786 public int getFormat() { 787 return format; 788 } 789 790 796 public String getFormatName() { 797 if (format >= 0 && format < FORMAT_NAMES.length) { 798 return FORMAT_NAMES[format]; 799 } else { 800 return "?"; 801 } 802 } 803 804 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 836 public String getMimeType() { 837 if (format >= 0 && format < MIME_TYPE_STRINGS.length) { 838 if (format == FORMAT_JPEG && progressive) { 839 return "image/pjpeg"; 840 } 841 return MIME_TYPE_STRINGS[format]; 842 } else { 843 return null; 844 } 845 } 846 847 856 public int getNumberOfComments() { 857 if (comments == null) { 858 return 0; 859 } else { 860 return comments.size(); 861 } 862 } 863 864 872 public int getNumberOfImages() { 873 return numberOfImages; 874 } 875 876 885 public int getPhysicalHeightDpi() { 886 return physicalHeightDpi; 887 } 888 889 898 public float getPhysicalHeightInch() { 899 int h = getHeight(); 900 int ph = getPhysicalHeightDpi(); 901 if (h > 0 && ph > 0) { 902 return ((float) h) / ((float) ph); 903 } else { 904 return -1.0f; 905 } 906 } 907 908 917 public int getPhysicalWidthDpi() { 918 return physicalWidthDpi; 919 } 920 921 930 public float getPhysicalWidthInch() { 931 int w = getWidth(); 932 int pw = getPhysicalWidthDpi(); 933 if (w > 0 && pw > 0) { 934 return ((float) w) / ((float) pw); 935 } else { 936 return -1.0f; 937 } 938 } 939 940 private int getShortBigEndian(byte[] a, int offs) { 941 return 942 (a[offs] & 0xff) << 8 | 943 (a[offs + 1] & 0xff); 944 } 945 946 private int getShortLittleEndian(byte[] a, int offs) { 947 return (a[offs] & 0xff) | (a[offs + 1] & 0xff) << 8; 948 } 949 950 956 public int getWidth() { 957 return width; 958 } 959 960 965 public boolean isProgressive() { 966 return progressive; 967 } 968 969 978 public static void main(String [] args) { 979 ImageInfo imageInfo = new ImageInfo(); 980 imageInfo.setDetermineImageNumber(true); 981 boolean verbose = determineVerbosity(args); 982 if (args.length == 0) { 983 run(null, System.in, imageInfo, verbose); 984 } else { 985 int index = 0; 986 while (index < args.length) { 987 InputStream in = null; 988 try { 989 String name = args[index++]; 990 System.out.print(name + ";"); 991 if (name.startsWith("http://")) { 992 in = new URL (name).openConnection().getInputStream(); 993 } else { 994 in = new FileInputStream (name); 995 } 996 run(name, in, imageInfo, verbose); 997 in.close(); 998 } catch (Exception e) { 999 System.out.println(e); 1000 try { 1001 in.close(); 1002 } catch (Exception ee) { 1003 } 1004 } 1005 } 1006 } 1007 } 1008 1009 private static void print(String sourceName, ImageInfo ii, boolean verbose) { 1010 if (verbose) { 1011 printVerbose(sourceName, ii); 1012 } else { 1013 printCompact(sourceName, ii); 1014 } 1015 } 1016 1017 private static void printCompact(String sourceName, ImageInfo imageInfo) { 1018 System.out.println(imageInfo.getFormatName() + ";" + 1019 imageInfo.getMimeType() + ";" + 1020 imageInfo.getWidth() + ";" + 1021 imageInfo.getHeight() + ";" + 1022 imageInfo.getBitsPerPixel() + ";" + 1023 imageInfo.getNumberOfImages() + ";" + 1024 imageInfo.getPhysicalWidthDpi() + ";" + 1025 imageInfo.getPhysicalHeightDpi() + ";" + 1026 imageInfo.getPhysicalWidthInch() + ";" + 1027 imageInfo.getPhysicalHeightInch() + ";" + 1028 imageInfo.isProgressive()); 1029 } 1030 1031 private static void printLine(int indentLevels, String text, float value, float minValidValue) { 1032 if (value < minValidValue) { 1033 return; 1034 } 1035 printLine(indentLevels, text, Float.toString(value)); 1036 } 1037 1038 private static void printLine(int indentLevels, String text, int value, int minValidValue) { 1039 if (value >= minValidValue) { 1040 printLine(indentLevels, text, Integer.toString(value)); 1041 } 1042 } 1043 1044 private static void printLine(int indentLevels, String text, String value) { 1045 if (value == null || value.length() == 0) { 1046 return; 1047 } 1048 while (indentLevels-- > 0) { 1049 System.out.print("\t"); 1050 } 1051 if (text != null && text.length() > 0) { 1052 System.out.print(text); 1053 System.out.print(" "); 1054 } 1055 System.out.println(value); 1056 } 1057 1058 private static void printVerbose(String sourceName, ImageInfo ii) { 1059 printLine(0, null, sourceName); 1060 printLine(1, "File format: ", ii.getFormatName()); 1061 printLine(1, "MIME type: ", ii.getMimeType()); 1062 printLine(1, "Width (pixels): ", ii.getWidth(), 1); 1063 printLine(1, "Height (pixels): ", ii.getHeight(), 1); 1064 printLine(1, "Bits per pixel: ", ii.getBitsPerPixel(), 1); 1065 printLine(1, "Progressive: ", Boolean.toString(ii.isProgressive())); 1066 printLine(1, "Number of images: ", ii.getNumberOfImages(), 1); 1067 printLine(1, "Physical width (dpi): ", ii.getPhysicalWidthDpi(), 1); 1068 printLine(1, "Physical height (dpi): ", ii.getPhysicalHeightDpi(), 1); 1069 printLine(1, "Physical width (inches): ", ii.getPhysicalWidthInch(), 1.0f); 1070 printLine(1, "Physical height (inches): ", ii.getPhysicalHeightInch(), 1.0f); 1071 int numComments = ii.getNumberOfComments(); 1072 printLine(1, "Number of textual comments: ", numComments, 1); 1073 if (numComments > 0) { 1074 for (int i = 0; i < numComments; i++) { 1075 printLine(2, null, ii.getComment(i)); 1076 } 1077 } 1078 } 1079 1080 private int read() throws IOException { 1081 if (in != null) { 1082 return in.read(); 1083 } else { 1084 return din.readByte(); 1085 } 1086 } 1087 1088 private int read(byte[] a) throws IOException { 1089 if (in != null) { 1090 return in.read(a); 1091 } else { 1092 din.readFully(a); 1093 return a.length; 1094 } 1095 } 1096 1097 private int read(byte[] a, int offset, int num) throws IOException { 1098 if (in != null) { 1099 return in.read(a, offset, num); 1100 } else { 1101 din.readFully(a, offset, num); 1102 return num; 1103 } 1104 } 1105 1106 private String readLine() throws IOException { 1107 return readLine(new StringBuffer ()); 1108 } 1109 1110 private String readLine(StringBuffer sb) throws IOException { 1111 boolean finished; 1112 do { 1113 int value = read(); 1114 finished = (value == -1 || value == 10); 1115 if (!finished) { 1116 sb.append((char) value); 1117 } 1118 } while (!finished); 1119 return sb.toString(); 1120 } 1121 1122 private long readUBits(int numBits) throws IOException { 1123 if (numBits == 0) { 1124 return 0; 1125 } 1126 int bitsLeft = numBits; 1127 long result = 0; 1128 if (bitPos == 0) { if (in != null) { 1130 bitBuf = in.read(); 1131 } else { 1132 bitBuf = din.readByte(); 1133 } 1134 bitPos = 8; 1135 } 1136 1137 while (true) { 1138 int shift = bitsLeft - bitPos; 1139 if (shift > 0) { 1140 result |= bitBuf << shift; 1142 bitsLeft -= bitPos; 1143 1144 if (in != null) { 1146 bitBuf = in.read(); 1147 } else { 1148 bitBuf = din.readByte(); 1149 } 1150 bitPos = 8; 1151 } else { 1152 result |= bitBuf >> -shift; 1154 bitPos -= bitsLeft; 1155 bitBuf &= 0xff >> (8 - bitPos); 1157 return result; 1158 } 1159 } 1160 } 1161 1162 1165 private int readSBits(int numBits) throws IOException { 1166 long uBits = readUBits(numBits); 1168 1169 if ((uBits & (1L << (numBits - 1))) != 0) { 1171 uBits |= -1L << numBits; 1173 } 1174 1175 return (int) uBits; 1176 } 1177 1178 private void synchBits() { 1179 bitBuf = 0; 1180 bitPos = 0; 1181 } 1182 1183 private String readLine(int firstChar) throws IOException { 1184 StringBuffer result = new StringBuffer (); 1185 result.append((char) firstChar); 1186 return readLine(result); 1187 } 1188 1189 private static void run(String sourceName, InputStream in, ImageInfo imageInfo, boolean verbose) { 1190 imageInfo.setInput(in); 1191 imageInfo.setDetermineImageNumber(false); 1192 imageInfo.setCollectComments(verbose); 1193 if (imageInfo.check()) { 1194 print(sourceName, imageInfo, verbose); 1195 } 1196 } 1197 1198 1207 public void setCollectComments(boolean newValue) { 1208 collectComments = newValue; 1209 } 1210 1211 1226 public void setDetermineImageNumber(boolean newValue) { 1227 determineNumberOfImages = newValue; 1228 } 1229 1230 1237 public void setInput(DataInput dataInput) { 1238 din = dataInput; 1239 in = null; 1240 } 1241 1242 1247 public void setInput(InputStream inputStream) { 1248 in = inputStream; 1249 din = null; 1250 } 1251 1252 private void setPhysicalHeightDpi(int newValue) { 1253 physicalWidthDpi = newValue; 1254 } 1255 1256 private void setPhysicalWidthDpi(int newValue) { 1257 physicalHeightDpi = newValue; 1258 } 1259 1260 private void skip(int num) throws IOException { 1261 while (num > 0) { 1262 long result; 1263 if (in != null) { 1264 result = in.skip(num); 1265 } else { 1266 result = din.skipBytes(num); 1267 } 1268 if (result > 0) { 1269 num -= result; 1270 } 1271 } 1272 } 1273} 1274 | Popular Tags |