Program: 33354
Project: 33354
Buggy source:
private BufferedImage decodeTiledTiff(IFD ifd) throws Exception {
  TiffField<?> field=ifd.getField(TiffTag.COMPRESSION.getValue());
  short[] data=(short[])field.getData();
  TiffFieldEnum.Compression compression=TiffFieldEnum.Compression.fromValue(data[0] & 0xffff);
  System.out.println("String_Node_Str" + compression.getDescription());
  TiffField<?> f_tileOffsets=ifd.getField(TiffTag.TILE_OFFSETS.getValue());
  if (f_tileOffsets == null)   f_tileOffsets=ifd.getField(TiffTag.STRIP_OFFSETS.getValue());
  TiffField<?> f_tileByteCounts=ifd.getField(TiffTag.TILE_BYTE_COUNTS.getValue());
  if (f_tileByteCounts == null)   f_tileByteCounts=ifd.getField(TiffTag.STRIP_BYTE_COUNTS.getValue());
  int[] tileOffsets=f_tileOffsets.getDataAsLong();
  int[] tileByteCounts=f_tileByteCounts.getDataAsLong();
  int imageWidth=ifd.getField(TiffTag.IMAGE_WIDTH.getValue()).getDataAsLong()[0];
  int imageHeight=ifd.getField(TiffTag.IMAGE_LENGTH.getValue()).getDataAsLong()[0];
  System.out.println("String_Node_Str" + imageWidth);
  System.out.println("String_Node_Str" + imageHeight);
  TiffField<?> f_tileWidth=ifd.getField(TiffTag.TILE_WIDTH.getValue());
  TiffField<?> f_tileLength=ifd.getField(TiffTag.TILE_LENGTH.getValue());
  int tileWidth=imageWidth;
  if (f_tileWidth != null)   tileWidth=f_tileWidth.getDataAsLong()[0];
  int tileLength=imageHeight;
  if (f_tileLength != null)   tileLength=f_tileLength.getDataAsLong()[0];
  TiffField<?> f_photoMetric=ifd.getField(TiffTag.PHOTOMETRIC_INTERPRETATION.getValue());
  int photoMetric=f_photoMetric.getDataAsLong()[0];
  TiffFieldEnum.PhotoMetric e_photoMetric=TiffFieldEnum.PhotoMetric.fromValue(photoMetric);
  System.out.println("String_Node_Str" + e_photoMetric);
  TiffField<?> f_bitsPerSample=ifd.getField(TiffTag.BITS_PER_SAMPLE.getValue());
  int bitsPerSample=f_bitsPerSample.getDataAsLong()[0];
  System.out.println("String_Node_Str" + bitsPerSample);
  TiffField<?> f_samplesPerPixel=ifd.getField(TiffTag.SAMPLES_PER_PIXEL.getValue());
  int samplesPerPixel=f_samplesPerPixel.getDataAsLong()[0];
  System.out.println("String_Node_Str" + samplesPerPixel);
  TiffField<?> f_predictor=ifd.getField(TiffTag.PREDICTOR.getValue());
  int predictor=0;
  if (f_predictor != null) {
    predictor=f_predictor.getDataAsLong()[0];
    System.out.println("String_Node_Str" + predictor);
  }
  TiffField<?> f_planaryConfiguration=ifd.getField(TiffTag.PLANAR_CONFIGURATTION.getValue());
  int planaryConfiguration=1;
  if (f_planaryConfiguration != null)   planaryConfiguration=f_planaryConfiguration.getDataAsLong()[0];
  TiffFieldEnum.PlanarConfiguration e_planaryConfiguration=TiffFieldEnum.PlanarConfiguration.fromValue(planaryConfiguration);
  System.out.println("String_Node_Str" + e_planaryConfiguration);
  TiffField<?> f_sampleFormat=ifd.getField(TiffTag.SAMPLE_FORMAT.getValue());
  TiffField<?> f_sampleMaxValue=ifd.getField(TiffTag.S_MAX_SAMPLE_VALUE.getValue());
  TiffField<?> f_sampleMinValue=ifd.getField(TiffTag.S_MIN_SAMPLE_VALUE.getValue());
  boolean floatSample=false;
  boolean isAssociatedAlpha=false;
  if (f_sampleFormat != null && f_sampleFormat.getDataAsLong()[0] == 3) {
    floatSample=true;
    double maxValue=(bitsPerSample <= 32) ? Float.MAX_VALUE : Double.MAX_VALUE;
    double minValue=(bitsPerSample <= 32) ? Float.MIN_VALUE : Double.MIN_VALUE;
    if (bitsPerSample <= 32 && f_sampleMaxValue != null) {
      maxValue=((float[])f_sampleMaxValue.getData())[0];
    }
 else     if (bitsPerSample > 32 && f_sampleMaxValue != null) {
      maxValue=((double[])f_sampleMaxValue.getData())[0];
    }
    if (bitsPerSample <= 32 && f_sampleMinValue != null) {
      minValue=((float[])f_sampleMinValue.getData())[0];
    }
 else     if (bitsPerSample > 32 && f_sampleMinValue != null) {
      minValue=((double[])f_sampleMinValue.getData())[0];
    }
    System.out.println("String_Node_Str" + maxValue);
    System.out.println("String_Node_Str" + minValue);
  }
  int tilesAcross=(imageWidth + tileWidth - 1) / tileWidth;
  int tilesDown=(imageHeight + tileLength - 1) / tileLength;
  int tilesPerImage=tilesAcross * tilesDown;
  ImageDecoder decoder=null;
  byte[] pixels=null;
  int bytes2Read=((tileWidth * bitsPerSample + 7) / 8) * samplesPerPixel * tileLength;
  int xoff=0;
  int yoff=0;
  int tileCounter=0;
  WritableRaster raster=null;
  DataBuffer db=null;
  ColorModel cm=null;
switch (e_photoMetric) {
case PALETTE_COLOR:
    short[] colorMap=(short[])ifd.getField(TiffTag.COLORMAP.getValue()).getData();
  rgbColorPalette=new int[colorMap.length / 3];
int numOfColors=(1 << bitsPerSample);
int numOfColors2=(numOfColors << 1);
for (int i=0, index=0; i < colorMap.length / 3; i++) {
rgbColorPalette[index++]=0xff000000 | ((colorMap[i] & 0xff00) << 8) | ((colorMap[i + numOfColors] & 0xff00))| ((colorMap[i + numOfColors2] & 0xff00) >> 8);
}
int bytesPerScanLine=tilesAcross * (tileWidth * bitsPerSample + 7) / 8;
pixels=new byte[bytesPerScanLine * tilesDown * tileLength];
short[] spixels=null;
db=new DataBufferByte(pixels,pixels.length);
cm=new IndexColorModel(bitsPerSample,rgbColorPalette.length,rgbColorPalette,0,false,-1,DataBuffer.TYPE_BYTE);
if (bitsPerSample < 8) {
raster=Raster.createPackedRaster(db,tileWidth * tilesAcross,tileLength * tilesDown,bitsPerSample,null);
}
 else {
int[] off={0};
if (bitsPerSample > 8) {
spixels=new short[pixels.length / 2];
db=new DataBufferUShort(spixels,spixels.length);
cm=new IndexColorModel(bitsPerSample,rgbColorPalette.length,rgbColorPalette,0,false,-1,DataBuffer.TYPE_USHORT);
}
raster=Raster.createInterleavedRaster(db,tileWidth * tilesAcross,tileLength * tilesDown,tileWidth * tilesAcross,1,off,null);
}
switch (compression) {
case NONE:
for (int i=0; i < tileByteCounts.length; i++) {
byte[] temp=new byte[tileByteCounts[i]];
randIS.seek(tileOffsets[i]);
randIS.readFully(temp);
if (bitsPerSample == 16) {
raster.setDataElements(xoff,yoff,tileWidth,tileLength,ArrayUtils.toShortArray(temp,endian == IOUtils.BIG_ENDIAN));
}
 else {
DataBuffer tileDataBuffer=new DataBufferByte(temp,temp.length);
WritableRaster tileRaster=Raster.createPackedRaster(tileDataBuffer,tileWidth,tileLength,bitsPerSample,null);
raster.setDataElements(xoff,yoff,tileRaster);
}
xoff+=tileWidth;
tileCounter++;
if (tileCounter >= tilesAcross) {
xoff=0;
yoff+=tileLength;
tileCounter=0;
}
}
break;
case LZW:
decoder=new LZWTreeDecoder(8,true);
break;
case DEFLATE:
case DEFLATE_ADOBE:
decoder=new DeflateDecoder();
break;
default :
}
if (decoder != null) {
for (int i=0; i < tileByteCounts.length; i++) {
byte[] temp=new byte[tileByteCounts[i]];
byte[] temp2=new byte[bytes2Read];
randIS.seek(tileOffsets[i]);
randIS.readFully(temp);
decoder.setInput(temp);
decoder.decode(temp2,0,bytes2Read);
if (bitsPerSample == 16) {
raster.setDataElements(xoff,yoff,tileWidth,tileLength,ArrayUtils.toShortArray(temp2,endian == IOUtils.BIG_ENDIAN));
}
 else raster.setDataElements(xoff,yoff,tileWidth,tileLength,temp2);
xoff+=tileWidth;
tileCounter++;
if (tileCounter >= tilesAcross) {
xoff=0;
yoff+=tileLength;
tileCounter=0;
}
}
}
return new BufferedImage(cm,raster,false,null).getSubimage(0,0,imageWidth,imageHeight);
case RGB:
int[] bandoff=new int[samplesPerPixel];
int[] nBits=new int[samplesPerPixel];
Arrays.fill(nBits,bitsPerSample);
for (int i=0; i < samplesPerPixel; i++) {
bandoff[i]=i;
}
boolean transparent=false;
int trans=Transparency.OPAQUE;
if (samplesPerPixel >= 4) {
trans=Transparency.TRANSLUCENT;
transparent=true;
}
if (floatSample) {
if (bitsPerSample == 64) {
cm=new ComponentColorModel(ColorSpace.getInstance(ColorSpace.CS_sRGB),nBits,transparent,false,trans,DataBuffer.TYPE_DOUBLE);
}
 else if (bitsPerSample >= 16 && bitsPerSample <= 32) {
cm=new ComponentColorModel(ColorSpace.getInstance(ColorSpace.CS_sRGB),nBits,transparent,false,trans,DataBuffer.TYPE_FLOAT);
}
}
 else {
if (bitsPerSample < 8) {
cm=new DirectColorModel(bitsPerSample * samplesPerPixel,redMask[bitsPerSample],greenMask[bitsPerSample],blueMask[bitsPerSample]);
}
 else if (bitsPerSample == 16) {
cm=new ComponentColorModel(ColorSpace.getInstance(ColorSpace.CS_sRGB),nBits,transparent,isAssociatedAlpha,trans,DataBuffer.TYPE_USHORT);
}
 else if (bitsPerSample == 24) {
cm=new ComponentColorModel(ColorSpace.getInstance(ColorSpace.CS_sRGB),nBits,transparent,isAssociatedAlpha,trans,DataBuffer.TYPE_INT);
}
 else if (bitsPerSample == 32) {
cm=new Int32ComponentColorModel(ColorSpace.getInstance(ColorSpace.CS_sRGB),transparent);
}
 else if (bitsPerSample == 64) {
cm=new Int32ComponentColorModel(ColorSpace.getInstance(ColorSpace.CS_sRGB),transparent);
}
 else cm=new ComponentColorModel(ColorSpace.getInstance(ColorSpace.CS_sRGB),nBits,transparent,isAssociatedAlpha,trans,DataBuffer.TYPE_BYTE);
}
raster=cm.createCompatibleWritableRaster(tileWidth * tilesAcross,tileLength * tilesDown);
switch (compression) {
case NONE:
if (planaryConfiguration == 1) {
for (int i=0; i < tileByteCounts.length; i++) {
byte[] temp=new byte[tileByteCounts[i]];
randIS.seek(tileOffsets[i]);
randIS.readFully(temp);
if (floatSample) {
Object tempArray=null;
if (bitsPerSample == 64) tempArray=ArrayUtils.toDoubleArray(temp,endian == IOUtils.BIG_ENDIAN);
 else if (bitsPerSample == 32) {
tempArray=ArrayUtils.toFloatArray(temp,endian == IOUtils.BIG_ENDIAN);
}
 else if (bitsPerSample == 24) {
tempArray=ArrayUtils.to24BitFloatArray(temp,endian == IOUtils.BIG_ENDIAN);
}
 else if (bitsPerSample == 16) tempArray=ArrayUtils.to16BitFloatArray(temp,endian == IOUtils.BIG_ENDIAN);
 else throw new UnsupportedOperationException("String_Node_Str" + bitsPerSample);
raster.setDataElements(xoff,yoff,tileWidth,tileLength,tempArray);
}
 else {
if (bitsPerSample < 8) {
raster.setDataElements(xoff,yoff,tileWidth,tileLength,ArrayUtils.toNBits(bitsPerSample * samplesPerPixel,temp,tileWidth,true));
}
 else if (bitsPerSample == 8) {
raster.setDataElements(xoff,yoff,tileWidth,tileLength,temp);
}
 else if (bitsPerSample % 8 == 0) {
Object tempArray=ArrayUtils.toNBits(bitsPerSample,temp,samplesPerPixel * tileWidth,endian == IOUtils.BIG_ENDIAN);
raster.setDataElements(xoff,yoff,tileWidth,tileLength,tempArray);
}
 else {
Object tempArray=ArrayUtils.toNBits(bitsPerSample,temp,samplesPerPixel * tileWidth,true);
raster.setDataElements(xoff,yoff,tileWidth,tileLength,tempArray);
}
}
xoff+=tileWidth;
tileCounter++;
if (tileCounter >= tilesAcross) {
xoff=0;
yoff+=tileLength;
tileCounter=0;
}
}
}
 else {
byte[][] rgb=new byte[samplesPerPixel][];
Raster tileRaster=null;
DataBuffer tileDatabuffer=null;
int[] bankIndices={0,1,2};
bandoff=new int[]{0,0,0};
int dataBufferType=DataBuffer.TYPE_BYTE;
for (int i=0; i < tilesPerImage; i++) {
rgb[0]=new byte[tileByteCounts[i]];
randIS.seek(tileOffsets[i]);
randIS.readFully(rgb[0]);
int greenOff=i + tilesPerImage;
rgb[1]=new byte[tileByteCounts[greenOff]];
randIS.seek(tileOffsets[greenOff]);
randIS.readFully(rgb[1]);
int blueOff=greenOff + tilesPerImage;
rgb[2]=new byte[tileByteCounts[blueOff]];
randIS.seek(tileOffsets[blueOff]);
randIS.readFully(rgb[2]);
if (floatSample) {
if (bitsPerSample >= 16 && bitsPerSample <= 32) {
float[][] floats=new float[samplesPerPixel][];
if (bitsPerSample == 16) {
for (int j=0; j < samplesPerPixel; j++) floats[j]=ArrayUtils.to16BitFloatArray(rgb[j],endian == IOUtils.BIG_ENDIAN);
}
 else if (bitsPerSample == 24) {
for (int j=0; j < samplesPerPixel; j++) floats[j]=ArrayUtils.to24BitFloatArray(rgb[j],endian == IOUtils.BIG_ENDIAN);
}
 else if (bitsPerSample == 32) {
for (int j=0; j < samplesPerPixel; j++) floats[j]=ArrayUtils.toFloatArray(rgb[j],endian == IOUtils.BIG_ENDIAN);
}
tileDatabuffer=new DataBufferFloat(floats,floats[0].length);
dataBufferType=DataBuffer.TYPE_FLOAT;
}
 else if (bitsPerSample == 64) {
double[][] doubles=new double[samplesPerPixel][];
for (int j=0; j < samplesPerPixel; j++) doubles[j]=ArrayUtils.toDoubleArray(rgb[j],endian == IOUtils.BIG_ENDIAN);
tileDatabuffer=new DataBufferDouble(doubles,doubles[0].length);
dataBufferType=DataBuffer.TYPE_DOUBLE;
}
 else {
throw new UnsupportedOperationException("String_Node_Str" + bitsPerSample);
}
SampleModel sampleModel=new BandedSampleModel(dataBufferType,tileWidth,tileLength,tileWidth,bankIndices,bandoff);
tileRaster=Raster.createWritableRaster(sampleModel,tileDatabuffer,null);
}
 else {
if (bitsPerSample == 16) {
tileDatabuffer=new DataBufferUShort(new short[][]{ArrayUtils.toShortArray(rgb[0],endian == IOUtils.BIG_ENDIAN),ArrayUtils.toShortArray(rgb[1],endian == IOUtils.BIG_ENDIAN),ArrayUtils.toShortArray(rgb[2],endian == IOUtils.BIG_ENDIAN)},tileWidth * tileLength);
}
 else if (bitsPerSample > 16 && bitsPerSample <= 32) {
tileDatabuffer=new DataBufferInt(new int[][]{(int[])(ArrayUtils.toNBits(bitsPerSample,rgb[0],tileWidth,endian == IOUtils.BIG_ENDIAN)),(int[])(ArrayUtils.toNBits(bitsPerSample,rgb[1],tileWidth,endian == IOUtils.BIG_ENDIAN)),(int[])(ArrayUtils.toNBits(bitsPerSample,rgb[2],tileWidth,endian == IOUtils.BIG_ENDIAN))},tileWidth * tileLength);
}
 else if (bitsPerSample == 64) {
tileDatabuffer=new DataBufferInt(new int[][]{ArrayUtils.to32BitsLongArray(rgb[0],endian == IOUtils.BIG_ENDIAN),ArrayUtils.to32BitsLongArray(rgb[1],endian == IOUtils.BIG_ENDIAN),ArrayUtils.to32BitsLongArray(rgb[2],endian == IOUtils.BIG_ENDIAN)},tileWidth * tileLength);
}
 else {
tileDatabuffer=new DataBufferByte(rgb,rgb[0].length);
}
tileRaster=Raster.createBandedRaster(tileDatabuffer,tileWidth,tileLength,tileWidth,bankIndices,bandoff,null);
}
raster.setRect(xoff,yoff,tileRaster);
xoff+=tileWidth;
tileCounter++;
if (tileCounter >= tilesAcross) {
xoff=0;
yoff+=tileLength;
tileCounter=0;
}
}
}
break;
case PACKBITS:
for (int i=0; i < tileByteCounts.length; i++) {
byte[] temp=new byte[tileByteCounts[i]];
randIS.seek(tileOffsets[i]);
randIS.readFully(temp);
byte[] temp2=new byte[bytes2Read];
Packbits.unpackbits(temp,temp2);
if (bitsPerSample == 16) {
raster.setDataElements(xoff,yoff,tileWidth,tileLength,ArrayUtils.toShortArray(temp2,endian == IOUtils.BIG_ENDIAN));
}
 else raster.setDataElements(xoff,yoff,tileWidth,tileLength,temp2);
xoff+=tileWidth;
tileCounter++;
if (tileCounter >= tilesAcross) {
xoff=0;
yoff+=tileLength;
tileCounter=0;
}
}
break;
case LZW:
decoder=new LZWTreeDecoder(8,true);
break;
case DEFLATE:
case DEFLATE_ADOBE:
decoder=new DeflateDecoder();
break;
default :
}
if (decoder != null) {
for (int i=0; i < tileByteCounts.length; i++) {
byte[] temp=new byte[tileByteCounts[i]];
byte[] temp2=new byte[bytes2Read];
randIS.seek(tileOffsets[i]);
randIS.readFully(temp);
decoder.setInput(temp);
decoder.decode(temp2,0,bytes2Read);
if (bitsPerSample == 16) {
raster.setDataElements(xoff,yoff,tileWidth,tileLength,ArrayUtils.toShortArray(temp2,endian == IOUtils.BIG_ENDIAN));
}
 else raster.setDataElements(xoff,yoff,tileWidth,tileLength,temp2);
xoff+=tileWidth;
tileCounter++;
if (tileCounter >= tilesAcross) {
xoff=0;
yoff+=tileLength;
tileCounter=0;
}
}
}
if (predictor == 2 && planaryConfiguration == 1 && bitsPerPixel == 8) pixels=applyDePredictor(samplesPerPixel,pixels,imageWidth,imageHeight);
return new BufferedImage(cm,raster,false,null).getSubimage(0,0,imageWidth,imageHeight);
default :
break;
}
return null;
}

