Program: 154062
Project: 154062
Buggy source:
/** 
 * Constructs a TIFFImage that acquires its data from a given SeekableStream and reads from a particular IFD of the stream. The index of the first IFD is 0.
 * @param stream the SeekableStream to read from.
 * @param param an instance of TIFFDecodeParam, or null.
 * @param directory the index of the IFD to read from.
 */
public TIFFImage(SeekableStream stream,TIFFDecodeParam param,int directory) throws IOException {
  this.stream=stream;
  if (param == null) {
    param=new TIFFDecodeParam();
  }
  decodePaletteAsShorts=param.getDecodePaletteAsShorts();
  TIFFDirectory dir=param.getIFDOffset() == null ? new TIFFDirectory(stream,directory) : new TIFFDirectory(stream,param.getIFDOffset().longValue(),directory);
  properties.put("String_Node_Str",dir);
  TIFFField sfield=dir.getField(TIFFImageDecoder.TIFF_SAMPLES_PER_PIXEL);
  int samplesPerPixel=sfield == null ? 1 : (int)sfield.getAsLong(0);
  TIFFField planarConfigurationField=dir.getField(TIFFImageDecoder.TIFF_PLANAR_CONFIGURATION);
  char[] planarConfiguration=planarConfigurationField == null ? new char[]{1} : planarConfigurationField.getAsChars();
  if (planarConfiguration[0] != 1 && samplesPerPixel != 1) {
    throw new RuntimeException(JaiI18N.getString("String_Node_Str"));
  }
  TIFFField bitsField=dir.getField(TIFFImageDecoder.TIFF_BITS_PER_SAMPLE);
  char[] bitsPerSample=null;
  if (bitsField != null) {
    bitsPerSample=bitsField.getAsChars();
  }
 else {
    bitsPerSample=new char[]{1};
    for (int i=1; i < bitsPerSample.length; i++) {
      if (bitsPerSample[i] != bitsPerSample[0]) {
        throw new RuntimeException(JaiI18N.getString("String_Node_Str"));
      }
    }
  }
  sampleSize=(int)bitsPerSample[0];
  TIFFField sampleFormatField=dir.getField(TIFFImageDecoder.TIFF_SAMPLE_FORMAT);
  char[] sampleFormat=null;
  if (sampleFormatField != null) {
    sampleFormat=sampleFormatField.getAsChars();
    for (int l=1; l < sampleFormat.length; l++) {
      if (sampleFormat[l] != sampleFormat[0]) {
        throw new RuntimeException(JaiI18N.getString("String_Node_Str"));
      }
    }
  }
 else {
    sampleFormat=new char[]{1};
  }
  boolean isValidDataFormat=false;
switch (sampleSize) {
case 1:
case 4:
case 8:
    if (sampleFormat[0] != 3) {
      dataType=DataBuffer.TYPE_BYTE;
      isValidDataFormat=true;
    }
  break;
case 16:
if (sampleFormat[0] != 3) {
  dataType=sampleFormat[0] == 2 ? DataBuffer.TYPE_SHORT : DataBuffer.TYPE_USHORT;
  isValidDataFormat=true;
}
break;
case 32:
dataType=sampleFormat[0] == 3 ? DataBuffer.TYPE_FLOAT : DataBuffer.TYPE_INT;
isValidDataFormat=true;
break;
}
if (!isValidDataFormat) {
throw new RuntimeException(JaiI18N.getString("String_Node_Str"));
}
TIFFField compField=dir.getField(TIFFImageDecoder.TIFF_COMPRESSION);
compression=compField == null ? COMP_NONE : compField.getAsInt(0);
TIFFField photoInterpField=dir.getField(TIFFImageDecoder.TIFF_PHOTOMETRIC_INTERPRETATION);
int photometricType;
if (photoInterpField != null) {
photometricType=(int)photoInterpField.getAsLong(0);
}
 else {
if (dir.getField(TIFFImageDecoder.TIFF_COLORMAP) != null) {
photometricType=3;
}
 else if (sampleSize == 1) {
if (compression == COMP_FAX_G3_1D || compression == COMP_FAX_G3_2D || compression == COMP_FAX_G4_2D) {
photometricType=0;
}
 else {
photometricType=1;
}
}
 else if (samplesPerPixel == 3 || samplesPerPixel == 4) {
photometricType=2;
}
 else {
photometricType=1;
}
}
imageType=TYPE_UNSUPPORTED;
switch (photometricType) {
case 0:
isWhiteZero=true;
case 1:
if (sampleSize == 1 && samplesPerPixel == 1) {
imageType=TYPE_BILEVEL;
}
 else if (sampleSize == 4 && samplesPerPixel == 1) {
imageType=TYPE_GRAY_4BIT;
}
 else if (sampleSize % 8 == 0) {
if (samplesPerPixel == 1) {
imageType=TYPE_GRAY;
}
 else if (samplesPerPixel == 2) {
imageType=TYPE_GRAY_ALPHA;
}
 else {
imageType=TYPE_GENERIC;
}
}
break;
case 2:
if (sampleSize % 8 == 0) {
if (samplesPerPixel == 3) {
imageType=TYPE_RGB;
}
 else if (samplesPerPixel == 4) {
imageType=TYPE_RGB_ALPHA;
}
 else {
imageType=TYPE_GENERIC;
}
}
break;
case 3:
if (samplesPerPixel == 1 && (sampleSize == 4 || sampleSize == 8 || sampleSize == 16)) {
imageType=TYPE_PALETTE;
}
break;
case 4:
if (sampleSize == 1 && samplesPerPixel == 1) {
imageType=TYPE_BILEVEL;
}
break;
case 6:
if (compression == COMP_JPEG_TTN2 && sampleSize == 8 && samplesPerPixel == 3) {
colorConvertJPEG=param.getJPEGDecompressYCbCrToRGB();
imageType=colorConvertJPEG ? TYPE_RGB : TYPE_GENERIC;
}
 else {
TIFFField chromaField=dir.getField(TIFF_YCBCR_SUBSAMPLING);
if (chromaField != null) {
chromaSubH=chromaField.getAsInt(0);
chromaSubV=chromaField.getAsInt(1);
}
 else {
chromaSubH=chromaSubV=2;
}
if (chromaSubH * chromaSubV == 1) {
imageType=TYPE_GENERIC;
}
 else if (sampleSize == 8 && samplesPerPixel == 3) {
imageType=TYPE_YCBCR_SUB;
}
}
break;
default :
if (sampleSize % 8 == 0) {
imageType=TYPE_GENERIC;
}
}
if (imageType == TYPE_UNSUPPORTED) {
throw new RuntimeException(JaiI18N.getString("String_Node_Str"));
}
minX=minY=0;
width=(int)(getField(dir,TIFFImageDecoder.TIFF_IMAGE_WIDTH,"String_Node_Str").getAsLong(0));
height=(int)(getField(dir,TIFFImageDecoder.TIFF_IMAGE_LENGTH,"String_Node_Str").getAsLong(0));
numBands=samplesPerPixel;
TIFFField efield=dir.getField(TIFFImageDecoder.TIFF_EXTRA_SAMPLES);
int extraSamples=efield == null ? 0 : (int)efield.getAsLong(0);
if (dir.getField(TIFFImageDecoder.TIFF_TILE_OFFSETS) != null) {
isTiled=true;
tileWidth=(int)(getField(dir,TIFFImageDecoder.TIFF_TILE_WIDTH,"String_Node_Str").getAsLong(0));
tileHeight=(int)(getField(dir,TIFFImageDecoder.TIFF_TILE_LENGTH,"String_Node_Str").getAsLong(0));
tileOffsets=(getField(dir,TIFFImageDecoder.TIFF_TILE_OFFSETS,"String_Node_Str")).getAsLongs();
tileByteCounts=getFieldAsLongs(getField(dir,TIFFImageDecoder.TIFF_TILE_BYTE_COUNTS,"String_Node_Str"));
}
 else {
isTiled=false;
tileWidth=dir.getField(TIFFImageDecoder.TIFF_TILE_WIDTH) != null ? (int)dir.getFieldAsLong(TIFFImageDecoder.TIFF_TILE_WIDTH) : width;
TIFFField field=dir.getField(TIFFImageDecoder.TIFF_ROWS_PER_STRIP);
if (field == null) {
tileHeight=dir.getField(TIFFImageDecoder.TIFF_TILE_LENGTH) != null ? (int)dir.getFieldAsLong(TIFFImageDecoder.TIFF_TILE_LENGTH) : height;
}
 else {
long l=field.getAsLong(0);
long infinity=1;
infinity=(infinity << 32) - 1;
if (l == infinity || l > height) {
tileHeight=height;
}
 else {
tileHeight=(int)l;
}
}
TIFFField tileOffsetsField=getField(dir,TIFFImageDecoder.TIFF_STRIP_OFFSETS,"String_Node_Str");
tileOffsets=getFieldAsLongs(tileOffsetsField);
TIFFField tileByteCountsField=dir.getField(TIFFImageDecoder.TIFF_STRIP_BYTE_COUNTS);
if (tileByteCountsField == null) {
int totalBytes=((sampleSize + 7) / 8) * numBands * width* height;
int bytesPerStrip=((sampleSize + 7) / 8) * numBands * width* tileHeight;
int cumulativeBytes=0;
tileByteCounts=new long[tileOffsets.length];
for (int i=0; i < tileOffsets.length; i++) {
tileByteCounts[i]=Math.min(totalBytes - cumulativeBytes,bytesPerStrip);
cumulativeBytes+=bytesPerStrip;
}
if (compression != COMP_NONE) {
this.stream=new NoEOFStream(stream);
}
}
 else {
tileByteCounts=getFieldAsLongs(tileByteCountsField);
}
int maxBytes=width * height * numBands* ((sampleSize + 7) / 8);
if (tileByteCounts.length == 1 && compression == COMP_NONE && tileByteCounts[0] > maxBytes) {
tileByteCounts[0]=maxBytes;
}
}
tilesX=(width + tileWidth - 1) / tileWidth;
tilesY=(height + tileHeight - 1) / tileHeight;
tileSize=tileWidth * tileHeight * numBands;
isBigEndian=dir.isBigEndian();
TIFFField fillOrderField=dir.getField(TIFFImageDecoder.TIFF_FILL_ORDER);
if (fillOrderField != null) {
fillOrder=fillOrderField.getAsInt(0);
}
 else {
fillOrder=1;
}
switch (compression) {
case COMP_NONE:
case COMP_PACKBITS:
break;
case COMP_DEFLATE:
inflater=new Inflater();
break;
case COMP_FAX_G3_1D:
case COMP_FAX_G3_2D:
case COMP_FAX_G4_2D:
if (sampleSize != 1) {
throw new RuntimeException(JaiI18N.getString("String_Node_Str"));
}
if (compression == 3) {
TIFFField t4OptionsField=dir.getField(TIFFImageDecoder.TIFF_T4_OPTIONS);
if (t4OptionsField != null) {
tiffT4Options=t4OptionsField.getAsLong(0);
}
 else {
tiffT4Options=0;
}
}
if (compression == 4) {
TIFFField t6OptionsField=dir.getField(TIFFImageDecoder.TIFF_T6_OPTIONS);
if (t6OptionsField != null) {
tiffT6Options=t6OptionsField.getAsLong(0);
}
 else {
tiffT6Options=0;
}
}
decoder=new TIFFFaxDecoder(fillOrder,tileWidth,tileHeight);
break;
case COMP_LZW:
TIFFField predictorField=dir.getField(TIFFImageDecoder.TIFF_PREDICTOR);
if (predictorField == null) {
predictor=1;
}
 else {
predictor=predictorField.getAsInt(0);
if (predictor != 1 && predictor != 2) {
throw new RuntimeException(JaiI18N.getString("String_Node_Str"));
}
if (predictor == 2 && sampleSize != 8) {
throw new RuntimeException(sampleSize + JaiI18N.getString("String_Node_Str"));
}
}
lzwDecoder=new TIFFLZWDecoder(tileWidth,predictor,samplesPerPixel);
break;
case COMP_JPEG_OLD:
throw new RuntimeException(JaiI18N.getString("String_Node_Str"));
case COMP_JPEG_TTN2:
if (!(sampleSize == 8 && ((imageType == TYPE_GRAY && samplesPerPixel == 1) || (imageType == TYPE_PALETTE && samplesPerPixel == 1) || (imageType == TYPE_RGB && samplesPerPixel == 3)))) {
throw new RuntimeException(JaiI18N.getString("String_Node_Str"));
}
if (dir.isTagPresent(TIFF_JPEG_TABLES)) {
TIFFField jpegTableField=dir.getField(TIFF_JPEG_TABLES);
byte[] jpegTable=jpegTableField.getAsBytes();
ByteArrayInputStream tableStream=new ByteArrayInputStream(jpegTable);
JPEGImageDecoder decoder=JPEGCodec.createJPEGDecoder(tableStream);
decoder.decodeAsRaster();
decodeParam=decoder.getJPEGDecodeParam();
}
break;
default :
throw new RuntimeException(JaiI18N.getString("String_Node_Str"));
}
switch (imageType) {
case TYPE_BILEVEL:
case TYPE_GRAY_4BIT:
sampleModel=new MultiPixelPackedSampleModel(dataType,tileWidth,tileHeight,sampleSize);
if (imageType == TYPE_BILEVEL) {
byte[] map=new byte[]{(byte)(isWhiteZero ? 255 : 0),(byte)(isWhiteZero ? 0 : 255)};
colorModel=new IndexColorModel(1,2,map,map,map);
}
 else {
colorModel=ImageCodec.createGrayIndexColorModel(sampleModel,!isWhiteZero);
}
break;
case TYPE_GRAY:
case TYPE_GRAY_ALPHA:
case TYPE_RGB:
case TYPE_RGB_ALPHA:
int[] RGBOffsets=new int[numBands];
if (compression == COMP_JPEG_TTN2) {
for (int i=0; i < numBands; i++) {
RGBOffsets[i]=numBands - 1 - i;
}
}
 else {
for (int i=0; i < numBands; i++) {
RGBOffsets[i]=i;
}
}
sampleModel=createPixelInterleavedSampleModel(dataType,tileWidth,tileHeight,numBands,numBands * tileWidth,RGBOffsets);
if (imageType == TYPE_GRAY || imageType == TYPE_RGB) {
colorModel=ImageCodec.createComponentColorModel(sampleModel);
}
 else {
int transparency=Transparency.OPAQUE;
if (extraSamples == 1 || extraSamples == 2) {
transparency=Transparency.TRANSLUCENT;
}
colorModel=createAlphaComponentColorModel(dataType,numBands,extraSamples == 1,transparency);
}
break;
case TYPE_GENERIC:
case TYPE_YCBCR_SUB:
int[] bandOffsets=new int[numBands];
for (int i=0; i < numBands; i++) {
bandOffsets[i]=i;
}
sampleModel=createPixelInterleavedSampleModel(dataType,tileWidth,tileHeight,numBands,numBands * tileWidth,bandOffsets);
colorModel=null;
break;
case TYPE_PALETTE:
TIFFField cfield=getField(dir,TIFFImageDecoder.TIFF_COLORMAP,"String_Node_Str");
colormap=cfield.getAsChars();
if (decodePaletteAsShorts) {
numBands=3;
if (dataType == DataBuffer.TYPE_BYTE) {
dataType=DataBuffer.TYPE_USHORT;
}
sampleModel=RasterFactory.createPixelInterleavedSampleModel(dataType,tileWidth,tileHeight,numBands);
colorModel=ImageCodec.createComponentColorModel(sampleModel);
}
 else {
numBands=1;
if (sampleSize == 4) {
sampleModel=new MultiPixelPackedSampleModel(DataBuffer.TYPE_BYTE,tileWidth,tileHeight,sampleSize);
}
 else if (sampleSize == 8) {
sampleModel=RasterFactory.createPixelInterleavedSampleModel(DataBuffer.TYPE_BYTE,tileWidth,tileHeight,numBands);
}
 else if (sampleSize == 16) {
dataType=DataBuffer.TYPE_USHORT;
sampleModel=RasterFactory.createPixelInterleavedSampleModel(DataBuffer.TYPE_USHORT,tileWidth,tileHeight,numBands);
}
int bandLength=colormap.length / 3;
byte r[]=new byte[bandLength];
byte g[]=new byte[bandLength];
byte b[]=new byte[bandLength];
int gIndex=bandLength;
int bIndex=bandLength * 2;
if (dataType == DataBuffer.TYPE_SHORT) {
for (int i=0; i < bandLength; i++) {
r[i]=param.decodeSigned16BitsTo8Bits((short)colormap[i]);
g[i]=param.decodeSigned16BitsTo8Bits((short)colormap[gIndex + i]);
b[i]=param.decodeSigned16BitsTo8Bits((short)colormap[bIndex + i]);
}
}
 else {
for (int i=0; i < bandLength; i++) {
r[i]=param.decode16BitsTo8Bits(colormap[i] & 0xffff);
g[i]=param.decode16BitsTo8Bits(colormap[gIndex + i] & 0xffff);
b[i]=param.decode16BitsTo8Bits(colormap[bIndex + i] & 0xffff);
}
}
colorModel=new IndexColorModel(sampleSize,bandLength,r,g,b);
}
break;
default :
throw new RuntimeException("String_Node_Str");
}
}

