1 /*
   2  * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 package com.sun.imageio.plugins.tiff;
  26 
  27 import java.awt.Rectangle;
  28 import java.awt.Transparency;
  29 import java.awt.color.ColorSpace;
  30 import java.awt.image.BufferedImage;
  31 import java.awt.image.ColorModel;
  32 import java.awt.image.ComponentColorModel;
  33 import java.awt.image.ComponentSampleModel;
  34 import java.awt.image.DataBuffer;
  35 import java.awt.image.DataBufferByte;
  36 import java.awt.image.DataBufferDouble;
  37 import java.awt.image.DataBufferFloat;
  38 import java.awt.image.DataBufferInt;
  39 import java.awt.image.DataBufferShort;
  40 import java.awt.image.DataBufferUShort;
  41 import java.awt.image.MultiPixelPackedSampleModel;
  42 import java.awt.image.PixelInterleavedSampleModel;
  43 import java.awt.image.Raster;
  44 import java.awt.image.SampleModel;
  45 import java.awt.image.SinglePixelPackedSampleModel;
  46 import java.awt.image.WritableRaster;
  47 import java.io.ByteArrayInputStream;
  48 import java.io.IOException;
  49 import java.nio.ByteOrder;
  50 import javax.imageio.IIOException;
  51 import javax.imageio.ImageReader;
  52 import javax.imageio.ImageTypeSpecifier;
  53 import javax.imageio.metadata.IIOMetadata;
  54 import javax.imageio.stream.ImageInputStream;
  55 import javax.imageio.stream.MemoryCacheImageInputStream;
  56 import javax.imageio.plugins.tiff.BaselineTIFFTagSet;
  57 import com.sun.imageio.plugins.common.ImageUtil;
  58 import com.sun.imageio.plugins.common.BogusColorSpace;
  59 import com.sun.imageio.plugins.common.SimpleCMYKColorSpace;
  60 
  61 /**
  62  * A class defining a pluggable TIFF decompressor.
  63  *
  64  * <p> The mapping between source and destination Y coordinates is
  65  * given by the equations:
  66  *
  67  * <pre>
  68  * dx = (sx - sourceXOffset)/subsampleX + dstXOffset;
  69  * dy = (sy - sourceYOffset)/subsampleY + dstYOffset;
  70  * </pre>
  71  *
  72  * Note that the mapping from source coordinates to destination
  73  * coordinates is not one-to-one if subsampling is being used, since
  74  * only certain source pixels are to be copied to the
  75  * destination. However, * the inverse mapping is always one-to-one:
  76  *
  77  * <pre>
  78  * sx = (dx - dstXOffset)*subsampleX + sourceXOffset;
  79  * sy = (dy - dstYOffset)*subsampleY + sourceYOffset;
  80  * </pre>
  81  *
  82  * <p> Decompressors may be written with various levels of complexity.
  83  * The most complex decompressors will override the
  84  * {@code decode} method, and will perform all the work of
  85  * decoding, subsampling, offsetting, clipping, and format conversion.
  86  * This approach may be the most efficient, since it is possible to
  87  * avoid the use of extra image buffers, and it may be possible to
  88  * avoid decoding portions of the image that will not be copied into
  89  * the destination.
  90  *
  91  * <p> Less ambitious decompressors may override the
  92  * {@code decodeRaw} method, which is responsible for
  93  * decompressing the entire tile or strip into a byte array (or other
  94  * appropriate datatype).  The default implementation of
  95  * {@code decode} will perform all necessary setup of buffers,
  96  * call {@code decodeRaw} to perform the actual decoding, perform
  97  * subsampling, and copy the results into the final destination image.
  98  * Where possible, it will pass the real image buffer to
  99  * {@code decodeRaw} in order to avoid making an extra copy.
 100  *
 101  * <p> Slightly more ambitious decompressors may override
 102  * {@code decodeRaw}, but avoid writing pixels that will be
 103  * discarded in the subsampling phase.
 104  */
 105 public abstract class TIFFDecompressor {
 106 
 107     /**
 108      * The {@code ImageReader} calling this
 109      * {@code TIFFDecompressor}.
 110      */
 111     protected ImageReader reader;
 112 
 113     /**
 114      * The {@code IIOMetadata} object containing metadata for the
 115      * current image.
 116      */
 117     protected IIOMetadata metadata;
 118 
 119     /**
 120      * The value of the {@code PhotometricInterpretation} tag.
 121      * Legal values are {@link
 122      * BaselineTIFFTagSet#PHOTOMETRIC_INTERPRETATION_WHITE_IS_ZERO },
 123      * {@link
 124      * BaselineTIFFTagSet#PHOTOMETRIC_INTERPRETATION_BLACK_IS_ZERO},
 125      * {@link BaselineTIFFTagSet#PHOTOMETRIC_INTERPRETATION_RGB},
 126      * {@link
 127      * BaselineTIFFTagSet#PHOTOMETRIC_INTERPRETATION_PALETTE_COLOR},
 128      * {@link
 129      * BaselineTIFFTagSet#PHOTOMETRIC_INTERPRETATION_TRANSPARENCY_MASK},
 130      * {@link BaselineTIFFTagSet#PHOTOMETRIC_INTERPRETATION_Y_CB_CR},
 131      * {@link BaselineTIFFTagSet#PHOTOMETRIC_INTERPRETATION_CIELAB},
 132      * {@link BaselineTIFFTagSet#PHOTOMETRIC_INTERPRETATION_ICCLAB},
 133      * or other value defined by a TIFF extension.
 134      */
 135     protected int photometricInterpretation;
 136 
 137     /**
 138      * The value of the {@code Compression} tag. Legal values are
 139      * {@link BaselineTIFFTagSet#COMPRESSION_NONE}, {@link
 140      * BaselineTIFFTagSet#COMPRESSION_CCITT_RLE}, {@link
 141      * BaselineTIFFTagSet#COMPRESSION_CCITT_T_4}, {@link
 142      * BaselineTIFFTagSet#COMPRESSION_CCITT_T_6}, {@link
 143      * BaselineTIFFTagSet#COMPRESSION_LZW}, {@link
 144      * BaselineTIFFTagSet#COMPRESSION_OLD_JPEG}, {@link
 145      * BaselineTIFFTagSet#COMPRESSION_JPEG}, {@link
 146      * BaselineTIFFTagSet#COMPRESSION_ZLIB}, {@link
 147      * BaselineTIFFTagSet#COMPRESSION_PACKBITS}, {@link
 148      * BaselineTIFFTagSet#COMPRESSION_DEFLATE}, or other value
 149      * defined by a TIFF extension.
 150      */
 151     protected int compression;
 152 
 153     /**
 154      * {@code true} if the image is encoded using separate planes.
 155      */
 156     protected boolean planar;
 157 
 158     /**
 159      * The value of the {@code SamplesPerPixel} tag.
 160      */
 161     protected int samplesPerPixel;
 162 
 163     /**
 164      * The value of the {@code BitsPerSample} tag.
 165      *
 166      */
 167     protected int[] bitsPerSample;
 168 
 169     /**
 170      * The value of the {@code SampleFormat} tag.  Legal values
 171      * are {@link BaselineTIFFTagSet#SAMPLE_FORMAT_UNSIGNED_INTEGER},
 172      * {@link BaselineTIFFTagSet#SAMPLE_FORMAT_SIGNED_INTEGER}, {@link
 173      * BaselineTIFFTagSet#SAMPLE_FORMAT_FLOATING_POINT}, {@link
 174      * BaselineTIFFTagSet#SAMPLE_FORMAT_UNDEFINED}, or other value
 175      * defined by a TIFF extension.
 176      */
 177     protected int[] sampleFormat =
 178         new int[] {BaselineTIFFTagSet.SAMPLE_FORMAT_UNSIGNED_INTEGER};
 179 
 180     /**
 181      * The value of the {@code ExtraSamples} tag.  Legal values
 182      * are {@link BaselineTIFFTagSet#EXTRA_SAMPLES_UNSPECIFIED},
 183      * {@link BaselineTIFFTagSet#EXTRA_SAMPLES_ASSOCIATED_ALPHA},
 184      * {@link BaselineTIFFTagSet#EXTRA_SAMPLES_UNASSOCIATED_ALPHA},
 185      * or other value defined by a TIFF extension.
 186      */
 187     protected int[] extraSamples;
 188 
 189     /**
 190      * The value of the {@code ColorMap} tag.
 191      *
 192      */
 193     protected char[] colorMap;
 194 
 195     // Region of input stream containing the data
 196 
 197     /**
 198      * The {@code ImageInputStream} containing the TIFF source
 199      * data.
 200      */
 201     protected ImageInputStream stream;
 202 
 203     /**
 204      * The offset in the source {@code ImageInputStream} of the
 205      * start of the data to be decompressed.
 206      */
 207     protected long offset;
 208 
 209     /**
 210      * The number of bytes of data from the source
 211      * {@code ImageInputStream} to be decompressed.
 212      */
 213     protected int byteCount;
 214 
 215     // Region of the file image represented in the stream
 216     // This is unaffected by subsampling
 217 
 218     /**
 219      * The X coordinate of the upper-left pixel of the source region
 220      * being decoded from the source stream.  This value is not affected
 221      * by source subsampling.
 222      */
 223     protected int srcMinX;
 224 
 225     /**
 226      * The Y coordinate of the upper-left pixel of the source region
 227      * being decoded from the source stream.  This value is not affected
 228      * by source subsampling.
 229      */
 230     protected int srcMinY;
 231 
 232     /**
 233      * The width of the source region being decoded from the source
 234      * stream.  This value is not affected by source subsampling.
 235      */
 236     protected int srcWidth;
 237 
 238     /**
 239      * The height of the source region being decoded from the source
 240      * stream.  This value is not affected by source subsampling.
 241      */
 242     protected int srcHeight;
 243 
 244     // Subsampling to be performed
 245 
 246     /**
 247      * The source X offset used, along with {@code dstXOffset}
 248      * and {@code subsampleX}, to map between horizontal source
 249      * and destination pixel coordinates.
 250      */
 251     protected int sourceXOffset;
 252 
 253     /**
 254      * The horizontal destination offset used, along with
 255      * {@code sourceXOffset} and {@code subsampleX}, to map
 256      * between horizontal source and destination pixel coordinates.
 257      * See the comment for {@link #sourceXOffset sourceXOffset} for
 258      * the mapping equations.
 259      */
 260     protected int dstXOffset;
 261 
 262     /**
 263      * The source Y offset used, along with {@code dstYOffset}
 264      * and {@code subsampleY}, to map between vertical source and
 265      * destination pixel coordinates.
 266      */
 267     protected int sourceYOffset;
 268 
 269     /**
 270      * The vertical destination offset used, along with
 271      * {@code sourceYOffset} and {@code subsampleY}, to map
 272      * between horizontal source and destination pixel coordinates.
 273      * See the comment for {@link #sourceYOffset sourceYOffset} for
 274      * the mapping equations.
 275      */
 276     protected int dstYOffset;
 277 
 278     /**
 279      * The horizontal subsampling factor.  A factor of 1 means that
 280      * every column is copied to the destination; a factor of 2 means
 281      * that every second column is copied, etc.
 282      */
 283     protected int subsampleX;
 284 
 285     /**
 286      * The vertical subsampling factor.  A factor of 1 means that
 287      * every row is copied to the destination; a factor of 2 means
 288      * that every second row is copied, etc.
 289      */
 290     protected int subsampleY;
 291 
 292     // Band subsetting/rearrangement
 293 
 294     /**
 295      * The sequence of source bands that are to be copied into the
 296      * destination.
 297      */
 298     protected int[] sourceBands;
 299 
 300     /**
 301      * The sequence of destination bands to receive the source data.
 302      */
 303     protected int[] destinationBands;
 304 
 305     // Destination for decodeRaw
 306 
 307     /**
 308      * A {@code BufferedImage} for the {@code decodeRaw}
 309      * method to write into.
 310      */
 311     protected BufferedImage rawImage;
 312 
 313     // Destination
 314 
 315     /**
 316      * The final destination image.
 317      */
 318     protected BufferedImage image;
 319 
 320     /**
 321      * The X coordinate of the upper left pixel to be written in the
 322      * destination image.
 323      */
 324     protected int dstMinX;
 325 
 326     /**
 327      * The Y coordinate of the upper left pixel to be written in the
 328      * destination image.
 329      */
 330     protected int dstMinY;
 331 
 332     /**
 333      * The width of the region of the destination image to be written.
 334      */
 335     protected int dstWidth;
 336 
 337     /**
 338      * The height of the region of the destination image to be written.
 339      */
 340     protected int dstHeight;
 341 
 342     // Region of source contributing to the destination
 343 
 344     /**
 345      * The X coordinate of the upper-left source pixel that will
 346      * actually be copied into the destination image, taking into
 347      * account all subsampling, offsetting, and clipping.  That is,
 348      * the pixel at ({@code activeSrcMinX},
 349      * {@code activeSrcMinY}) is to be copied into the
 350      * destination pixel at ({@code dstMinX},
 351      * {@code dstMinY}).
 352      *
 353      * <p> The pixels in the source region to be copied are
 354      * those with X coordinates of the form {@code activeSrcMinX +
 355      * k*subsampleX}, where {@code k} is an integer such
 356      * that {@code 0 <= k < dstWidth}.
 357      */
 358     protected int activeSrcMinX;
 359 
 360     /**
 361      * The Y coordinate of the upper-left source pixel that will
 362      * actually be copied into the destination image, taking into account
 363      * all subsampling, offsetting, and clipping.
 364      *
 365      * <p> The pixels in the source region to be copied are
 366      * those with Y coordinates of the form {@code activeSrcMinY +
 367      * k*subsampleY}, where {@code k} is an integer such
 368      * that {@code 0 <= k < dstHeight}.
 369      */
 370     protected int activeSrcMinY;
 371 
 372     /**
 373      * The width of the source region that will actually be copied
 374      * into the destination image, taking into account all
 375      * susbampling, offsetting, and clipping.
 376      *
 377      * <p> The active source width will always be equal to
 378      * {@code (dstWidth - 1)*subsampleX + 1}.
 379      */
 380     protected int activeSrcWidth;
 381 
 382     /**
 383      * The height of the source region that will actually be copied
 384      * into the destination image, taking into account all
 385      * susbampling, offsetting, and clipping.
 386      *
 387      * <p> The active source height will always be equal to
 388      * {@code (dstHeight - 1)*subsampleY + 1}.
 389      */
 390     protected int activeSrcHeight;
 391 
 392     /**
 393      * A {@code TIFFColorConverter} object describing the color space of
 394      * the encoded pixel data, or {@code null}.
 395      */
 396     protected TIFFColorConverter colorConverter;
 397 
 398     private boolean isBilevel;
 399     private boolean isContiguous;
 400     private boolean isImageSimple;
 401     private boolean adjustBitDepths;
 402     private int[][] bitDepthScale;
 403 
 404     // source pixel at (sx, sy) should map to dst pixel (dx, dy), where:
 405     //
 406     // dx = (sx - sourceXOffset)/subsampleX + dstXOffset;
 407     // dy = (sy - sourceYOffset)/subsampleY + dstYOffset;
 408     //
 409     // Note that this mapping is many-to-one.  Source pixels such that
 410     // (sx - sourceXOffset) % subsampleX != 0 should not be copied
 411     // (and similarly for y).
 412     //
 413     // The backwards mapping from dest to source is one-to-one:
 414     //
 415     // sx = (dx - dstXOffset)*subsampleX + sourceXOffset;
 416     // sy = (dy - dstYOffset)*subsampleY + sourceYOffset;
 417     //
 418     // The reader will always hand us the full source region as it
 419     // exists in the file.  It will take care of clipping the dest region
 420     // to exactly those dest pixels that are present in the source region.
 421 
 422     /**
 423      * Create a {@code PixelInterleavedSampleModel} for use in creating
 424      * an {@code ImageTypeSpecifier}.  Its dimensions will be 1x1 and
 425      * it will have ascending band offsets as {0, 1, 2, ..., numBands}.
 426      *
 427      * @param dataType The data type (DataBuffer.TYPE_*).
 428      * @param numBands The number of bands.
 429      * @return A {@code PixelInterleavedSampleModel}.
 430      */
 431     static SampleModel createInterleavedSM(int dataType,
 432                                            int numBands) {
 433         int[] bandOffsets = new int[numBands];
 434         for(int i = 0; i < numBands; i++) {
 435             bandOffsets[i] = i;
 436         }
 437         return new PixelInterleavedSampleModel(dataType,
 438                                                1, // width
 439                                                1, // height
 440                                                numBands, // pixelStride,
 441                                                numBands, // scanlineStride
 442                                                bandOffsets);
 443     }
 444 
 445     /**
 446      * Create a {@code ComponentColorModel} for use in creating
 447      * an {@code ImageTypeSpecifier}.
 448      */
 449     // This code was copied from javax.imageio.ImageTypeSpecifier.
 450     static ColorModel createComponentCM(ColorSpace colorSpace,
 451                                         int numBands,
 452                                         int dataType,
 453                                         boolean hasAlpha,
 454                                         boolean isAlphaPremultiplied) {
 455         int transparency =
 456             hasAlpha ? Transparency.TRANSLUCENT : Transparency.OPAQUE;
 457 
 458         int[] numBits = new int[numBands];
 459         int bits = DataBuffer.getDataTypeSize(dataType);
 460 
 461         for (int i = 0; i < numBands; i++) {
 462             numBits[i] = bits;
 463         }
 464 
 465         return new ComponentColorModel(colorSpace,
 466                                        numBits,
 467                                        hasAlpha,
 468                                        isAlphaPremultiplied,
 469                                        transparency,
 470                                        dataType);
 471     }
 472 
 473     private static int createMask(int[] bitsPerSample, int band) {
 474         int mask = (1 << bitsPerSample[band]) - 1;
 475         for (int i = band + 1; i < bitsPerSample.length; i++) {
 476             mask <<= bitsPerSample[i];
 477         }
 478 
 479         return mask;
 480     }
 481 
 482     private static int getDataTypeFromNumBits(int numBits, boolean isSigned) {
 483         int dataType;
 484 
 485         if (numBits <= 8) {
 486             dataType = DataBuffer.TYPE_BYTE;
 487         } else if (numBits <= 16) {
 488             dataType = isSigned ?
 489                 DataBuffer.TYPE_SHORT : DataBuffer.TYPE_USHORT;
 490         } else {
 491             dataType = DataBuffer.TYPE_INT;
 492         }
 493 
 494         return dataType;
 495     }
 496 
 497     private static boolean areIntArraysEqual(int[] a, int[] b) {
 498         if(a == null || b == null) {
 499             if(a == null && b == null) {
 500                 return true;
 501             } else { // one is null and one is not
 502                 return false;
 503             }
 504         }
 505 
 506         if(a.length != b.length) {
 507             return false;
 508         }
 509 
 510         int length = a.length;
 511         for(int i = 0; i < length; i++) {
 512             if(a[i] != b[i]) {
 513                 return false;
 514             }
 515         }
 516 
 517         return true;
 518     }
 519 
 520     /**
 521      * Return the number of bits occupied by {@code dataType}
 522      * which must be one of the {@code DataBuffer} {@code TYPE}s.
 523      */
 524     private static int getDataTypeSize(int dataType) throws IIOException {
 525         int dataTypeSize = 0;
 526         switch(dataType) {
 527         case DataBuffer.TYPE_BYTE:
 528             dataTypeSize = 8;
 529             break;
 530         case DataBuffer.TYPE_SHORT:
 531         case DataBuffer.TYPE_USHORT:
 532             dataTypeSize = 16;
 533             break;
 534         case DataBuffer.TYPE_INT:
 535         case DataBuffer.TYPE_FLOAT:
 536             dataTypeSize = 32;
 537             break;
 538         case DataBuffer.TYPE_DOUBLE:
 539             dataTypeSize = 64;
 540             break;
 541         default:
 542             throw new IIOException("Unknown data type "+dataType);
 543         }
 544 
 545         return dataTypeSize;
 546     }
 547 
 548     /**
 549      * Returns the number of bits per pixel.
 550      */
 551     private static int getBitsPerPixel(SampleModel sm) {
 552         int bitsPerPixel = 0;
 553         int[] sampleSize = sm.getSampleSize();
 554         int numBands = sampleSize.length;
 555         for(int i = 0; i < numBands; i++) {
 556             bitsPerPixel += sampleSize[i];
 557         }
 558         return bitsPerPixel;
 559     }
 560 
 561     /**
 562      * Returns whether all samples have the same number of bits.
 563      */
 564     private static boolean areSampleSizesEqual(SampleModel sm) {
 565         boolean allSameSize = true;
 566         int[] sampleSize = sm.getSampleSize();
 567         int sampleSize0 = sampleSize[0];
 568         int numBands = sampleSize.length;
 569 
 570         for(int i = 1; i < numBands; i++) {
 571             if(sampleSize[i] != sampleSize0) {
 572                 allSameSize = false;
 573                 break;
 574             }
 575         }
 576 
 577         return allSameSize;
 578     }
 579 
 580     /**
 581      * Determines whether the {@code DataBuffer} is filled without
 582      * any interspersed padding bits.
 583      */
 584     private static boolean isDataBufferBitContiguous(SampleModel sm)
 585         throws IIOException {
 586         int dataTypeSize = getDataTypeSize(sm.getDataType());
 587 
 588         if(sm instanceof ComponentSampleModel) {
 589             int numBands = sm.getNumBands();
 590             for(int i = 0; i < numBands; i++) {
 591                 if(sm.getSampleSize(i) != dataTypeSize) {
 592                     // Sample does not fill data element.
 593                     return false;
 594                 }
 595             }
 596         } else if(sm instanceof MultiPixelPackedSampleModel) {
 597             MultiPixelPackedSampleModel mppsm =
 598                 (MultiPixelPackedSampleModel)sm;
 599             if(dataTypeSize % mppsm.getPixelBitStride() != 0) {
 600                 // Pixels do not fill the data element.
 601                 return false;
 602             }
 603         } else if(sm instanceof SinglePixelPackedSampleModel) {
 604             SinglePixelPackedSampleModel sppsm =
 605                 (SinglePixelPackedSampleModel)sm;
 606             int numBands = sm.getNumBands();
 607             int numBits = 0;
 608             for(int i = 0; i < numBands; i++) {
 609                 numBits += sm.getSampleSize(i);
 610             }
 611             if(numBits != dataTypeSize) {
 612                 // Pixel does not fill the data element.
 613                 return false;
 614             }
 615         } else {
 616             // Unknown SampleModel class.
 617             return false;
 618         }
 619 
 620         return true;
 621     }
 622 
 623     /**
 624      * Reformats data read as bytes into a short or int buffer.
 625      */
 626     private static void reformatData(byte[] buf,
 627                                      int bytesPerRow,
 628                                      int numRows,
 629                                      short[] shortData,
 630                                      int[] intData,
 631                                      int outOffset,
 632                                      int outStride)
 633         throws IIOException {
 634 
 635         if(shortData != null) {
 636             int inOffset = 0;
 637             int shortsPerRow = bytesPerRow/2;
 638             int numExtraBytes = bytesPerRow % 2;
 639             for(int j = 0; j < numRows; j++) {
 640                 int k = outOffset;
 641                 for(int i = 0; i < shortsPerRow; i++) {
 642                     shortData[k++] =
 643                         (short)(((buf[inOffset++]&0xff) << 8) |
 644                                 (buf[inOffset++]&0xff));
 645                 }
 646                 if(numExtraBytes != 0) {
 647                     shortData[k++] = (short)((buf[inOffset++]&0xff) << 8);
 648                 }
 649                 outOffset += outStride;
 650             }
 651         } else if(intData != null) {
 652             int inOffset = 0;
 653             int intsPerRow = bytesPerRow/4;
 654             int numExtraBytes = bytesPerRow % 4;
 655             for(int j = 0; j < numRows; j++) {
 656                 int k = outOffset;
 657                 for(int i = 0; i < intsPerRow; i++) {
 658                     intData[k++] =
 659                         ((buf[inOffset++]&0xff) << 24) |
 660                         ((buf[inOffset++]&0xff) << 16) |
 661                         ((buf[inOffset++]&0xff) << 8) |
 662                         (buf[inOffset++]&0xff);
 663                 }
 664                 if(numExtraBytes != 0) {
 665                     int shift = 24;
 666                     int ival = 0;
 667                     for(int b = 0; b < numExtraBytes; b++) {
 668                         ival |= (buf[inOffset++]&0xff) << shift;
 669                         shift -= 8;
 670                     }
 671                     intData[k++] = ival;
 672                 }
 673                 outOffset += outStride;
 674             }
 675         } else {
 676             throw new IIOException("shortData == null && intData == null!");
 677         }
 678     }
 679 
 680     /**
 681      * Reformats bit-discontiguous data into the {@code DataBuffer}
 682      * of the supplied {@code WritableRaster}.
 683      */
 684     private static void reformatDiscontiguousData(byte[] buf,
 685                                                   int stride,
 686                                                   int w,
 687                                                   int h,
 688                                                   WritableRaster raster)
 689         throws IOException {
 690 
 691         // Get SampleModel info.
 692         SampleModel sm = raster.getSampleModel();
 693         int numBands = sm.getNumBands();
 694         int[] sampleSize = sm.getSampleSize();
 695 
 696         // Initialize input stream.
 697         ByteArrayInputStream is = new ByteArrayInputStream(buf);
 698         ImageInputStream iis = new MemoryCacheImageInputStream(is);
 699 
 700         // Reformat.
 701         long iisPosition = 0L;
 702         int y = raster.getMinY();
 703         for(int j = 0; j < h; j++, y++) {
 704             iis.seek(iisPosition);
 705             int x = raster.getMinX();
 706             for(int i = 0; i < w; i++, x++) {
 707                 for(int b = 0; b < numBands; b++) {
 708                     long bits = iis.readBits(sampleSize[b]);
 709                     raster.setSample(x, y, b, (int)bits);
 710                 }
 711             }
 712             iisPosition += stride;
 713         }
 714     }
 715 
 716     /**
 717      * A utility method that returns an
 718      * {@code ImageTypeSpecifier} suitable for decoding an image
 719      * with the given parameters.
 720      *
 721      * @param photometricInterpretation the value of the
 722      * {@code PhotometricInterpretation} field.
 723      * @param compression the value of the {@code Compression} field.
 724      * @param samplesPerPixel the value of the
 725      * {@code SamplesPerPixel} field.
 726      * @param bitsPerSample the value of the {@code BitsPerSample} field.
 727      * @param sampleFormat the value of the {@code SampleFormat} field.
 728      * @param extraSamples the value of the {@code ExtraSamples} field.
 729      * @param colorMap the value of the {@code ColorMap} field.
 730      *
 731      * @return a suitable {@code ImageTypeSpecifier}, or
 732      * {@code null} if it is not possible to create one.
 733      */
 734     public static ImageTypeSpecifier
 735         getRawImageTypeSpecifier(int photometricInterpretation,
 736                                  int compression,
 737                                  int samplesPerPixel,
 738                                  int[] bitsPerSample,
 739                                  int[] sampleFormat,
 740                                  int[] extraSamples,
 741                                  char[] colorMap) {
 742 
 743         //
 744         // Types to support:
 745         //
 746         // 1, 2, 4, 8, or 16 bit grayscale or indexed
 747         // 8,8-bit gray+alpha
 748         // 16,16-bit gray+alpha
 749         // 8,8,8-bit RGB
 750         // 8,8,8,8-bit RGB+alpha
 751         // 16,16,16-bit RGB
 752         // 16,16,16,16-bit RGB+alpha
 753         // R+G+B = 8-bit RGB
 754         // R+G+B+A = 8-bit RGB
 755         // R+G+B = 16-bit RGB
 756         // R+G+B+A = 16-bit RGB
 757         // 8X-bits/sample, arbitrary numBands.
 758         // Arbitrary non-indexed, non-float layouts (discontiguous).
 759         //
 760 
 761         // Band-sequential
 762 
 763         // 1, 2, 4, 8, or 16 bit grayscale or indexed images
 764         if (samplesPerPixel == 1 &&
 765             (bitsPerSample[0] == 1 ||
 766              bitsPerSample[0] == 2 ||
 767              bitsPerSample[0] == 4 ||
 768              bitsPerSample[0] == 8 ||
 769              bitsPerSample[0] == 16)) {
 770 
 771             // 2 and 16 bits images are not in the baseline
 772             // specification, but we will allow them anyway
 773             // since they fit well into Java2D
 774             //
 775             // this raises the issue of how to write such images...
 776 
 777             if (colorMap == null) {
 778                 // Grayscale
 779                 boolean isSigned = (sampleFormat[0] ==
 780                               BaselineTIFFTagSet.SAMPLE_FORMAT_SIGNED_INTEGER);
 781                 int dataType;
 782                 if (bitsPerSample[0] <= 8) {
 783                     dataType = DataBuffer.TYPE_BYTE;
 784                 } else {
 785                     dataType = sampleFormat[0] ==
 786                         BaselineTIFFTagSet.SAMPLE_FORMAT_SIGNED_INTEGER ?
 787                         DataBuffer.TYPE_SHORT :
 788                         DataBuffer.TYPE_USHORT;
 789                 }
 790 
 791                 return ImageTypeSpecifier.createGrayscale(bitsPerSample[0],
 792                                                           dataType,
 793                                                           isSigned);
 794             } else {
 795                 // Indexed
 796                 int mapSize = 1 << bitsPerSample[0];
 797                 byte[] redLut = new byte[mapSize];
 798                 byte[] greenLut = new byte[mapSize];
 799                 byte[] blueLut = new byte[mapSize];
 800                 byte[] alphaLut = null;
 801 
 802                 int idx = 0;
 803                 for (int i = 0; i < mapSize; i++) {
 804                     redLut[i] = (byte)((colorMap[i]*255)/65535);
 805                     greenLut[i] = (byte)((colorMap[mapSize + i]*255)/65535);
 806                     blueLut[i] = (byte)((colorMap[2*mapSize + i]*255)/65535);
 807                 }
 808 
 809                 int dataType = bitsPerSample[0] == 8 ?
 810                     DataBuffer.TYPE_BYTE : DataBuffer.TYPE_USHORT;
 811                 return ImageTypeSpecifier.createIndexed(redLut,
 812                                                         greenLut,
 813                                                         blueLut,
 814                                                         alphaLut,
 815                                                         bitsPerSample[0],
 816                                                         dataType);
 817             }
 818         }
 819 
 820         // 8-bit gray-alpha
 821         if (samplesPerPixel == 2 &&
 822             bitsPerSample[0] == 8 &&
 823             bitsPerSample[1] == 8) {
 824             int dataType = DataBuffer.TYPE_BYTE;
 825             boolean alphaPremultiplied = false;
 826             if (extraSamples != null &&
 827                 extraSamples[0] ==
 828                 BaselineTIFFTagSet.EXTRA_SAMPLES_ASSOCIATED_ALPHA) {
 829                 alphaPremultiplied = true;
 830             }
 831             return ImageTypeSpecifier.createGrayscale(8,
 832                                                       dataType,
 833                                                       false,
 834                                                       alphaPremultiplied);
 835         }
 836 
 837         // 16-bit gray-alpha
 838         if (samplesPerPixel == 2 &&
 839             bitsPerSample[0] == 16 &&
 840             bitsPerSample[1] == 16) {
 841             int dataType = sampleFormat[0] ==
 842                 BaselineTIFFTagSet.SAMPLE_FORMAT_SIGNED_INTEGER ?
 843                 DataBuffer.TYPE_SHORT :
 844                 DataBuffer.TYPE_USHORT;
 845             boolean alphaPremultiplied = false;
 846             if (extraSamples != null &&
 847                 extraSamples[0] ==
 848                 BaselineTIFFTagSet.EXTRA_SAMPLES_ASSOCIATED_ALPHA) {
 849                 alphaPremultiplied = true;
 850             }
 851             boolean isSigned = dataType == DataBuffer.TYPE_SHORT;
 852             return ImageTypeSpecifier.createGrayscale(16,
 853                                                       dataType,
 854                                                       isSigned,
 855                                                       alphaPremultiplied);
 856         }
 857 
 858         ColorSpace rgb = ColorSpace.getInstance(ColorSpace.CS_sRGB);
 859 
 860         // 8-bit RGB
 861         if (samplesPerPixel == 3 &&
 862             bitsPerSample[0] == 8 &&
 863             bitsPerSample[1] == 8 &&
 864             bitsPerSample[2] == 8) {
 865             int[] bandOffsets = new int[3];
 866             bandOffsets[0] = 0;
 867             bandOffsets[1] = 1;
 868             bandOffsets[2] = 2;
 869             int dataType = DataBuffer.TYPE_BYTE;
 870             ColorSpace theColorSpace;
 871             if((photometricInterpretation ==
 872                 BaselineTIFFTagSet.PHOTOMETRIC_INTERPRETATION_Y_CB_CR &&
 873                 compression != BaselineTIFFTagSet.COMPRESSION_JPEG &&
 874                 compression != BaselineTIFFTagSet.COMPRESSION_OLD_JPEG) ||
 875                photometricInterpretation ==
 876                BaselineTIFFTagSet.PHOTOMETRIC_INTERPRETATION_CIELAB) {
 877                 theColorSpace =
 878                     ColorSpace.getInstance(ColorSpace.CS_LINEAR_RGB);
 879             } else {
 880                 theColorSpace = rgb;
 881             }
 882             return ImageTypeSpecifier.createInterleaved(theColorSpace,
 883                                                         bandOffsets,
 884                                                         dataType,
 885                                                         false,
 886                                                         false);
 887         }
 888 
 889         // 8-bit RGBA
 890         if (samplesPerPixel == 4 &&
 891             bitsPerSample[0] == 8 &&
 892             bitsPerSample[1] == 8 &&
 893             bitsPerSample[2] == 8 &&
 894             bitsPerSample[3] == 8) {
 895             int[] bandOffsets = new int[4];
 896             bandOffsets[0] = 0;
 897             bandOffsets[1] = 1;
 898             bandOffsets[2] = 2;
 899             bandOffsets[3] = 3;
 900             int dataType = DataBuffer.TYPE_BYTE;
 901 
 902             ColorSpace theColorSpace;
 903             boolean hasAlpha;
 904             boolean alphaPremultiplied = false;
 905             if(photometricInterpretation ==
 906                BaselineTIFFTagSet.PHOTOMETRIC_INTERPRETATION_CMYK) {
 907                 theColorSpace = SimpleCMYKColorSpace.getInstance();
 908                 hasAlpha = false;
 909             } else {
 910                 theColorSpace = rgb;
 911                 hasAlpha = true;
 912                 if (extraSamples != null &&
 913                     extraSamples[0] ==
 914                     BaselineTIFFTagSet.EXTRA_SAMPLES_ASSOCIATED_ALPHA) {
 915                     alphaPremultiplied = true;
 916                 }
 917             }
 918 
 919             return ImageTypeSpecifier.createInterleaved(theColorSpace,
 920                                                         bandOffsets,
 921                                                         dataType,
 922                                                         hasAlpha,
 923                                                         alphaPremultiplied);
 924         }
 925 
 926         // 16-bit RGB
 927         if (samplesPerPixel == 3 &&
 928             bitsPerSample[0] == 16 &&
 929             bitsPerSample[1] == 16 &&
 930             bitsPerSample[2] == 16) {
 931             int[] bandOffsets = new int[3];
 932             bandOffsets[0] = 0;
 933             bandOffsets[1] = 1;
 934             bandOffsets[2] = 2;
 935             int dataType = sampleFormat[0] ==
 936                 BaselineTIFFTagSet.SAMPLE_FORMAT_SIGNED_INTEGER ?
 937                 DataBuffer.TYPE_SHORT :
 938                 DataBuffer.TYPE_USHORT;
 939             return ImageTypeSpecifier.createInterleaved(rgb,
 940                                                         bandOffsets,
 941                                                         dataType,
 942                                                         false,
 943                                                         false);
 944         }
 945 
 946         // 16-bit RGBA
 947         if (samplesPerPixel == 4 &&
 948             bitsPerSample[0] == 16 &&
 949             bitsPerSample[1] == 16 &&
 950             bitsPerSample[2] == 16 &&
 951             bitsPerSample[3] == 16) {
 952             int[] bandOffsets = new int[4];
 953             bandOffsets[0] = 0;
 954             bandOffsets[1] = 1;
 955             bandOffsets[2] = 2;
 956             bandOffsets[3] = 3;
 957             int dataType = sampleFormat[0] ==
 958                 BaselineTIFFTagSet.SAMPLE_FORMAT_SIGNED_INTEGER ?
 959                 DataBuffer.TYPE_SHORT :
 960                 DataBuffer.TYPE_USHORT;
 961 
 962             boolean alphaPremultiplied = false;
 963             if (extraSamples != null &&
 964                 extraSamples[0] ==
 965                 BaselineTIFFTagSet.EXTRA_SAMPLES_ASSOCIATED_ALPHA) {
 966                 alphaPremultiplied = true;
 967             }
 968             return ImageTypeSpecifier.createInterleaved(rgb,
 969                                                         bandOffsets,
 970                                                         dataType,
 971                                                         true,
 972                                                         alphaPremultiplied);
 973         }
 974 
 975         // Compute bits per pixel.
 976         int totalBits = 0;
 977         for (int i = 0; i < bitsPerSample.length; i++) {
 978             totalBits += bitsPerSample[i];
 979         }
 980 
 981         // Packed: 3- or 4-band, 8- or 16-bit.
 982         if ((samplesPerPixel == 3 || samplesPerPixel == 4) &&
 983             (totalBits == 8 || totalBits == 16)) {
 984             int redMask = createMask(bitsPerSample, 0);
 985             int greenMask = createMask(bitsPerSample, 1);
 986             int blueMask = createMask(bitsPerSample, 2);
 987             int alphaMask = (samplesPerPixel == 4) ?
 988                 createMask(bitsPerSample, 3) : 0;
 989             int transferType = totalBits == 8 ?
 990                 DataBuffer.TYPE_BYTE : DataBuffer.TYPE_USHORT;
 991             boolean alphaPremultiplied = false;
 992             if (extraSamples != null &&
 993                 extraSamples[0] ==
 994                 BaselineTIFFTagSet.EXTRA_SAMPLES_ASSOCIATED_ALPHA) {
 995                 alphaPremultiplied = true;
 996             }
 997             return ImageTypeSpecifier.createPacked(rgb,
 998                                                    redMask,
 999                                                    greenMask,
1000                                                    blueMask,
1001                                                    alphaMask,
1002                                                    transferType,
1003                                                    alphaPremultiplied);
1004         }
1005 
1006         // Generic components with 8X bits per sample.
1007         if(bitsPerSample[0] % 8 == 0) {
1008             // Check whether all bands have same bit depth.
1009             boolean allSameBitDepth = true;
1010             for(int i = 1; i < bitsPerSample.length; i++) {
1011                 if(bitsPerSample[i] != bitsPerSample[i-1]) {
1012                     allSameBitDepth = false;
1013                     break;
1014                 }
1015             }
1016 
1017             // Proceed if all bands have same bit depth.
1018             if(allSameBitDepth) {
1019                 // Determine the data type.
1020                 int dataType = -1;
1021                 boolean isDataTypeSet = false;
1022                 switch(bitsPerSample[0]) {
1023                 case 8:
1024                     if(sampleFormat[0] !=
1025                        BaselineTIFFTagSet.SAMPLE_FORMAT_FLOATING_POINT) {
1026                         // Ignore whether signed or unsigned:
1027                         // treat all as unsigned.
1028                         dataType = DataBuffer.TYPE_BYTE;
1029                         isDataTypeSet = true;
1030                     }
1031                     break;
1032                 case 16:
1033                     if(sampleFormat[0] !=
1034                        BaselineTIFFTagSet.SAMPLE_FORMAT_FLOATING_POINT) {
1035                         if(sampleFormat[0] ==
1036                            BaselineTIFFTagSet.SAMPLE_FORMAT_SIGNED_INTEGER) {
1037                             dataType = DataBuffer.TYPE_SHORT;
1038                         } else {
1039                             dataType = DataBuffer.TYPE_USHORT;
1040                         }
1041                         isDataTypeSet = true;
1042                     }
1043                     break;
1044                 case 32:
1045                     if(sampleFormat[0] ==
1046                        BaselineTIFFTagSet.SAMPLE_FORMAT_FLOATING_POINT) {
1047                         dataType = DataBuffer.TYPE_FLOAT;
1048                     } else {
1049                         dataType = DataBuffer.TYPE_INT;
1050                     }
1051                     isDataTypeSet = true;
1052                     break;
1053                 case 64:
1054                     if(sampleFormat[0] ==
1055                        BaselineTIFFTagSet.SAMPLE_FORMAT_FLOATING_POINT) {
1056                         dataType = DataBuffer.TYPE_DOUBLE;
1057                         isDataTypeSet = true;
1058                     }
1059                     break;
1060                 }
1061 
1062                 if(isDataTypeSet) {
1063                     // Create the SampleModel.
1064                     SampleModel sm = createInterleavedSM(dataType,
1065                                                          samplesPerPixel);
1066 
1067                     // Create the ColorModel.
1068                     ColorModel cm;
1069                     if(samplesPerPixel >= 1 && samplesPerPixel <= 4 &&
1070                        (dataType == DataBuffer.TYPE_INT ||
1071                         dataType == DataBuffer.TYPE_FLOAT)) {
1072                         // Handle the 32-bit cases for 1-4 bands.
1073                         ColorSpace cs = samplesPerPixel <= 2 ?
1074                             ColorSpace.getInstance(ColorSpace.CS_GRAY) : rgb;
1075                         boolean hasAlpha = ((samplesPerPixel % 2) == 0);
1076                         boolean alphaPremultiplied = false;
1077                         if(hasAlpha && extraSamples != null &&
1078                            extraSamples[0] ==
1079                            BaselineTIFFTagSet.EXTRA_SAMPLES_ASSOCIATED_ALPHA) {
1080                             alphaPremultiplied = true;
1081                         }
1082 
1083                         cm = createComponentCM(cs,
1084                                                samplesPerPixel,
1085                                                dataType,
1086                                                hasAlpha,
1087                                                alphaPremultiplied);
1088                     } else {
1089                         ColorSpace cs = new BogusColorSpace(samplesPerPixel);
1090                         cm = createComponentCM(cs,
1091                                                samplesPerPixel,
1092                                                dataType,
1093                                                false, // hasAlpha
1094                                                false); // alphaPremultiplied
1095                     }
1096                     return new ImageTypeSpecifier(cm, sm);
1097                 }
1098             }
1099         }
1100 
1101         // Other more bizarre cases including discontiguous DataBuffers
1102         // such as for the image in bug 4918959.
1103 
1104         if(colorMap == null &&
1105            sampleFormat[0] !=
1106            BaselineTIFFTagSet.SAMPLE_FORMAT_FLOATING_POINT) {
1107 
1108             // Determine size of largest sample.
1109             int maxBitsPerSample = 0;
1110             for(int i = 0; i < bitsPerSample.length; i++) {
1111                 if(bitsPerSample[i] > maxBitsPerSample) {
1112                     maxBitsPerSample = bitsPerSample[i];
1113                 }
1114             }
1115 
1116             // Determine whether data are signed.
1117             boolean isSigned =
1118                 (sampleFormat[0] ==
1119                  BaselineTIFFTagSet.SAMPLE_FORMAT_SIGNED_INTEGER);
1120 
1121             // Grayscale
1122             if(samplesPerPixel == 1) {
1123                 int dataType =
1124                     getDataTypeFromNumBits(maxBitsPerSample, isSigned);
1125 
1126                 return ImageTypeSpecifier.createGrayscale(maxBitsPerSample,
1127                                                           dataType,
1128                                                           isSigned);
1129             }
1130 
1131             // Gray-alpha
1132             if (samplesPerPixel == 2) {
1133                 boolean alphaPremultiplied = false;
1134                 if (extraSamples != null &&
1135                     extraSamples[0] ==
1136                     BaselineTIFFTagSet.EXTRA_SAMPLES_ASSOCIATED_ALPHA) {
1137                     alphaPremultiplied = true;
1138                 }
1139 
1140                 int dataType =
1141                     getDataTypeFromNumBits(maxBitsPerSample, isSigned);
1142 
1143                 return ImageTypeSpecifier.createGrayscale(maxBitsPerSample,
1144                                                           dataType,
1145                                                           false,
1146                                                           alphaPremultiplied);
1147             }
1148 
1149             if (samplesPerPixel == 3 || samplesPerPixel == 4) {
1150                 if(totalBits <= 32 && !isSigned) {
1151                     // Packed RGB or RGBA
1152                     int redMask = createMask(bitsPerSample, 0);
1153                     int greenMask = createMask(bitsPerSample, 1);
1154                     int blueMask = createMask(bitsPerSample, 2);
1155                     int alphaMask = (samplesPerPixel == 4) ?
1156                         createMask(bitsPerSample, 3) : 0;
1157                     int transferType =
1158                         getDataTypeFromNumBits(totalBits, false);
1159                     boolean alphaPremultiplied = false;
1160                     if (extraSamples != null &&
1161                         extraSamples[0] ==
1162                         BaselineTIFFTagSet.EXTRA_SAMPLES_ASSOCIATED_ALPHA) {
1163                         alphaPremultiplied = true;
1164                     }
1165                     return ImageTypeSpecifier.createPacked(rgb,
1166                                                            redMask,
1167                                                            greenMask,
1168                                                            blueMask,
1169                                                            alphaMask,
1170                                                            transferType,
1171                                                            alphaPremultiplied);
1172                 } else if(samplesPerPixel == 3) {
1173                     // Interleaved RGB
1174                     int[] bandOffsets = new int[] {0, 1, 2};
1175                     int dataType =
1176                         getDataTypeFromNumBits(maxBitsPerSample, isSigned);
1177                     return ImageTypeSpecifier.createInterleaved(rgb,
1178                                                                 bandOffsets,
1179                                                                 dataType,
1180                                                                 false,
1181                                                                 false);
1182                 } else if(samplesPerPixel == 4) {
1183                     // Interleaved RGBA
1184                     int[] bandOffsets = new int[] {0, 1, 2, 3};
1185                     int dataType =
1186                         getDataTypeFromNumBits(maxBitsPerSample, isSigned);
1187                     boolean alphaPremultiplied = false;
1188                     if (extraSamples != null &&
1189                         extraSamples[0] ==
1190                         BaselineTIFFTagSet.EXTRA_SAMPLES_ASSOCIATED_ALPHA) {
1191                         alphaPremultiplied = true;
1192                     }
1193                     return ImageTypeSpecifier.createInterleaved(rgb,
1194                                                                 bandOffsets,
1195                                                                 dataType,
1196                                                                 true,
1197                                                                 alphaPremultiplied);
1198                 }
1199             } else {
1200                 // Arbitrary Interleaved.
1201                 int dataType =
1202                     getDataTypeFromNumBits(maxBitsPerSample, isSigned);
1203                 SampleModel sm = createInterleavedSM(dataType,
1204                                                      samplesPerPixel);
1205                 ColorSpace cs = new BogusColorSpace(samplesPerPixel);
1206                 ColorModel cm = createComponentCM(cs,
1207                                                   samplesPerPixel,
1208                                                   dataType,
1209                                                   false, // hasAlpha
1210                                                   false); // alphaPremultiplied
1211                 return new ImageTypeSpecifier(cm, sm);
1212             }
1213         }
1214 
1215         return null;
1216     }
1217 
1218     /**
1219      * Sets the value of the {@code reader} field.
1220      *
1221      * <p> If this method is called, the {@code beginDecoding}
1222      * method must be called prior to calling any of the decode
1223      * methods.
1224      *
1225      * @param reader the current {@code ImageReader}.
1226      */
1227     public void setReader(ImageReader reader) {
1228         this.reader = reader;
1229     }
1230 
1231     /**
1232      * Sets the value of the {@code metadata} field.
1233      *
1234      * <p> If this method is called, the {@code beginDecoding}
1235      * method must be called prior to calling any of the decode
1236      * methods.
1237      *
1238      * @param metadata the {@code IIOMetadata} object for the
1239      * image being read.
1240      */
1241     public void setMetadata(IIOMetadata metadata) {
1242         this.metadata = metadata;
1243     }
1244 
1245     /**
1246      * Sets the value of the {@code photometricInterpretation}
1247      * field.
1248      *
1249      * <p> If this method is called, the {@code beginDecoding}
1250      * method must be called prior to calling any of the decode
1251      * methods.
1252      *
1253      * @param photometricInterpretation the photometric interpretation
1254      * value.
1255      */
1256     public void setPhotometricInterpretation(int photometricInterpretation) {
1257         this.photometricInterpretation = photometricInterpretation;
1258     }
1259 
1260     /**
1261      * Sets the value of the {@code compression} field.
1262      *
1263      * <p> If this method is called, the {@code beginDecoding}
1264      * method must be called prior to calling any of the decode
1265      * methods.
1266      *
1267      * @param compression the compression type.
1268      */
1269     public void setCompression(int compression) {
1270         this.compression = compression;
1271     }
1272 
1273     /**
1274      * Sets the value of the {@code planar} field.
1275      *
1276      * <p> If this method is called, the {@code beginDecoding}
1277      * method must be called prior to calling any of the decode
1278      * methods.
1279      *
1280      * @param planar {@code true} if the image to be decoded is
1281      * stored in planar format.
1282      */
1283     public void setPlanar(boolean planar) {
1284         this.planar = planar;
1285     }
1286 
1287     /**
1288      * Sets the value of the {@code samplesPerPixel} field.
1289      *
1290      * <p> If this method is called, the {@code beginDecoding}
1291      * method must be called prior to calling any of the decode
1292      * methods.
1293      *
1294      * @param samplesPerPixel the number of samples in each source
1295      * pixel.
1296      */
1297     public void setSamplesPerPixel(int samplesPerPixel) {
1298         this.samplesPerPixel = samplesPerPixel;
1299     }
1300 
1301     /**
1302      * Sets the value of the {@code bitsPerSample} field.
1303      *
1304      * <p> If this method is called, the {@code beginDecoding}
1305      * method must be called prior to calling any of the decode
1306      * methods.
1307      *
1308      * @param bitsPerSample the number of bits for each source image
1309      * sample.
1310      */
1311     public void setBitsPerSample(int[] bitsPerSample) {
1312         this.bitsPerSample = bitsPerSample == null ?
1313             null : bitsPerSample.clone();
1314     }
1315 
1316     /**
1317      * Sets the value of the {@code sampleFormat} field.
1318      *
1319      * <p> If this method is called, the {@code beginDecoding}
1320      * method must be called prior to calling any of the decode
1321      * methods.
1322      *
1323      * @param sampleFormat the format of the source image data,
1324      * for example unsigned integer or floating-point.
1325      */
1326     public void setSampleFormat(int[] sampleFormat) {
1327         this.sampleFormat = sampleFormat == null ?
1328             new int[] {BaselineTIFFTagSet.SAMPLE_FORMAT_UNSIGNED_INTEGER} :
1329             sampleFormat.clone();
1330     }
1331 
1332     /**
1333      * Sets the value of the {@code extraSamples} field.
1334      *
1335      * <p> If this method is called, the {@code beginDecoding}
1336      * method must be called prior to calling any of the decode
1337      * methods.
1338      *
1339      * @param extraSamples the interpretation of any samples in the
1340      * source file beyond those used for basic color or grayscale
1341      * information.
1342      */
1343     public void setExtraSamples(int[] extraSamples) {
1344         this.extraSamples = extraSamples == null ?
1345             null : extraSamples.clone();
1346     }
1347 
1348     /**
1349      * Sets the value of the {@code colorMap} field.
1350      *
1351      * <p> If this method is called, the {@code beginDecoding}
1352      * method must be called prior to calling any of the decode
1353      * methods.
1354      *
1355      * @param colorMap the color map to apply to the source data,
1356      * as an array of {@code char}s.
1357      */
1358     public void setColorMap(char[] colorMap) {
1359         this.colorMap = colorMap == null ?
1360             null : colorMap.clone();
1361     }
1362 
1363     /**
1364      * Sets the value of the {@code stream} field.
1365      *
1366      * <p> If this method is called, the {@code beginDecoding}
1367      * method must be called prior to calling any of the decode
1368      * methods.
1369      *
1370      * @param stream the {@code ImageInputStream} to be read.
1371      */
1372     public void setStream(ImageInputStream stream) {
1373         this.stream = stream;
1374     }
1375 
1376     /**
1377      * Sets the value of the {@code offset} field.
1378      *
1379      * <p> If this method is called, the {@code beginDecoding}
1380      * method must be called prior to calling any of the decode
1381      * methods.
1382      *
1383      * @param offset the offset of the beginning of the compressed
1384      * data.
1385      */
1386     public void setOffset(long offset) {
1387         this.offset = offset;
1388     }
1389 
1390     /**
1391      * Sets the value of the {@code byteCount} field.
1392      *
1393      * <p> If this method is called, the {@code beginDecoding}
1394      * method must be called prior to calling any of the decode
1395      * methods.
1396      *
1397      * @param byteCount the number of bytes of compressed data.
1398      */
1399     public void setByteCount(int byteCount) {
1400         this.byteCount = byteCount;
1401     }
1402 
1403     // Region of the file image represented in the stream
1404 
1405     /**
1406      * Sets the value of the {@code srcMinX} field.
1407      *
1408      * <p> If this method is called, the {@code beginDecoding}
1409      * method must be called prior to calling any of the decode
1410      * methods.
1411      *
1412      * @param srcMinX the minimum X coordinate of the source region
1413      * being decoded, irrespective of how it will be copied into the
1414      * destination.
1415      */
1416     public void setSrcMinX(int srcMinX) {
1417         this.srcMinX = srcMinX;
1418     }
1419 
1420     /**
1421      * Sets the value of the {@code srcMinY} field.
1422      *
1423      * <p> If this method is called, the {@code beginDecoding}
1424      * method must be called prior to calling any of the decode
1425      * methods.
1426      *
1427      * @param srcMinY the minimum Y coordinate of the source region
1428      * being decoded, irrespective of how it will be copied into the
1429      * destination.
1430      */
1431     public void setSrcMinY(int srcMinY) {
1432         this.srcMinY = srcMinY;
1433     }
1434 
1435     /**
1436      * Sets the value of the {@code srcWidth} field.
1437      *
1438      * <p> If this method is called, the {@code beginDecoding}
1439      * method must be called prior to calling any of the decode
1440      * methods.
1441      *
1442      * @param srcWidth the width of the source region being decoded,
1443      * irrespective of how it will be copied into the destination.
1444      */
1445     public void setSrcWidth(int srcWidth) {
1446         this.srcWidth = srcWidth;
1447     }
1448 
1449     /**
1450      * Sets the value of the {@code srcHeight} field.
1451      *
1452      * <p> If this method is called, the {@code beginDecoding}
1453      * method must be called prior to calling any of the decode
1454      * methods.
1455      *
1456      * @param srcHeight the height of the source region being decoded,
1457      * irrespective of how it will be copied into the destination.
1458      */
1459     public void setSrcHeight(int srcHeight) {
1460         this.srcHeight = srcHeight;
1461     }
1462 
1463     // First source pixel to be read
1464 
1465     /**
1466      * Sets the value of the {@code sourceXOffset} field.
1467      *
1468      * <p> If this method is called, the {@code beginDecoding}
1469      * method must be called prior to calling any of the decode
1470      * methods.
1471      *
1472      * @param sourceXOffset the horizontal source offset to be used when
1473      * mapping between source and destination coordinates.
1474      */
1475     public void setSourceXOffset(int sourceXOffset) {
1476         this.sourceXOffset = sourceXOffset;
1477     }
1478 
1479     /**
1480      * Sets the value of the {@code dstXOffset} field.
1481      *
1482      * <p> If this method is called, the {@code beginDecoding}
1483      * method must be called prior to calling any of the decode
1484      * methods.
1485      *
1486      * @param dstXOffset the horizontal destination offset to be
1487      * used when mapping between source and destination coordinates.
1488      */
1489     public void setDstXOffset(int dstXOffset) {
1490         this.dstXOffset = dstXOffset;
1491     }
1492 
1493     /**
1494      * Sets the value of the {@code sourceYOffset}.
1495      *
1496      * <p> If this method is called, the {@code beginDecoding}
1497      * method must be called prior to calling any of the decode
1498      * methods.
1499      *
1500      * @param sourceYOffset the vertical source offset to be used when
1501      * mapping between source and destination coordinates.
1502      */
1503     public void setSourceYOffset(int sourceYOffset) {
1504         this.sourceYOffset = sourceYOffset;
1505     }
1506 
1507     /**
1508      * Sets the value of the {@code dstYOffset} field.
1509      *
1510      * <p> If this method is called, the {@code beginDecoding}
1511      * method must be called prior to calling any of the decode
1512      * methods.
1513      *
1514      * @param dstYOffset the vertical destination offset to be
1515      * used when mapping between source and destination coordinates.
1516      */
1517     public void setDstYOffset(int dstYOffset) {
1518         this.dstYOffset = dstYOffset;
1519     }
1520 
1521     // Subsampling to be performed
1522 
1523     /**
1524      * Sets the value of the {@code subsampleX} field.
1525      *
1526      * <p> If this method is called, the {@code beginDecoding}
1527      * method must be called prior to calling any of the decode
1528      * methods.
1529      *
1530      * @param subsampleX the horizontal subsampling factor.
1531      *
1532      * @throws IllegalArgumentException if {@code subsampleX} is
1533      * less than or equal to 0.
1534      */
1535     public void setSubsampleX(int subsampleX) {
1536         if (subsampleX <= 0) {
1537             throw new IllegalArgumentException("subsampleX <= 0!");
1538         }
1539         this.subsampleX = subsampleX;
1540     }
1541 
1542     /**
1543      * Sets the value of the {@code subsampleY} field.
1544      *
1545      * <p> If this method is called, the {@code beginDecoding}
1546      * method must be called prior to calling any of the decode
1547      * methods.
1548      *
1549      * @param subsampleY the vertical subsampling factor.
1550      *
1551      * @throws IllegalArgumentException if {@code subsampleY} is
1552      * less than or equal to 0.
1553      */
1554     public void setSubsampleY(int subsampleY) {
1555         if (subsampleY <= 0) {
1556             throw new IllegalArgumentException("subsampleY <= 0!");
1557         }
1558         this.subsampleY = subsampleY;
1559     }
1560 
1561     // Band subsetting/rearrangement
1562 
1563     /**
1564      * Sets the value of the {@code sourceBands} field.
1565      *
1566      * <p> If this method is called, the {@code beginDecoding}
1567      * method must be called prior to calling any of the decode
1568      * methods.
1569      *
1570      * @param sourceBands an array of {@code int}s
1571      * specifying the source bands to be read.
1572      */
1573     public void setSourceBands(int[] sourceBands) {
1574         this.sourceBands = sourceBands == null ?
1575             null : sourceBands.clone();
1576     }
1577 
1578     /**
1579      * Sets the value of the {@code destinationBands} field.
1580      *
1581      * <p> If this method is called, the {@code beginDecoding}
1582      * method must be called prior to calling any of the decode
1583      * methods.
1584      *
1585      * @param destinationBands an array of {@code int}s
1586      * specifying the destination bands to be written.
1587      */
1588     public void setDestinationBands(int[] destinationBands) {
1589         this.destinationBands = destinationBands == null ?
1590             null : destinationBands.clone();
1591     }
1592 
1593     // Destination image and region
1594 
1595     /**
1596      * Sets the value of the {@code image} field.
1597      *
1598      * <p> If this method is called, the {@code beginDecoding}
1599      * method must be called prior to calling any of the decode
1600      * methods.
1601      *
1602      * @param image the destination {@code BufferedImage}.
1603      */
1604     public void setImage(BufferedImage image) {
1605         this.image = image;
1606     }
1607 
1608     /**
1609      * Sets the value of the {@code dstMinX} field.
1610      *
1611      * <p> If this method is called, the {@code beginDecoding}
1612      * method must be called prior to calling any of the decode
1613      * methods.
1614      *
1615      * @param dstMinX the minimum X coordinate of the destination
1616      * region.
1617      */
1618     public void setDstMinX(int dstMinX) {
1619         this.dstMinX = dstMinX;
1620     }
1621 
1622     /**
1623      * Sets the value of the {@code dstMinY} field.
1624      *
1625      * <p> If this method is called, the {@code beginDecoding}
1626      * method must be called prior to calling any of the decode
1627      * methods.
1628      *
1629      * @param dstMinY the minimum Y coordinate of the destination
1630      * region.
1631      */
1632     public void setDstMinY(int dstMinY) {
1633         this.dstMinY = dstMinY;
1634     }
1635 
1636     /**
1637      * Sets the value of the {@code dstWidth} field.
1638      *
1639      * <p> If this method is called, the {@code beginDecoding}
1640      * method must be called prior to calling any of the decode
1641      * methods.
1642      *
1643      * @param dstWidth the width of the destination region.
1644      */
1645     public void setDstWidth(int dstWidth) {
1646         this.dstWidth = dstWidth;
1647     }
1648 
1649     /**
1650      * Sets the value of the {@code dstHeight} field.
1651      *
1652      * <p> If this method is called, the {@code beginDecoding}
1653      * method must be called prior to calling any of the decode
1654      * methods.
1655      *
1656      * @param dstHeight the height of the destination region.
1657      */
1658     public void setDstHeight(int dstHeight) {
1659         this.dstHeight = dstHeight;
1660     }
1661 
1662     // Active source region
1663 
1664     /**
1665      * Sets the value of the {@code activeSrcMinX} field.
1666      *
1667      * <p> If this method is called, the {@code beginDecoding}
1668      * method must be called prior to calling any of the decode
1669      * methods.
1670      *
1671      * @param activeSrcMinX the minimum X coordinate of the active
1672      * source region.
1673      */
1674     public void setActiveSrcMinX(int activeSrcMinX) {
1675         this.activeSrcMinX = activeSrcMinX;
1676     }
1677 
1678     /**
1679      * Sets the value of the {@code activeSrcMinY} field.
1680      *
1681      * <p> If this method is called, the {@code beginDecoding}
1682      * method must be called prior to calling any of the decode
1683      * methods.
1684      *
1685      * @param activeSrcMinY the minimum Y coordinate of the active
1686      * source region.
1687      */
1688     public void setActiveSrcMinY(int activeSrcMinY) {
1689         this.activeSrcMinY = activeSrcMinY;
1690     }
1691 
1692     /**
1693      * Sets the value of the {@code activeSrcWidth} field.
1694      *
1695      * <p> If this method is called, the {@code beginDecoding}
1696      * method must be called prior to calling any of the decode
1697      * methods.
1698      *
1699      * @param activeSrcWidth the width of the active source region.
1700      */
1701     public void setActiveSrcWidth(int activeSrcWidth) {
1702         this.activeSrcWidth = activeSrcWidth;
1703     }
1704 
1705     /**
1706      * Sets the value of the {@code activeSrcHeight} field.
1707      *
1708      * <p> If this method is called, the {@code beginDecoding}
1709      * method must be called prior to calling any of the decode
1710      * methods.
1711      *
1712      * @param activeSrcHeight the height of the active source region.
1713      */
1714     public void setActiveSrcHeight(int activeSrcHeight) {
1715         this.activeSrcHeight = activeSrcHeight;
1716     }
1717 
1718     /**
1719      * Sets the {@code TIFFColorConverter} object describing the color
1720      * space of the encoded data in the input stream.  If no
1721      * {@code TIFFColorConverter} is set, no conversion will be performed.
1722      *
1723      * @param colorConverter a {@code TIFFColorConverter} object, or
1724      * {@code null}.
1725      */
1726     public void setColorConverter(TIFFColorConverter colorConverter) {
1727         this.colorConverter = colorConverter;
1728     }
1729 
1730     /**
1731      * Returns an {@code ImageTypeSpecifier} describing an image
1732      * whose underlying data array has the same format as the raw
1733      * source pixel data.
1734      *
1735      * @return an {@code ImageTypeSpecifier}.
1736      */
1737     public ImageTypeSpecifier getRawImageType() {
1738         ImageTypeSpecifier its =
1739             getRawImageTypeSpecifier(photometricInterpretation,
1740                                      compression,
1741                                      samplesPerPixel,
1742                                      bitsPerSample,
1743                                      sampleFormat,
1744                                      extraSamples,
1745                                      colorMap);
1746         return its;
1747     }
1748 
1749     /**
1750      * Creates a {@code BufferedImage} whose underlying data
1751      * array will be suitable for holding the raw decoded output of
1752      * the {@code decodeRaw} method.
1753      *
1754      * <p> The default implementation calls
1755      * {@code getRawImageType}, and calls the resulting
1756      * {@code ImageTypeSpecifier}'s
1757      * {@code createBufferedImage} method.
1758      *
1759      * @return a {@code BufferedImage} whose underlying data
1760      * array has the same format as the raw source pixel data, or
1761      * {@code null} if it is not possible to create such an
1762      * image.
1763      */
1764     public BufferedImage createRawImage() {
1765         if (planar) {
1766             // Create a single-banded image of the appropriate data type.
1767 
1768             // Get the number of bits per sample.
1769             int bps = bitsPerSample[sourceBands[0]];
1770 
1771             // Determine the data type.
1772             int dataType;
1773             if(sampleFormat[0] ==
1774                BaselineTIFFTagSet.SAMPLE_FORMAT_FLOATING_POINT) {
1775                 if(bps <= 32) {
1776                     dataType = DataBuffer.TYPE_FLOAT;
1777                 } else {
1778                     dataType = DataBuffer.TYPE_DOUBLE;
1779                 }
1780             } else if(bps <= 8) {
1781                 dataType = DataBuffer.TYPE_BYTE;
1782             } else if(bps <= 16) {
1783                 if(sampleFormat[0] ==
1784                    BaselineTIFFTagSet.SAMPLE_FORMAT_SIGNED_INTEGER) {
1785                     dataType = DataBuffer.TYPE_SHORT;
1786                 } else {
1787                     dataType = DataBuffer.TYPE_USHORT;
1788                 }
1789             } else {
1790                 dataType = DataBuffer.TYPE_INT;
1791             }
1792 
1793             ColorSpace csGray = ColorSpace.getInstance(ColorSpace.CS_GRAY);
1794             ImageTypeSpecifier its =
1795                 ImageTypeSpecifier.createInterleaved(csGray,
1796                                                      new int[] {0},
1797                                                      dataType,
1798                                                      false,
1799                                                      false);
1800 
1801             return its.createBufferedImage(srcWidth, srcHeight);
1802         } else {
1803             ImageTypeSpecifier its = getRawImageType();
1804             if (its == null) {
1805                 return null;
1806             }
1807 
1808             BufferedImage bi = its.createBufferedImage(srcWidth, srcHeight);
1809             return bi;
1810         }
1811     }
1812 
1813     /**
1814      * Decodes the source data into the provided {@code byte}
1815      * array {@code b}, starting at the offset given by
1816      * {@code dstOffset}.  Each pixel occupies
1817      * {@code bitsPerPixel} bits, with no padding between pixels.
1818      * Scanlines are separated by {@code scanlineStride}
1819      * {@code byte}s.
1820      *
1821      * @param b a {@code byte} array to be written.
1822      * @param dstOffset the starting offset in {@code b} to be
1823      * written.
1824      * @param bitsPerPixel the number of bits for each pixel.
1825      * @param scanlineStride the number of {@code byte}s to
1826      * advance between that starting pixels of each scanline.
1827      *
1828      * @throws IOException if an error occurs reading from the source
1829      * {@code ImageInputStream}.
1830      */
1831     public abstract void decodeRaw(byte[] b,
1832                                    int dstOffset,
1833                                    int bitsPerPixel,
1834                                    int scanlineStride) throws IOException;
1835 
1836     /**
1837      * Decodes the source data into the provided {@code short}
1838      * array {@code s}, starting at the offset given by
1839      * {@code dstOffset}.  Each pixel occupies
1840      * {@code bitsPerPixel} bits, with no padding between pixels.
1841      * Scanlines are separated by {@code scanlineStride}
1842      * {@code short}s
1843      *
1844      * <p> The default implementation calls {@code decodeRaw(byte[] b,
1845      * ...)} and copies the resulting data into {@code s}.
1846      *
1847      * @param s a {@code short} array to be written.
1848      * @param dstOffset the starting offset in {@code s} to be
1849      * written.
1850      * @param bitsPerPixel the number of bits for each pixel.
1851      * @param scanlineStride the number of {@code short}s to
1852      * advance between that starting pixels of each scanline.
1853      *
1854      * @throws IOException if an error occurs reading from the source
1855      * {@code ImageInputStream}.
1856      */
1857     public void decodeRaw(short[] s,
1858                           int dstOffset,
1859                           int bitsPerPixel,
1860                           int scanlineStride) throws IOException {
1861         int bytesPerRow = (srcWidth*bitsPerPixel + 7)/8;
1862         int shortsPerRow = bytesPerRow/2;
1863 
1864         byte[] b = new byte[bytesPerRow*srcHeight];
1865         decodeRaw(b, 0, bitsPerPixel, bytesPerRow);
1866 
1867         int bOffset = 0;
1868         if(stream.getByteOrder() == ByteOrder.BIG_ENDIAN) {
1869             for (int j = 0; j < srcHeight; j++) {
1870                 for (int i = 0; i < shortsPerRow; i++) {
1871                     short hiVal = b[bOffset++];
1872                     short loVal = b[bOffset++];
1873                     short sval = (short)((hiVal << 8) | (loVal & 0xff));
1874                     s[dstOffset + i] = sval;
1875                 }
1876 
1877                 dstOffset += scanlineStride;
1878             }
1879         } else { // ByteOrder.LITLE_ENDIAN
1880             for (int j = 0; j < srcHeight; j++) {
1881                 for (int i = 0; i < shortsPerRow; i++) {
1882                     short loVal = b[bOffset++];
1883                     short hiVal = b[bOffset++];
1884                     short sval = (short)((hiVal << 8) | (loVal & 0xff));
1885                     s[dstOffset + i] = sval;
1886                 }
1887 
1888                 dstOffset += scanlineStride;
1889             }
1890         }
1891     }
1892 
1893     /**
1894      * Decodes the source data into the provided {@code int}
1895      * array {@code i}, starting at the offset given by
1896      * {@code dstOffset}.  Each pixel occupies
1897      * {@code bitsPerPixel} bits, with no padding between pixels.
1898      * Scanlines are separated by {@code scanlineStride}
1899      * {@code int}s.
1900      *
1901      * <p> The default implementation calls {@code decodeRaw(byte[] b,
1902      * ...)} and copies the resulting data into {@code i}.
1903      *
1904      * @param i an {@code int} array to be written.
1905      * @param dstOffset the starting offset in {@code i} to be
1906      * written.
1907      * @param bitsPerPixel the number of bits for each pixel.
1908      * @param scanlineStride the number of {@code int}s to
1909      * advance between that starting pixels of each scanline.
1910      *
1911      * @throws IOException if an error occurs reading from the source
1912      * {@code ImageInputStream}.
1913      */
1914     public void decodeRaw(int[] i,
1915                           int dstOffset,
1916                           int bitsPerPixel,
1917                           int scanlineStride) throws IOException {
1918         int numBands = bitsPerPixel/32;
1919         int intsPerRow = srcWidth*numBands;
1920         int bytesPerRow = intsPerRow*4;
1921 
1922         byte[] b = new byte[bytesPerRow*srcHeight];
1923         decodeRaw(b, 0, bitsPerPixel, bytesPerRow);
1924 
1925         int bOffset = 0;
1926         if(stream.getByteOrder() == ByteOrder.BIG_ENDIAN) {
1927             for (int j = 0; j < srcHeight; j++) {
1928                 for (int k = 0; k < intsPerRow; k++) {
1929                     int v0 = b[bOffset++] & 0xff;
1930                     int v1 = b[bOffset++] & 0xff;
1931                     int v2 = b[bOffset++] & 0xff;
1932                     int v3 = b[bOffset++] & 0xff;
1933                     int ival = (v0 << 24) | (v1 << 16) | (v2 << 8) | v3;
1934                     i[dstOffset + k] = ival;
1935                 }
1936 
1937                 dstOffset += scanlineStride;
1938             }
1939         } else { // ByteOrder.LITLE_ENDIAN
1940             for (int j = 0; j < srcHeight; j++) {
1941                 for (int k = 0; k < intsPerRow; k++) {
1942                     int v3 = b[bOffset++] & 0xff;
1943                     int v2 = b[bOffset++] & 0xff;
1944                     int v1 = b[bOffset++] & 0xff;
1945                     int v0 = b[bOffset++] & 0xff;
1946                     int ival = (v0 << 24) | (v1 << 16) | (v2 << 8) | v3;
1947                     i[dstOffset + k] = ival;
1948                 }
1949 
1950                 dstOffset += scanlineStride;
1951             }
1952         }
1953     }
1954 
1955     /**
1956      * Decodes the source data into the provided {@code float}
1957      * array {@code f}, starting at the offset given by
1958      * {@code dstOffset}.  Each pixel occupies
1959      * {@code bitsPerPixel} bits, with no padding between pixels.
1960      * Scanlines are separated by {@code scanlineStride}
1961      * {@code float}s.
1962      *
1963      * <p> The default implementation calls {@code decodeRaw(byte[] b,
1964      * ...)} and copies the resulting data into {@code f}.
1965      *
1966      * @param f a {@code float} array to be written.
1967      * @param dstOffset the starting offset in {@code f} to be
1968      * written.
1969      * @param bitsPerPixel the number of bits for each pixel.
1970      * @param scanlineStride the number of {@code float}s to
1971      * advance between that starting pixels of each scanline.
1972      *
1973      * @throws IOException if an error occurs reading from the source
1974      * {@code ImageInputStream}.
1975      */
1976     public void decodeRaw(float[] f,
1977                           int dstOffset,
1978                           int bitsPerPixel,
1979                           int scanlineStride) throws IOException {
1980         int numBands = bitsPerPixel/32;
1981         int floatsPerRow = srcWidth*numBands;
1982         int bytesPerRow = floatsPerRow*4;
1983 
1984         byte[] b = new byte[bytesPerRow*srcHeight];
1985         decodeRaw(b, 0, bitsPerPixel, bytesPerRow);
1986 
1987         int bOffset = 0;
1988         if(stream.getByteOrder() == ByteOrder.BIG_ENDIAN) {
1989             for (int j = 0; j < srcHeight; j++) {
1990                 for (int i = 0; i < floatsPerRow; i++) {
1991                     int v0 = b[bOffset++] & 0xff;
1992                     int v1 = b[bOffset++] & 0xff;
1993                     int v2 = b[bOffset++] & 0xff;
1994                     int v3 = b[bOffset++] & 0xff;
1995                     int ival = (v0 << 24) | (v1 << 16) | (v2 << 8) | v3;
1996                     float fval = Float.intBitsToFloat(ival);
1997                     f[dstOffset + i] = fval;
1998                 }
1999 
2000                 dstOffset += scanlineStride;
2001             }
2002         } else { // ByteOrder.LITLE_ENDIAN
2003             for (int j = 0; j < srcHeight; j++) {
2004                 for (int i = 0; i < floatsPerRow; i++) {
2005                     int v3 = b[bOffset++] & 0xff;
2006                     int v2 = b[bOffset++] & 0xff;
2007                     int v1 = b[bOffset++] & 0xff;
2008                     int v0 = b[bOffset++] & 0xff;
2009                     int ival = (v0 << 24) | (v1 << 16) | (v2 << 8) | v3;
2010                     float fval = Float.intBitsToFloat(ival);
2011                     f[dstOffset + i] = fval;
2012                 }
2013 
2014                 dstOffset += scanlineStride;
2015             }
2016         }
2017     }
2018 
2019     /**
2020      * Decodes the source data into the provided {@code double}
2021      * array {@code f}, starting at the offset given by
2022      * {@code dstOffset}.  Each pixel occupies
2023      * {@code bitsPerPixel} bits, with no padding between pixels.
2024      * Scanlines are separated by {@code scanlineStride}
2025      * {@code double}s.
2026      *
2027      * <p> The default implementation calls {@code decodeRaw(byte[] b,
2028      * ...)} and copies the resulting data into {@code f}.
2029      *
2030      * @param f a {@code double} array to be written.
2031      * @param dstOffset the starting offset in {@code f} to be
2032      * written.
2033      * @param bitsPerPixel the number of bits for each pixel.
2034      * @param scanlineStride the number of {@code double}s to
2035      * advance between that starting pixels of each scanline.
2036      *
2037      * @throws IOException if an error occurs reading from the source
2038      * {@code ImageInputStream}.
2039      */
2040     public void decodeRaw(double[] d,
2041                           int dstOffset,
2042                           int bitsPerPixel,
2043                           int scanlineStride) throws IOException {
2044         int numBands = bitsPerPixel/64;
2045         int doublesPerRow = srcWidth*numBands;
2046         int bytesPerRow = doublesPerRow*8;
2047 
2048         byte[] b = new byte[bytesPerRow*srcHeight];
2049         decodeRaw(b, 0, bitsPerPixel, bytesPerRow);
2050 
2051         int bOffset = 0;
2052         if(stream.getByteOrder() == ByteOrder.BIG_ENDIAN) {
2053             for (int j = 0; j < srcHeight; j++) {
2054                 for (int i = 0; i < doublesPerRow; i++) {
2055                     long v0 = b[bOffset++] & 0xff;
2056                     long v1 = b[bOffset++] & 0xff;
2057                     long v2 = b[bOffset++] & 0xff;
2058                     long v3 = b[bOffset++] & 0xff;
2059                     long v4 = b[bOffset++] & 0xff;
2060                     long v5 = b[bOffset++] & 0xff;
2061                     long v6 = b[bOffset++] & 0xff;
2062                     long v7 = b[bOffset++] & 0xff;
2063                     long lval =
2064                         (v0 << 56) | (v1 << 48) | (v2 << 40) | (v3 << 32)
2065                         | (v4 << 24) | (v5 << 16) | (v6 << 8) | v7;
2066                     double dval = Double.longBitsToDouble(lval);
2067                     d[dstOffset + i] = dval;
2068                 }
2069 
2070                 dstOffset += scanlineStride;
2071             }
2072         } else { // ByteOrder.LITLE_ENDIAN
2073             for (int j = 0; j < srcHeight; j++) {
2074                 for (int i = 0; i < doublesPerRow; i++) {
2075                     long v7 = b[bOffset++] & 0xff;
2076                     long v6 = b[bOffset++] & 0xff;
2077                     long v5 = b[bOffset++] & 0xff;
2078                     long v4 = b[bOffset++] & 0xff;
2079                     long v3 = b[bOffset++] & 0xff;
2080                     long v2 = b[bOffset++] & 0xff;
2081                     long v1 = b[bOffset++] & 0xff;
2082                     long v0 = b[bOffset++] & 0xff;
2083                     long lval =
2084                         (v0 << 56) | (v1 << 48) | (v2 << 40) | (v3 << 32)
2085                         | (v4 << 24) | (v5 << 16) | (v6 << 8) | v7;
2086                     double dval = Double.longBitsToDouble(lval);
2087                     d[dstOffset + i] = dval;
2088                 }
2089 
2090                 dstOffset += scanlineStride;
2091             }
2092         }
2093     }
2094 
2095     //
2096     // Values used to prevent unneeded recalculation of bit adjustment table.
2097     //
2098     private boolean isFirstBitDepthTable = true;
2099     private boolean planarCache = false;
2100     private int[] destBitsPerSampleCache = null;
2101     private int[] sourceBandsCache = null;
2102     private int[] bitsPerSampleCache = null;
2103     private int[] destinationBandsCache = null;
2104 
2105     /**
2106      * This routine is called prior to a sequence of calls to the
2107      * {@code decode} method, in order to allow any necessary
2108      * tables or other structures to be initialized based on metadata
2109      * values.  This routine is guaranteed to be called any time the
2110      * metadata values have changed.
2111      *
2112      * <p> The default implementation computes tables used by the
2113      * {@code decode} method to rescale components to different
2114      * bit depths.  Thus, if this method is overridden, it is
2115      * important for the subclass method to call {@code super()},
2116      * unless it overrides {@code decode} as well.
2117      */
2118     public void beginDecoding() {
2119         // Note: This method assumes that sourceBands, destinationBands,
2120         // and bitsPerSample are all non-null which is true as they are
2121         // set up that way in TIFFImageReader. Also the lengths and content
2122         // of sourceBands and destinationBands are checked in TIFFImageReader
2123         // before the present method is invoked.
2124 
2125         // Determine if all of the relevant output bands have the
2126         // same bit depth as the source data
2127         this.adjustBitDepths = false;
2128         int numBands = destinationBands.length;
2129         int[] destBitsPerSample = null;
2130         if(planar) {
2131             int totalNumBands = bitsPerSample.length;
2132             destBitsPerSample = new int[totalNumBands];
2133             int dbps = image.getSampleModel().getSampleSize(0);
2134             for(int b = 0; b < totalNumBands; b++) {
2135                 destBitsPerSample[b] = dbps;
2136             }
2137         } else {
2138             destBitsPerSample = image.getSampleModel().getSampleSize();
2139         }
2140 
2141         for (int b = 0; b < numBands; b++) {
2142             if (destBitsPerSample[destinationBands[b]] !=
2143                 bitsPerSample[sourceBands[b]]) {
2144                 adjustBitDepths = true;
2145                 break;
2146             }
2147         }
2148 
2149         // If the bit depths differ, create a lookup table
2150         // per band to perform the conversion
2151         if(adjustBitDepths) {
2152             // Compute the table only if this is the first time one is
2153             // being computed or if any of the variables on which the
2154             // table is based have changed.
2155             if(this.isFirstBitDepthTable ||
2156                planar != planarCache ||
2157                !areIntArraysEqual(destBitsPerSample,
2158                                   destBitsPerSampleCache) ||
2159                !areIntArraysEqual(sourceBands,
2160                                   sourceBandsCache) ||
2161                !areIntArraysEqual(bitsPerSample,
2162                                   bitsPerSampleCache) ||
2163                !areIntArraysEqual(destinationBands,
2164                                   destinationBandsCache)) {
2165 
2166                 this.isFirstBitDepthTable = false;
2167 
2168                 // Cache some variables.
2169                 this.planarCache = planar;
2170                 this.destBitsPerSampleCache =
2171                     destBitsPerSample.clone(); // never null ...
2172                 this.sourceBandsCache = sourceBands == null ?
2173                     null : sourceBands.clone();
2174                 this.bitsPerSampleCache = bitsPerSample == null ?
2175                     null : bitsPerSample.clone();
2176                 this.destinationBandsCache = destinationBands.clone();
2177 
2178                 // Allocate and fill the table.
2179                 bitDepthScale = new int[numBands][];
2180                 for (int b = 0; b < numBands; b++) {
2181                     int maxInSample = (1 << bitsPerSample[sourceBands[b]]) - 1;
2182                     int halfMaxInSample = maxInSample/2;
2183 
2184                     int maxOutSample =
2185                         (1 << destBitsPerSample[destinationBands[b]]) - 1;
2186 
2187                     bitDepthScale[b] = new int[maxInSample + 1];
2188                     for (int s = 0; s <= maxInSample; s++) {
2189                         bitDepthScale[b][s] =
2190                             (s*maxOutSample + halfMaxInSample)/
2191                             maxInSample;
2192                     }
2193                 }
2194             }
2195         } else { // !adjustBitDepths
2196             // Clear any prior table.
2197             this.bitDepthScale = null;
2198         }
2199 
2200         // Determine whether source and destination band lists are ramps.
2201         // Note that these conditions will be true for planar images if
2202         // and only if samplesPerPixel == 1, sourceBands[0] == 0, and
2203         // destinationBands[0] == 0. For the purposes of this method, the
2204         // only difference between such a planar image and a chunky image
2205         // is the setting of the PlanarConfiguration field.
2206         boolean sourceBandsNormal = false;
2207         boolean destinationBandsNormal = false;
2208         if (numBands == samplesPerPixel) {
2209             sourceBandsNormal = true;
2210             destinationBandsNormal = true;
2211             for (int i = 0; i < numBands; i++) {
2212                 if (sourceBands[i] != i) {
2213                     sourceBandsNormal = false;
2214                 }
2215                 if (destinationBands[i] != i) {
2216                     destinationBandsNormal = false;
2217                 }
2218             }
2219         }
2220 
2221         // Determine whether the image is bilevel and/or contiguous.
2222         // Note that a planar image could be bilevel but it will not
2223         // be contiguous unless it has a single component band stored
2224         // in a single bank.
2225         this.isBilevel =
2226             ImageUtil.isBinary(this.image.getRaster().getSampleModel());
2227         this.isContiguous = this.isBilevel ?
2228             true : ImageUtil.imageIsContiguous(this.image);
2229 
2230         // Analyze destination image to see if we can copy into it
2231         // directly
2232 
2233         this.isImageSimple =
2234             (colorConverter == null) &&
2235             (subsampleX == 1) && (subsampleY == 1) &&
2236             (srcWidth == dstWidth) && (srcHeight == dstHeight) &&
2237             ((dstMinX + dstWidth) <= image.getWidth()) &&
2238             ((dstMinY + dstHeight) <= image.getHeight()) &&
2239             sourceBandsNormal && destinationBandsNormal &&
2240             !adjustBitDepths;
2241     }
2242 
2243     /**
2244      * Decodes the input bit stream (located in the
2245      * {@code ImageInputStream} {@code stream}, at offset
2246      * {@code offset}, and continuing for {@code byteCount}
2247      * bytes) into the output {@code BufferedImage}
2248      * {@code image}.
2249      *
2250      * <p> The default implementation analyzes the destination image
2251      * to determine if it is suitable as the destination for the
2252      * {@code decodeRaw} method.  If not, a suitable image is
2253      * created.  Next, {@code decodeRaw} is called to perform the
2254      * actual decoding, and the results are copied into the
2255      * destination image if necessary.  Subsampling and offsetting are
2256      * performed automatically.
2257      *
2258      * <p> The precise responsibilities of this routine are as
2259      * follows.  The input bit stream is defined by the instance
2260      * variables {@code stream}, {@code offset}, and
2261      * {@code byteCount}.  These bits contain the data for the
2262      * region of the source image defined by {@code srcMinX},
2263      * {@code srcMinY}, {@code srcWidth}, and
2264      * {@code srcHeight}.
2265      *
2266      * <p> The source data is required to be subsampling, starting at
2267      * the {@code sourceXOffset}th column and including
2268      * every {@code subsampleX}th pixel thereafter (and similarly
2269      * for {@code sourceYOffset} and
2270      * {@code subsampleY}).
2271      *
2272      * <p> Pixels are copied into the destination with an addition shift of
2273      * ({@code dstXOffset}, {@code dstYOffset}).  The complete
2274      * set of formulas relating the source and destination coordinate spaces
2275      * are:
2276      *
2277      * <pre>
2278      * dx = (sx - sourceXOffset)/subsampleX + dstXOffset;
2279      * dy = (sy - sourceYOffset)/subsampleY + dstYOffset;
2280      * </pre>
2281      *
2282      * Only source pixels such that {@code (sx - sourceXOffset) %
2283      * subsampleX == 0} and {@code (sy - sourceYOffset) %
2284      * subsampleY == 0} are copied.
2285      *
2286      * <p> The inverse mapping, from destination to source coordinates,
2287      * is one-to-one:
2288      *
2289      * <pre>
2290      * sx = (dx - dstXOffset)*subsampleX + sourceXOffset;
2291      * sy = (dy - dstYOffset)*subsampleY + sourceYOffset;
2292      * </pre>
2293      *
2294      * <p> The region of the destination image to be updated is given
2295      * by the instance variables {@code dstMinX},
2296      * {@code dstMinY}, {@code dstWidth}, and
2297      * {@code dstHeight}.
2298      *
2299      * <p> It is possible that not all of the source data being read
2300      * will contribute to the destination image.  For example, the
2301      * destination offsets could be set such that some of the source
2302      * pixels land outside of the bounds of the image.  As a
2303      * convenience, the bounds of the active source region (that is,
2304      * the region of the strip or tile being read that actually
2305      * contributes to the destination image, taking clipping into
2306      * account) are available as {@code activeSrcMinX},
2307      * {@code activeSrcMinY}, {@code activeSrcWidth} and
2308      * {@code activeSrcHeight}.  Thus, the source pixel at
2309      * ({@code activeSrcMinX}, {@code activeSrcMinY}) will
2310      * map to the destination pixel ({@code dstMinX},
2311      * {@code dstMinY}).
2312      *
2313      * <p> The sequence of source bands given by
2314      * {@code sourceBands} are to be copied into the sequence of
2315      * bands in the destination given by
2316      * {@code destinationBands}.
2317      *
2318      * <p> Some standard tag information is provided the instance
2319      * variables {@code photometricInterpretation},
2320      * {@code compression}, {@code samplesPerPixel},
2321      * {@code bitsPerSample}, {@code sampleFormat},
2322      * {@code extraSamples}, and {@code colorMap}.
2323      *
2324      * <p> In practice, unless there is a significant performance
2325      * advantage to be gained by overriding this routine, most users
2326      * will prefer to use the default implementation of this routine,
2327      * and instead override the {@code decodeRaw} and/or
2328      * {@code getRawImageType} methods.
2329      *
2330      * @exception IOException if an error occurs in
2331      * {@code decodeRaw}.
2332      */
2333     public void decode() throws IOException {
2334         byte[] byteData = null;
2335         short[] shortData = null;
2336         int[] intData = null;
2337         float[] floatData = null;
2338         double[] doubleData = null;
2339 
2340         int dstOffset = 0;
2341         int pixelBitStride = 1;
2342         int scanlineStride = 0;
2343 
2344         // Analyze raw image
2345 
2346         this.rawImage = null;
2347         if(isImageSimple) {
2348             if(isBilevel) {
2349                 rawImage = this.image;
2350             } else if (isContiguous) {
2351                 rawImage =
2352                     image.getSubimage(dstMinX, dstMinY, dstWidth, dstHeight);
2353             }
2354         }
2355 
2356         boolean isDirectCopy = rawImage != null;
2357 
2358         if(rawImage == null) {
2359             rawImage = createRawImage();
2360             if (rawImage == null) {
2361                 throw new IIOException("Couldn't create image buffer!");
2362             }
2363         }
2364 
2365         WritableRaster ras = rawImage.getRaster();
2366 
2367         if(isBilevel) {
2368             Rectangle rect = isImageSimple ?
2369                 new Rectangle(dstMinX, dstMinY, dstWidth, dstHeight) :
2370                 ras.getBounds();
2371             byteData = ImageUtil.getPackedBinaryData(ras, rect);
2372             dstOffset = 0;
2373             pixelBitStride = 1;
2374             scanlineStride = (rect.width + 7)/8;
2375         } else {
2376             SampleModel sm = ras.getSampleModel();
2377             DataBuffer db = ras.getDataBuffer();
2378 
2379             boolean isSupportedType = false;
2380 
2381             if (sm instanceof ComponentSampleModel) {
2382                 ComponentSampleModel csm = (ComponentSampleModel)sm;
2383                 dstOffset = csm.getOffset(-ras.getSampleModelTranslateX(),
2384                                           -ras.getSampleModelTranslateY());
2385                 scanlineStride = csm.getScanlineStride();
2386                 if(db instanceof DataBufferByte) {
2387                     DataBufferByte dbb = (DataBufferByte)db;
2388 
2389                     byteData = dbb.getData();
2390                     pixelBitStride = csm.getPixelStride()*8;
2391                     isSupportedType = true;
2392                 } else if(db instanceof DataBufferUShort) {
2393                     DataBufferUShort dbus = (DataBufferUShort)db;
2394 
2395                     shortData = dbus.getData();
2396                     pixelBitStride = csm.getPixelStride()*16;
2397                     isSupportedType = true;
2398                 } else if(db instanceof DataBufferShort) {
2399                     DataBufferShort dbs = (DataBufferShort)db;
2400 
2401                     shortData = dbs.getData();
2402                     pixelBitStride = csm.getPixelStride()*16;
2403                     isSupportedType = true;
2404                 } else if(db instanceof DataBufferInt) {
2405                     DataBufferInt dbi = (DataBufferInt)db;
2406 
2407                     intData = dbi.getData();
2408                     pixelBitStride = csm.getPixelStride()*32;
2409                     isSupportedType = true;
2410                 } else if(db instanceof DataBufferFloat) {
2411                     DataBufferFloat dbf = (DataBufferFloat)db;
2412 
2413                     floatData = dbf.getData();
2414                     pixelBitStride = csm.getPixelStride()*32;
2415                     isSupportedType = true;
2416                 } else if(db instanceof DataBufferDouble) {
2417                     DataBufferDouble dbd = (DataBufferDouble)db;
2418 
2419                     doubleData = dbd.getData();
2420                     pixelBitStride = csm.getPixelStride()*64;
2421                     isSupportedType = true;
2422                 }
2423             } else if (sm instanceof MultiPixelPackedSampleModel) {
2424                 MultiPixelPackedSampleModel mppsm =
2425                     (MultiPixelPackedSampleModel)sm;
2426                 dstOffset =
2427                     mppsm.getOffset(-ras.getSampleModelTranslateX(),
2428                                     -ras.getSampleModelTranslateY());
2429                 pixelBitStride = mppsm.getPixelBitStride();
2430                 scanlineStride = mppsm.getScanlineStride();
2431                 if(db instanceof DataBufferByte) {
2432                     DataBufferByte dbb = (DataBufferByte)db;
2433 
2434                     byteData = dbb.getData();
2435                     isSupportedType = true;
2436                 } else if(db instanceof DataBufferUShort) {
2437                     DataBufferUShort dbus = (DataBufferUShort)db;
2438 
2439                     shortData = dbus.getData();
2440                     isSupportedType = true;
2441                 } else if(db instanceof DataBufferInt) {
2442                     DataBufferInt dbi = (DataBufferInt)db;
2443 
2444                     intData = dbi.getData();
2445                     isSupportedType = true;
2446                 }
2447             } else if (sm instanceof SinglePixelPackedSampleModel) {
2448                 SinglePixelPackedSampleModel sppsm =
2449                     (SinglePixelPackedSampleModel)sm;
2450                 dstOffset =
2451                     sppsm.getOffset(-ras.getSampleModelTranslateX(),
2452                                     -ras.getSampleModelTranslateY());
2453                 scanlineStride = sppsm.getScanlineStride();
2454                 if(db instanceof DataBufferByte) {
2455                     DataBufferByte dbb = (DataBufferByte)db;
2456 
2457                     byteData = dbb.getData();
2458                     pixelBitStride = 8;
2459                     isSupportedType = true;
2460                 } else if(db instanceof DataBufferUShort) {
2461                     DataBufferUShort dbus = (DataBufferUShort)db;
2462 
2463                     shortData = dbus.getData();
2464                     pixelBitStride = 16;
2465                     isSupportedType = true;
2466                 } else if(db instanceof DataBufferInt) {
2467                     DataBufferInt dbi = (DataBufferInt)db;
2468 
2469                     intData = dbi.getData();
2470                     pixelBitStride = 32;
2471                     isSupportedType = true;
2472                 }
2473             }
2474 
2475             if(!isSupportedType) {
2476                 throw new IIOException
2477                     ("Unsupported raw image type: SampleModel = "+sm+
2478                      "; DataBuffer = "+db);
2479             }
2480         }
2481 
2482         if(isBilevel) {
2483             // Bilevel data are always in a contiguous byte buffer.
2484             decodeRaw(byteData, dstOffset, pixelBitStride, scanlineStride);
2485         } else {
2486             SampleModel sm = ras.getSampleModel();
2487 
2488             // Branch based on whether data are bit-contiguous, i.e.,
2489             // data are packaed as tightly as possible leaving no unused
2490             // bits except at the end of a row.
2491             if(isDataBufferBitContiguous(sm)) {
2492                 // Use byte or float data directly.
2493                 if (byteData != null) {
2494                     decodeRaw(byteData, dstOffset,
2495                               pixelBitStride, scanlineStride);
2496                 } else if (floatData != null) {
2497                     decodeRaw(floatData, dstOffset,
2498                               pixelBitStride, scanlineStride);
2499                 } else if (doubleData != null) {
2500                     decodeRaw(doubleData, dstOffset,
2501                               pixelBitStride, scanlineStride);
2502                 } else {
2503                     if (shortData != null) {
2504                         if(areSampleSizesEqual(sm) &&
2505                            sm.getSampleSize(0) == 16) {
2506                             // Decode directly into short data.
2507                             decodeRaw(shortData, dstOffset,
2508                                       pixelBitStride, scanlineStride);
2509                         } else {
2510                             // Decode into bytes and reformat into shorts.
2511                             int bpp = getBitsPerPixel(sm);
2512                             int bytesPerRow = (bpp*srcWidth + 7)/8;
2513                             byte[] buf = new byte[bytesPerRow*srcHeight];
2514                             decodeRaw(buf, 0, bpp, bytesPerRow);
2515                             reformatData(buf, bytesPerRow, srcHeight,
2516                                          shortData, null,
2517                                          dstOffset, scanlineStride);
2518                         }
2519                     } else if (intData != null) {
2520                         if(areSampleSizesEqual(sm) &&
2521                            sm.getSampleSize(0) == 32) {
2522                             // Decode directly into int data.
2523                             decodeRaw(intData, dstOffset,
2524                                       pixelBitStride, scanlineStride);
2525                         } else {
2526                             // Decode into bytes and reformat into ints.
2527                             int bpp = getBitsPerPixel(sm);
2528                             int bytesPerRow = (bpp*srcWidth + 7)/8;
2529                             byte[] buf = new byte[bytesPerRow*srcHeight];
2530                             decodeRaw(buf, 0, bpp, bytesPerRow);
2531                             reformatData(buf, bytesPerRow, srcHeight,
2532                                          null, intData,
2533                                          dstOffset, scanlineStride);
2534                         }
2535                     }
2536                 }
2537             } else {
2538                 // Read discontiguous data into bytes and set the samples
2539                 // into the Raster.
2540                 int bpp = getBitsPerPixel(sm);
2541                 int bytesPerRow = (bpp*srcWidth + 7)/8;
2542                 byte[] buf = new byte[bytesPerRow*srcHeight];
2543                 decodeRaw(buf, 0, bpp, bytesPerRow);
2544                 reformatDiscontiguousData(buf, bytesPerRow,
2545                                           srcWidth, srcHeight,
2546                                           ras);
2547             }
2548         }
2549 
2550         if (colorConverter != null) {
2551             float[] rgb = new float[3];
2552 
2553             if(byteData != null) {
2554                 for (int j = 0; j < dstHeight; j++) {
2555                     int idx = dstOffset;
2556                     for (int i = 0; i < dstWidth; i++) {
2557                         float x0 = (float)(byteData[idx] & 0xff);
2558                         float x1 = (float)(byteData[idx + 1] & 0xff);
2559                         float x2 = (float)(byteData[idx + 2] & 0xff);
2560 
2561                         colorConverter.toRGB(x0, x1, x2, rgb);
2562 
2563                         byteData[idx] = (byte)(rgb[0]);
2564                         byteData[idx + 1] = (byte)(rgb[1]);
2565                         byteData[idx + 2] = (byte)(rgb[2]);
2566 
2567                         idx += 3;
2568                     }
2569 
2570                     dstOffset += scanlineStride;
2571                 }
2572             } else if(shortData != null) {
2573                 if(sampleFormat[0] ==
2574                    BaselineTIFFTagSet.SAMPLE_FORMAT_SIGNED_INTEGER) {
2575                     for (int j = 0; j < dstHeight; j++) {
2576                         int idx = dstOffset;
2577                         for (int i = 0; i < dstWidth; i++) {
2578                             float x0 = (float)shortData[idx];
2579                             float x1 = (float)shortData[idx + 1];
2580                             float x2 = (float)shortData[idx + 2];
2581 
2582                             colorConverter.toRGB(x0, x1, x2, rgb);
2583 
2584                             shortData[idx] = (short)(rgb[0]);
2585                             shortData[idx + 1] = (short)(rgb[1]);
2586                             shortData[idx + 2] = (short)(rgb[2]);
2587 
2588                             idx += 3;
2589                         }
2590 
2591                         dstOffset += scanlineStride;
2592                     }
2593                 } else {
2594                     for (int j = 0; j < dstHeight; j++) {
2595                         int idx = dstOffset;
2596                         for (int i = 0; i < dstWidth; i++) {
2597                             float x0 = (float)(shortData[idx] & 0xffff);
2598                             float x1 = (float)(shortData[idx + 1] & 0xffff);
2599                             float x2 = (float)(shortData[idx + 2] & 0xffff);
2600 
2601                             colorConverter.toRGB(x0, x1, x2, rgb);
2602 
2603                             shortData[idx] = (short)(rgb[0]);
2604                             shortData[idx + 1] = (short)(rgb[1]);
2605                             shortData[idx + 2] = (short)(rgb[2]);
2606 
2607                             idx += 3;
2608                         }
2609 
2610                         dstOffset += scanlineStride;
2611                     }
2612                 }
2613             } else if(intData != null) {
2614                 for (int j = 0; j < dstHeight; j++) {
2615                     int idx = dstOffset;
2616                     for (int i = 0; i < dstWidth; i++) {
2617                         float x0 = (float)intData[idx];
2618                         float x1 = (float)intData[idx + 1];
2619                         float x2 = (float)intData[idx + 2];
2620 
2621                         colorConverter.toRGB(x0, x1, x2, rgb);
2622 
2623                         intData[idx] = (int)(rgb[0]);
2624                         intData[idx + 1] = (int)(rgb[1]);
2625                         intData[idx + 2] = (int)(rgb[2]);
2626 
2627                         idx += 3;
2628                     }
2629 
2630                     dstOffset += scanlineStride;
2631                 }
2632             } else if(floatData != null) {
2633                 for (int j = 0; j < dstHeight; j++) {
2634                     int idx = dstOffset;
2635                     for (int i = 0; i < dstWidth; i++) {
2636                         float x0 = floatData[idx];
2637                         float x1 = floatData[idx + 1];
2638                         float x2 = floatData[idx + 2];
2639 
2640                         colorConverter.toRGB(x0, x1, x2, rgb);
2641 
2642                         floatData[idx] = rgb[0];
2643                         floatData[idx + 1] = rgb[1];
2644                         floatData[idx + 2] = rgb[2];
2645 
2646                         idx += 3;
2647                     }
2648 
2649                     dstOffset += scanlineStride;
2650                 }
2651             } else if(doubleData != null) {
2652                 for (int j = 0; j < dstHeight; j++) {
2653                     int idx = dstOffset;
2654                     for (int i = 0; i < dstWidth; i++) {
2655                         // Note: Possible loss of precision.
2656                         float x0 = (float)doubleData[idx];
2657                         float x1 = (float)doubleData[idx + 1];
2658                         float x2 = (float)doubleData[idx + 2];
2659 
2660                         colorConverter.toRGB(x0, x1, x2, rgb);
2661 
2662                         doubleData[idx] = rgb[0];
2663                         doubleData[idx + 1] = rgb[1];
2664                         doubleData[idx + 2] = rgb[2];
2665 
2666                         idx += 3;
2667                     }
2668 
2669                     dstOffset += scanlineStride;
2670                 }
2671             }
2672         }
2673 
2674         if (photometricInterpretation ==
2675             BaselineTIFFTagSet.PHOTOMETRIC_INTERPRETATION_WHITE_IS_ZERO) {
2676             if(byteData != null) {
2677                 int bytesPerRow = (srcWidth*pixelBitStride + 7)/8;
2678                 for (int y = 0; y < srcHeight; y++) {
2679                     int offset = dstOffset + y*scanlineStride;
2680                     for (int i = 0; i < bytesPerRow; i++) {
2681                         byteData[offset + i] ^= 0xff;
2682                     }
2683                 }
2684             } else if(shortData != null) {
2685                 int shortsPerRow = (srcWidth*pixelBitStride + 15)/16;
2686                 if(sampleFormat[0] ==
2687                    BaselineTIFFTagSet.SAMPLE_FORMAT_SIGNED_INTEGER) {
2688                     for (int y = 0; y < srcHeight; y++) {
2689                         int offset = dstOffset + y*scanlineStride;
2690                         for (int i = 0; i < shortsPerRow; i++) {
2691                             int shortOffset = offset + i;
2692                             shortData[shortOffset] =
2693                                 (short)(Short.MAX_VALUE -
2694                                         shortData[shortOffset]);
2695                         }
2696                     }
2697                 } else {
2698                     for (int y = 0; y < srcHeight; y++) {
2699                         int offset = dstOffset + y*scanlineStride;
2700                         for (int i = 0; i < shortsPerRow; i++) {
2701                             shortData[offset + i] ^= 0xffff;
2702                         }
2703                     }
2704                 }
2705             } else if(intData != null) {
2706                 int intsPerRow = (srcWidth*pixelBitStride + 31)/32;
2707                 for (int y = 0; y < srcHeight; y++) {
2708                     int offset = dstOffset + y*scanlineStride;
2709                     for (int i = 0; i < intsPerRow; i++) {
2710                         int intOffset = offset + i;
2711                         intData[intOffset] =
2712                             Integer.MAX_VALUE - intData[intOffset];
2713                     }
2714                 }
2715             } else if(floatData != null) {
2716                 int floatsPerRow = (srcWidth*pixelBitStride + 31)/32;
2717                 for (int y = 0; y < srcHeight; y++) {
2718                     int offset = dstOffset + y*scanlineStride;
2719                     for (int i = 0; i < floatsPerRow; i++) {
2720                         int floatOffset = offset + i;
2721                         floatData[floatOffset] =
2722                             1.0F - floatData[floatOffset];
2723                     }
2724                 }
2725             } else if(doubleData != null) {
2726                 int doublesPerRow = (srcWidth*pixelBitStride + 63)/64;
2727                 for (int y = 0; y < srcHeight; y++) {
2728                     int offset = dstOffset + y*scanlineStride;
2729                     for (int i = 0; i < doublesPerRow; i++) {
2730                         int doubleOffset = offset + i;
2731                         doubleData[doubleOffset] =
2732                             1.0F - doubleData[doubleOffset];
2733                     }
2734                 }
2735             }
2736         }
2737 
2738         if(isBilevel) {
2739             Rectangle rect = isImageSimple ?
2740                 new Rectangle(dstMinX, dstMinY, dstWidth, dstHeight) :
2741                 ras.getBounds();
2742             ImageUtil.setPackedBinaryData(byteData, ras, rect);
2743         }
2744 
2745         if (isDirectCopy) { // rawImage == image) {
2746             return;
2747         }
2748 
2749         // Copy the raw image data into the true destination image
2750         Raster src = rawImage.getRaster();
2751 
2752         // Create band child of source
2753         Raster srcChild = src.createChild(0, 0,
2754                                           srcWidth, srcHeight,
2755                                           srcMinX, srcMinY,
2756                                           planar ? null : sourceBands);
2757 
2758         WritableRaster dst = image.getRaster();
2759 
2760         // Create dst child covering area and bands to be written
2761         WritableRaster dstChild = dst.createWritableChild(dstMinX, dstMinY,
2762                                                           dstWidth, dstHeight,
2763                                                           dstMinX, dstMinY,
2764                                                           destinationBands);
2765 
2766         if (subsampleX == 1 && subsampleY == 1 && !adjustBitDepths) {
2767             srcChild = srcChild.createChild(activeSrcMinX,
2768                                             activeSrcMinY,
2769                                             activeSrcWidth, activeSrcHeight,
2770                                             dstMinX, dstMinY,
2771                                             null);
2772 
2773             dstChild.setRect(srcChild);
2774         } else if (subsampleX == 1 && !adjustBitDepths) {
2775             int sy = activeSrcMinY;
2776             int dy = dstMinY;
2777             while (sy < srcMinY + srcHeight) {
2778                 Raster srcRow = srcChild.createChild(activeSrcMinX, sy,
2779                                                      activeSrcWidth, 1,
2780                                                      dstMinX, dy,
2781                                                      null);
2782                 dstChild.setRect(srcRow);
2783 
2784                 sy += subsampleY;
2785                 ++dy;
2786             }
2787         } else {
2788             int[] p = srcChild.getPixel(srcMinX, srcMinY, (int[])null);
2789             int numBands = p.length;
2790 
2791             int sy = activeSrcMinY;
2792             int dy = dstMinY;
2793 
2794             while (sy < activeSrcMinY + activeSrcHeight) {
2795                 int sx = activeSrcMinX;
2796                 int dx = dstMinX;
2797 
2798                 while (sx < activeSrcMinX + activeSrcWidth) {
2799                     srcChild.getPixel(sx, sy, p);
2800                     if (adjustBitDepths) {
2801                         for (int band = 0; band < numBands; band++) {
2802                             p[band] = bitDepthScale[band][p[band]];
2803                         }
2804                     }
2805                     dstChild.setPixel(dx, dy, p);
2806 
2807                     sx += subsampleX;
2808                     ++dx;
2809                 }
2810 
2811                 sy += subsampleY;
2812                 ++dy;
2813             }
2814         }
2815     }
2816 }