Fixed version (ground truth):
private BufferedImage decodeTiledTiff(IFD ifd) throws Exception {
  TiffField<?> field=ifd.getField(TiffTag.COMPRESSION.getValue());
  short[] data=(short[])field.getData();
  TiffFieldEnum.Compression compression=TiffFieldEnum.Compression.fromValue(data[0] & 0xffff);
  System.out.println("String_Node_Str" + compression.getDescription());
  TiffField<?> f_tileOffsets=ifd.getField(TiffTag.TILE_OFFSETS.getValue());
  if (f_tileOffsets == null)   f_tileOffsets=ifd.getField(TiffTag.STRIP_OFFSETS.getValue());
  TiffField<?> f_tileByteCounts=ifd.getField(TiffTag.TILE_BYTE_COUNTS.getValue());
  if (f_tileByteCounts == null)   f_tileByteCounts=ifd.getField(TiffTag.STRIP_BYTE_COUNTS.getValue());
  int[] tileOffsets=f_tileOffsets.getDataAsLong();
  int[] tileByteCounts=f_tileByteCounts.getDataAsLong();
  int imageWidth=ifd.getField(TiffTag.IMAGE_WIDTH.getValue()).getDataAsLong()[0];
  int imageHeight=ifd.getField(TiffTag.IMAGE_LENGTH.getValue()).getDataAsLong()[0];
  System.out.println("String_Node_Str" + imageWidth);
  System.out.println("String_Node_Str" + imageHeight);
  TiffField<?> f_tileWidth=ifd.getField(TiffTag.TILE_WIDTH.getValue());
  TiffField<?> f_tileLength=ifd.getField(TiffTag.TILE_LENGTH.getValue());
  int tileWidth=imageWidth;
  if (f_tileWidth != null)   tileWidth=f_tileWidth.getDataAsLong()[0];
  int tileLength=imageHeight;
  if (f_tileLength != null)   tileLength=f_tileLength.getDataAsLong()[0];
  TiffField<?> f_photoMetric=ifd.getField(TiffTag.PHOTOMETRIC_INTERPRETATION.getValue());
  int photoMetric=f_photoMetric.getDataAsLong()[0];
  TiffFieldEnum.PhotoMetric e_photoMetric=TiffFieldEnum.PhotoMetric.fromValue(photoMetric);
  System.out.println("String_Node_Str" + e_photoMetric);
  TiffField<?> f_bitsPerSample=ifd.getField(TiffTag.BITS_PER_SAMPLE.getValue());
  int bitsPerSample=f_bitsPerSample.getDataAsLong()[0];
  System.out.println("String_Node_Str" + bitsPerSample);
  TiffField<?> f_samplesPerPixel=ifd.getField(TiffTag.SAMPLES_PER_PIXEL.getValue());
  int samplesPerPixel=f_samplesPerPixel.getDataAsLong()[0];
  System.out.println("String_Node_Str" + samplesPerPixel);
  TiffField<?> f_predictor=ifd.getField(TiffTag.PREDICTOR.getValue());
  int predictor=0;
  if (f_predictor != null) {
    predictor=f_predictor.getDataAsLong()[0];
    System.out.println("String_Node_Str" + predictor);
  }
  TiffField<?> f_planaryConfiguration=ifd.getField(TiffTag.PLANAR_CONFIGURATTION.getValue());
  int planaryConfiguration=1;
  if (f_planaryConfiguration != null)   planaryConfiguration=f_planaryConfiguration.getDataAsLong()[0];
  TiffFieldEnum.PlanarConfiguration e_planaryConfiguration=TiffFieldEnum.PlanarConfiguration.fromValue(planaryConfiguration);
  System.out.println("String_Node_Str" + e_planaryConfiguration);
  TiffField<?> f_sampleFormat=ifd.getField(TiffTag.SAMPLE_FORMAT.getValue());
  TiffField<?> f_sampleMaxValue=ifd.getField(TiffTag.S_MAX_SAMPLE_VALUE.getValue());
  TiffField<?> f_sampleMinValue=ifd.getField(TiffTag.S_MIN_SAMPLE_VALUE.getValue());
  boolean floatSample=false;
  boolean isAssociatedAlpha=false;
  if (f_sampleFormat != null && f_sampleFormat.getDataAsLong()[0] == 3) {
    floatSample=true;
    double maxValue=(bitsPerSample <= 32) ? Float.MAX_VALUE : Double.MAX_VALUE;
    double minValue=(bitsPerSample <= 32) ? Float.MIN_VALUE : Double.MIN_VALUE;
    if (bitsPerSample <= 32 && f_sampleMaxValue != null) {
      maxValue=((float[])f_sampleMaxValue.getData())[0];
    }
 else     if (bitsPerSample > 32 && f_sampleMaxValue != null) {
      maxValue=((double[])f_sampleMaxValue.getData())[0];
    }
    if (bitsPerSample <= 32 && f_sampleMinValue != null) {
      minValue=((float[])f_sampleMinValue.getData())[0];
    }
 else     if (bitsPerSample > 32 && f_sampleMinValue != null) {
      minValue=((double[])f_sampleMinValue.getData())[0];
    }
    System.out.println("String_Node_Str" + maxValue);
    System.out.println("String_Node_Str" + minValue);
  }
  int tilesAcross=(imageWidth + tileWidth - 1) / tileWidth;
  int tilesDown=(imageHeight + tileLength - 1) / tileLength;
  int tilesPerImage=tilesAcross * tilesDown;
  ImageDecoder decoder=null;
  byte[] pixels=null;
  int bytes2Read=((tileWidth * bitsPerSample + 7) / 8) * samplesPerPixel * tileLength;
  int xoff=0;
  int yoff=0;
  int tileCounter=0;
  WritableRaster raster=null;
  DataBuffer db=null;
  ColorModel cm=null;
switch (e_photoMetric) {
case PALETTE_COLOR:
    short[] colorMap=(short[])ifd.getField(TiffTag.COLORMAP.getValue()).getData();
  rgbColorPalette=new int[colorMap.length / 3];
int numOfColors=(1 << bitsPerSample);
int numOfColors2=(numOfColors << 1);
for (int i=0, index=0; i < colorMap.length / 3; i++) {
rgbColorPalette[index++]=0xff000000 | ((colorMap[i] & 0xff00) << 8) | ((colorMap[i + numOfColors] & 0xff00))| ((colorMap[i + numOfColors2] & 0xff00) >> 8);
}
int bytesPerScanLine=tilesAcross * (tileWidth * bitsPerSample + 7) / 8;
pixels=new byte[bytesPerScanLine * tilesDown * tileLength];
short[] spixels=null;
db=new DataBufferByte(pixels,pixels.length);
cm=new IndexColorModel(bitsPerSample,rgbColorPalette.length,rgbColorPalette,0,false,-1,DataBuffer.TYPE_BYTE);
if (bitsPerSample < 8) {
raster=Raster.createPackedRaster(db,tileWidth * tilesAcross,tileLength * tilesDown,bitsPerSample,null);
}
 else {
int[] off={0};
if (bitsPerSample > 8) {
spixels=new short[pixels.length / 2];
db=new DataBufferUShort(spixels,spixels.length);
cm=new IndexColorModel(bitsPerSample,rgbColorPalette.length,rgbColorPalette,0,false,-1,DataBuffer.TYPE_USHORT);
}
raster=Raster.createInterleavedRaster(db,tileWidth * tilesAcross,tileLength * tilesDown,tileWidth * tilesAcross,1,off,null);
}
switch (compression) {
case NONE:
for (int i=0; i < tileByteCounts.length; i++) {
byte[] temp=new byte[tileByteCounts[i]];
randIS.seek(tileOffsets[i]);
randIS.readFully(temp);
if (bitsPerSample == 16) {
raster.setDataElements(xoff,yoff,tileWidth,tileLength,ArrayUtils.toShortArray(temp,endian == IOUtils.BIG_ENDIAN));
}
 else {
DataBuffer tileDataBuffer=new DataBufferByte(temp,temp.length);
WritableRaster tileRaster=Raster.createPackedRaster(tileDataBuffer,tileWidth,tileLength,bitsPerSample,null);
raster.setDataElements(xoff,yoff,tileRaster);
}
xoff+=tileWidth;
tileCounter++;
if (tileCounter >= tilesAcross) {
xoff=0;
yoff+=tileLength;
tileCounter=0;
}
}
break;
case LZW:
decoder=new LZWTreeDecoder(8,true);
break;
case DEFLATE:
case DEFLATE_ADOBE:
decoder=new DeflateDecoder();
break;
default :
}
if (decoder != null) {
for (int i=0; i < tileByteCounts.length; i++) {
byte[] temp=new byte[tileByteCounts[i]];
byte[] temp2=new byte[bytes2Read];
randIS.seek(tileOffsets[i]);
randIS.readFully(temp);
decoder.setInput(temp);
decoder.decode(temp2,0,bytes2Read);
if (bitsPerSample == 16) {
raster.setDataElements(xoff,yoff,tileWidth,tileLength,ArrayUtils.toShortArray(temp2,endian == IOUtils.BIG_ENDIAN));
}
 else raster.setDataElements(xoff,yoff,tileWidth,tileLength,temp2);
xoff+=tileWidth;
tileCounter++;
if (tileCounter >= tilesAcross) {
xoff=0;
yoff+=tileLength;
tileCounter=0;
}
}
}
return new BufferedImage(cm,raster,false,null).getSubimage(0,0,imageWidth,imageHeight);
case RGB:
int[] bandoff=new int[samplesPerPixel];
int[] nBits=new int[samplesPerPixel];
Arrays.fill(nBits,bitsPerSample);
for (int i=0; i < samplesPerPixel; i++) {
bandoff[i]=i;
}
boolean transparent=false;
int trans=Transparency.OPAQUE;
if (samplesPerPixel >= 4) {
trans=Transparency.TRANSLUCENT;
transparent=true;
}
if (floatSample) {
if (bitsPerSample == 64) {
cm=new ComponentColorModel(ColorSpace.getInstance(ColorSpace.CS_sRGB),nBits,transparent,false,trans,DataBuffer.TYPE_DOUBLE);
}
 else if (bitsPerSample >= 16 && bitsPerSample <= 32) {
cm=new ComponentColorModel(ColorSpace.getInstance(ColorSpace.CS_sRGB),nBits,transparent,false,trans,DataBuffer.TYPE_FLOAT);
}
}
 else {
if (bitsPerSample < 8) {
cm=new DirectColorModel(bitsPerSample * samplesPerPixel,redMask[bitsPerSample],greenMask[bitsPerSample],blueMask[bitsPerSample]);
}
 else if (bitsPerSample == 16) {
cm=new ComponentColorModel(ColorSpace.getInstance(ColorSpace.CS_sRGB),nBits,transparent,isAssociatedAlpha,trans,DataBuffer.TYPE_USHORT);
}
 else if (bitsPerSample == 24) {
cm=new ComponentColorModel(ColorSpace.getInstance(ColorSpace.CS_sRGB),nBits,transparent,isAssociatedAlpha,trans,DataBuffer.TYPE_INT);
}
 else if (bitsPerSample == 32) {
cm=new Int32ComponentColorModel(ColorSpace.getInstance(ColorSpace.CS_sRGB),transparent);
}
 else if (bitsPerSample == 64) {
cm=new Int32ComponentColorModel(ColorSpace.getInstance(ColorSpace.CS_sRGB),transparent);
}
 else cm=new ComponentColorModel(ColorSpace.getInstance(ColorSpace.CS_sRGB),nBits,transparent,isAssociatedAlpha,trans,DataBuffer.TYPE_BYTE);
}
raster=cm.createCompatibleWritableRaster(tileWidth * tilesAcross,tileLength * tilesDown);
switch (compression) {
case NONE:
if (planaryConfiguration == 1) {
for (int i=0; i < tileByteCounts.length; i++) {
byte[] temp=new byte[tileByteCounts[i]];
randIS.seek(tileOffsets[i]);
randIS.readFully(temp);
if (floatSample) {
Object tempArray=null;
if (bitsPerSample == 64) tempArray=ArrayUtils.toDoubleArray(temp,endian == IOUtils.BIG_ENDIAN);
 else if (bitsPerSample == 32) {
tempArray=ArrayUtils.toFloatArray(temp,endian == IOUtils.BIG_ENDIAN);
}
 else if (bitsPerSample == 24) {
tempArray=ArrayUtils.to24BitFloatArray(temp,endian == IOUtils.BIG_ENDIAN);
}
 else if (bitsPerSample == 16) tempArray=ArrayUtils.to16BitFloatArray(temp,endian == IOUtils.BIG_ENDIAN);
 else throw new UnsupportedOperationException("String_Node_Str" + bitsPerSample);
raster.setDataElements(xoff,yoff,tileWidth,tileLength,tempArray);
}
 else {
if (bitsPerSample < 8) {
raster.setDataElements(xoff,yoff,tileWidth,tileLength,ArrayUtils.toNBits(bitsPerSample * samplesPerPixel,temp,tileWidth,true));
}
 else if (bitsPerSample == 8) {
raster.setDataElements(xoff,yoff,tileWidth,tileLength,temp);
}
 else if (bitsPerSample % 8 == 0) {
Object tempArray=ArrayUtils.toNBits(bitsPerSample,temp,samplesPerPixel * tileWidth,endian == IOUtils.BIG_ENDIAN);
raster.setDataElements(xoff,yoff,tileWidth,tileLength,tempArray);
}
 else {
Object tempArray=ArrayUtils.toNBits(bitsPerSample,temp,samplesPerPixel * tileWidth,true);
raster.setDataElements(xoff,yoff,tileWidth,tileLength,tempArray);
}
}
xoff+=tileWidth;
tileCounter++;
if (tileCounter >= tilesAcross) {
xoff=0;
yoff+=tileLength;
tileCounter=0;
}
}
}
 else {
byte[][] rgb=new byte[samplesPerPixel][];
Raster tileRaster=null;
DataBuffer tileDatabuffer=null;
int[] bankIndices={0,1,2};
bandoff=new int[]{0,0,0};
int dataBufferType=DataBuffer.TYPE_BYTE;
for (int i=0; i < tilesPerImage; i++) {
rgb[0]=new byte[tileByteCounts[i]];
randIS.seek(tileOffsets[i]);
randIS.readFully(rgb[0]);
int greenOff=i + tilesPerImage;
rgb[1]=new byte[tileByteCounts[greenOff]];
randIS.seek(tileOffsets[greenOff]);
randIS.readFully(rgb[1]);
int blueOff=greenOff + tilesPerImage;
rgb[2]=new byte[tileByteCounts[blueOff]];
randIS.seek(tileOffsets[blueOff]);
randIS.readFully(rgb[2]);
if (floatSample) {
if (bitsPerSample >= 16 && bitsPerSample <= 32) {
float[][] floats=new float[samplesPerPixel][];
if (bitsPerSample == 16) {
for (int j=0; j < samplesPerPixel; j++) floats[j]=ArrayUtils.to16BitFloatArray(rgb[j],endian == IOUtils.BIG_ENDIAN);
}
 else if (bitsPerSample == 24) {
for (int j=0; j < samplesPerPixel; j++) floats[j]=ArrayUtils.to24BitFloatArray(rgb[j],endian == IOUtils.BIG_ENDIAN);
}
 else if (bitsPerSample == 32) {
for (int j=0; j < samplesPerPixel; j++) floats[j]=ArrayUtils.toFloatArray(rgb[j],endian == IOUtils.BIG_ENDIAN);
}
tileDatabuffer=new DataBufferFloat(floats,floats[0].length);
dataBufferType=DataBuffer.TYPE_FLOAT;
}
 else if (bitsPerSample == 64) {
double[][] doubles=new double[samplesPerPixel][];
for (int j=0; j < samplesPerPixel; j++) doubles[j]=ArrayUtils.toDoubleArray(rgb[j],endian == IOUtils.BIG_ENDIAN);
tileDatabuffer=new DataBufferDouble(doubles,doubles[0].length);
dataBufferType=DataBuffer.TYPE_DOUBLE;
}
 else {
throw new UnsupportedOperationException("String_Node_Str" + bitsPerSample);
}
SampleModel sampleModel=new BandedSampleModel(dataBufferType,tileWidth,tileLength,tileWidth,bankIndices,bandoff);
tileRaster=Raster.createWritableRaster(sampleModel,tileDatabuffer,null);
}
 else {
if (bitsPerSample == 16) {
tileDatabuffer=new DataBufferUShort(new short[][]{ArrayUtils.toShortArray(rgb[0],endian == IOUtils.BIG_ENDIAN),ArrayUtils.toShortArray(rgb[1],endian == IOUtils.BIG_ENDIAN),ArrayUtils.toShortArray(rgb[2],endian == IOUtils.BIG_ENDIAN)},tileWidth * tileLength);
}
 else if (bitsPerSample > 16 && bitsPerSample <= 32) {
boolean bigEndian=(bitsPerSample % 8 == 0) ? endian == IOUtils.BIG_ENDIAN : true;
tileDatabuffer=new DataBufferInt(new int[][]{(int[])(ArrayUtils.toNBits(bitsPerSample,rgb[0],tileWidth,bigEndian)),(int[])(ArrayUtils.toNBits(bitsPerSample,rgb[1],tileWidth,bigEndian)),(int[])(ArrayUtils.toNBits(bitsPerSample,rgb[2],tileWidth,bigEndian))},tileWidth * tileLength);
}
 else if (bitsPerSample == 64) {
tileDatabuffer=new DataBufferInt(new int[][]{ArrayUtils.to32BitsLongArray(rgb[0],endian == IOUtils.BIG_ENDIAN),ArrayUtils.to32BitsLongArray(rgb[1],endian == IOUtils.BIG_ENDIAN),ArrayUtils.to32BitsLongArray(rgb[2],endian == IOUtils.BIG_ENDIAN)},tileWidth * tileLength);
}
 else {
tileDatabuffer=new DataBufferByte(rgb,rgb[0].length);
}
tileRaster=Raster.createBandedRaster(tileDatabuffer,tileWidth,tileLength,tileWidth,bankIndices,bandoff,null);
}
raster.setRect(xoff,yoff,tileRaster);
xoff+=tileWidth;
tileCounter++;
if (tileCounter >= tilesAcross) {
xoff=0;
yoff+=tileLength;
tileCounter=0;
}
}
}
break;
case PACKBITS:
for (int i=0; i < tileByteCounts.length; i++) {
byte[] temp=new byte[tileByteCounts[i]];
randIS.seek(tileOffsets[i]);
randIS.readFully(temp);
byte[] temp2=new byte[bytes2Read];
Packbits.unpackbits(temp,temp2);
if (bitsPerSample == 16) {
raster.setDataElements(xoff,yoff,tileWidth,tileLength,ArrayUtils.toShortArray(temp2,endian == IOUtils.BIG_ENDIAN));
}
 else raster.setDataElements(xoff,yoff,tileWidth,tileLength,temp2);
xoff+=tileWidth;
tileCounter++;
if (tileCounter >= tilesAcross) {
xoff=0;
yoff+=tileLength;
tileCounter=0;
}
}
break;
case LZW:
decoder=new LZWTreeDecoder(8,true);
break;
case DEFLATE:
case DEFLATE_ADOBE:
decoder=new DeflateDecoder();
break;
default :
}
if (decoder != null) {
for (int i=0; i < tileByteCounts.length; i++) {
byte[] temp=new byte[tileByteCounts[i]];
byte[] temp2=new byte[bytes2Read];
randIS.seek(tileOffsets[i]);
randIS.readFully(temp);
decoder.setInput(temp);
decoder.decode(temp2,0,bytes2Read);
if (bitsPerSample == 16) {
raster.setDataElements(xoff,yoff,tileWidth,tileLength,ArrayUtils.toShortArray(temp2,endian == IOUtils.BIG_ENDIAN));
}
 else raster.setDataElements(xoff,yoff,tileWidth,tileLength,temp2);
xoff+=tileWidth;
tileCounter++;
if (tileCounter >= tilesAcross) {
xoff=0;
yoff+=tileLength;
tileCounter=0;
}
}
}
if (predictor == 2 && planaryConfiguration == 1 && bitsPerPixel == 8) pixels=applyDePredictor(samplesPerPixel,pixels,imageWidth,imageHeight);
return new BufferedImage(cm,raster,false,null).getSubimage(0,0,imageWidth,imageHeight);
default :
break;
}
return null;
}