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

Not writing offset of next IFD #70

Open
CampbellMG opened this issue Sep 10, 2019 · 1 comment
Open

Not writing offset of next IFD #70

CampbellMG opened this issue Sep 10, 2019 · 1 comment

Comments

@CampbellMG
Copy link

What should be happening:

As per the TIFF documentation, each IFD should end with:

OFFSET - Count TYPE - Description
0002h + "NUM"*12 - 1 dword - Offset of next IFD in file, 0 if none follow

The key part here is the 0 if none follow.

What is actually happening:

Piexifjs is not writing this value at all meaning several EXIF parsers (such as PHP's Pel library) will attempt to read the "four bytes over" information as an offset for the next IFD.

To reproduce the issue:

  1. Load, dump and insert EXIF for any image with GPS EXIF
  2. Open the image with PHP's Pel library, in my case I receive the following error:
#0 vendor\lsolesen\pel\src\PelDataWindow.php(424): lsolesen\pel\PelDataWindow->validateOffset(-277)
#1 vendor\lsolesen\pel\src\PelIfd.php(272): lsolesen\pel\PelDataWindow->getLong(-277)
#2 vendor\lsolesen\pel\src\PelIfd.php(285): lsolesen\pel\PelIfd->load(Object(lsolesen\pel\PelDataWindow), 35)
#3 vendor\lsolesen\pel\src\PelIfd.php(221): lsolesen\pel\PelIfd->load(Object(lsolesen\pel\PelDataWindow), 226)
#4 vendor\lsolesen\pel\src\PelTiff.php(159): lsolesen\pel\PelIfd->load(Object(lsolesen\pel\PelDataWindow), 10)
#5 vendor\lsolesen\pel\src\PelExif.php(108): lsolesen\pel\PelTiff->load(Object(lsolesen\pel\PelDataWindow))
#6 vendor\lsolesen\pel\src\PelJpeg.php(216): lsolesen\pel\PelExif->load(Object(lsolesen\pel\PelDataWindow))
#7 vendor\lsolesen\pel\src\PelJpeg.php(286): lsolesen\pel\PelJpeg->load(Object(lsolesen\pel\PelDataWindow))
#8 vendor\lsolesen\pel\src\PelJpeg.php(123): lsolesen\pel\PelJpeg->loadFile('...')

Alternatively, you can compare the raw binary before and after parsing the image with piexifjs and you will notice it strips out the 00 00 00 00 that separates the entries (key, type, length & value) from the overflow values (greater than 4 bytes).

I have implemented a temporary fix with the following:

function _dict_to_bytes(ifd_dict, ifd, ifd_offset) {
        var TIFF_HEADER_LENGTH = 8;
        var tag_count = Object.keys(ifd_dict).length;
        var entry_header = pack(">H", [tag_count]);
        var entries_length;
        if (["0th", "1st"].indexOf(ifd) > -1) {
            entries_length = 2 + tag_count * 12 + 4;
        } else {
            entries_length = 2 + tag_count * 12;
        }
        var entries = "";
        var values = "\x00\x00\x00\x00"; // Updated this line from an empty string
        var key;

However, this adds two trailing zeros after the 0th IFD as the library seems to be including this value only on the first.

I am very new to TIFF and EXIF standards so take all of this with a grain of salt. Is there a more permanent solution to this issue?

@hanoncs
Copy link

hanoncs commented Nov 13, 2020

Thank you so much! I'm shrinking images clientside and needed to clone the EXIF data to the shrunk image, this bug was causing PHP issues and not allowing me to read the GPS data. This fixed my issue, I know its not a perfect solution but thank you so much!

carestad added a commit to kvalitetskontroll/piexifjs that referenced this issue Dec 21, 2020
Implement fix from hMatoba#70 to solve GPS data being lost when using this library.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants