Skip to content

Commit

Permalink
Merge pull request #612 from drewnoakes/fix-exif-thumbnail-offset
Browse files Browse the repository at this point in the history
Fix Exif thumbnail offset
  • Loading branch information
drewnoakes authored May 8, 2023
2 parents 8e26c65 + b4a2422 commit 006a6fe
Show file tree
Hide file tree
Showing 11 changed files with 63 additions and 16 deletions.
2 changes: 1 addition & 1 deletion Source/com/drew/imaging/png/PngMetadataReader.java
Original file line number Diff line number Diff line change
Expand Up @@ -330,7 +330,7 @@ private static void processChunk(@NotNull Metadata metadata, @NotNull PngChunk c
metadata.addDirectory(directory);
} else if (chunkType.equals(PngChunkType.eXIf)) {
try {
ExifTiffHandler handler = new ExifTiffHandler(metadata, null);
ExifTiffHandler handler = new ExifTiffHandler(metadata, null, 0);
new TiffReader().processTiff(new ByteArrayReader(bytes), handler, 0);
} catch (TiffProcessingException ex) {
PngDirectory directory = new PngDirectory(PngChunkType.eXIf);
Expand Down
2 changes: 1 addition & 1 deletion Source/com/drew/imaging/tiff/TiffMetadataReader.java
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ public static Metadata readMetadata(@NotNull InputStream inputStream) throws IOE
public static Metadata readMetadata(@NotNull RandomAccessReader reader) throws IOException, TiffProcessingException
{
Metadata metadata = new Metadata();
ExifTiffHandler handler = new ExifTiffHandler(metadata, null);
ExifTiffHandler handler = new ExifTiffHandler(metadata, null, 0);
new TiffReader().processTiff(reader, handler, 0);
return metadata;
}
Expand Down
2 changes: 1 addition & 1 deletion Source/com/drew/metadata/exif/ExifReader.java
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ public void extract(@NotNull final RandomAccessReader reader, @NotNull final Met
/** Reads TIFF formatted Exif data at a specified offset within a {@link RandomAccessReader}. */
public void extract(@NotNull final RandomAccessReader reader, @NotNull final Metadata metadata, int readerOffset, @Nullable Directory parentDirectory)
{
ExifTiffHandler exifTiffHandler = new ExifTiffHandler(metadata, parentDirectory);
ExifTiffHandler exifTiffHandler = new ExifTiffHandler(metadata, parentDirectory, readerOffset);

try {
// Read the TIFF-formatted Exif data
Expand Down
5 changes: 3 additions & 2 deletions Source/com/drew/metadata/exif/ExifThumbnailDescriptor.java
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,8 @@ public String getThumbnailLengthDescription()
@Nullable
public String getThumbnailOffsetDescription()
{
String value = _directory.getString(TAG_THUMBNAIL_OFFSET);
return value == null ? null : value + " bytes";
Integer offset = _directory.getAdjustedThumbnailOffset();

return offset == null ? null : offset.intValue() + " bytes";
}
}
42 changes: 40 additions & 2 deletions Source/com/drew/metadata/exif/ExifThumbnailDirectory.java
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,11 @@
public class ExifThumbnailDirectory extends ExifDirectoryBase
{
/**
* The offset to thumbnail image bytes.
* The offset to thumbnail image bytes, relative to the start of the IFD.
*
* To obtain the offset relative to the start of the TIFF data stream, use
* <code>getAdjustedThumbnailOffset</code>, which includes the value of
* <code>getExifStartOffset</code>.
*/
public static final int TAG_THUMBNAIL_OFFSET = 0x0201;
/**
Expand All @@ -59,8 +63,11 @@ public class ExifThumbnailDirectory extends ExifDirectoryBase
_tagNameMap.put(TAG_THUMBNAIL_LENGTH, "Thumbnail Length");
}

public ExifThumbnailDirectory()
private final int _exifStartOffset;

public ExifThumbnailDirectory(int exifStartOffset)
{
_exifStartOffset = exifStartOffset;
this.setDescriptor(new ExifThumbnailDescriptor(this));
}

Expand All @@ -77,4 +84,35 @@ protected HashMap<Integer, String> getTagNameMap()
{
return _tagNameMap;
}

/**
* Gets the offset at which the Exif data stream commenced within any containing stream.
*/
public int getExifStartOffset()
{
return _exifStartOffset;
}

/**
* Returns the offset to thumbnail data within the outermost data stream.
*
* The value for <code>TagThumbnailOffset</code> is relative to the Exif data stream.
* Generally, consumers of thumbnail data need this value relative to the outermost stream,
* so that the thumbnail data may be extracted from that stream.
*
* This property adds the value of <code>ExifStartOffset</code> to this tag's value in order
* to produce that value.
*
* Returns <code>null</code> when the tag is not defined in this directory.
*/
public Integer getAdjustedThumbnailOffset()
{
Integer offset = this.getInteger(TAG_THUMBNAIL_OFFSET);

if (offset == null) {
return null;
}

return offset.intValue() + _exifStartOffset;
}
}
7 changes: 5 additions & 2 deletions Source/com/drew/metadata/exif/ExifTiffHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,12 @@
*/
public class ExifTiffHandler extends DirectoryTiffHandler
{
public ExifTiffHandler(@NotNull Metadata metadata, @Nullable Directory parentDirectory)
private final int _exifStartOffset;

public ExifTiffHandler(@NotNull Metadata metadata, @Nullable Directory parentDirectory, int exifStartOffset)
{
super(metadata, parentDirectory);
_exifStartOffset = exifStartOffset;
}

public void setTiffMarker(int marker) throws TiffProcessingException
Expand Down Expand Up @@ -149,7 +152,7 @@ public boolean hasFollowerIfd()
if (_currentDirectory.containsTag(ExifDirectoryBase.TAG_PAGE_NUMBER))
pushDirectory(ExifImageDirectory.class);
else
pushDirectory(ExifThumbnailDirectory.class);
pushDirectory(new ExifThumbnailDirectory(_exifStartOffset));
return true;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ public class PhotoshopTiffHandler extends ExifTiffHandler

public PhotoshopTiffHandler(Metadata metadata, Directory parentDirectory)
{
super(metadata, parentDirectory);
super(metadata, parentDirectory, 0);
}

public boolean customProcessTag(final int tagOffset,
Expand Down
11 changes: 8 additions & 3 deletions Source/com/drew/metadata/tiff/DirectoryTiffHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -67,21 +67,26 @@ protected void pushDirectory(@NotNull Class<? extends Directory> directoryClass)
throw new RuntimeException(e);
}

pushDirectory(newDirectory);
}

protected void pushDirectory(@NotNull Directory directory)
{
// If this is the first directory, don't add to the stack
if (_currentDirectory == null) {
// Apply any pending root parent to this new directory
if (_rootParentDirectory != null) {
newDirectory.setParent(_rootParentDirectory);
directory.setParent(_rootParentDirectory);
_rootParentDirectory = null;
}
}
else {
// The current directory is pushed onto the stack, and set as the new directory's parent
_directoryStack.push(_currentDirectory);
newDirectory.setParent(_currentDirectory);
directory.setParent(_currentDirectory);
}

_currentDirectory = newDirectory;
_currentDirectory = directory;
_metadata.addDirectory(_currentDirectory);
}

Expand Down
2 changes: 1 addition & 1 deletion Tests/com/drew/metadata/MetadataTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ public void testOrderOfDifferentTypes()
{
Metadata metadata = new Metadata();
Directory directory1 = new ExifSubIFDDirectory();
Directory directory2 = new ExifThumbnailDirectory();
Directory directory2 = new ExifThumbnailDirectory(0);
Directory directory3 = new ExifIFD0Directory();

metadata.addDirectory(directory1);
Expand Down
2 changes: 1 addition & 1 deletion Tests/com/drew/metadata/exif/ExifDirectoryTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ public void testGetDirectoryName() throws Exception
{
Directory subIFDDirectory = new ExifSubIFDDirectory();
Directory ifd0Directory = new ExifIFD0Directory();
Directory thumbDirectory = new ExifThumbnailDirectory();
Directory thumbDirectory = new ExifThumbnailDirectory(0);
Directory gpsDirectory = new GpsDirectory();

assertFalse(subIFDDirectory.hasErrors());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public class ExifThumbnailDescriptorTest
@Test
public void testGetYCbCrSubsamplingDescription() throws Exception
{
ExifThumbnailDirectory directory = new ExifThumbnailDirectory();
ExifThumbnailDirectory directory = new ExifThumbnailDirectory(0);
directory.setIntArray(TAG_YCBCR_SUBSAMPLING, new int[]{2, 1});

ExifThumbnailDescriptor descriptor = new ExifThumbnailDescriptor(directory);
Expand Down

0 comments on commit 006a6fe

Please sign in to comment.