Fixed version (ground truth):
/** 
 * Constructs a TIFFImage that acquires its data from a given SeekableStream and reads from a particular IFD of the stream. The index of the first IFD is 0.
 * @param stream the SeekableStream to read from.
 * @param param an instance of TIFFDecodeParam, or null.
 * @param directory the index of the IFD to read from.
 */
public TIFFImage(SeekableStream stream,TIFFDecodeParam param,int directory) throws IOException {
  this.stream=stream;
  if (param == null) {
    param=new TIFFDecodeParam();
  }
  decodePaletteAsShorts=param.getDecodePaletteAsShorts();
  TIFFDirectory dir=param.getIFDOffset() == null ? new TIFFDirectory(stream,directory) : new TIFFDirectory(stream,param.getIFDOffset().longValue(),directory);
  properties.put("String_Node_Str",dir);
  TIFFField sfield=dir.getField(TIFFImageDecoder.TIFF_SAMPLES_PER_PIXEL);
  int samplesPerPixel=sfield == null ? 1 : (int)sfield.getAsLong(0);
  TIFFField planarConfigurationField=dir.getField(TIFFImageDecoder.TIFF_PLANAR_CONFIGURATION);
  char[] planarConfiguration=planarConfigurationField == null ? new char[]{1} : planarConfigurationField.getAsChars();
  if (planarConfiguration[0] != 1 && samplesPerPixel != 1) {
    throw new RuntimeException(JaiI18N.getString("String_Node_Str"));
  }
  TIFFField bitsField=dir.getField(TIFFImageDecoder.TIFF_BITS_PER_SAMPLE);
  char[] bitsPerSample=null;
  if (bitsField != null) {
    bitsPerSample=bitsField.getAsChars();
  }
 else {
    bitsPerSample=new char[]{1};
    for (int i=1; i < bitsPerSample.length; i++) {
      if (bitsPerSample[i] != bitsPerSample[0]) {
        throw new RuntimeException(JaiI18N.getString("String_Node_Str"));
      }
    }
  }
  sampleSize=(int)bitsPerSample[0];
  TIFFField sampleFormatField=dir.getField(TIFFImageDecoder.TIFF_SAMPLE_FORMAT);
  char[] sampleFormat=null;
  if (sampleFormatField != null) {
    sampleFormat=sampleFormatField.getAsChars();
    for (int l=1; l < sampleFormat.length; l++) {
      if (sampleFormat[l] != sampleFormat[0]) {
        throw new RuntimeException(JaiI18N.getString("String_Node_Str"));
      }
    }
  }
 else {
    sampleFormat=new char[]{1};
  }
  boolean isValidDataFormat=false;
switch (sampleSize) {
case 1:
case 4:
case 8:
    if (sampleFormat[0] != 3) {
      dataType=DataBuffer.TYPE_BYTE;
      isValidDataFormat=true;
    }
  break;
case 16:
if (sampleFormat[0] != 3) {
  dataType=sampleFormat[0] == 2 ? DataBuffer.TYPE_SHORT : DataBuffer.TYPE_USHORT;
  isValidDataFormat=true;
}
break;
case 32:
dataType=sampleFormat[0] == 3 ? DataBuffer.TYPE_FLOAT : DataBuffer.TYPE_INT;
isValidDataFormat=true;
break;
}
if (!isValidDataFormat) {
throw new RuntimeException(JaiI18N.getString("String_Node_Str"));
}
TIFFField compField=dir.getField(TIFFImageDecoder.TIFF_COMPRESSION);
compression=compField == null ? COMP_NONE : compField.getAsInt(0);
TIFFField photoInterpField=dir.getField(TIFFImageDecoder.TIFF_PHOTOMETRIC_INTERPRETATION);
int photometricType;
if (photoInterpField != null) {
photometricType=(int)photoInterpField.getAsLong(0);
}
 else {
if (dir.getField(TIFFImageDecoder.TIFF_COLORMAP) != null) {
photometricType=3;
}
 else if (sampleSize == 1) {
if (compression == COMP_FAX_G3_1D || compression == COMP_FAX_G3_2D || compression == COMP_FAX_G4_2D) {
photometricType=0;
}
 else {
photometricType=1;
}
}
 else if (samplesPerPixel == 3 || samplesPerPixel == 4) {
photometricType=2;
}
 else {
photometricType=1;
}
}
imageType=TYPE_UNSUPPORTED;
switch (photometricType) {
case 0:
isWhiteZero=true;
case 1:
if (sampleSize == 1 && samplesPerPixel == 1) {
imageType=TYPE_BILEVEL;
}
 else if (sampleSize == 4 && samplesPerPixel == 1) {
imageType=TYPE_GRAY_4BIT;
}
 else if (sampleSize % 8 == 0) {
if (samplesPerPixel == 1) {
imageType=TYPE_GRAY;
}
 else if (samplesPerPixel == 2) {
imageType=TYPE_GRAY_ALPHA;
}
 else {
imageType=TYPE_GENERIC;
}
}
break;
case 2:
if (sampleSize % 8 == 0) {
if (samplesPerPixel == 3) {
imageType=TYPE_RGB;
}
 else if (samplesPerPixel == 4) {
imageType=TYPE_RGB_ALPHA;
}
 else {
imageType=TYPE_GENERIC;
}
}
break;
case 3:
if (samplesPerPixel == 1 && (sampleSize == 4 || sampleSize == 8 || sampleSize == 16)) {
imageType=TYPE_PALETTE;
}
break;
case 4:
if (sampleSize == 1 && samplesPerPixel == 1) {
imageType=TYPE_BILEVEL;
}
break;
case 5:
if (sampleSize == 8 && samplesPerPixel == 4) {
imageType=TYPE_CMYK;
}
case 6:
if (compression == COMP_JPEG_TTN2 && sampleSize == 8 && samplesPerPixel == 3) {
colorConvertJPEG=param.getJPEGDecompressYCbCrToRGB();
imageType=colorConvertJPEG ? TYPE_RGB : TYPE_GENERIC;
}
 else {
TIFFField chromaField=dir.getField(TIFF_YCBCR_SUBSAMPLING);
if (chromaField != null) {
chromaSubH=chromaField.getAsInt(0);
chromaSubV=chromaField.getAsInt(1);
}
 else {
chromaSubH=chromaSubV=2;
}
if (chromaSubH * chromaSubV == 1) {
imageType=TYPE_GENERIC;
}
 else if (sampleSize == 8 && samplesPerPixel == 3) {
imageType=TYPE_YCBCR_SUB;
}
}
break;
default :
if (sampleSize % 8 == 0) {
imageType=TYPE_GENERIC;
}
}
if (imageType == TYPE_UNSUPPORTED) {
throw new RuntimeException(JaiI18N.getString("String_Node_Str"));
}
minX=minY=0;
width=(int)(getField(dir,TIFFImageDecoder.TIFF_IMAGE_WIDTH,"String_Node_Str").getAsLong(0));
height=(int)(getField(dir,TIFFImageDecoder.TIFF_IMAGE_LENGTH,"String_Node_Str").getAsLong(0));
numBands=samplesPerPixel;
TIFFField efield=dir.getField(TIFFImageDecoder.TIFF_EXTRA_SAMPLES);
int extraSamples=efield == null ? 0 : (int)efield.getAsLong(0);
if (dir.getField(TIFFImageDecoder.TIFF_TILE_OFFSETS) != null) {
isTiled=true;
tileWidth=(int)(getField(dir,TIFFImageDecoder.TIFF_TILE_WIDTH,"String_Node_Str").getAsLong(0));
tileHeight=(int)(getField(dir,TIFFImageDecoder.TIFF_TILE_LENGTH,"String_Node_Str").getAsLong(0));
tileOffsets=(getField(dir,TIFFImageDecoder.TIFF_TILE_OFFSETS,"String_Node_Str")).getAsLongs();
tileByteCounts=getFieldAsLongs(getField(dir,TIFFImageDecoder.TIFF_TILE_BYTE_COUNTS,"String_Node_Str"));
}
 else {
isTiled=false;
tileWidth=dir.getField(TIFFImageDecoder.TIFF_TILE_WIDTH) != null ? (int)dir.getFieldAsLong(TIFFImageDecoder.TIFF_TILE_WIDTH) : width;
TIFFField field=dir.getField(TIFFImageDecoder.TIFF_ROWS_PER_STRIP);
if (field == null) {
tileHeight=dir.getField(TIFFImageDecoder.TIFF_TILE_LENGTH) != null ? (int)dir.getFieldAsLong(TIFFImageDecoder.TIFF_TILE_LENGTH) : height;
}
 else {
long l=field.getAsLong(0);
long infinity=1;
infinity=(infinity << 32) - 1;
if (l == infinity || l > height) {
tileHeight=height;
}
 else {
tileHeight=(int)l;
}
}
TIFFField tileOffsetsField=getField(dir,TIFFImageDecoder.TIFF_STRIP_OFFSETS,"String_Node_Str");
tileOffsets=getFieldAsLongs(tileOffsetsField);
TIFFField tileByteCountsField=dir.getField(TIFFImageDecoder.TIFF_STRIP_BYTE_COUNTS);
if (tileByteCountsField == null) {
int totalBytes=((sampleSize + 7) / 8) * numBands * width* height;
int bytesPerStrip=((sampleSize + 7) / 8) * numBands * width* tileHeight;
int cumulativeBytes=0;
tileByteCounts=new long[tileOffsets.length];
for (int i=0; i < tileOffsets.length; i++) {
tileByteCounts[i]=Math.min(totalBytes - cumulativeBytes,bytesPerStrip);
cumulativeBytes+=bytesPerStrip;
}
if (compression != COMP_NONE) {
this.stream=new NoEOFStream(stream);
}
}
 else {
tileByteCounts=getFieldAsLongs(tileByteCountsField);
}
int maxBytes=width * height * numBands* ((sampleSize + 7) / 8);
if (tileByteCounts.length == 1 && compression == COMP_NONE && tileByteCounts[0] > maxBytes) {
tileByteCounts[0]=maxBytes;
}
}
tilesX=(width + tileWidth - 1) / tileWidth;
tilesY=(height + tileHeight - 1) / tileHeight;
tileSize=tileWidth * tileHeight * numBands;
isBigEndian=dir.isBigEndian();
TIFFField fillOrderField=dir.getField(TIFFImageDecoder.TIFF_FILL_ORDER);
if (fillOrderField != null) {
fillOrder=fillOrderField.getAsInt(0);
}
 else {
fillOrder=1;
}
switch (compression) {
case COMP_NONE:
case COMP_PACKBITS:
break;
case COMP_DEFLATE:
inflater=new Inflater();
break;
case COMP_FAX_G3_1D:
case COMP_FAX_G3_2D:
case COMP_FAX_G4_2D:
if (sampleSize != 1) {
throw new RuntimeException(JaiI18N.getString("String_Node_Str"));
}
if (compression == 3) {
TIFFField t4OptionsField=dir.getField(TIFFImageDecoder.TIFF_T4_OPTIONS);
if (t4OptionsField != null) {
tiffT4Options=t4OptionsField.getAsLong(0);
}
 else {
tiffT4Options=0;
}
}
if (compression == 4) {
TIFFField t6OptionsField=dir.getField(TIFFImageDecoder.TIFF_T6_OPTIONS);
if (t6OptionsField != null) {
tiffT6Options=t6OptionsField.getAsLong(0);
}
 else {
tiffT6Options=0;
}
}
decoder=new TIFFFaxDecoder(fillOrder,tileWidth,tileHeight);
break;
case COMP_LZW:
TIFFField predictorField=dir.getField(TIFFImageDecoder.TIFF_PREDICTOR);
if (predictorField == null) {
predictor=1;
}
 else {
predictor=predictorField.getAsInt(0);
if (predictor != 1 && predictor != 2) {
throw new RuntimeException(JaiI18N.getString("String_Node_Str"));
}
if (predictor == 2 && sampleSize != 8) {
throw new RuntimeException(sampleSize + JaiI18N.getString("String_Node_Str"));
}
}
lzwDecoder=new TIFFLZWDecoder(tileWidth,predictor,samplesPerPixel);
break;
case COMP_JPEG_OLD:
throw new RuntimeException(JaiI18N.getString("String_Node_Str"));
case COMP_JPEG_TTN2:
if (!(sampleSize == 8 && ((imageType == TYPE_GRAY && samplesPerPixel == 1) || (imageType == TYPE_PALETTE && samplesPerPixel == 1) || (imageType == TYPE_RGB && samplesPerPixel == 3)))) {
throw new RuntimeException(JaiI18N.getString("String_Node_Str"));
}
if (dir.isTagPresent(TIFF_JPEG_TABLES)) {
TIFFField jpegTableField=dir.getField(TIFF_JPEG_TABLES);
byte[] jpegTable=jpegTableField.getAsBytes();
ByteArrayInputStream tableStream=new ByteArrayInputStream(jpegTable);
JPEGImageDecoder decoder=JPEGCodec.createJPEGDecoder(tableStream);
decoder.decodeAsRaster();
decodeParam=decoder.getJPEGDecodeParam();
}
break;
default :
throw new RuntimeException(JaiI18N.getString("String_Node_Str"));
}
switch (imageType) {
case TYPE_BILEVEL:
case TYPE_GRAY_4BIT:
sampleModel=new MultiPixelPackedSampleModel(dataType,tileWidth,tileHeight,sampleSize);
if (imageType == TYPE_BILEVEL) {
byte[] map=new byte[]{(byte)(isWhiteZero ? 255 : 0),(byte)(isWhiteZero ? 0 : 255)};
colorModel=new IndexColorModel(1,2,map,map,map);
}
 else {
colorModel=ImageCodec.createGrayIndexColorModel(sampleModel,!isWhiteZero);
}
break;
case TYPE_GRAY:
case TYPE_GRAY_ALPHA:
case TYPE_RGB:
case TYPE_RGB_ALPHA:
case TYPE_CMYK:
int[] RGBOffsets=new int[numBands];
if (compression == COMP_JPEG_TTN2) {
for (int i=0; i < numBands; i++) {
RGBOffsets[i]=numBands - 1 - i;
}
}
 else {
for (int i=0; i < numBands; i++) {
RGBOffsets[i]=i;
}
}
sampleModel=createPixelInterleavedSampleModel(dataType,tileWidth,tileHeight,numBands,numBands * tileWidth,RGBOffsets);
if (imageType == TYPE_GRAY || imageType == TYPE_RGB) {
colorModel=ImageCodec.createComponentColorModel(sampleModel);
}
 else if (imageType == TYPE_CMYK) {
colorModel=ImageCodec.createComponentColorModel(sampleModel,new SimpleCMYKColorSpace());
}
 else {
int transparency=Transparency.OPAQUE;
if (extraSamples == 1 || extraSamples == 2) {
transparency=Transparency.TRANSLUCENT;
}
colorModel=createAlphaComponentColorModel(dataType,numBands,extraSamples == 1,transparency);
}
break;
case TYPE_GENERIC:
case TYPE_YCBCR_SUB:
int[] bandOffsets=new int[numBands];
for (int i=0; i < numBands; i++) {
bandOffsets[i]=i;
}
sampleModel=createPixelInterleavedSampleModel(dataType,tileWidth,tileHeight,numBands,numBands * tileWidth,bandOffsets);
colorModel=null;
break;
case TYPE_PALETTE:
TIFFField cfield=getField(dir,TIFFImageDecoder.TIFF_COLORMAP,"String_Node_Str");
colormap=cfield.getAsChars();
if (decodePaletteAsShorts) {
numBands=3;
if (dataType == DataBuffer.TYPE_BYTE) {
dataType=DataBuffer.TYPE_USHORT;
}
sampleModel=RasterFactory.createPixelInterleavedSampleModel(dataType,tileWidth,tileHeight,numBands);
colorModel=ImageCodec.createComponentColorModel(sampleModel);
}
 else {
numBands=1;
if (sampleSize == 4) {
sampleModel=new MultiPixelPackedSampleModel(DataBuffer.TYPE_BYTE,tileWidth,tileHeight,sampleSize);
}
 else if (sampleSize == 8) {
sampleModel=RasterFactory.createPixelInterleavedSampleModel(DataBuffer.TYPE_BYTE,tileWidth,tileHeight,numBands);
}
 else if (sampleSize == 16) {
dataType=DataBuffer.TYPE_USHORT;
sampleModel=RasterFactory.createPixelInterleavedSampleModel(DataBuffer.TYPE_USHORT,tileWidth,tileHeight,numBands);
}
int bandLength=colormap.length / 3;
byte r[]=new byte[bandLength];
byte g[]=new byte[bandLength];
byte b[]=new byte[bandLength];
int gIndex=bandLength;
int bIndex=bandLength * 2;
if (dataType == DataBuffer.TYPE_SHORT) {
for (int i=0; i < bandLength; i++) {
r[i]=param.decodeSigned16BitsTo8Bits((short)colormap[i]);
g[i]=param.decodeSigned16BitsTo8Bits((short)colormap[gIndex + i]);
b[i]=param.decodeSigned16BitsTo8Bits((short)colormap[bIndex + i]);
}
}
 else {
for (int i=0; i < bandLength; i++) {
r[i]=param.decode16BitsTo8Bits(colormap[i] & 0xffff);
g[i]=param.decode16BitsTo8Bits(colormap[gIndex + i] & 0xffff);
b[i]=param.decode16BitsTo8Bits(colormap[bIndex + i] & 0xffff);
}
}
colorModel=new IndexColorModel(sampleSize,bandLength,r,g,b);
}
break;
default :
throw new RuntimeException("String_Node_Str");
}
}