1 7 8 package com.sun.imageio.plugins.bmp; 9 10 import java.awt.Point ; 11 import java.awt.Rectangle ; 12 import java.awt.Transparency ; 13 import java.awt.color.ColorSpace ; 14 import java.awt.color.ICC_ColorSpace ; 15 import java.awt.color.ICC_Profile ; 16 import java.awt.image.BufferedImage ; 17 import java.awt.image.ColorModel ; 18 import java.awt.image.ComponentColorModel ; 19 import java.awt.image.ComponentSampleModel ; 20 import java.awt.image.DataBuffer ; 21 import java.awt.image.DataBufferByte ; 22 import java.awt.image.DataBufferInt ; 23 import java.awt.image.DataBufferUShort ; 24 import java.awt.image.DirectColorModel ; 25 import java.awt.image.IndexColorModel ; 26 import java.awt.image.MultiPixelPackedSampleModel ; 27 import java.awt.image.PixelInterleavedSampleModel ; 28 import java.awt.image.Raster ; 29 import java.awt.image.SampleModel ; 30 import java.awt.image.SinglePixelPackedSampleModel ; 31 import java.awt.image.WritableRaster ; 32 33 import javax.imageio.IIOException ; 34 import javax.imageio.ImageIO ; 35 import javax.imageio.ImageReader ; 36 import javax.imageio.ImageReadParam ; 37 import javax.imageio.ImageTypeSpecifier ; 38 import javax.imageio.metadata.IIOMetadata ; 39 import javax.imageio.spi.ImageReaderSpi ; 40 import javax.imageio.stream.ImageInputStream ; 41 import javax.imageio.event.IIOReadProgressListener ; 42 import javax.imageio.event.IIOReadUpdateListener ; 43 import javax.imageio.event.IIOReadWarningListener ; 44 45 import java.io.*; 46 import java.nio.*; 47 import java.util.ArrayList ; 48 import java.util.Iterator ; 49 import java.util.StringTokenizer ; 50 51 import com.sun.imageio.plugins.common.ImageUtil; 52 import com.sun.imageio.plugins.common.I18N; 53 54 62 public class BMPImageReader extends ImageReader implements BMPConstants { 63 private static final int VERSION_2_1_BIT = 0; 65 private static final int VERSION_2_4_BIT = 1; 66 private static final int VERSION_2_8_BIT = 2; 67 private static final int VERSION_2_24_BIT = 3; 68 69 private static final int VERSION_3_1_BIT = 4; 70 private static final int VERSION_3_4_BIT = 5; 71 private static final int VERSION_3_8_BIT = 6; 72 private static final int VERSION_3_24_BIT = 7; 73 74 private static final int VERSION_3_NT_16_BIT = 8; 75 private static final int VERSION_3_NT_32_BIT = 9; 76 77 private static final int VERSION_4_1_BIT = 10; 78 private static final int VERSION_4_4_BIT = 11; 79 private static final int VERSION_4_8_BIT = 12; 80 private static final int VERSION_4_16_BIT = 13; 81 private static final int VERSION_4_24_BIT = 14; 82 private static final int VERSION_4_32_BIT = 15; 83 84 private long bitmapFileSize; 86 private long bitmapOffset; 87 private long compression; 88 private long imageSize; 89 private byte palette[]; 90 private int imageType; 91 private int numBands; 92 private boolean isBottomUp; 93 private int bitsPerPixel; 94 private int redMask, greenMask, blueMask, alphaMask; 95 96 private SampleModel sampleModel, originalSampleModel; 97 private ColorModel colorModel, originalColorModel; 98 99 100 private ImageInputStream iis = null; 101 102 103 private boolean gotHeader = false; 104 105 106 private int width; 107 108 109 private int height; 110 111 112 private Rectangle destinationRegion; 113 114 115 private Rectangle sourceRegion; 116 117 118 private BMPMetadata metadata; 119 120 121 private BufferedImage bi; 122 123 126 private boolean noTransform = true; 127 128 129 private boolean seleBand = false; 130 131 132 private int scaleX, scaleY; 133 134 135 private int[] sourceBands, destBands; 136 137 140 public BMPImageReader(ImageReaderSpi originator) { 141 super(originator); 142 } 143 144 145 public void setInput(Object input, 146 boolean seekForwardOnly, 147 boolean ignoreMetadata) { 148 super.setInput(input, seekForwardOnly, ignoreMetadata); 149 iis = (ImageInputStream ) input; if(iis != null) 151 iis.setByteOrder(ByteOrder.LITTLE_ENDIAN); 152 resetHeaderInfo(); 153 } 154 155 156 public int getNumImages(boolean allowSearch) throws IOException { 157 if (iis == null) { 158 throw new IllegalStateException (I18N.getString("GetNumImages0")); 159 } 160 if (seekForwardOnly && allowSearch) { 161 throw new IllegalStateException (I18N.getString("GetNumImages1")); 162 } 163 return 1; 164 } 165 166 public int getWidth(int imageIndex) throws IOException { 167 checkIndex(imageIndex); 168 readHeader(); 169 return width; 170 } 171 172 public int getHeight(int imageIndex) throws IOException { 173 checkIndex(imageIndex); 174 readHeader(); 175 return height; 176 } 177 178 private void checkIndex(int imageIndex) { 179 if (imageIndex != 0) { 180 throw new IndexOutOfBoundsException (I18N.getString("BMPImageReader0")); 181 } 182 } 183 184 public void readHeader() throws IOException { 185 if (gotHeader) 186 return; 187 188 if (iis == null) { 189 throw new IllegalStateException ("Input source not set!"); 190 } 191 int profileData = 0, profileSize = 0; 192 193 this.metadata = new BMPMetadata(); 194 iis.mark(); 195 196 byte[] marker = new byte[2]; 198 iis.read(marker); 199 if (marker[0] != 0x42 || marker[1] != 0x4d) 200 throw new IllegalArgumentException (I18N.getString("BMPImageReader1")); 201 202 bitmapFileSize = iis.readUnsignedInt(); 204 iis.skipBytes(4); 206 207 bitmapOffset = iis.readUnsignedInt(); 209 211 long size = iis.readUnsignedInt(); 213 214 if (size == 12) { 215 width = iis.readShort(); 216 height = iis.readShort(); 217 } else { 218 width = iis.readInt(); 219 height = iis.readInt(); 220 } 221 222 metadata.width = width; 223 metadata.height = height; 224 225 int planes = iis.readUnsignedShort(); 226 bitsPerPixel = iis.readUnsignedShort(); 227 228 metadata.bitsPerPixel = (short)bitsPerPixel; 230 231 numBands = 3; 234 235 if (size == 12) { 236 metadata.bmpVersion = VERSION_2; 238 239 if (bitsPerPixel == 1) { 241 imageType = VERSION_2_1_BIT; 242 } else if (bitsPerPixel == 4) { 243 imageType = VERSION_2_4_BIT; 244 } else if (bitsPerPixel == 8) { 245 imageType = VERSION_2_8_BIT; 246 } else if (bitsPerPixel == 24) { 247 imageType = VERSION_2_24_BIT; 248 } 249 250 int numberOfEntries = (int)((bitmapOffset - 14 - size) / 3); 252 int sizeOfPalette = numberOfEntries*3; 253 palette = new byte[sizeOfPalette]; 254 iis.readFully(palette, 0, sizeOfPalette); 255 metadata.palette = palette; 256 metadata.paletteSize = numberOfEntries; 257 } else { 258 compression = iis.readUnsignedInt(); 259 imageSize = iis.readUnsignedInt(); 260 long xPelsPerMeter = iis.readInt(); 261 long yPelsPerMeter = iis.readInt(); 262 long colorsUsed = iis.readUnsignedInt(); 263 long colorsImportant = iis.readUnsignedInt(); 264 265 metadata.compression = (int)compression; 266 metadata.xPixelsPerMeter = (int)xPelsPerMeter; 267 metadata.yPixelsPerMeter = (int)yPelsPerMeter; 268 metadata.colorsUsed = (int)colorsUsed; 269 metadata.colorsImportant = (int)colorsImportant; 270 271 if (size == 40) { 272 switch((int)compression) { 274 275 case BI_RGB: case BI_RLE8: case BI_RLE4: case BI_PNG: 279 case BI_JPEG: 280 281 int numberOfEntries = (int)((bitmapOffset-14-size) / 4); 283 int sizeOfPalette = numberOfEntries * 4; 284 palette = new byte[sizeOfPalette]; 285 iis.readFully(palette, 0, sizeOfPalette); 286 287 metadata.palette = palette; 288 metadata.paletteSize = numberOfEntries; 289 290 if (bitsPerPixel == 1) { 291 imageType = VERSION_3_1_BIT; 292 } else if (bitsPerPixel == 4) { 293 imageType = VERSION_3_4_BIT; 294 } else if (bitsPerPixel == 8) { 295 imageType = VERSION_3_8_BIT; 296 } else if (bitsPerPixel == 24) { 297 imageType = VERSION_3_24_BIT; 298 } else if (bitsPerPixel == 16) { 299 imageType = VERSION_3_NT_16_BIT; 300 301 redMask = 0x7C00; 302 greenMask = 0x3E0; 303 blueMask = (1 << 5) - 1; metadata.redMask = redMask; 305 metadata.greenMask = greenMask; 306 metadata.blueMask = blueMask; 307 } else if (bitsPerPixel == 32) { 308 imageType = VERSION_3_NT_32_BIT; 309 redMask = 0x00FF0000; 310 greenMask = 0x0000FF00; 311 blueMask = 0x000000FF; 312 metadata.redMask = redMask; 313 metadata.greenMask = greenMask; 314 metadata.blueMask = blueMask; 315 } 316 317 metadata.bmpVersion = VERSION_3; 318 break; 319 320 case BI_BITFIELDS: 321 322 if (bitsPerPixel == 16) { 323 imageType = VERSION_3_NT_16_BIT; 324 } else if (bitsPerPixel == 32) { 325 imageType = VERSION_3_NT_32_BIT; 326 } 327 328 redMask = (int)iis.readUnsignedInt(); 330 greenMask = (int)iis.readUnsignedInt(); 331 blueMask = (int)iis.readUnsignedInt(); 332 metadata.redMask = redMask; 333 metadata.greenMask = greenMask; 334 metadata.blueMask = blueMask; 335 336 if (colorsUsed != 0) { 337 sizeOfPalette = (int)colorsUsed*4; 339 palette = new byte[sizeOfPalette]; 340 iis.readFully(palette, 0, sizeOfPalette); 341 342 metadata.palette = palette; 343 metadata.paletteSize = (int)colorsUsed; 344 } 345 metadata.bmpVersion = VERSION_3_NT; 346 347 break; 348 default: 349 throw new 350 RuntimeException (I18N.getString("BMPImageReader2")); 351 } 352 } else if (size == 108 || size == 124) { 353 if (size == 108) 355 metadata.bmpVersion = VERSION_4; 356 else if (size == 124) 357 metadata.bmpVersion = VERSION_5; 358 359 redMask = (int)iis.readUnsignedInt(); 361 greenMask = (int)iis.readUnsignedInt(); 362 blueMask = (int)iis.readUnsignedInt(); 363 alphaMask = (int)iis.readUnsignedInt(); 365 long csType = iis.readUnsignedInt(); 366 int redX = iis.readInt(); 367 int redY = iis.readInt(); 368 int redZ = iis.readInt(); 369 int greenX = iis.readInt(); 370 int greenY = iis.readInt(); 371 int greenZ = iis.readInt(); 372 int blueX = iis.readInt(); 373 int blueY = iis.readInt(); 374 int blueZ = iis.readInt(); 375 long gammaRed = iis.readUnsignedInt(); 376 long gammaGreen = iis.readUnsignedInt(); 377 long gammaBlue = iis.readUnsignedInt(); 378 379 if (size == 124) { 380 metadata.intent = iis.readInt(); 381 profileData = iis.readInt(); 382 profileSize = iis.readInt(); 383 iis.skipBytes(4); 384 } 385 386 metadata.colorSpace = (int)csType; 387 388 if (csType == LCS_CALIBRATED_RGB) { 389 metadata.redX = redX; 391 metadata.redY = redY; 392 metadata.redZ = redZ; 393 metadata.greenX = greenX; 394 metadata.greenY = greenY; 395 metadata.greenZ = greenZ; 396 metadata.blueX = blueX; 397 metadata.blueY = blueY; 398 metadata.blueZ = blueZ; 399 metadata.gammaRed = (int)gammaRed; 400 metadata.gammaGreen = (int)gammaGreen; 401 metadata.gammaBlue = (int)gammaBlue; 402 } 403 404 int numberOfEntries = (int)((bitmapOffset-14-size) / 4); 406 int sizeOfPalette = numberOfEntries*4; 407 palette = new byte[sizeOfPalette]; 408 iis.readFully(palette, 0, sizeOfPalette); 409 metadata.palette = palette; 410 metadata.paletteSize = numberOfEntries; 411 412 if (bitsPerPixel == 1) { 413 imageType = VERSION_4_1_BIT; 414 } else if (bitsPerPixel == 4) { 415 imageType = VERSION_4_4_BIT; 416 } else if (bitsPerPixel == 8) { 417 imageType = VERSION_4_8_BIT; 418 } else if (bitsPerPixel == 16) { 419 imageType = VERSION_4_16_BIT; 420 if ((int)compression == BI_RGB) { 421 redMask = 0x7C00; 422 greenMask = 0x3E0; 423 blueMask = 0x1F; 424 } 425 } else if (bitsPerPixel == 24) { 426 imageType = VERSION_4_24_BIT; 427 } else if (bitsPerPixel == 32) { 428 imageType = VERSION_4_32_BIT; 429 if ((int)compression == BI_RGB) { 430 redMask = 0x00FF0000; 431 greenMask = 0x0000FF00; 432 blueMask = 0x000000FF; 433 } 434 } 435 436 metadata.redMask = redMask; 437 metadata.greenMask = greenMask; 438 metadata.blueMask = blueMask; 439 metadata.alphaMask = alphaMask; 440 } else { 441 throw new 442 RuntimeException (I18N.getString("BMPImageReader3")); 443 } 444 } 445 446 if (height > 0) { 447 isBottomUp = true; 449 } else { 450 isBottomUp = false; 452 height = Math.abs(height); 453 } 454 455 ColorSpace colorSpace = ColorSpace.getInstance(ColorSpace.CS_sRGB); 458 if (metadata.colorSpace == PROFILE_LINKED || 459 metadata.colorSpace == PROFILE_EMBEDDED) { 460 461 iis.mark(); 462 iis.skipBytes(profileData - size); 463 byte[] profile = new byte[profileSize]; 464 iis.readFully(profile, 0, profileSize); 465 iis.reset(); 466 467 try { 468 if (metadata.colorSpace == PROFILE_LINKED) 469 colorSpace = 470 new ICC_ColorSpace (ICC_Profile.getInstance(new String (profile))); 471 else 472 colorSpace = 473 new ICC_ColorSpace (ICC_Profile.getInstance(profile)); 474 } catch (Exception e) { 475 colorSpace = ColorSpace.getInstance(ColorSpace.CS_sRGB); 476 } 477 } 478 479 if (bitsPerPixel == 1 || bitsPerPixel == 4 || bitsPerPixel == 8) { 481 482 numBands = 1; 483 484 if (bitsPerPixel == 8) { 485 int[] bandOffsets = new int[numBands]; 486 for (int i = 0; i < numBands; i++) { 487 bandOffsets[i] = numBands -1 -i; 488 } 489 sampleModel = 490 new PixelInterleavedSampleModel (DataBuffer.TYPE_BYTE, 491 width, height, 492 numBands, 493 numBands * width, 494 bandOffsets); 495 } else { 496 sampleModel = 498 new MultiPixelPackedSampleModel (DataBuffer.TYPE_BYTE, 499 width, height, 500 bitsPerPixel); 501 } 502 503 byte r[], g[], b[]; 505 if (imageType == VERSION_2_1_BIT || 506 imageType == VERSION_2_4_BIT || 507 imageType == VERSION_2_8_BIT) { 508 509 510 size = palette.length/3; 511 512 if (size > 256) { 513 size = 256; 514 } 515 516 int off; 517 r = new byte[(int)size]; 518 g = new byte[(int)size]; 519 b = new byte[(int)size]; 520 for (int i=0; i<(int)size; i++) { 521 off = 3 * i; 522 b[i] = palette[off]; 523 g[i] = palette[off+1]; 524 r[i] = palette[off+2]; 525 } 526 } else { 527 size = palette.length/4; 528 529 if (size > 256) { 530 size = 256; 531 } 532 533 int off; 534 r = new byte[(int)size]; 535 g = new byte[(int)size]; 536 b = new byte[(int)size]; 537 for (int i=0; i<size; i++) { 538 off = 4 * i; 539 b[i] = palette[off]; 540 g[i] = palette[off+1]; 541 r[i] = palette[off+2]; 542 } 543 } 544 545 if (ImageUtil.isIndicesForGrayscale(r, g, b)) 546 colorModel = 547 ImageUtil.createColorModel(null, sampleModel); 548 else 549 colorModel = new IndexColorModel (bitsPerPixel, (int)size, r, g, b); 550 } else if (bitsPerPixel == 16) { 551 numBands = 3; 552 sampleModel = 553 new SinglePixelPackedSampleModel (DataBuffer.TYPE_USHORT, 554 width, height, 555 new int[] {redMask, greenMask, blueMask}); 556 557 colorModel = 558 new DirectColorModel (colorSpace, 559 16, redMask, greenMask, blueMask, 0, 560 false, DataBuffer.TYPE_USHORT); 561 562 } else if (bitsPerPixel == 32) { 563 numBands = alphaMask == 0 ? 3 : 4; 564 565 int[] bitMasks = numBands == 3 ? 568 new int[] {redMask, greenMask, blueMask} : 569 new int[] {redMask, greenMask, blueMask, alphaMask}; 570 571 sampleModel = 572 new SinglePixelPackedSampleModel (DataBuffer.TYPE_INT, 573 width, height, 574 bitMasks); 575 576 colorModel = 577 new DirectColorModel (colorSpace, 578 32, redMask, greenMask, blueMask, alphaMask, 579 false, DataBuffer.TYPE_INT); 580 } else { 581 numBands = 3; 582 int[] bandOffsets = new int[numBands]; 584 for (int i = 0; i < numBands; i++) { 585 bandOffsets[i] = numBands -1 -i; 586 } 587 588 sampleModel = 589 new PixelInterleavedSampleModel (DataBuffer.TYPE_BYTE, 590 width, height, 591 numBands, 592 numBands * width, 593 bandOffsets); 594 595 colorModel = 596 ImageUtil.createColorModel(colorSpace, sampleModel); 597 } 598 599 originalSampleModel = sampleModel; 600 originalColorModel = colorModel; 601 602 iis.reset(); 605 iis.skipBytes(bitmapOffset); 606 gotHeader = true; 607 } 608 609 public Iterator getImageTypes(int imageIndex) 610 throws IOException { 611 checkIndex(imageIndex); 612 readHeader(); 613 ArrayList list = new ArrayList (1); 614 list.add(new ImageTypeSpecifier (originalColorModel, 615 originalSampleModel)); 616 return list.iterator(); 617 } 618 619 public ImageReadParam getDefaultReadParam() { 620 return new ImageReadParam (); 621 } 622 623 public IIOMetadata getImageMetadata(int imageIndex) 624 throws IOException { 625 checkIndex(imageIndex); 626 if (metadata == null) { 627 readHeader(); 628 } 629 return metadata; 630 } 631 632 public IIOMetadata getStreamMetadata() throws IOException { 633 return null; 634 } 635 636 public boolean isRandomAccessEasy(int imageIndex) throws IOException { 637 checkIndex(imageIndex); 638 readHeader(); 639 return metadata.compression == BI_RGB; 640 } 641 642 public BufferedImage read(int imageIndex, ImageReadParam param) 643 throws IOException { 644 645 if (iis == null) { 646 throw new IllegalStateException (I18N.getString("BMPImageReader5")); 647 } 648 649 checkIndex(imageIndex); 650 clearAbortRequest(); 651 processImageStarted(imageIndex); 652 653 if (param == null) 654 param = getDefaultReadParam(); 655 656 readHeader(); 658 659 sourceRegion = new Rectangle (0, 0, 0, 0); 660 destinationRegion = new Rectangle (0, 0, 0, 0); 661 662 computeRegions(param, this.width, this.height, 663 param.getDestination(), 664 sourceRegion, 665 destinationRegion); 666 667 scaleX = param.getSourceXSubsampling(); 668 scaleY = param.getSourceYSubsampling(); 669 670 sourceBands = param.getSourceBands(); 672 destBands = param.getDestinationBands(); 673 674 seleBand = (sourceBands != null) && (destBands != null); 675 noTransform = 676 destinationRegion.equals(new Rectangle (0, 0, width, height)) || 677 seleBand; 678 679 if (!seleBand) { 680 sourceBands = new int[numBands]; 681 destBands = new int[numBands]; 682 for (int i = 0; i < numBands; i++) 683 destBands[i] = sourceBands[i] = i; 684 } 685 686 bi = param.getDestination(); 688 689 WritableRaster raster = null; 691 692 if (bi == null) { 693 sampleModel = 694 sampleModel.createCompatibleSampleModel(destinationRegion.x + 695 destinationRegion.width, 696 destinationRegion.y + 697 destinationRegion.height); 698 if (seleBand) 699 sampleModel = sampleModel.createSubsetSampleModel(sourceBands); 700 raster = Raster.createWritableRaster(sampleModel, new Point ()); 701 bi = new BufferedImage (colorModel, raster, false, null); 702 } else { 703 raster = bi.getWritableTile(0, 0); 704 sampleModel = bi.getSampleModel(); 705 colorModel = bi.getColorModel(); 706 707 noTransform &= destinationRegion.equals(raster.getBounds()); 708 } 709 710 byte bdata[] = null; short sdata[] = null; int idata[] = null; 714 if (sampleModel.getDataType() == DataBuffer.TYPE_BYTE) 715 bdata = (byte[])((DataBufferByte )raster.getDataBuffer()).getData(); 716 else if (sampleModel.getDataType() == DataBuffer.TYPE_USHORT) 717 sdata = (short[])((DataBufferUShort )raster.getDataBuffer()).getData(); 718 else if (sampleModel.getDataType() == DataBuffer.TYPE_INT) 719 idata = (int[])((DataBufferInt )raster.getDataBuffer()).getData(); 720 721 switch(imageType) { 723 724 case VERSION_2_1_BIT: 725 read1Bit(bdata); 727 break; 728 729 case VERSION_2_4_BIT: 730 read4Bit(bdata); 732 break; 733 734 case VERSION_2_8_BIT: 735 read8Bit(bdata); 737 break; 738 739 case VERSION_2_24_BIT: 740 read24Bit(bdata); 742 break; 743 744 case VERSION_3_1_BIT: 745 read1Bit(bdata); 747 break; 748 749 case VERSION_3_4_BIT: 750 switch((int)compression) { 751 case BI_RGB: 752 read4Bit(bdata); 753 break; 754 755 case BI_RLE4: 756 readRLE4(bdata); 757 break; 758 759 case BI_JPEG: 760 readEmbedded("JPEG", bi, param); 761 break; 762 763 case BI_PNG: 764 readEmbedded("PNG", bi, param); 765 break; 766 767 default: 768 throw new 769 RuntimeException (I18N.getString("BMPImageReader1")); 770 } 771 break; 772 773 case VERSION_3_8_BIT: 774 switch((int)compression) { 775 case BI_RGB: 776 read8Bit(bdata); 777 break; 778 779 case BI_RLE8: 780 readRLE8(bdata); 781 break; 782 783 case BI_JPEG: 784 readEmbedded("JPEG", bi, param); 785 break; 786 787 case BI_PNG: 788 readEmbedded("PNG", bi, param); 789 break; 790 791 default: 792 throw new 793 RuntimeException (I18N.getString("BMPImageReader1")); 794 } 795 796 break; 797 798 case VERSION_3_24_BIT: 799 read24Bit(bdata); 801 break; 802 803 case VERSION_3_NT_16_BIT: 804 read16Bit(sdata); 805 break; 806 807 case VERSION_3_NT_32_BIT: 808 switch((int)compression) { 809 case BI_JPEG: 810 iis.seek(54); 811 readEmbedded("JPEG", bi, param); 812 break; 813 814 case BI_PNG: 815 readEmbedded("PNG", bi, param); 816 break; 817 default: 818 read32Bit(idata); 819 } 820 break; 821 822 case VERSION_4_1_BIT: 823 read1Bit(bdata); 824 break; 825 826 case VERSION_4_4_BIT: 827 switch((int)compression) { 828 829 case BI_RGB: 830 read4Bit(bdata); 831 break; 832 833 case BI_RLE4: 834 readRLE4(bdata); 835 break; 836 837 case BI_JPEG: 838 readEmbedded("JPEG", bi, param); 839 break; 840 841 case BI_PNG: 842 readEmbedded("PNG", bi, param); 843 break; 844 845 default: 846 throw new 847 RuntimeException (I18N.getString("BMPImageReader1")); 848 } 849 850 case VERSION_4_8_BIT: 851 switch((int)compression) { 852 853 case BI_RGB: 854 read8Bit(bdata); 855 break; 856 857 case BI_RLE8: 858 readRLE8(bdata); 859 break; 860 861 case BI_JPEG: 862 readEmbedded("JPEG", bi, param); 863 break; 864 865 case BI_PNG: 866 readEmbedded("PNG", bi, param); 867 break; 868 869 default: 870 throw new 871 RuntimeException (I18N.getString("BMPImageReader1")); 872 } 873 break; 874 875 case VERSION_4_16_BIT: 876 read16Bit(sdata); 877 break; 878 879 case VERSION_4_24_BIT: 880 read24Bit(bdata); 881 break; 882 883 case VERSION_4_32_BIT: 884 read32Bit(idata); 885 break; 886 } 887 888 if (abortRequested()) 889 processReadAborted(); 890 else 891 processImageComplete(); 892 893 return bi; 894 } 895 896 public boolean canReadRaster() { 897 return true; 898 } 899 900 public Raster readRaster(int imageIndex, 901 ImageReadParam param) throws IOException { 902 BufferedImage bi = read(imageIndex, param); 903 return bi.getData(); 904 } 905 906 private void resetHeaderInfo() { 907 gotHeader = false; 908 bi = null; 909 sampleModel = originalSampleModel = null; 910 colorModel = originalColorModel = null; 911 } 912 913 public void reset() { 914 super.reset(); 915 iis = null; 916 resetHeaderInfo(); 917 } 918 919 private void read1Bit(byte[] bdata) throws IOException { 921 int bytesPerScanline = (width + 7) / 8; 922 int padding = bytesPerScanline % 4; 923 if (padding != 0) { 924 padding = 4 - padding; 925 } 926 927 int lineLength = bytesPerScanline + padding; 928 929 if (noTransform) { 930 int j = isBottomUp ? (height -1)*bytesPerScanline : 0; 931 932 for (int i=0; i<height; i++) { 933 if (abortRequested()) { 934 break; 935 } 936 iis.readFully(bdata, j, bytesPerScanline); 937 iis.skipBytes(padding); 938 j += isBottomUp ? -bytesPerScanline : bytesPerScanline; 939 processImageUpdate(bi, 0, i, 940 destinationRegion.width, 1, 1, 1, 941 new int[]{0}); 942 processImageProgress(100.0F * i/destinationRegion.height); 943 } 944 } else { 945 byte[] buf = new byte[lineLength]; 946 int lineStride = 947 ((MultiPixelPackedSampleModel )sampleModel).getScanlineStride(); 948 949 if (isBottomUp) { 950 int lastLine = 951 sourceRegion.y + (destinationRegion.height - 1) * scaleY; 952 iis.skipBytes(lineLength * (height - 1 - lastLine)); 953 } else 954 iis.skipBytes(lineLength * sourceRegion.y); 955 956 int skipLength = lineLength * (scaleY - 1); 957 958 int[] srcOff = new int[destinationRegion.width]; 960 int[] destOff = new int[destinationRegion.width]; 961 int[] srcPos = new int[destinationRegion.width]; 962 int[] destPos = new int[destinationRegion.width]; 963 964 for (int i = destinationRegion.x, x = sourceRegion.x, j = 0; 965 i < destinationRegion.x + destinationRegion.width; 966 i++, j++, x += scaleX) { 967 srcPos[j] = x >> 3; 968 srcOff[j] = 7 - (x & 7); 969 destPos[j] = i >> 3; 970 destOff[j] = 7 - (i & 7); 971 } 972 973 int k = destinationRegion.y * lineStride; 974 if (isBottomUp) 975 k += (destinationRegion.height - 1) * lineStride; 976 977 for (int j = 0, y = sourceRegion.y; 978 j < destinationRegion.height; j++, y+=scaleY) { 979 980 if (abortRequested()) 981 break; 982 iis.read(buf, 0, lineLength); 983 for (int i = 0; i < destinationRegion.width; i++) { 984 int v = (buf[srcPos[i]] >> srcOff[i]) & 1; 986 bdata[k + destPos[i]] |= v << destOff[i]; 987 } 988 989 k += isBottomUp ? -lineStride : lineStride; 990 iis.skipBytes(skipLength); 991 processImageUpdate(bi, 0, j, 992 destinationRegion.width, 1, 1, 1, 993 new int[]{0}); 994 processImageProgress(100.0F*j/destinationRegion.height); 995 } 996 } 997 } 998 999 private void read4Bit(byte[] bdata) throws IOException { 1001 1002 int bytesPerScanline = (width + 1) / 2; 1003 1004 int padding = bytesPerScanline % 4; 1006 if (padding != 0) 1007 padding = 4 - padding; 1008 1009 int lineLength = bytesPerScanline + padding; 1010 1011 if (noTransform) { 1012 int j = isBottomUp ? (height -1) * bytesPerScanline : 0; 1013 1014 for (int i=0; i<height; i++) { 1015 if (abortRequested()) { 1016 break; 1017 } 1018 iis.readFully(bdata, j, bytesPerScanline); 1019 iis.skipBytes(padding); 1020 j += isBottomUp ? -bytesPerScanline : bytesPerScanline; 1021 processImageUpdate(bi, 0, i, 1022 destinationRegion.width, 1, 1, 1, 1023 new int[]{0}); 1024 processImageProgress(100.0F * i/destinationRegion.height); 1025 } 1026 } else { 1027 byte[] buf = new byte[lineLength]; 1028 int lineStride = 1029 ((MultiPixelPackedSampleModel )sampleModel).getScanlineStride(); 1030 1031 if (isBottomUp) { 1032 int lastLine = 1033 sourceRegion.y + (destinationRegion.height - 1) * scaleY; 1034 iis.skipBytes(lineLength * (height - 1 - lastLine)); 1035 } else 1036 iis.skipBytes(lineLength * sourceRegion.y); 1037 1038 int skipLength = lineLength * (scaleY - 1); 1039 1040 int[] srcOff = new int[destinationRegion.width]; 1042 int[] destOff = new int[destinationRegion.width]; 1043 int[] srcPos = new int[destinationRegion.width]; 1044 int[] destPos = new int[destinationRegion.width]; 1045 1046 for (int i = destinationRegion.x, x = sourceRegion.x, j = 0; 1047 i < destinationRegion.x + destinationRegion.width; 1048 i++, j++, x += scaleX) { 1049 srcPos[j] = x >> 1; 1050 srcOff[j] = (1 - (x & 1)) << 2; 1051 destPos[j] = i >> 1; 1052 destOff[j] = (1 - (i & 1)) << 2; 1053 } 1054 1055 int k = destinationRegion.y * lineStride; 1056 if (isBottomUp) 1057 k += (destinationRegion.height - 1) * lineStride; 1058 1059 for (int j = 0, y = sourceRegion.y; 1060 j < destinationRegion.height; j++, y+=scaleY) { 1061 1062 if (abortRequested()) 1063 break; 1064 iis.read(buf, 0, lineLength); 1065 for (int i = 0; i < destinationRegion.width; i++) { 1066 int v = (buf[srcPos[i]] >> srcOff[i]) & 0x0F; 1068 bdata[k + destPos[i]] |= v << destOff[i]; 1069 } 1070 1071 k += isBottomUp ? -lineStride : lineStride; 1072 iis.skipBytes(skipLength); 1073 processImageUpdate(bi, 0, j, 1074 destinationRegion.width, 1, 1, 1, 1075 new int[]{0}); 1076 processImageProgress(100.0F*j/destinationRegion.height); 1077 } 1078 } 1079 } 1080 1081 private void read8Bit(byte[] bdata) throws IOException { 1083 1084 int padding = width % 4; 1086 if (padding != 0) { 1087 padding = 4 - padding; 1088 } 1089 1090 int lineLength = width + padding; 1091 1092 if (noTransform) { 1093 int j = isBottomUp ? (height -1) * width : 0; 1094 1095 for (int i=0; i<height; i++) { 1096 if (abortRequested()) { 1097 break; 1098 } 1099 iis.readFully(bdata, j, width); 1100 iis.skipBytes(padding); 1101 j += isBottomUp ? -width : width; 1102 processImageUpdate(bi, 0, i, 1103 destinationRegion.width, 1, 1, 1, 1104 new int[]{0}); 1105 processImageProgress(100.0F * i/destinationRegion.height); 1106 } 1107 } else { 1108 byte[] buf = new byte[lineLength]; 1109 int lineStride = 1110 ((ComponentSampleModel )sampleModel).getScanlineStride(); 1111 1112 if (isBottomUp) { 1113 int lastLine = 1114 sourceRegion.y + (destinationRegion.height - 1) * scaleY; 1115 iis.skipBytes(lineLength * (height - 1 - lastLine)); 1116 } else 1117 iis.skipBytes(lineLength * sourceRegion.y); 1118 1119 int skipLength = lineLength * (scaleY - 1); 1120 1121 int k = destinationRegion.y * lineStride; 1122 if (isBottomUp) 1123 k += (destinationRegion.height - 1) * lineStride; 1124 k += destinationRegion.x; 1125 1126 for (int j = 0, y = sourceRegion.y; 1127 j < destinationRegion.height; j++, y+=scaleY) { 1128 1129 if (abortRequested()) 1130 break; 1131 iis.read(buf, 0, lineLength); 1132 for (int i = 0, m = sourceRegion.x; 1133 i < destinationRegion.width; i++, m += scaleX) { 1134 bdata[k + i] = buf[m]; 1136 } 1137 1138 k += isBottomUp ? -lineStride : lineStride; 1139 iis.skipBytes(skipLength); 1140 processImageUpdate(bi, 0, j, 1141 destinationRegion.width, 1, 1, 1, 1142 new int[]{0}); 1143 processImageProgress(100.0F*j/destinationRegion.height); 1144 } 1145 } 1146 } 1147 1148 private void read24Bit(byte[] bdata) throws IOException { 1150 int padding = width * 3 % 4; 1153 if ( padding != 0) 1154 padding = 4 - padding; 1155 1156 int lineStride = width * 3; 1157 int lineLength = lineStride + padding; 1158 1159 if (noTransform) { 1160 int j = isBottomUp ? (height -1) * width * 3 : 0; 1161 1162 for (int i=0; i<height; i++) { 1163 if (abortRequested()) { 1164 break; 1165 } 1166 iis.readFully(bdata, j, lineStride); 1167 iis.skipBytes(padding); 1168 j += isBottomUp ? -lineStride : lineStride; 1169 processImageUpdate(bi, 0, i, 1170 destinationRegion.width, 1, 1, 1, 1171 new int[]{0}); 1172 processImageProgress(100.0F * i/destinationRegion.height); 1173 } 1174 } else { 1175 byte[] buf = new byte[lineLength]; 1176 lineStride = 1177 ((ComponentSampleModel )sampleModel).getScanlineStride(); 1178 1179 if (isBottomUp) { 1180 int lastLine = 1181 sourceRegion.y + (destinationRegion.height - 1) * scaleY; 1182 iis.skipBytes(lineLength * (height - 1 - lastLine)); 1183 } else 1184 iis.skipBytes(lineLength * sourceRegion.y); 1185 1186 int skipLength = lineLength * (scaleY - 1); 1187 1188 int k = destinationRegion.y * lineStride; 1189 if (isBottomUp) 1190 k += (destinationRegion.height - 1) * lineStride; 1191 k += destinationRegion.x * 3; 1192 1193 for (int j = 0, y = sourceRegion.y; 1194 j < destinationRegion.height; j++, y+=scaleY) { 1195 1196 if (abortRequested()) 1197 break; 1198 iis.read(buf, 0, lineLength); 1199 for (int i = 0, m = 3 * sourceRegion.x; 1200 i < destinationRegion.width; i++, m += 3 * scaleX) { 1201 int n = 3 * i + k; 1203 for (int b = 0; b < destBands.length; b++) 1204 bdata[n + destBands[b]] = buf[m + sourceBands[b]]; 1205 } 1206 1207 k += isBottomUp ? -lineStride : lineStride; 1208 iis.skipBytes(skipLength); 1209 processImageUpdate(bi, 0, j, 1210 destinationRegion.width, 1, 1, 1, 1211 new int[]{0}); 1212 processImageProgress(100.0F*j/destinationRegion.height); 1213 } 1214 } 1215 } 1216 1217 private void read16Bit(short sdata[]) throws IOException { 1218 int padding = width * 2 % 4; 1221 1222 if ( padding != 0) 1223 padding = 4 - padding; 1224 1225 int lineLength = width + padding / 2; 1226 1227 if (noTransform) { 1228 int j = isBottomUp ? (height -1) * width : 0; 1229 for (int i=0; i<height; i++) { 1230 if (abortRequested()) { 1231 break; 1232 } 1233 1234 iis.readFully(sdata, j, width); 1235 iis.skipBytes(padding); 1236 1237 j += isBottomUp ? -width : width; 1238 processImageUpdate(bi, 0, i, 1239 destinationRegion.width, 1, 1, 1, 1240 new int[]{0}); 1241 processImageProgress(100.0F * i/destinationRegion.height); 1242 } 1243 } else { 1244 short[] buf = new short[lineLength]; 1245 int lineStride = 1246 ((SinglePixelPackedSampleModel )sampleModel).getScanlineStride(); 1247 1248 if (isBottomUp) { 1249 int lastLine = 1250 sourceRegion.y + (destinationRegion.height - 1) * scaleY; 1251 iis.skipBytes(lineLength * (height - 1 - lastLine) << 1); 1252 } else 1253 iis.skipBytes(lineLength * sourceRegion.y << 1); 1254 1255 int skipLength = lineLength * (scaleY - 1) << 1; 1256 1257 int k = destinationRegion.y * lineStride; 1258 if (isBottomUp) 1259 k += (destinationRegion.height - 1) * lineStride; 1260 k += destinationRegion.x; 1261 1262 for (int j = 0, y = sourceRegion.y; 1263 j < destinationRegion.height; j++, y+=scaleY) { 1264 1265 if (abortRequested()) 1266 break; 1267 iis.readFully(buf, 0, lineLength); 1268 for (int i = 0, m = sourceRegion.x; 1269 i < destinationRegion.width; i++, m += scaleX) { 1270 sdata[k + i] = buf[m]; 1272 } 1273 1274 k += isBottomUp ? -lineStride : lineStride; 1275 iis.skipBytes(skipLength); 1276 processImageUpdate(bi, 0, j, 1277 destinationRegion.width, 1, 1, 1, 1278 new int[]{0}); 1279 processImageProgress(100.0F*j/destinationRegion.height); 1280 } 1281 } 1282 } 1283 1284 private void read32Bit(int idata[]) throws IOException { 1285 if (noTransform) { 1286 int j = isBottomUp ? (height -1) * width : 0; 1287 1288 for (int i=0; i<height; i++) { 1289 if (abortRequested()) { 1290 break; 1291 } 1292 iis.readFully(idata, j, width); 1293 j += isBottomUp ? -width : width; 1294 processImageUpdate(bi, 0, i, 1295 destinationRegion.width, 1, 1, 1, 1296 new int[]{0}); 1297 processImageProgress(100.0F * i/destinationRegion.height); 1298 } 1299 } else { 1300 int[] buf = new int[width]; 1301 int lineStride = 1302 ((SinglePixelPackedSampleModel )sampleModel).getScanlineStride(); 1303 1304 if (isBottomUp) { 1305 int lastLine = 1306 sourceRegion.y + (destinationRegion.height - 1) * scaleY; 1307 iis.skipBytes(width * (height - 1 - lastLine) << 2); 1308 } else 1309 iis.skipBytes(width * sourceRegion.y << 2); 1310 1311 int skipLength = width * (scaleY - 1) << 2; 1312 1313 int k = destinationRegion.y * lineStride; 1314 if (isBottomUp) 1315 k += (destinationRegion.height - 1) * lineStride; 1316 k += destinationRegion.x; 1317 1318 for (int j = 0, y = sourceRegion.y; 1319 j < destinationRegion.height; j++, y+=scaleY) { 1320 1321 if (abortRequested()) 1322 break; 1323 iis.readFully(buf, 0, width); 1324 for (int i = 0, m = sourceRegion.x; 1325 i < destinationRegion.width; i++, m += scaleX) { 1326 idata[k + i] = buf[m]; 1328 } 1329 1330 k += isBottomUp ? -lineStride : lineStride; 1331 iis.skipBytes(skipLength); 1332 processImageUpdate(bi, 0, j, 1333 destinationRegion.width, 1, 1, 1, 1334 new int[]{0}); 1335 processImageProgress(100.0F*j/destinationRegion.height); 1336 } 1337 } 1338 } 1339 1340 private void readRLE8(byte bdata[]) throws IOException { 1341 int imSize = (int)imageSize; 1343 if (imSize == 0) { 1344 imSize = (int)(bitmapFileSize - bitmapOffset); 1345 } 1346 1347 int padding = 0; 1348 int remainder = width % 4; 1351 if (remainder != 0) { 1352 padding = 4 - remainder; 1353 } 1354 1355 byte values[] = new byte[imSize]; 1357 int bytesRead = 0; 1358 iis.readFully(values, 0, imSize); 1359 1360 decodeRLE8(imSize, padding, values, bdata); 1362 } 1363 1364 private void decodeRLE8(int imSize, 1365 int padding, 1366 byte[] values, 1367 byte[] bdata) throws IOException { 1368 1369 byte val[] = new byte[width * height]; 1370 int count = 0, l = 0; 1371 int value; 1372 boolean flag = false; 1373 int lineNo = isBottomUp ? height - 1 : 0; 1374 int lineStride = 1375 ((ComponentSampleModel )sampleModel).getScanlineStride(); 1376 int finished = 0; 1377 1378 while (count != imSize) { 1379 value = values[count++] & 0xff; 1380 if (value == 0) { 1381 switch(values[count++] & 0xff) { 1382 1383 case 0: 1384 if (lineNo >= sourceRegion.y && 1386 lineNo < sourceRegion.y + sourceRegion.width) { 1387 if (noTransform) { 1388 int pos = lineNo * width; 1389 for(int i = 0; i < width; i++) 1390 bdata[pos++] = val[i]; 1391 processImageUpdate(bi, 0, lineNo, 1392 destinationRegion.width, 1, 1, 1, 1393 new int[]{0}); 1394 finished++; 1395 } else if ((lineNo - sourceRegion.y) % scaleY == 0) { 1396 int currentLine = (lineNo - sourceRegion.y) / scaleY + 1397 destinationRegion.y; 1398 int pos = currentLine * lineStride; 1399 pos += destinationRegion.x; 1400 for (int i = sourceRegion.x; 1401 i < sourceRegion.x + sourceRegion.width; 1402 i += scaleX) 1403 bdata[pos++] = val[i]; 1404 processImageUpdate(bi, 0, currentLine, 1405 destinationRegion.width, 1, 1, 1, 1406 new int[]{0}); 1407 finished++; 1408 } 1409 } 1410 processImageProgress(100.0F * finished / destinationRegion.height); 1411 lineNo += isBottomUp ? -1 : 1; 1412 l = 0; 1413 1414 if (abortRequested()) { 1415 flag = true; 1416 } 1417 1418 break; 1419 1420 case 1: 1421 flag = true; 1423 break; 1424 1425 case 2: 1426 int xoff = values[count++] & 0xff; 1428 int yoff = values[count] & 0xff; 1429 l += xoff + yoff*width; 1431 break; 1432 1433 default: 1434 int end = values[count-1] & 0xff; 1435 for (int i=0; i<end; i++) { 1436 val[l++] = (byte)(values[count++] & 0xff); 1437 } 1438 1439 if ((end & 1) == 1) { 1442 count++; 1443 } 1444 } 1445 } else { 1446 for (int i=0; i<value; i++) { 1447 val[l++] = (byte)(values[count] & 0xff); 1448 } 1449 1450 count++; 1451 } 1452 1453 if (flag) { 1455 break; 1456 } 1457 } 1458 } 1459 1460 private void readRLE4(byte[] bdata) throws IOException { 1461 1462 int imSize = (int)imageSize; 1464 if (imSize == 0) { 1465 imSize = (int)(bitmapFileSize - bitmapOffset); 1466 } 1467 1468 int padding = 0; 1469 int remainder = width % 4; 1472 if (remainder != 0) { 1473 padding = 4 - remainder; 1474 } 1475 1476 byte[] values = new byte[imSize]; 1478 iis.readFully(values, 0, imSize); 1479 1480 decodeRLE4(imSize, padding, values, bdata); 1482 } 1483 1484 private void decodeRLE4(int imSize, 1485 int padding, 1486 byte[] values, 1487 byte[] bdata) throws IOException { 1488 byte[] val = new byte[width]; 1489 int count = 0, l = 0; 1490 int value; 1491 boolean flag = false; 1492 int lineNo = isBottomUp ? height - 1 : 0; 1493 int lineStride = 1494 ((MultiPixelPackedSampleModel )sampleModel).getScanlineStride(); 1495 int finished = 0; 1496 1497 while (count != imSize) { 1498 1499 value = values[count++] & 0xFF; 1500 if (value == 0) { 1501 1502 1503 switch(values[count++] & 0xFF) { 1505 1506 case 0: 1507 if (lineNo >= sourceRegion.y && 1510 lineNo < sourceRegion.y + sourceRegion.width) { 1511 if (noTransform) { 1512 int pos = lineNo * (width + 1 >> 1); 1513 for(int i = 0, j = 0; i < width >> 1; i++) 1514 bdata[pos++] = 1515 (byte)((val[j++] << 4) | val[j++]); 1516 if ((width & 1) == 1) 1517 bdata[pos] |= val[width - 1] << 4; 1518 1519 processImageUpdate(bi, 0, lineNo, 1520 destinationRegion.width, 1, 1, 1, 1521 new int[]{0}); 1522 finished++; 1523 } else if ((lineNo - sourceRegion.y) % scaleY == 0) { 1524 int currentLine = (lineNo - sourceRegion.y) / scaleY + 1525 destinationRegion.y; 1526 int pos = currentLine * lineStride; 1527 pos += destinationRegion.x >> 1; 1528 int shift = (1 - (destinationRegion.x & 1)) << 2; 1529 for (int i = sourceRegion.x; 1530 i < sourceRegion.x + sourceRegion.width; 1531 i += scaleX) { 1532 bdata[pos] |= val[i] << shift; 1533 shift += 4; 1534 if (shift == 4) { 1535 pos++; 1536 } 1537 shift &= 7; 1538 } 1539 processImageUpdate(bi, 0, currentLine, 1540 destinationRegion.width, 1, 1, 1, 1541 new int[]{0}); 1542 finished++; 1543 } 1544 } 1545 processImageProgress(100.0F * finished / destinationRegion.height); 1546 lineNo += isBottomUp ? -1 : 1; 1547 l = 0; 1548 1549 if (abortRequested()) { 1550 flag = true; 1551 } 1552 1553 break; 1554 1555 case 1: 1556 flag = true; 1558 break; 1559 1560 case 2: 1561 int xoff = values[count++] & 0xFF; 1563 int yoff = values[count] & 0xFF; 1564 l += xoff + yoff*width; 1566 break; 1567 1568 default: 1569 int end = values[count-1] & 0xFF; 1570 for (int i=0; i<end; i++) { 1571 val[l++] = (byte)(((i & 1) == 0) ? (values[count] & 0xf0) >> 4 1572 : (values[count++] & 0x0f)); 1573 } 1574 1575 if ((end & 1) == 1) { 1578 count++; 1579 } 1580 1581 if ((((int)Math.ceil(end/2)) & 1) ==1 ) { 1584 count++; 1585 } 1586 break; 1587 } 1588 } else { 1589 int alternate[] = { (values[count] & 0xf0) >> 4, 1591 values[count] & 0x0f }; 1592 for (int i=0; (i < value) && (l < width); i++) { 1593 val[l++] = (byte)alternate[i & 1]; 1594 } 1595 1596 count++; 1597 } 1598 1599 if (flag) { 1601 break; 1602 } 1603 } 1604 } 1605 1606 1614 1615 private void readEmbedded(String format, 1616 BufferedImage bi, ImageReadParam bmpParam) 1617 throws IOException { 1618 Iterator iterator = ImageIO.getImageReadersByFormatName(format); 1619 ImageReader reader = null; 1620 if (iterator.hasNext()) 1621 reader = (ImageReader )iterator.next(); 1622 if (reader != null) { 1623 byte[] buff = new byte[(int)imageSize]; 1625 iis.read(buff); 1626 reader.setInput(ImageIO.createImageInputStream(new ByteArrayInputStream(buff))); 1627 1628 reader.addIIOReadProgressListener(new EmbeddedProgressAdapter() { 1629 public void imageProgress(ImageReader source, 1630 float percentageDone) 1631 { 1632 processImageProgress(percentageDone); 1633 } 1634 }); 1635 1636 reader.addIIOReadUpdateListener(new IIOReadUpdateListener () { 1637 public void imageUpdate(ImageReader source, 1638 BufferedImage theImage, 1639 int minX, int minY, 1640 int width, int height, 1641 int periodX, int periodY, 1642 int[] bands) 1643 { 1644 processImageUpdate(theImage, minX, minY, 1645 width, height, 1646 periodX, periodY, bands); 1647 } 1648 public void passComplete(ImageReader source, 1649 BufferedImage theImage) 1650 { 1651 processPassComplete(theImage); 1652 } 1653 public void passStarted(ImageReader source, 1654 BufferedImage theImage, 1655 int pass, 1656 int minPass, int maxPass, 1657 int minX, int minY, 1658 int periodX, int periodY, 1659 int[] bands) 1660 { 1661 processPassStarted(theImage, pass, minPass, maxPass, 1662 minX, minY, periodX, periodY, 1663 bands); 1664 } 1665 public void thumbnailPassComplete(ImageReader source, 1666 BufferedImage thumb) {} 1667 public void thumbnailPassStarted(ImageReader source, 1668 BufferedImage thumb, 1669 int pass, 1670 int minPass, int maxPass, 1671 int minX, int minY, 1672 int periodX, int periodY, 1673 int[] bands) {} 1674 public void thumbnailUpdate(ImageReader source, 1675 BufferedImage theThumbnail, 1676 int minX, int minY, 1677 int width, int height, 1678 int periodX, int periodY, 1679 int[] bands) {} 1680 }); 1681 1682 reader.addIIOReadWarningListener(new IIOReadWarningListener () { 1683 public void warningOccurred(ImageReader source, String warning) { 1684 processWarningOccurred(warning); 1685 } 1686 }); 1687 1688 ImageReadParam param = reader.getDefaultReadParam(); 1689 param.setDestination(bi); 1690 param.setDestinationBands(bmpParam.getDestinationBands()); 1691 param.setDestinationOffset(bmpParam.getDestinationOffset()); 1692 param.setSourceBands(bmpParam.getSourceBands()); 1693 param.setSourceRegion(bmpParam.getSourceRegion()); 1694 param.setSourceSubsampling(bmpParam.getSourceXSubsampling(), 1695 bmpParam.getSourceYSubsampling(), 1696 bmpParam.getSubsamplingXOffset(), 1697 bmpParam.getSubsamplingYOffset()); 1698 reader.read(0, param); 1699 } else 1700 throw new RuntimeException (I18N.getString("BMPImageReader4") + " " + format); 1701 } 1702 1703 private class EmbeddedProgressAdapter implements IIOReadProgressListener { 1704 public void imageComplete(ImageReader src) {} 1705 public void imageProgress(ImageReader src, float percentageDone) {} 1706 public void imageStarted(ImageReader src, int imageIndex) {} 1707 public void thumbnailComplete(ImageReader src) {} 1708 public void thumbnailProgress(ImageReader src, float percentageDone) {} 1709 public void thumbnailStarted(ImageReader src, int iIdx, int tIdx) {} 1710 public void sequenceComplete(ImageReader src) {} 1711 public void sequenceStarted(ImageReader src, int minIndex) {} 1712 public void readAborted(ImageReader src) {} 1713 } 1714} 1715 | Popular Tags |