Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Possible invalid/missing EXIF IFD end directory link #1921

Closed
4 tasks done
danpetitt opened this issue Jan 3, 2022 · 4 comments
Closed
4 tasks done

Possible invalid/missing EXIF IFD end directory link #1921

danpetitt opened this issue Jan 3, 2022 · 4 comments

Comments

@danpetitt
Copy link

danpetitt commented Jan 3, 2022

Prerequisites

  • I have written a descriptive issue title
  • I have verified that I am running the latest version of ImageSharp
  • I have verified if the problem exist in both DEBUG and RELEASE mode
  • I have searched open and closed issues to ensure it has not already been reported

Description

The IFD does not contain the final 4 byte 0 after the last directory which makes it hard to determine if there are any other linked directories or not.

From the TIFF specification (https://www.itu.int/itudoc/itu-t/com16/tiff-fx/docs/tiff6.pdf):

An Image File Directory (IFD) consists of a 2-byte count of the number of directory entries (i.e., the number of fields), followed by a sequence of 12-byte field entries, followed by a 4-byte offset of the next IFD (or 0 if none). (Do not forget to write the 4 bytes of 0 after the last IFD.)

(the emphasis on the final sentence in brackets is mine).

Steps to Reproduce

using( var image = Image.Load( "metadata.jpg" ) )
{
  var exif = new ExifProfile();
  exif.SetValue<byte[]>( ExifTag.XPAuthor, Encoding.GetEncoding( "UCS-2" ).GetBytes( "Dan Petitt" ) );
  image.Metadata.ExifProfile = exif;

  image.Save( "metadata-with-exif.jpg" );
}

Binary dump of above shows the beginning of the EXIF/TIFF chunk (showing the byte order marker bytes) which is where the data offsets will start from (30:
image

Below shows the first offset (which is always 8 from the start offset):
image

Then we start the 12 byte data chunks for each bit of metadata from offset 38; the first 2 bytes shows the directory count:
image

Next 10 bytes is the component size, count and the last 4 bytes will be the offset where the actual data lives which is 1A or 26 + 30 start offset = 56:
image

Actual data in UCS2 (double-byte) encoding:
image

After the 12 byte chunk we should get a 4 byte marker to next IFD or 4 bytes of 0 to show no more IFDs exist; here we get 2E:
image

But the 4 bytes at offset 2E (46 + 30 = 76) is not the start of a new IFD its 2 byte null and then a 2 byte JPEG marker FFDB for a quantization table:
image

This looks to me to be a bit of a bug; the 4 bytes at offset 50 should be 4 x 0s.

But I may be incorrect; there does seem to be a bit of ambiguity amongst the various specs I have read where in some places the 12 byte chunks + 4 byte next IFD reference is fixed and always applicable (as in the TIFF spec above), and sometimes it seems to imply that perhaps it is only applicable to IF0 IFDs.

Using metadata2go to edit and re-save the metadata, you can see that after the 12 byte chunk it writes out 4 byte 0 for the end of IFD which is what I was expecting:
image

Image saved by ImageSharp:
metadata

Image fixed by metadata2go:
metadata-fixed

System Configuration

  • ImageSharp version: v1.04
  • Other ImageSharp packages and versions:
  • Environment (Operating system, version and so on): Windows 11 Pro
  • .NET Framework version: .NET 6
  • Additional information: Visual Studio 2022
@JimBobSquarePants
Copy link
Member

But I may be incorrect; there does seem to be a bit of ambiguity amongst the various specs I have read where in some places the 12 byte chunks + 4 byte next IFD reference is fixed and always applicable (as in the TIFF spec above), and sometimes it seems to imply that perhaps it is only applicable to IF0 IFDs.

Yeah this seems ambiguous and the expected result, to me, unexpected. IFDs are specific to TIFF files. @IldarKhayrutdinov @brianpopow @dlemstra would any of you be able to confirm?

@danpetitt
Copy link
Author

danpetitt commented Jan 4, 2022

IFDs are specific to TIFF files

Yeah and the EXIF is written as a TIFF chunk if I read things properly; so should adhere to the same layout and specification I think.

@IldarKhayrutdinov
Copy link
Contributor

IldarKhayrutdinov commented Jan 4, 2022

Indeed, at the end of exif are write 2 bytes

According to the Exif specification, next IFD offset size is 4 bytes. PR: #1923

@IldarKhayrutdinov IldarKhayrutdinov mentioned this issue Jan 4, 2022
4 tasks
@JimBobSquarePants
Copy link
Member

@IldarKhayrutdinov Thanks very much for confirming!!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants