1 18 package org.apache.batik.ext.awt.image.codec.tiff; 19 20 import java.awt.Rectangle ; 21 import java.awt.Transparency ; 22 import java.awt.color.ColorSpace ; 23 import java.awt.image.ColorModel ; 24 import java.awt.image.ComponentColorModel ; 25 import java.awt.image.DataBuffer ; 26 import java.awt.image.DataBufferByte ; 27 import java.awt.image.DataBufferInt ; 28 import java.awt.image.DataBufferShort ; 29 import java.awt.image.DataBufferUShort ; 30 import java.awt.image.IndexColorModel ; 31 import java.awt.image.MultiPixelPackedSampleModel ; 32 import java.awt.image.PixelInterleavedSampleModel ; 33 import java.awt.image.Raster ; 34 import java.awt.image.SampleModel ; 35 import java.awt.image.WritableRaster ; 36 import java.io.ByteArrayInputStream ; 37 import java.io.IOException ; 38 import java.util.HashMap ; 39 import java.util.Map ; 40 import java.util.zip.DataFormatException ; 41 import java.util.zip.Inflater ; 42 43 import org.apache.batik.ext.awt.image.codec.SeekableStream; 44 import org.apache.batik.ext.awt.image.rendered.AbstractRed; 45 import org.apache.batik.ext.awt.image.rendered.CachableRed; 46 47 import com.sun.image.codec.jpeg.JPEGCodec; 48 import com.sun.image.codec.jpeg.JPEGDecodeParam; 49 import com.sun.image.codec.jpeg.JPEGImageDecoder; 50 51 public class TIFFImage extends AbstractRed { 52 53 public static final int COMP_NONE = 1; 55 public static final int COMP_FAX_G3_1D = 2; 56 public static final int COMP_FAX_G3_2D = 3; 57 public static final int COMP_FAX_G4_2D = 4; 58 public static final int COMP_LZW = 5; 59 public static final int COMP_JPEG_OLD = 6; 60 public static final int COMP_JPEG_TTN2 = 7; 61 public static final int COMP_PACKBITS = 32773; 62 public static final int COMP_DEFLATE = 32946; 63 64 private static final int TYPE_UNSUPPORTED = -1; 66 private static final int TYPE_BILEVEL = 0; 67 private static final int TYPE_GRAY_4BIT = 1; 68 private static final int TYPE_GRAY = 2; 69 private static final int TYPE_GRAY_ALPHA = 3; 70 private static final int TYPE_PALETTE = 4; 71 private static final int TYPE_RGB = 5; 72 private static final int TYPE_RGB_ALPHA = 6; 73 private static final int TYPE_YCBCR_SUB = 7; 74 private static final int TYPE_GENERIC = 8; 75 76 private static final int TIFF_JPEG_TABLES = 347; 78 private static final int TIFF_YCBCR_SUBSAMPLING = 530; 79 80 SeekableStream stream; 81 int tileSize; 82 int tilesX, tilesY; 83 long[] tileOffsets; 84 long[] tileByteCounts; 85 char[] colormap; 86 int sampleSize; 87 int compression; 88 byte[] palette; 89 int numBands; 90 91 int chromaSubH; 92 int chromaSubV; 93 94 long tiffT4Options; 96 long tiffT6Options; 97 int fillOrder; 98 99 int predictor; 101 102 JPEGDecodeParam decodeParam = null; 104 boolean colorConvertJPEG = false; 105 106 Inflater inflater = null; 108 109 boolean isBigEndian; 111 112 int imageType; 113 boolean isWhiteZero = false; 114 int dataType; 115 116 boolean decodePaletteAsShorts; 117 boolean tiled; 118 119 private TIFFFaxDecoder decoder = null; 121 private TIFFLZWDecoder lzwDecoder = null; 122 123 135 private static final Raster decodeJPEG(byte[] data, 136 JPEGDecodeParam decodeParam, 137 boolean colorConvert, 138 int minX, 139 int minY) { 140 ByteArrayInputStream jpegStream = new ByteArrayInputStream (data); 142 143 JPEGImageDecoder decoder = decodeParam == null ? 145 JPEGCodec.createJPEGDecoder(jpegStream) : 146 JPEGCodec.createJPEGDecoder(jpegStream, 147 decodeParam); 148 149 Raster jpegRaster; 151 try { 152 jpegRaster = colorConvert ? 153 decoder.decodeAsBufferedImage().getWritableTile(0, 0) : 154 decoder.decodeAsRaster(); 155 } catch (IOException ioe) { 156 throw new RuntimeException ("TIFFImage13"); 157 } 158 159 return jpegRaster.createTranslatedChild(minX, minY); 161 } 162 163 167 private final void inflate(byte[] deflated, byte[] inflated) { 168 inflater.setInput(deflated); 169 try { 170 inflater.inflate(inflated); 171 } catch(DataFormatException dfe) { 172 throw new RuntimeException ("TIFFImage17"+": "+ 173 dfe.getMessage()); 174 } 175 inflater.reset(); 176 } 177 178 private static SampleModel createPixelInterleavedSampleModel 179 (int dataType, int tileWidth, int tileHeight, int bands) { 180 int [] bandOffsets = new int[bands]; 181 for (int i=0; i<bands; i++) 182 bandOffsets[i] = i; 183 return new PixelInterleavedSampleModel 184 (dataType, tileWidth, tileHeight, bands, 185 tileWidth*bands, bandOffsets); 186 } 187 188 191 private final long[] getFieldAsLongs(TIFFField field) { 192 long[] value = null; 193 194 if(field.getType() == TIFFField.TIFF_SHORT) { 195 char[] charValue = field.getAsChars(); 196 value = new long[charValue.length]; 197 for(int i = 0; i < charValue.length; i++) { 198 value[i] = charValue[i] & 0xffff; 199 } 200 } else if(field.getType() == TIFFField.TIFF_LONG) { 201 value = field.getAsLongs(); 202 } else { 203 throw new RuntimeException (); 204 } 205 206 return value; 207 } 208 209 218 public TIFFImage(SeekableStream stream, 219 TIFFDecodeParam param, 220 int directory) 221 throws IOException { 222 223 this.stream = stream; 224 if (param == null) { 225 param = new TIFFDecodeParam(); 226 } 227 228 decodePaletteAsShorts = param.getDecodePaletteAsShorts(); 229 230 TIFFDirectory dir = param.getIFDOffset() == null ? 232 new TIFFDirectory(stream, directory) : 233 new TIFFDirectory(stream, param.getIFDOffset().longValue(), 234 directory); 235 236 TIFFField sfield = dir.getField(TIFFImageDecoder.TIFF_SAMPLES_PER_PIXEL); 238 int samplesPerPixel = sfield == null ? 1 : (int)sfield.getAsLong(0); 239 240 TIFFField planarConfigurationField = 242 dir.getField(TIFFImageDecoder.TIFF_PLANAR_CONFIGURATION); 243 char[] planarConfiguration = planarConfigurationField == null ? 244 new char[] {1} : 245 planarConfigurationField.getAsChars(); 246 247 if (planarConfiguration[0] != 1 && samplesPerPixel != 1) { 249 throw new RuntimeException ("TIFFImage0"); 250 } 251 252 TIFFField bitsField = 254 dir.getField(TIFFImageDecoder.TIFF_BITS_PER_SAMPLE); 255 char[] bitsPerSample = null; 256 if(bitsField != null) { 257 bitsPerSample = bitsField.getAsChars(); 258 } else { 259 bitsPerSample = new char[] {1}; 260 261 for (int i = 1; i < bitsPerSample.length; i++) { 263 if (bitsPerSample[i] != bitsPerSample[0]) { 264 throw new RuntimeException ("TIFFImage1"); 265 } 266 } 267 } 268 sampleSize = bitsPerSample[0]; 269 270 TIFFField sampleFormatField = 273 dir.getField(TIFFImageDecoder.TIFF_SAMPLE_FORMAT); 274 275 char[] sampleFormat = null; 276 if (sampleFormatField != null) { 277 sampleFormat = sampleFormatField.getAsChars(); 278 279 for (int l=1; l<sampleFormat.length; l++) { 281 if (sampleFormat[l] != sampleFormat[0]) { 282 throw new RuntimeException ("TIFFImage2"); 283 } 284 } 285 286 } else { 287 sampleFormat = new char[] {1}; 288 } 289 290 boolean isValidDataFormat = false; 292 switch(sampleSize) { 293 case 1: 294 case 4: 295 case 8: 296 if(sampleFormat[0] != 3) { 297 dataType = DataBuffer.TYPE_BYTE; 299 isValidDataFormat = true; 300 } 301 break; 302 case 16: 303 if(sampleFormat[0] != 3) { 304 dataType = sampleFormat[0] == 2 ? 305 DataBuffer.TYPE_SHORT : DataBuffer.TYPE_USHORT; 306 isValidDataFormat = true; 307 } 308 break; 309 case 32: 310 if (sampleFormat[0] == 3) 311 isValidDataFormat = false; 312 else { 313 dataType = DataBuffer.TYPE_INT; 314 isValidDataFormat = true; 315 } 316 break; 317 } 318 319 if(!isValidDataFormat) { 320 throw new RuntimeException ("TIFFImage3"); 321 } 322 323 TIFFField compField = dir.getField(TIFFImageDecoder.TIFF_COMPRESSION); 325 compression = compField == null ? COMP_NONE : compField.getAsInt(0); 326 327 int photometricType = (int)dir.getFieldAsLong( 329 TIFFImageDecoder.TIFF_PHOTOMETRIC_INTERPRETATION); 330 331 imageType = TYPE_UNSUPPORTED; 333 switch(photometricType) { 334 case 0: isWhiteZero = true; 336 case 1: if(sampleSize == 1 && samplesPerPixel == 1) { 338 imageType = TYPE_BILEVEL; 339 } else if(sampleSize == 4 && samplesPerPixel == 1) { 340 imageType = TYPE_GRAY_4BIT; 341 } else if(sampleSize % 8 == 0) { 342 if(samplesPerPixel == 1) { 343 imageType = TYPE_GRAY; 344 } else if(samplesPerPixel == 2) { 345 imageType = TYPE_GRAY_ALPHA; 346 } else { 347 imageType = TYPE_GENERIC; 348 } 349 } 350 break; 351 case 2: if(sampleSize % 8 == 0) { 353 if(samplesPerPixel == 3) { 354 imageType = TYPE_RGB; 355 } else if(samplesPerPixel == 4) { 356 imageType = TYPE_RGB_ALPHA; 357 } else { 358 imageType = TYPE_GENERIC; 359 } 360 } 361 break; 362 case 3: if(samplesPerPixel == 1 && 364 (sampleSize == 4 || sampleSize == 8 || sampleSize == 16)) { 365 imageType = TYPE_PALETTE; 366 } 367 break; 368 case 4: if(sampleSize == 1 && samplesPerPixel == 1) { 370 imageType = TYPE_BILEVEL; 371 } 372 break; 373 case 6: if(compression == COMP_JPEG_TTN2 && 375 sampleSize == 8 && samplesPerPixel == 3) { 376 colorConvertJPEG = param.getJPEGDecompressYCbCrToRGB(); 378 379 imageType = colorConvertJPEG ? TYPE_RGB : TYPE_GENERIC; 381 } else { 382 TIFFField chromaField = dir.getField(TIFF_YCBCR_SUBSAMPLING); 383 if(chromaField != null) { 384 chromaSubH = chromaField.getAsInt(0); 385 chromaSubV = chromaField.getAsInt(1); 386 } else { 387 chromaSubH = chromaSubV = 2; 388 } 389 390 if(chromaSubH*chromaSubV == 1) { 391 imageType = TYPE_GENERIC; 392 } else if(sampleSize == 8 && samplesPerPixel == 3) { 393 imageType = TYPE_YCBCR_SUB; 394 } 395 } 396 break; 397 default: if(sampleSize % 8 == 0) { 399 imageType = TYPE_GENERIC; 400 } 401 } 402 403 if(imageType == TYPE_UNSUPPORTED) { 405 throw new RuntimeException ("TIFFImage4"); 406 } 407 408 Rectangle bounds = new Rectangle 410 (0, 0, 411 (int)dir.getFieldAsLong(TIFFImageDecoder.TIFF_IMAGE_WIDTH), 412 (int)dir.getFieldAsLong(TIFFImageDecoder.TIFF_IMAGE_LENGTH)); 413 414 numBands = samplesPerPixel; 416 417 TIFFField efield = dir.getField(TIFFImageDecoder.TIFF_EXTRA_SAMPLES); 419 int extraSamples = efield == null ? 0 : (int)efield.getAsLong(0); 420 421 int tileWidth, tileHeight; 422 if (dir.getField(TIFFImageDecoder.TIFF_TILE_OFFSETS) != null) { 423 tiled = true; 424 tileWidth = 426 (int)dir.getFieldAsLong(TIFFImageDecoder.TIFF_TILE_WIDTH); 427 tileHeight = 428 (int)dir.getFieldAsLong(TIFFImageDecoder.TIFF_TILE_LENGTH); 429 tileOffsets = 430 (dir.getField(TIFFImageDecoder.TIFF_TILE_OFFSETS)).getAsLongs(); 431 tileByteCounts = 432 getFieldAsLongs(dir.getField(TIFFImageDecoder.TIFF_TILE_BYTE_COUNTS)); 433 434 } else { 435 tiled = false; 436 437 tileWidth = 443 dir.getField(TIFFImageDecoder.TIFF_TILE_WIDTH) != null ? 444 (int)dir.getFieldAsLong(TIFFImageDecoder.TIFF_TILE_WIDTH) : 445 bounds.width; 446 TIFFField field = 447 dir.getField(TIFFImageDecoder.TIFF_ROWS_PER_STRIP); 448 if (field == null) { 449 451 tileHeight = 452 dir.getField(TIFFImageDecoder.TIFF_TILE_LENGTH) != null ? 453 (int)dir.getFieldAsLong(TIFFImageDecoder.TIFF_TILE_LENGTH): 454 bounds.height; 455 } else { 456 long l = field.getAsLong(0); 457 long infinity = 1; 458 infinity = (infinity << 32) - 1; 459 if (l == infinity) { 460 tileHeight = bounds.height; 462 } else { 463 tileHeight = (int)l; 464 } 465 } 466 467 TIFFField tileOffsetsField = 468 dir.getField(TIFFImageDecoder.TIFF_STRIP_OFFSETS); 469 if (tileOffsetsField == null) { 470 throw new RuntimeException ("TIFFImage5"); 471 } else { 472 tileOffsets = getFieldAsLongs(tileOffsetsField); 473 } 474 475 TIFFField tileByteCountsField = 476 dir.getField(TIFFImageDecoder.TIFF_STRIP_BYTE_COUNTS); 477 if (tileByteCountsField == null) { 478 throw new RuntimeException ("TIFFImage6"); 479 } else { 480 tileByteCounts = getFieldAsLongs(tileByteCountsField); 481 } 482 } 483 484 tilesX = (bounds.width + tileWidth - 1)/tileWidth; 486 tilesY = (bounds.height + tileHeight - 1)/tileHeight; 487 tileSize = tileWidth * tileHeight * numBands; 488 489 isBigEndian = dir.isBigEndian(); 491 492 TIFFField fillOrderField = 493 dir.getField(TIFFImageDecoder.TIFF_FILL_ORDER); 494 if (fillOrderField != null) { 495 fillOrder = fillOrderField.getAsInt(0); 496 } else { 497 fillOrder = 1; 499 } 500 501 switch(compression) { 502 case COMP_NONE: 503 case COMP_PACKBITS: 504 break; 506 case COMP_DEFLATE: 507 inflater = new Inflater (); 508 break; 509 case COMP_FAX_G3_1D: 510 case COMP_FAX_G3_2D: 511 case COMP_FAX_G4_2D: 512 if(sampleSize != 1) { 513 throw new RuntimeException ("TIFFImage7"); 514 } 515 516 if (compression == 3) { 518 TIFFField t4OptionsField = 519 dir.getField(TIFFImageDecoder.TIFF_T4_OPTIONS); 520 if (t4OptionsField != null) { 521 tiffT4Options = t4OptionsField.getAsLong(0); 522 } else { 523 tiffT4Options = 0; 525 } 526 } 527 528 if (compression == 4) { 530 TIFFField t6OptionsField = 531 dir.getField(TIFFImageDecoder.TIFF_T6_OPTIONS); 532 if (t6OptionsField != null) { 533 tiffT6Options = t6OptionsField.getAsLong(0); 534 } else { 535 tiffT6Options = 0; 537 } 538 } 539 540 decoder = new TIFFFaxDecoder(fillOrder, 542 tileWidth, tileHeight); 543 break; 544 545 case COMP_LZW: 546 TIFFField predictorField = 548 dir.getField(TIFFImageDecoder.TIFF_PREDICTOR); 549 550 if (predictorField == null) { 551 predictor = 1; 552 } else { 553 predictor = predictorField.getAsInt(0); 554 555 if (predictor != 1 && predictor != 2) { 556 throw new RuntimeException ("TIFFImage8"); 557 } 558 559 if (predictor == 2 && sampleSize != 8) { 560 throw new RuntimeException (sampleSize + 561 "TIFFImage9"); 562 } 563 } 564 565 lzwDecoder = new TIFFLZWDecoder(tileWidth, predictor, 566 samplesPerPixel); 567 break; 568 569 case COMP_JPEG_OLD: 570 throw new RuntimeException ("TIFFImage15"); 571 572 case COMP_JPEG_TTN2: 573 if(!(sampleSize == 8 && 574 ((imageType == TYPE_GRAY && samplesPerPixel == 1) || 575 (imageType == TYPE_PALETTE && samplesPerPixel == 1) || 576 (imageType == TYPE_RGB && samplesPerPixel == 3)))) { 577 throw new RuntimeException ("TIFFImage16"); 578 } 579 580 if(dir.isTagPresent(TIFF_JPEG_TABLES)) { 582 TIFFField jpegTableField = dir.getField(TIFF_JPEG_TABLES); 583 byte[] jpegTable = jpegTableField.getAsBytes(); 584 ByteArrayInputStream tableStream = 585 new ByteArrayInputStream (jpegTable); 586 JPEGImageDecoder decoder = 587 JPEGCodec.createJPEGDecoder(tableStream); 588 decoder.decodeAsRaster(); 589 decodeParam = decoder.getJPEGDecodeParam(); 590 } 591 592 break; 593 default: 594 throw new RuntimeException ("TIFFImage10"); 595 } 596 597 ColorModel colorModel = null; 598 SampleModel sampleModel = null; 599 switch(imageType) { 600 case TYPE_BILEVEL: 601 case TYPE_GRAY_4BIT: 602 sampleModel = 603 new MultiPixelPackedSampleModel (dataType, 604 tileWidth, 605 tileHeight, 606 sampleSize); 607 if(imageType == TYPE_BILEVEL) { 608 byte[] map = new byte[] {(byte)(isWhiteZero ? 255 : 0), 609 (byte)(isWhiteZero ? 0 : 255)}; 610 colorModel = new IndexColorModel (1, 2, map, map, map); 611 } else { 612 byte [] map = new byte[16]; 613 if (isWhiteZero) { 614 for (int i=0; i<map.length; i++) 615 map[i] = (byte)(255-(16*i)); 616 } else { 617 for (int i=0; i<map.length; i++) 618 map[i] = (byte)(16*i); 619 } 620 colorModel = new IndexColorModel (4, 16, map, map, map); 621 } 622 break; 623 624 case TYPE_GRAY: 625 case TYPE_GRAY_ALPHA: 626 case TYPE_RGB: 627 case TYPE_RGB_ALPHA: 628 int[] reverseOffsets = new int[numBands]; 631 for (int i=0; i<numBands; i++) { 632 reverseOffsets[i] = numBands - 1 - i; 633 } 634 sampleModel = new PixelInterleavedSampleModel 635 (dataType, tileWidth, tileHeight, 636 numBands, numBands*tileWidth, reverseOffsets); 637 638 if(imageType == TYPE_GRAY) { 639 colorModel = new ComponentColorModel 640 (ColorSpace.getInstance(ColorSpace.CS_GRAY), 641 new int[] { sampleSize }, false, false, 642 Transparency.OPAQUE, dataType); 643 } else if (imageType == TYPE_RGB) { 644 colorModel = new ComponentColorModel 645 (ColorSpace.getInstance(ColorSpace.CS_sRGB), 646 new int[] { sampleSize, sampleSize, sampleSize }, 647 false, false, Transparency.OPAQUE, dataType); 648 } else { int transparency = Transparency.OPAQUE; 654 if(extraSamples == 1) { transparency = Transparency.TRANSLUCENT; 656 } else if(extraSamples == 2) { transparency = Transparency.BITMASK; 658 } 659 660 colorModel = 661 createAlphaComponentColorModel(dataType, 662 numBands, 663 extraSamples == 1, 664 transparency); 665 } 666 break; 667 668 case TYPE_GENERIC: 669 case TYPE_YCBCR_SUB: 670 674 int[] bandOffsets = new int[numBands]; 675 for (int i=0; i<numBands; i++) { 676 bandOffsets[i] = i; 677 } 678 679 sampleModel = new PixelInterleavedSampleModel 680 (dataType, tileWidth, tileHeight, 681 numBands, numBands * tileWidth, bandOffsets); 682 colorModel = null; 683 break; 684 685 case TYPE_PALETTE: 686 TIFFField cfield = dir.getField(TIFFImageDecoder.TIFF_COLORMAP); 688 if (cfield == null) { 689 throw new RuntimeException ("TIFFImage11"); 690 } else { 691 colormap = cfield.getAsChars(); 692 } 693 694 if (decodePaletteAsShorts) { 697 numBands = 3; 698 699 if (dataType == DataBuffer.TYPE_BYTE) { 705 dataType = DataBuffer.TYPE_USHORT; 706 } 707 708 sampleModel = createPixelInterleavedSampleModel 712 (dataType, tileWidth, tileHeight, numBands); 713 714 colorModel = new ComponentColorModel 715 (ColorSpace.getInstance(ColorSpace.CS_sRGB), 716 new int[] { 16, 16, 16 }, false, false, 717 Transparency.OPAQUE, dataType); 718 719 } else { 720 721 numBands = 1; 722 723 if (sampleSize == 4) { 724 sampleModel = new MultiPixelPackedSampleModel 728 (DataBuffer.TYPE_BYTE, tileWidth, tileHeight, 729 sampleSize); 730 } else if (sampleSize == 8) { 731 732 sampleModel = createPixelInterleavedSampleModel 733 (DataBuffer.TYPE_BYTE, tileWidth, tileHeight, 734 numBands); 735 } else if (sampleSize == 16) { 736 737 dataType = DataBuffer.TYPE_USHORT; 743 sampleModel = createPixelInterleavedSampleModel 744 (DataBuffer.TYPE_USHORT, tileWidth, tileHeight, 745 numBands); 746 } 747 748 int bandLength = colormap.length/3; 749 byte r[] = new byte[bandLength]; 750 byte g[] = new byte[bandLength]; 751 byte b[] = new byte[bandLength]; 752 753 int gIndex = bandLength; 754 int bIndex = bandLength * 2; 755 756 if (dataType == DataBuffer.TYPE_SHORT) { 757 758 for (int i=0; i<bandLength; i++) { 759 r[i] = param.decodeSigned16BitsTo8Bits 760 ((short)colormap[i]); 761 g[i] = param.decodeSigned16BitsTo8Bits 762 ((short)colormap[gIndex+i]); 763 b[i] = param.decodeSigned16BitsTo8Bits 764 ((short)colormap[bIndex+i]); 765 } 766 767 } else { 768 769 for (int i=0; i<bandLength; i++) { 770 r[i] = param.decode16BitsTo8Bits 771 (colormap[i] & 0xffff); 772 g[i] = param.decode16BitsTo8Bits 773 (colormap[gIndex+i] & 0xffff); 774 b[i] = param.decode16BitsTo8Bits 775 (colormap[bIndex+i] & 0xffff); 776 } 777 778 } 779 780 colorModel = new IndexColorModel (sampleSize, 781 bandLength, r, g, b); 782 } 783 break; 784 785 default: 786 throw new RuntimeException ("TIFFImage4"); 787 } 788 789 Map properties = new HashMap (); 790 properties.put("tiff_directory", dir); 792 793 795 init((CachableRed)null, bounds, colorModel, sampleModel, 796 0, 0, properties); 797 } 798 799 804 public TIFFDirectory getPrivateIFD(long offset) throws IOException { 805 return new TIFFDirectory(stream, offset, 0); 806 } 807 808 809 public WritableRaster copyData(WritableRaster wr) { 810 copyToRaster(wr); 811 return wr; 812 } 813 814 815 818 public synchronized Raster getTile(int tileX, int tileY) { 819 if ((tileX < 0) || (tileX >= tilesX) || 820 (tileY < 0) || (tileY >= tilesY)) { 821 throw new IllegalArgumentException ("TIFFImage12"); 822 } 823 824 826 827 byte bdata[] = null; 829 short sdata[] = null; 830 int idata[] = null; 831 832 SampleModel sampleModel = getSampleModel(); 833 WritableRaster tile = makeTile(tileX,tileY); 834 835 DataBuffer buffer = tile.getDataBuffer(); 836 837 int dataType = sampleModel.getDataType(); 838 if (dataType == DataBuffer.TYPE_BYTE) { 839 bdata = ((DataBufferByte )buffer).getData(); 840 } else if (dataType == DataBuffer.TYPE_USHORT) { 841 sdata = ((DataBufferUShort )buffer).getData(); 842 } else if (dataType == DataBuffer.TYPE_SHORT) { 843 sdata = ((DataBufferShort )buffer).getData(); 844 } else if (dataType == DataBuffer.TYPE_INT) { 845 idata = ((DataBufferInt )buffer).getData(); 846 } 847 848 byte bswap; 850 short sswap; 851 int iswap; 852 853 long save_offset = 0; 855 try { 856 save_offset = stream.getFilePointer(); 857 stream.seek(tileOffsets[tileY*tilesX + tileX]); 858 } catch (IOException ioe) { 859 throw new RuntimeException ("TIFFImage13"); 860 } 861 862 int byteCount = (int)tileByteCounts[tileY*tilesX + tileX]; 864 865 Rectangle newRect; 867 if (!tiled) 868 newRect = tile.getBounds(); 869 else 870 newRect = new Rectangle (tile.getMinX(), tile.getMinY(), 871 tileWidth, tileHeight); 872 873 int unitsInThisTile = newRect.width * newRect.height * numBands; 874 875 byte data[] = compression != COMP_NONE || imageType == TYPE_PALETTE ? 877 new byte[byteCount] : null; 878 879 if(imageType == TYPE_BILEVEL) { try { 883 if (compression == COMP_PACKBITS) { 884 stream.readFully(data, 0, byteCount); 885 886 int bytesInThisTile; 889 if ((newRect.width % 8) == 0) { 890 bytesInThisTile = (newRect.width/8) * newRect.height; 891 } else { 892 bytesInThisTile = 893 (newRect.width/8 + 1) * newRect.height; 894 } 895 decodePackbits(data, bytesInThisTile, bdata); 896 } else if (compression == COMP_LZW) { 897 stream.readFully(data, 0, byteCount); 898 lzwDecoder.decode(data, bdata, newRect.height); 899 } else if (compression == COMP_FAX_G3_1D) { 900 stream.readFully(data, 0, byteCount); 901 decoder.decode1D(bdata, data, 0, newRect.height); 902 } else if (compression == COMP_FAX_G3_2D) { 903 stream.readFully(data, 0, byteCount); 904 decoder.decode2D(bdata, data, 0, newRect.height, 905 tiffT4Options); 906 } else if (compression == COMP_FAX_G4_2D) { 907 stream.readFully(data, 0, byteCount); 908 decoder.decodeT6(bdata, data, 0, newRect.height, 909 tiffT6Options); 910 } else if (compression == COMP_DEFLATE) { 911 stream.readFully(data, 0, byteCount); 912 inflate(data, bdata); 913 } else if (compression == COMP_NONE) { 914 stream.readFully(bdata, 0, byteCount); 915 } 916 917 stream.seek(save_offset); 918 } catch (IOException ioe) { 919 throw new RuntimeException ("TIFFImage13"); 920 } 921 } else if(imageType == TYPE_PALETTE) { if (sampleSize == 16) { 923 924 if (decodePaletteAsShorts) { 925 926 short tempData[]= null; 927 928 int unitsBeforeLookup = unitsInThisTile / 3; 933 934 int entries = unitsBeforeLookup * 2; 939 940 try { 942 943 if (compression == COMP_PACKBITS) { 944 945 stream.readFully(data, 0, byteCount); 946 947 byte byteArray[] = new byte[entries]; 948 decodePackbits(data, entries, byteArray); 949 tempData = new short[unitsBeforeLookup]; 950 interpretBytesAsShorts(byteArray, tempData, 951 unitsBeforeLookup); 952 953 } else if (compression == COMP_LZW) { 954 955 stream.readFully(data, 0, byteCount); 957 958 byte byteArray[] = new byte[entries]; 959 lzwDecoder.decode(data, byteArray, newRect.height); 960 tempData = new short[unitsBeforeLookup]; 961 interpretBytesAsShorts(byteArray, tempData, 962 unitsBeforeLookup); 963 964 } else if (compression == COMP_DEFLATE) { 965 966 stream.readFully(data, 0, byteCount); 967 byte byteArray[] = new byte[entries]; 968 inflate(data, byteArray); 969 tempData = new short[unitsBeforeLookup]; 970 interpretBytesAsShorts(byteArray, tempData, 971 unitsBeforeLookup); 972 973 } else if (compression == COMP_NONE) { 974 975 tempData = new short[byteCount/2]; 980 readShorts(byteCount/2, tempData); 981 } 982 983 stream.seek(save_offset); 984 985 } catch (IOException ioe) { 986 throw new RuntimeException ("TIFFImage13"); 987 } 988 989 if (dataType == DataBuffer.TYPE_USHORT) { 990 991 int cmapValue; 994 int count = 0, lookup, len = colormap.length/3; 995 int len2 = len * 2; 996 for (int i=0; i<unitsBeforeLookup; i++) { 997 lookup = tempData[i] & 0xffff; 999 cmapValue = colormap[lookup+len2]; 1001 sdata[count++] = (short)(cmapValue & 0xffff); 1002 cmapValue = colormap[lookup+len]; 1004 sdata[count++] = (short)(cmapValue & 0xffff); 1005 cmapValue = colormap[lookup]; 1007 sdata[count++] = (short)(cmapValue & 0xffff); 1008 } 1009 1010 } else if (dataType == DataBuffer.TYPE_SHORT) { 1011 1012 int cmapValue; 1015 int count = 0, lookup, len = colormap.length/3; 1016 int len2 = len * 2; 1017 for (int i=0; i<unitsBeforeLookup; i++) { 1018 lookup = tempData[i] & 0xffff; 1020 cmapValue = colormap[lookup+len2]; 1022 sdata[count++] = (short)cmapValue; 1023 cmapValue = colormap[lookup+len]; 1025 sdata[count++] = (short)cmapValue; 1026 cmapValue = colormap[lookup]; 1028 sdata[count++] = (short)cmapValue; 1029 } 1030 } 1031 1032 } else { 1033 1034 1037 try { 1038 1039 if (compression == COMP_PACKBITS) { 1040 1041 stream.readFully(data, 0, byteCount); 1042 1043 int bytesInThisTile = unitsInThisTile * 2; 1049 1050 byte byteArray[] = new byte[bytesInThisTile]; 1051 decodePackbits(data, bytesInThisTile, byteArray); 1052 interpretBytesAsShorts(byteArray, sdata, 1053 unitsInThisTile); 1054 1055 } else if (compression == COMP_LZW) { 1056 1057 stream.readFully(data, 0, byteCount); 1058 1059 byte byteArray[] = new byte[unitsInThisTile * 2]; 1065 lzwDecoder.decode(data, byteArray, newRect.height); 1066 interpretBytesAsShorts(byteArray, sdata, 1067 unitsInThisTile); 1068 1069 } else if (compression == COMP_DEFLATE) { 1070 1071 stream.readFully(data, 0, byteCount); 1072 byte byteArray[] = new byte[unitsInThisTile * 2]; 1073 inflate(data, byteArray); 1074 interpretBytesAsShorts(byteArray, sdata, 1075 unitsInThisTile); 1076 1077 } else if (compression == COMP_NONE) { 1078 1079 readShorts(byteCount/2, sdata); 1080 } 1081 1082 stream.seek(save_offset); 1083 1084 } catch (IOException ioe) { 1085 throw new RuntimeException ("TIFFImage13"); 1086 } 1087 } 1088 1089 } else if (sampleSize == 8) { 1090 1091 if (decodePaletteAsShorts) { 1092 1093 byte tempData[]= null; 1094 1095 int unitsBeforeLookup = unitsInThisTile / 3; 1100 1101 try { 1103 1104 if (compression == COMP_PACKBITS) { 1105 1106 stream.readFully(data, 0, byteCount); 1107 tempData = new byte[unitsBeforeLookup]; 1108 decodePackbits(data, unitsBeforeLookup, tempData); 1109 1110 } else if (compression == COMP_LZW) { 1111 1112 stream.readFully(data, 0, byteCount); 1113 tempData = new byte[unitsBeforeLookup]; 1114 lzwDecoder.decode(data, tempData, newRect.height); 1115 1116 } else if (compression == COMP_JPEG_TTN2) { 1117 1118 stream.readFully(data, 0, byteCount); 1119 Raster tempTile = decodeJPEG(data, 1120 decodeParam, 1121 colorConvertJPEG, 1122 tile.getMinX(), 1123 tile.getMinY()); 1124 int[] tempPixels = new int[unitsBeforeLookup]; 1125 tempTile.getPixels(tile.getMinX(), 1126 tile.getMinY(), 1127 tile.getWidth(), 1128 tile.getHeight(), 1129 tempPixels); 1130 tempData = new byte[unitsBeforeLookup]; 1131 for(int i = 0; i < unitsBeforeLookup; i++) { 1132 tempData[i] = (byte)tempPixels[i]; 1133 } 1134 1135 } else if (compression == COMP_DEFLATE) { 1136 1137 stream.readFully(data, 0, byteCount); 1138 tempData = new byte[unitsBeforeLookup]; 1139 inflate(data, tempData); 1140 1141 } else if (compression == COMP_NONE) { 1142 1143 tempData = new byte[byteCount]; 1144 stream.readFully(tempData, 0, byteCount); 1145 } 1146 1147 stream.seek(save_offset); 1148 1149 } catch (IOException ioe) { 1150 throw new RuntimeException ("TIFFImage13"); 1151 } 1152 1153 int cmapValue; 1156 int count = 0, lookup, len = colormap.length/3; 1157 int len2 = len * 2; 1158 for (int i=0; i<unitsBeforeLookup; i++) { 1159 lookup = tempData[i] & 0xff; 1161 cmapValue = colormap[lookup+len2]; 1163 sdata[count++] = (short)(cmapValue & 0xffff); 1164 cmapValue = colormap[lookup+len]; 1166 sdata[count++] = (short)(cmapValue & 0xffff); 1167 cmapValue = colormap[lookup]; 1169 sdata[count++] = (short)(cmapValue & 0xffff); 1170 } 1171 } else { 1172 1173 1176 try { 1177 1178 if (compression == COMP_PACKBITS) { 1179 1180 stream.readFully(data, 0, byteCount); 1181 decodePackbits(data, unitsInThisTile, bdata); 1182 1183 } else if (compression == COMP_LZW) { 1184 1185 stream.readFully(data, 0, byteCount); 1186 lzwDecoder.decode(data, bdata, newRect.height); 1187 1188 } else if (compression == COMP_JPEG_TTN2) { 1189 1190 stream.readFully(data, 0, byteCount); 1191 tile.setRect(decodeJPEG(data, 1192 decodeParam, 1193 colorConvertJPEG, 1194 tile.getMinX(), 1195 tile.getMinY())); 1196 1197 } else if (compression == COMP_DEFLATE) { 1198 1199 stream.readFully(data, 0, byteCount); 1200 inflate(data, bdata); 1201 1202 } else if (compression == COMP_NONE) { 1203 1204 stream.readFully(bdata, 0, byteCount); 1205 } 1206 1207 stream.seek(save_offset); 1208 1209 } catch (IOException ioe) { 1210 throw new RuntimeException ("TIFFImage13"); 1211 } 1212 } 1213 1214 } else if (sampleSize == 4) { 1215 1216 int padding = (newRect.width % 2 == 0) ? 0 : 1; 1217 int bytesPostDecoding = ((newRect.width/2 + padding) * 1218 newRect.height); 1219 1220 if (decodePaletteAsShorts) { 1222 1223 byte tempData[] = null; 1224 1225 try { 1226 stream.readFully(data, 0, byteCount); 1227 stream.seek(save_offset); 1228 } catch (IOException ioe) { 1229 throw new RuntimeException ("TIFFImage13"); 1230 } 1231 1232 if (compression == COMP_PACKBITS) { 1234 1235 tempData = new byte[bytesPostDecoding]; 1236 decodePackbits(data, bytesPostDecoding, tempData); 1237 1238 } else if (compression == COMP_LZW) { 1239 1240 tempData = new byte[bytesPostDecoding]; 1241 lzwDecoder.decode(data, tempData, newRect.height); 1242 1243 } else if (compression == COMP_DEFLATE) { 1244 1245 tempData = new byte[bytesPostDecoding]; 1246 inflate(data, tempData); 1247 1248 } else if (compression == COMP_NONE) { 1249 1250 tempData = data; 1251 } 1252 1253 int bytes = unitsInThisTile / 3; 1254 1255 data = new byte[bytes]; 1257 1258 int srcCount = 0, dstCount = 0; 1259 for (int j=0; j<newRect.height; j++) { 1260 for (int i=0; i<newRect.width/2; i++) { 1261 data[dstCount++] = 1262 (byte)((tempData[srcCount] & 0xf0) >> 4); 1263 data[dstCount++] = 1264 (byte)(tempData[srcCount++] & 0x0f); 1265 } 1266 1267 if (padding == 1) { 1268 data[dstCount++] = 1269 (byte)((tempData[srcCount++] & 0xf0) >> 4); 1270 } 1271 } 1272 1273 int len = colormap.length/3; 1274 int len2 = len*2; 1275 int cmapValue, lookup; 1276 int count = 0; 1277 for (int i=0; i<bytes; i++) { 1278 lookup = data[i] & 0xff; 1279 cmapValue = colormap[lookup+len2]; 1280 sdata[count++] = (short)(cmapValue & 0xffff); 1281 cmapValue = colormap[lookup+len]; 1282 sdata[count++] = (short)(cmapValue & 0xffff); 1283 cmapValue = colormap[lookup]; 1284 sdata[count++] = (short)(cmapValue & 0xffff); 1285 } 1286 } else { 1287 1288 try { 1290 1291 if (compression == COMP_PACKBITS) { 1293 1294 stream.readFully(data, 0, byteCount); 1295 decodePackbits(data, bytesPostDecoding, bdata); 1296 1297 } else if (compression == COMP_LZW) { 1298 1299 stream.readFully(data, 0, byteCount); 1300 lzwDecoder.decode(data, bdata, newRect.height); 1301 1302 } else if (compression == COMP_DEFLATE) { 1303 1304 stream.readFully(data, 0, byteCount); 1305 inflate(data, bdata); 1306 1307 } else if (compression == COMP_NONE) { 1308 1309 stream.readFully(bdata, 0, byteCount); 1310 } 1311 1312 stream.seek(save_offset); 1313 1314 } catch (IOException ioe) { 1315 throw new RuntimeException ("TIFFImage13"); 1316 } 1317 } 1318 } 1319 } else if(imageType == TYPE_GRAY_4BIT) { try { 1321 if (compression == COMP_PACKBITS) { 1322 1323 stream.readFully(data, 0, byteCount); 1324 1325 int bytesInThisTile; 1328 if ((newRect.width % 8) == 0) { 1329 bytesInThisTile = (newRect.width/2) * newRect.height; 1330 } else { 1331 bytesInThisTile = (newRect.width/2 + 1) * 1332 newRect.height; 1333 } 1334 1335 decodePackbits(data, bytesInThisTile, bdata); 1336 1337 } else if (compression == COMP_LZW) { 1338 1339 stream.readFully(data, 0, byteCount); 1340 lzwDecoder.decode(data, bdata, newRect.height); 1341 1342 } else if (compression == COMP_DEFLATE) { 1343 1344 stream.readFully(data, 0, byteCount); 1345 inflate(data, bdata); 1346 1347 } else { 1348 1349 stream.readFully(bdata, 0, byteCount); 1350 } 1351 1352 stream.seek(save_offset); 1353 } catch (IOException ioe) { 1354 throw new RuntimeException ("TIFFImage13"); 1355 } 1356 } else { try { 1358 1359 if (sampleSize == 8) { 1360 1361 if (compression == COMP_NONE) { 1362 stream.readFully(bdata, 0, byteCount); 1363 1364 } else if (compression == COMP_LZW) { 1365 1366 stream.readFully(data, 0, byteCount); 1367 lzwDecoder.decode(data, bdata, newRect.height); 1368 1369 } else if (compression == COMP_PACKBITS) { 1370 1371 stream.readFully(data, 0, byteCount); 1372 decodePackbits(data, unitsInThisTile, bdata); 1373 1374 } else if (compression == COMP_JPEG_TTN2) { 1375 1376 stream.readFully(data, 0, byteCount); 1377 tile.setRect(decodeJPEG(data, 1378 decodeParam, 1379 colorConvertJPEG, 1380 tile.getMinX(), 1381 tile.getMinY())); 1382 } else if (compression == COMP_DEFLATE) { 1383 1384 stream.readFully(data, 0, byteCount); 1385 inflate(data, bdata); 1386 } 1387 1388 } else if (sampleSize == 16) { 1389 1390 if (compression == COMP_NONE) { 1391 1392 readShorts(byteCount/2, sdata); 1393 1394 } else if (compression == COMP_LZW) { 1395 1396 stream.readFully(data, 0, byteCount); 1397 1398 byte byteArray[] = new byte[unitsInThisTile * 2]; 1404 lzwDecoder.decode(data, byteArray, newRect.height); 1405 interpretBytesAsShorts(byteArray, sdata, 1406 unitsInThisTile); 1407 1408 } else if (compression == COMP_PACKBITS) { 1409 1410 stream.readFully(data, 0, byteCount); 1411 1412 int bytesInThisTile = unitsInThisTile * 2; 1418 1419 byte byteArray[] = new byte[bytesInThisTile]; 1420 decodePackbits(data, bytesInThisTile, byteArray); 1421 interpretBytesAsShorts(byteArray, sdata, 1422 unitsInThisTile); 1423 } else if (compression == COMP_DEFLATE) { 1424 1425 stream.readFully(data, 0, byteCount); 1426 byte byteArray[] = new byte[unitsInThisTile * 2]; 1427 inflate(data, byteArray); 1428 interpretBytesAsShorts(byteArray, sdata, 1429 unitsInThisTile); 1430 1431 } 1432 } else if (sampleSize == 32 && 1433 dataType == DataBuffer.TYPE_INT) { if (compression == COMP_NONE) { 1435 1436 readInts(byteCount/4, idata); 1437 1438 } else if (compression == COMP_LZW) { 1439 1440 stream.readFully(data, 0, byteCount); 1441 1442 byte byteArray[] = new byte[unitsInThisTile * 4]; 1448 lzwDecoder.decode(data, byteArray, newRect.height); 1449 interpretBytesAsInts(byteArray, idata, 1450 unitsInThisTile); 1451 1452 } else if (compression == COMP_PACKBITS) { 1453 1454 stream.readFully(data, 0, byteCount); 1455 1456 int bytesInThisTile = unitsInThisTile * 4; 1462 1463 byte byteArray[] = new byte[bytesInThisTile]; 1464 decodePackbits(data, bytesInThisTile, byteArray); 1465 interpretBytesAsInts(byteArray, idata, 1466 unitsInThisTile); 1467 } else if (compression == COMP_DEFLATE) { 1468 1469 stream.readFully(data, 0, byteCount); 1470 byte byteArray[] = new byte[unitsInThisTile * 4]; 1471 inflate(data, byteArray); 1472 interpretBytesAsInts(byteArray, idata, 1473 unitsInThisTile); 1474 1475 } 1476 } 1477 1478 stream.seek(save_offset); 1479 1480 } catch (IOException ioe) { 1481 throw new RuntimeException ("TIFFImage13"); 1482 } 1483 1484 switch(imageType) { 1486 case TYPE_GRAY: 1487 case TYPE_GRAY_ALPHA: 1488 if(isWhiteZero) { 1489 if (dataType == DataBuffer.TYPE_BYTE && 1493 !(getColorModel() instanceof IndexColorModel )) { 1494 1495 for (int l = 0; l < bdata.length; l += numBands) { 1496 bdata[l] = (byte)(255 - bdata[l]); 1497 } 1498 } else if (dataType == DataBuffer.TYPE_USHORT) { 1499 1500 int ushortMax = Short.MAX_VALUE - Short.MIN_VALUE; 1501 for (int l = 0; l < sdata.length; l += numBands) { 1502 sdata[l] = (short)(ushortMax - sdata[l]); 1503 } 1504 1505 } else if (dataType == DataBuffer.TYPE_SHORT) { 1506 1507 for (int l = 0; l < sdata.length; l += numBands) { 1508 sdata[l] = (short)(~sdata[l]); 1509 } 1510 } else if (dataType == DataBuffer.TYPE_INT) { 1511 1512 long uintMax = ((long)Integer.MAX_VALUE - 1513 (long)Integer.MIN_VALUE); 1514 for (int l = 0; l < idata.length; l += numBands) { 1515 idata[l] = (int)(uintMax - idata[l]); 1516 } 1517 } 1518 } 1519 break; 1520 case TYPE_RGB: 1521 if (sampleSize == 8 && compression != COMP_JPEG_TTN2) { 1524 for (int i=0; i<unitsInThisTile; i+=3) { 1525 bswap = bdata[i]; 1526 bdata[i] = bdata[i+2]; 1527 bdata[i+2] = bswap; 1528 } 1529 } else if (sampleSize == 16) { 1530 for (int i=0; i<unitsInThisTile; i+=3) { 1531 sswap = sdata[i]; 1532 sdata[i] = sdata[i+2]; 1533 sdata[i+2] = sswap; 1534 } 1535 } else if (sampleSize == 32) { 1536 if(dataType == DataBuffer.TYPE_INT) { 1537 for (int i=0; i<unitsInThisTile; i+=3) { 1538 iswap = idata[i]; 1539 idata[i] = idata[i+2]; 1540 idata[i+2] = iswap; 1541 } 1542 } 1543 } 1544 break; 1545 case TYPE_RGB_ALPHA: 1546 if (sampleSize == 8) { 1548 for (int i=0; i<unitsInThisTile; i+=4) { 1549 bswap = bdata[i]; 1551 bdata[i] = bdata[i+3]; 1552 bdata[i+3] = bswap; 1553 1554 bswap = bdata[i+1]; 1556 bdata[i+1] = bdata[i+2]; 1557 bdata[i+2] = bswap; 1558 } 1559 } else if (sampleSize == 16) { 1560 for (int i=0; i<unitsInThisTile; i+=4) { 1561 sswap = sdata[i]; 1563 sdata[i] = sdata[i+3]; 1564 sdata[i+3] = sswap; 1565 1566 sswap = sdata[i+1]; 1568 sdata[i+1] = sdata[i+2]; 1569 sdata[i+2] = sswap; 1570 } 1571 } else if (sampleSize == 32) { 1572 if(dataType == DataBuffer.TYPE_INT) { 1573 for (int i=0; i<unitsInThisTile; i+=4) { 1574 iswap = idata[i]; 1576 idata[i] = idata[i+3]; 1577 idata[i+3] = iswap; 1578 1579 iswap = idata[i+1]; 1581 idata[i+1] = idata[i+2]; 1582 idata[i+2] = iswap; 1583 } 1584 } 1585 } 1586 break; 1587 case TYPE_YCBCR_SUB: 1588 int pixelsPerDataUnit = chromaSubH*chromaSubV; 1591 1592 int numH = newRect.width/chromaSubH; 1593 int numV = newRect.height/chromaSubV; 1594 1595 byte[] tempData = new byte[numH*numV*(pixelsPerDataUnit + 2)]; 1596 System.arraycopy(bdata, 0, tempData, 0, tempData.length); 1597 1598 int samplesPerDataUnit = pixelsPerDataUnit*3; 1599 int[] pixels = new int[samplesPerDataUnit]; 1600 1601 int bOffset = 0; 1602 int offsetCb = pixelsPerDataUnit; 1603 int offsetCr = offsetCb + 1; 1604 1605 int y = newRect.y; 1606 for(int j = 0; j < numV; j++) { 1607 int x = newRect.x; 1608 for(int i = 0; i < numH; i++) { 1609 int Cb = tempData[bOffset + offsetCb]; 1610 int Cr = tempData[bOffset + offsetCr]; 1611 int k = 0; 1612 while(k < samplesPerDataUnit) { 1613 pixels[k++] = tempData[bOffset++]; 1614 pixels[k++] = Cb; 1615 pixels[k++] = Cr; 1616 } 1617 bOffset += 2; 1618 tile.setPixels(x, y, chromaSubH, chromaSubV, pixels); 1619 x += chromaSubH; 1620 } 1621 y += chromaSubV; 1622 } 1623 1624 break; 1625 } 1626 } 1627 1628 return tile; 1629 } 1630 1631 private void readShorts(int shortCount, short shortArray[]) { 1632 1633 int byteCount = 2 * shortCount; 1636 byte byteArray[] = new byte[byteCount]; 1637 1638 try { 1639 stream.readFully(byteArray, 0, byteCount); 1640 } catch (IOException ioe) { 1641 throw new RuntimeException ("TIFFImage13"); 1642 } 1643 1644 interpretBytesAsShorts(byteArray, shortArray, shortCount); 1645 } 1646 1647 private void readInts(int intCount, int intArray[]) { 1648 1649 int byteCount = 4 * intCount; 1652 byte byteArray[] = new byte[byteCount]; 1653 1654 try { 1655 stream.readFully(byteArray, 0, byteCount); 1656 } catch (IOException ioe) { 1657 throw new RuntimeException ("TIFFImage13"); 1658 } 1659 1660 interpretBytesAsInts(byteArray, intArray, intCount); 1661 } 1662 1663 private void interpretBytesAsShorts(byte byteArray[], 1666 short shortArray[], 1667 int shortCount) { 1668 1669 int j = 0; 1670 int firstByte, secondByte; 1671 1672 if (isBigEndian) { 1673 1674 for (int i=0; i<shortCount; i++) { 1675 firstByte = byteArray[j++] & 0xff; 1676 secondByte = byteArray[j++] & 0xff; 1677 shortArray[i] = (short)((firstByte << 8) + secondByte); 1678 } 1679 1680 } else { 1681 1682 for (int i=0; i<shortCount; i++) { 1683 firstByte = byteArray[j++] & 0xff; 1684 secondByte = byteArray[j++] & 0xff; 1685 shortArray[i] = (short)((secondByte << 8) + firstByte); 1686 } 1687 } 1688 } 1689 1690 private void interpretBytesAsInts(byte byteArray[], 1693 int intArray[], 1694 int intCount) { 1695 1696 int j = 0; 1697 1698 if (isBigEndian) { 1699 1700 for (int i=0; i<intCount; i++) { 1701 intArray[i] = (((byteArray[j++] & 0xff) << 24) | 1702 ((byteArray[j++] & 0xff) << 16) | 1703 ((byteArray[j++] & 0xff) << 8) | 1704 ( byteArray[j++] & 0xff)); 1705 } 1706 1707 } else { 1708 1709 for (int i=0; i<intCount; i++) { 1710 intArray[i] = ((byteArray[j++] & 0xff) | 1711 ((byteArray[j++] & 0xff) << 8) | 1712 ((byteArray[j++] & 0xff) << 16) | 1713 ((byteArray[j++] & 0xff) << 24)); 1714 } 1715 } 1716 } 1717 1718 private byte[] decodePackbits(byte data[], int arraySize, byte[] dst) { 1720 1721 if (dst == null) { 1722 dst = new byte[arraySize]; 1723 } 1724 1725 int srcCount = 0, dstCount = 0; 1726 byte repeat, b; 1727 1728 try { 1729 1730 while (dstCount < arraySize) { 1731 1732 b = data[srcCount++]; 1733 1734 if (b >= 0 && b <= 127) { 1735 1736 for (int i=0; i<(b + 1); i++) { 1738 dst[dstCount++] = data[srcCount++]; 1739 } 1740 1741 } else if (b <= -1 && b >= -127) { 1742 1743 repeat = data[srcCount++]; 1745 for (int i=0; i<(-b + 1); i++) { 1746 dst[dstCount++] = repeat; 1747 } 1748 1749 } else { 1750 srcCount++; 1752 } 1753 } 1754 } catch (java.lang.ArrayIndexOutOfBoundsException ae) { 1755 throw new RuntimeException ("TIFFImage14"); 1756 } 1757 1758 return dst; 1759 } 1760 1761 private ComponentColorModel createAlphaComponentColorModel 1764 (int dataType, int numBands, 1765 boolean isAlphaPremultiplied, int transparency) { 1766 1767 ComponentColorModel ccm = null; 1768 int RGBBits[] = null; 1769 ColorSpace cs = null; 1770 switch(numBands) { 1771 case 2: cs = ColorSpace.getInstance(ColorSpace.CS_GRAY); 1773 break; 1774 case 4: cs = ColorSpace.getInstance(ColorSpace.CS_sRGB); 1776 break; 1777 default: 1778 throw new IllegalArgumentException (); 1779 } 1780 1781 int componentSize = 0; 1782 switch(dataType) { 1783 case DataBuffer.TYPE_BYTE: 1784 componentSize = 8; 1785 break; 1786 case DataBuffer.TYPE_USHORT: 1787 case DataBuffer.TYPE_SHORT: 1788 componentSize = 16; 1789 break; 1790 case DataBuffer.TYPE_INT: 1791 componentSize = 32; 1792 break; 1793 default: 1794 throw new IllegalArgumentException (); 1795 } 1796 1797 RGBBits = new int[numBands]; 1798 for(int i = 0; i < numBands; i++) { 1799 RGBBits[i] = componentSize; 1800 } 1801 1802 ccm = new ComponentColorModel (cs, 1803 RGBBits, 1804 true, 1805 isAlphaPremultiplied, 1806 transparency, 1807 dataType); 1808 1809 1810 return ccm; 1811 } 1812 1813} 1814 | Popular Tags |