in src/main/java/org/apache/xmlgraphics/image/codec/tiff/TIFFDirectory.java [212:361]
private void initialize(SeekableStream stream) throws IOException {
long nextTagOffset;
int i;
int j;
ifdOffset = stream.getFilePointer();
numEntries = readUnsignedShort(stream);
fields = new TIFFField[numEntries];
for (i = 0; i < numEntries; i++) {
int tag = readUnsignedShort(stream);
int type = readUnsignedShort(stream);
int count = (int)(readUnsignedInt(stream));
int value = 0;
// The place to return to to read the next tag
nextTagOffset = stream.getFilePointer() + 4;
try {
// If the tag data can't fit in 4 bytes, the next 4 bytes
// contain the starting offset of the data
if (count * SIZE_OF_TYPE[type] > 4) {
value = (int)(readUnsignedInt(stream));
stream.seek(value);
}
} catch (ArrayIndexOutOfBoundsException ae) {
// System.err.println(tag + " " + "TIFFDirectory4"); TODO - log this message
// if the data type is unknown we should skip this TIFF Field
stream.seek(nextTagOffset);
continue;
}
fieldIndex.put(tag, i);
Object obj = null;
switch (type) {
case TIFFField.TIFF_BYTE:
case TIFFField.TIFF_SBYTE:
case TIFFField.TIFF_UNDEFINED:
case TIFFField.TIFF_ASCII:
byte[] bvalues = new byte[count];
stream.readFully(bvalues, 0, count);
if (type == TIFFField.TIFF_ASCII) {
// Can be multiple strings
int index = 0;
int prevIndex = 0;
List v = new ArrayList();
while (index < count) {
while ((index < count) && (bvalues[index++] != 0)) {
// NOP
}
// When we encountered zero, means one string has ended
v.add(new String(bvalues, prevIndex,
(index - prevIndex), StandardCharsets.UTF_8));
prevIndex = index;
}
count = v.size();
String[] strings = new String[count];
v.toArray(strings);
obj = strings;
} else {
obj = bvalues;
}
break;
case TIFFField.TIFF_SHORT:
char[] cvalues = new char[count];
for (j = 0; j < count; j++) {
cvalues[j] = (char)(readUnsignedShort(stream));
}
obj = cvalues;
break;
case TIFFField.TIFF_LONG:
long[] lvalues = new long[count];
for (j = 0; j < count; j++) {
lvalues[j] = readUnsignedInt(stream);
}
obj = lvalues;
break;
case TIFFField.TIFF_RATIONAL:
long[][] llvalues = new long[count][2];
for (j = 0; j < count; j++) {
llvalues[j][0] = readUnsignedInt(stream);
llvalues[j][1] = readUnsignedInt(stream);
}
obj = llvalues;
break;
case TIFFField.TIFF_SSHORT:
short[] svalues = new short[count];
for (j = 0; j < count; j++) {
svalues[j] = readShort(stream);
}
obj = svalues;
break;
case TIFFField.TIFF_SLONG:
int[] ivalues = new int[count];
for (j = 0; j < count; j++) {
ivalues[j] = readInt(stream);
}
obj = ivalues;
break;
case TIFFField.TIFF_SRATIONAL:
int[][] iivalues = new int[count][2];
for (j = 0; j < count; j++) {
iivalues[j][0] = readInt(stream);
iivalues[j][1] = readInt(stream);
}
obj = iivalues;
break;
case TIFFField.TIFF_FLOAT:
float[] fvalues = new float[count];
for (j = 0; j < count; j++) {
fvalues[j] = readFloat(stream);
}
obj = fvalues;
break;
case TIFFField.TIFF_DOUBLE:
double[] dvalues = new double[count];
for (j = 0; j < count; j++) {
dvalues[j] = readDouble(stream);
}
obj = dvalues;
break;
default:
throw new RuntimeException(PropertyUtil.getString("TIFFDirectory0"));
}
fields[i] = new TIFFField(tag, type, count, obj);
stream.seek(nextTagOffset);
}
// Read the offset of the next IFD.
nextIFDOffset = readUnsignedInt(stream);
}