Manual merge of #223

This commit is contained in:
Harald Kuhr 2016-04-21 15:30:20 +02:00
commit f382f4b5f9
3 changed files with 44 additions and 38 deletions

View File

@ -71,7 +71,7 @@ public final class EXIFReader extends MetadataReader {
else if (bom[0] == 'M' && bom[1] == 'M') { else if (bom[0] == 'M' && bom[1] == 'M') {
input.setByteOrder(ByteOrder.BIG_ENDIAN); input.setByteOrder(ByteOrder.BIG_ENDIAN);
} }
else { else {
throw new IIOException(String.format("Invalid TIFF byte order mark '%s', expected: 'II' or 'MM'", StringUtil.decode(bom, 0, bom.length, "ASCII"))); throw new IIOException(String.format("Invalid TIFF byte order mark '%s', expected: 'II' or 'MM'", StringUtil.decode(bom, 0, bom.length, "ASCII")));
} }
@ -79,7 +79,7 @@ public final class EXIFReader extends MetadataReader {
// http://www.awaresystems.be/imaging/tiff/bigtiff.html // http://www.awaresystems.be/imaging/tiff/bigtiff.html
int magic = input.readUnsignedShort(); int magic = input.readUnsignedShort();
if (magic != TIFF.TIFF_MAGIC) { if (magic != TIFF.TIFF_MAGIC) {
throw new IIOException(String.format("Wrong TIFF magic in EXIF data: %04x, expected: %04x", magic, TIFF.TIFF_MAGIC)); throw new IIOException(String.format("Wrong TIFF magic in EXIF data: %04x, expected: %04x", magic, TIFF.TIFF_MAGIC));
} }
long directoryOffset = input.readUnsignedInt(); long directoryOffset = input.readUnsignedInt();
@ -105,16 +105,16 @@ public final class EXIFReader extends MetadataReader {
} }
for (int i = 0; i < entryCount; i++) { for (int i = 0; i < entryCount; i++) {
EXIFEntry entry = readEntry(pInput); try {
EXIFEntry entry = readEntry(pInput);
if (entry == null) { if (entry != null) {
// System.err.println("Expected: " + entryCount + " values, found only " + i); entries.add(entry);
// TODO: Log warning? }
nextOffset = 0; }
catch (IIOException e) {
break; break;
} }
entries.add(entry);
} }
if (readLinked) { if (readLinked) {
@ -144,7 +144,7 @@ public final class EXIFReader extends MetadataReader {
); );
ifds.add(0, new IFD(entries)); ifds.add(0, new IFD(entries));
return new EXIFDirectory(ifds); return new EXIFDirectory(ifds);
} }
@ -176,7 +176,7 @@ public final class EXIFReader extends MetadataReader {
// Replace the entry with parsed data // Replace the entry with parsed data
entries.set(i, new EXIFEntry(tagId, subIFDs.get(0), entry.getType())); entries.set(i, new EXIFEntry(tagId, subIFDs.get(0), entry.getType()));
} }
else { else {
// Replace the entry with parsed data // Replace the entry with parsed data
entries.set(i, new EXIFEntry(tagId, subIFDs.toArray(new IFD[subIFDs.size()]), entry.getType())); entries.set(i, new EXIFEntry(tagId, subIFDs.toArray(new IFD[subIFDs.size()]), entry.getType()));
} }
@ -213,7 +213,9 @@ public final class EXIFReader extends MetadataReader {
offsets = (long[]) value; offsets = (long[]) value;
} }
else { else {
throw new IIOException(String.format("Unknown pointer type: %s", (value != null ? value.getClass() : null))); throw new IIOException(String.format("Unknown pointer type: %s", (value != null
? value.getClass()
: null)));
} }
return offsets; return offsets;
@ -224,11 +226,6 @@ public final class EXIFReader extends MetadataReader {
int tagId = pInput.readUnsignedShort(); int tagId = pInput.readUnsignedShort();
short type = pInput.readShort(); short type = pInput.readShort();
// This isn't really an entry, and the directory entry count was wrong OR bad data...
if (tagId == 0 && type == 0) {
return null;
}
int count = pInput.readInt(); // Number of values int count = pInput.readInt(); // Number of values
// It's probably a spec violation to have count 0, but we'll be lenient about it // It's probably a spec violation to have count 0, but we'll be lenient about it
@ -237,32 +234,33 @@ public final class EXIFReader extends MetadataReader {
} }
if (type <= 0 || type > 13) { if (type <= 0 || type > 13) {
pInput.skipBytes(4); // read Value
// Invalid tag, this is just for debugging // Invalid tag, this is just for debugging
long offset = pInput.getStreamPosition() - 8l; long offset = pInput.getStreamPosition() - 12l;
if (DEBUG) { if (DEBUG) {
System.err.printf("Bad EXIF data @%08x\n", pInput.getStreamPosition()); System.err.printf("Bad EXIF data @%08x\n", pInput.getStreamPosition());
System.err.println("tagId: " + tagId + (tagId <= 0 ? " (INVALID)" : "")); System.err.println("tagId: " + tagId + (tagId <= 0 ? " (INVALID)" : ""));
System.err.println("type: " + type + " (INVALID)"); System.err.println("type: " + type + " (INVALID)");
System.err.println("count: " + count); System.err.println("count: " + count);
}
pInput.mark(); pInput.mark();
pInput.seek(offset); pInput.seek(offset);
try { try {
byte[] bytes = new byte[8 + Math.min(120, Math.max(24, count))]; byte[] bytes = new byte[8 + Math.min(120, Math.max(24, count))];
int len = pInput.read(bytes); int len = pInput.read(bytes);
if (DEBUG) { if (DEBUG) {
System.err.print(HexDump.dump(offset, bytes, 0, len)); System.err.print(HexDump.dump(offset, bytes, 0, len));
System.err.println(len < count ? "[...]" : ""); System.err.println(len < count ? "[...]" : "");
}
}
finally {
pInput.reset();
} }
} }
finally {
pInput.reset();
}
return null; return null;
} }
@ -510,7 +508,8 @@ public final class EXIFReader extends MetadataReader {
////////////////////// //////////////////////
// TODO: Stream based hex dump util? // TODO: Stream based hex dump util?
public static class HexDump { public static class HexDump {
private HexDump() {} private HexDump() {
}
private static final int WIDTH = 32; private static final int WIDTH = 32;
@ -524,7 +523,7 @@ public final class EXIFReader extends MetadataReader {
int i; int i;
for (i = 0; i < len; i++) { for (i = 0; i < len; i++) {
if (i % WIDTH == 0) { if (i % WIDTH == 0) {
if (i > 0 ) { if (i > 0) {
builder.append("\n"); builder.append("\n");
} }
builder.append(String.format("%08x: ", i + off + offset)); builder.append(String.format("%08x: ", i + off + offset));

View File

@ -279,10 +279,17 @@ public class EXIFReaderTest extends MetadataReaderAbstractTest {
@Test @Test
public void testReadExifWithMissingEOFMarker() throws IOException { public void testReadExifWithMissingEOFMarker() throws IOException {
ImageInputStream stream = ImageIO.createImageInputStream(getResource("/exif/noeof.tif")); try (ImageInputStream stream = ImageIO.createImageInputStream(getResource("/exif/noeof.tif"))) {
CompoundDirectory directory = (CompoundDirectory) createReader().read(stream); CompoundDirectory directory = (CompoundDirectory) createReader().read(stream);
assertEquals(15, directory.size()); assertEquals(15, directory.size());
assertEquals(1, directory.directoryCount()); assertEquals(1, directory.directoryCount());
stream.close(); }
}
public void testReadExifWithEmptyTag() throws IOException {
try (ImageInputStream stream = ImageIO.createImageInputStream(getResource("/exif/emptyexiftag.tif"))) {
CompoundDirectory directory = (CompoundDirectory) createReader().read(stream);
assertEquals(3, directory.directoryCount());
}
} }
} }