📄 tiffdecoder.java
字号:
for (int i=0; i<nEntries; i++) {
tag = getShort();
fieldType = getShort();
count = getInt();
value = getValue(fieldType, count);
if (debugMode && ifdCount<10) dumpTag(tag, count, value, fi);
//ij.IJ.write(i+"/"+nEntries+" "+tag + ", count=" + count + ", value=" + value);
//if (tag==0) return null;
switch (tag) {
case IMAGE_WIDTH:
fi.width = value;
break;
case IMAGE_LENGTH:
fi.height = value;
break;
case STRIP_OFFSETS:
if (count==1)
fi.stripOffsets = new int[] {value};
else {
int saveLoc = in.getFilePointer();
in.seek(value);
fi.stripOffsets = new int[count];
for (int c=0; c<count; c++) {
fi.stripOffsets[c] = getInt();
if (c > 0 && fi.stripOffsets[c] < fi.stripOffsets[c - 1] && fi.stripOffsets[c]!=0)
error("Strip offsets are not in order");
}
in.seek(saveLoc);
}
fi.offset = count > 0 ? fi.stripOffsets[0] : value;
break;
case STRIP_BYTE_COUNT:
if (count==1)
fi.stripLengths = new int[] {value};
else {
int saveLoc = in.getFilePointer();
in.seek(value);
fi.stripLengths = new int[count];
for (int c=0; c<count; c++)
fi.stripLengths[c] = getInt();
in.seek(saveLoc);
}
break;
case PHOTO_INTERP:
fi.whiteIsZero = value==0;
break;
case BITS_PER_SAMPLE:
if (count==1) {
if (value==8)
fi.fileType = FileInfo.GRAY8;
else if (value==16) {
fi.fileType = FileInfo.GRAY16_UNSIGNED;
fi.intelByteOrder = littleEndian;
} else if (value==32) {
fi.fileType = FileInfo.GRAY32_INT;
fi.intelByteOrder = littleEndian;
} else if (value==12) {
fi.fileType = FileInfo.GRAY12_UNSIGNED;
fi.intelByteOrder = littleEndian;
} else if (value==1)
fi.fileType = FileInfo.BITMAP;
else
error("Unsupported BitsPerSample: " + value);
} else if (count==3) {
int saveLoc = in.getFilePointer();
in.seek(value);
int bitDepth = getShort();
if (!(bitDepth==8||bitDepth==16))
error("ImageJ can only open 8 and 16 bit/channel RGB images ("+bitDepth+")");
if (bitDepth==16) {
fi.intelByteOrder = littleEndian;
fi.fileType = FileInfo.RGB48;
}
in.seek(saveLoc);
}
break;
case SAMPLES_PER_PIXEL:
if (value==3 && fi.fileType!=FileInfo.RGB48)
fi.fileType = FileInfo.RGB;
else if (!(value==1||value==3)) {
String msg = "Unsupported SamplesPerPixel: " + value;
if (value==4)
msg += " \n \n" + "ImageJ cannot open CMYK and RGB+alpha TIFFs";
error(msg);
}
break;
case X_RESOLUTION:
double xScale = getRational(value);
if (xScale!=0.0) fi.pixelWidth = 1.0/xScale;
break;
case Y_RESOLUTION:
double yScale = getRational(value);
if (yScale!=0.0) fi.pixelHeight = 1.0/yScale;
break;
case RESOLUTION_UNIT:
if (value==1&&fi.unit==null)
fi.unit = " ";
else if (value==2) {
if (fi.pixelWidth==1.0/72.0) {
fi.pixelWidth = 1.0;
fi.pixelHeight = 1.0;
} else
fi.unit = "inch";
} else if (value==3)
fi.unit = "cm";
break;
case PLANAR_CONFIGURATION:
if (value==2 && fi.fileType==FileInfo.RGB48)
fi.fileType = FileInfo.RGB48_PLANAR;
if (value==2 && fi.fileType==FileInfo.RGB)
fi.fileType = FileInfo.RGB_PLANAR;
break;
case COMPRESSION:
if (value==5) { // LZW compression is handled
int bpp = fi.getBytesPerPixel();
if (bpp==6)
error("ImageJ cannot open 48-bit LZW compressed TIFFs");
fi.compression = FileInfo.LZW;
} else if (value!=1 && value!=7) {
// don't abort with Spot camera compressed (7) thumbnails
// otherwise, this is an unknown compression type
fi.compression = FileInfo.COMPRESSION_UNKNOWN;
error("ImageJ cannot open TIFF files " +
"compressed in this fashion ("+value+")");
}
break;
case PREDICTOR:
if (value==2 && fi.compression==FileInfo.LZW)
fi.compression = FileInfo.LZW_WITH_DIFFERENCING;
break;
case COLOR_MAP:
if (count==768 && fi.fileType==FileInfo.GRAY8)
getColorMap(value, fi);
break;
case SAMPLE_FORMAT:
if (fi.fileType==FileInfo.GRAY32_INT && value==FLOATING_POINT)
fi.fileType = FileInfo.GRAY32_FLOAT;
if (fi.fileType==FileInfo.GRAY16_UNSIGNED && value==SIGNED)
fi.fileType = FileInfo.GRAY16_SIGNED;
break;
case IMAGE_DESCRIPTION:
if (ifdCount==1) {
byte[] s = getString(count,value);
if (s!=null) saveImageDescription(s,fi);
}
break;
case METAMORPH1: case METAMORPH2:
if (name.indexOf(".STK")>0 || name.indexOf(".stk")>0) {
if (tag==METAMORPH2)
fi.nImages=count;
else
fi.nImages=9999;
}
break;
case IPLAB:
fi.nImages=value;
break;
case NIH_IMAGE_HDR:
if (count==256)
decodeNIHImageHeader(value, fi);
break;
case META_DATA_BYTE_COUNTS:
int saveLoc = in.getFilePointer();
in.seek(value);
metaDataCounts = new int[count];
for (int c=0; c<count; c++)
metaDataCounts[c] = getInt();
in.seek(saveLoc);
break;
case META_DATA:
getMetaData(value, fi);
break;
default:
if (tag>10000 && tag<32768 && ifdCount>1)
return null;
}
}
fi.fileFormat = FileInfo.TIFF;
fi.fileName = name;
fi.directory = directory;
if (url!=null)
fi.url = url;
return fi;
}
void getMetaData(int loc, FileInfo fi) throws IOException {
if (metaDataCounts==null || metaDataCounts.length==0)
return;
int maxTypes = 10;
int saveLoc = in.getFilePointer();
in.seek(loc);
int n = metaDataCounts.length;
int hdrSize = metaDataCounts[0];
if (hdrSize<12 || hdrSize>804)
{in.seek(saveLoc); return;}
int magicNumber = getInt();
if (magicNumber!=0x494a494a) // "IJIJ"
{in.seek(saveLoc); return;}
int nTypes = (hdrSize-4)/8;
int[] types = new int[nTypes];
int[] counts = new int[nTypes];
int extraMetaDataEntries = 0;
for (int i=0; i<nTypes; i++) {
types[i] = getInt();
counts[i] = getInt();
if (types[i]<0xffffff)
extraMetaDataEntries += counts[i];
}
fi.metaDataTypes = new int[extraMetaDataEntries];
fi.metaData = new byte[extraMetaDataEntries][];
int start = 1;
int eMDindex = 0;
for (int i=0; i<nTypes; i++) {
if (types[i]==0x696e666f) // "info"
getInfoProperty(start, start+counts[i]-1, fi);
else if (types[i]==0x6c61626c) // "labl"
getSliceLabels(start, start+counts[i]-1, fi);
else if (types[i]<0xffffff) {
for (int j=start; j<start+counts[i]; j++) {
int len = metaDataCounts[j];
fi.metaData[eMDindex] = new byte[len];
in.readFully(fi.metaData[eMDindex], len);
fi.metaDataTypes[eMDindex] = types[i];
eMDindex++;
}
}
start += counts[i];
}
in.seek(saveLoc);
}
void getInfoProperty(int first, int last, FileInfo fi) throws IOException {
int len = metaDataCounts[first];
byte[] buffer = new byte[len];
in.readFully(buffer, len);
len /= 2;
char[] chars = new char[len];
for (int j=0, k=0; j<len; j++)
chars[j] = (char)((buffer[k++]<<8) + buffer[k++]);
fi.info = new String(chars);
}
void getSliceLabels(int first, int last, FileInfo fi) throws IOException {
fi.sliceLabels = new String[last-first+1];
int index = 0;
byte[] buffer = new byte[metaDataCounts[first]];
for (int i=first; i<=last; i++) {
int len = metaDataCounts[i];
if (len>buffer.length)
buffer = new byte[len];
in.readFully(buffer, len);
len /= 2;
char[] chars = new char[len];
for (int j=0, k=0; j<len; j++)
chars[j] = (char)((buffer[k++]<<8) + buffer[k++]);
fi.sliceLabels[index++] = new String(chars);
//ij.IJ.log(i+" "+fi.sliceLabels[i-1]+" "+len);
}
}
void error(String message) throws IOException {
if (in!=null) in.close();
throw new IOException(message);
}
public void enableDebugging() {
debugMode = true;
}
public FileInfo[] getTiffInfo() throws IOException {
int ifdOffset;
Vector info;
if (in==null)
in = new RandomAccessStream(new RandomAccessFile(directory + name, "r"));
info = new Vector();
ifdOffset = OpenImageFileHeader();
if (ifdOffset<0) {
in.close();
return null;
}
if (debugMode) dInfo = "\n " + name + ": opening\n";
while (ifdOffset>0) {
in.seek(ifdOffset);
FileInfo fi = OpenIFD();
if (fi!=null) {
info.addElement(fi);
ifdOffset = getInt();
} else
ifdOffset = 0;
if (debugMode && ifdCount<10) dInfo += " nextIFD=" + ifdOffset + "\n";
if (fi!=null) {
if (fi.nImages>1) // ignore extra IFDs in ImageJ and NIH Image stacks
ifdOffset = 0;
}
}
if (info.size()==0) {
in.close();
return null;
} else {
FileInfo[] fi = new FileInfo[info.size()];
info.copyInto((Object[])fi);
if (debugMode) fi[0].debugInfo = dInfo;
if (url!=null) {
in.seek(0);
fi[0].inputStream = in;
} else
in.close();
return fi;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -