int tag = stream.readUnsignedShort();
int type = stream.readUnsignedShort();
int count = (int)stream.readUnsignedInt();
// Get the associated TIFFTag.
TIFFTag tiffTag = getTag(tag, tagSetList);
// Ignore unknown fields.
if(ignoreUnknownFields && tiffTag == null) {
// Skip the value/offset so as to leave the stream
// position at the start of the next IFD entry.
stream.skipBytes(4);
// XXX Warning message ...
// Continue with the next IFD entry.
continue;
}
long nextTagOffset = stream.getStreamPosition() + 4;
int sizeOfType = TIFFTag.getSizeOfType(type);
if (count*sizeOfType > 4) {
long value = stream.readUnsignedInt();
stream.seek(value);
}
if (tag == BaselineTIFFTagSet.TAG_STRIP_BYTE_COUNTS ||
tag == BaselineTIFFTagSet.TAG_TILE_BYTE_COUNTS ||
tag == BaselineTIFFTagSet.TAG_JPEG_INTERCHANGE_FORMAT_LENGTH) {
this.stripOrTileByteCountsPosition =
stream.getStreamPosition();
} else if (tag == BaselineTIFFTagSet.TAG_STRIP_OFFSETS ||
tag == BaselineTIFFTagSet.TAG_TILE_OFFSETS ||
tag == BaselineTIFFTagSet.TAG_JPEG_INTERCHANGE_FORMAT) {
this.stripOrTileOffsetsPosition =
stream.getStreamPosition();
}
Object obj = null;
try {
switch (type) {
case TIFFTag.TIFF_BYTE:
case TIFFTag.TIFF_SBYTE:
case TIFFTag.TIFF_UNDEFINED:
case TIFFTag.TIFF_ASCII:
byte[] bvalues = new byte[count];
stream.readFully(bvalues, 0, count);
if (type == TIFFTag.TIFF_ASCII) {
// Can be multiple strings
Vector v = new Vector();
boolean inString = false;
int prevIndex = 0;
for (int index = 0; index <= count; index++) {
if (index < count && bvalues[index] != 0) {
if (!inString) {
// start of string
prevIndex = index;
inString = true;
}
} else { // null or special case at end of string
if (inString) {
// end of string
String s = new String(bvalues, prevIndex,
index - prevIndex);
v.add(s);
inString = false;
}
}
}
count = v.size();
String[] strings;
if(count != 0) {
strings = new String[count];
for (int c = 0 ; c < count; c++) {
strings[c] = (String)v.elementAt(c);
}
} else {
// This case has been observed when the value of
// 'count' recorded in the field is non-zero but
// the value portion contains all nulls.
count = 1;
strings = new String[] {""};
}
obj = strings;
} else {
obj = bvalues;
}
break;
case TIFFTag.TIFF_SHORT:
char[] cvalues = new char[count];
for (int j = 0; j < count; j++) {
cvalues[j] = (char)(stream.readUnsignedShort());
}
obj = cvalues;
break;
case TIFFTag.TIFF_LONG:
case TIFFTag.TIFF_IFD_POINTER:
long[] lvalues = new long[count];
for (int j = 0; j < count; j++) {
lvalues[j] = stream.readUnsignedInt();
}
obj = lvalues;
break;
case TIFFTag.TIFF_RATIONAL:
long[][] llvalues = new long[count][2];
for (int j = 0; j < count; j++) {
llvalues[j][0] = stream.readUnsignedInt();
llvalues[j][1] = stream.readUnsignedInt();
}
obj = llvalues;
break;
case TIFFTag.TIFF_SSHORT:
short[] svalues = new short[count];
for (int j = 0; j < count; j++) {
svalues[j] = stream.readShort();
}
obj = svalues;
break;
case TIFFTag.TIFF_SLONG:
int[] ivalues = new int[count];
for (int j = 0; j < count; j++) {
ivalues[j] = stream.readInt();
}
obj = ivalues;
break;
case TIFFTag.TIFF_SRATIONAL:
int[][] iivalues = new int[count][2];
for (int j = 0; j < count; j++) {
iivalues[j][0] = stream.readInt();
iivalues[j][1] = stream.readInt();
}
obj = iivalues;
break;
case TIFFTag.TIFF_FLOAT:
float[] fvalues = new float[count];
for (int j = 0; j < count; j++) {
fvalues[j] = stream.readFloat();
}
obj = fvalues;
break;
case TIFFTag.TIFF_DOUBLE:
double[] dvalues = new double[count];
for (int j = 0; j < count; j++) {
dvalues[j] = stream.readDouble();
}
obj = dvalues;
break;
default:
// XXX Warning
break;
}
} catch(EOFException eofe) {
// The TIFF 6.0 fields have tag numbers less than or equal
// to 532 (ReferenceBlackWhite) or equal to 33432 (Copyright).
// If there is an error reading a baseline tag, then re-throw
// the exception and fail; otherwise continue with the next
// field.
if(BaselineTIFFTagSet.getInstance().getTag(tag) == null) {
throw eofe;
}
}
if (tiffTag == null) {
// XXX Warning: unknown tag
} else if (!tiffTag.isDataTypeOK(type)) {
// XXX Warning: bad data type
} else if (tiffTag.isIFDPointer() && obj != null) {
stream.mark();
stream.seek(((long[])obj)[0]);
List tagSets = new ArrayList(1);
tagSets.add(tiffTag.getTagSet());
TIFFIFD subIFD = new TIFFIFD(tagSets);
// XXX Use same ignore policy for sub-IFD fields?
subIFD.initialize(stream, ignoreUnknownFields);
obj = subIFD;
stream.reset();
}
if (tiffTag == null) {
tiffTag = new TIFFTag(null, tag, 1 << type, null);
}
// Add the field if its contents have been initialized which
// will not be the case if an EOF was ignored above.
if(obj != null) {