Skip to content

Commit

Permalink
Always store offset to next IFD
Browse files Browse the repository at this point in the history
  • Loading branch information
jabriffa committed Jun 19, 2018
1 parent 2bec8f2 commit 0428dd6
Showing 1 changed file with 12 additions and 21 deletions.
33 changes: 12 additions & 21 deletions pyshared/jbtiff.py
Original file line number Diff line number Diff line change
Expand Up @@ -544,17 +544,14 @@ def __init__(self, fid):
return

# determine written length of TIFF directory, including end alignment
def get_directory_length(self, IFD, isleaf=False):
# length for count and sequence of entries
length = 2 + len(IFD)*12
# length for offset at end
if not isleaf:
length += 4
def get_directory_length(self, IFD):
# length for count, sequence of entries, and offset to next IFD
length = 2 + len(IFD)*12 + 4
# length of data for IFD entries
for i, (tag, (field_type, value_count, values, value_offset)) in enumerate(sorted(IFD.iteritems())):
# if this was a subdirectory, recurse
if isinstance(values, dict):
length += self.get_directory_length(values, True)
length += self.get_directory_length(values)
else:
# check count
assert value_count == len(values)
Expand Down Expand Up @@ -593,25 +590,22 @@ def write_cr2_header(self, fid, free_ptr):
return free_ptr+8, free_ptr+4

# write TIFF directory, starting at given offset
def write_directory(self, IFD, fid, ifd_offset, isleaf=False):
def write_directory(self, IFD, fid, ifd_offset):
# write number of IFD entries
fid.seek(ifd_offset)
entry_count = len(IFD)
tiff_file.write_word(entry_count, fid, 2, False, self.little_endian)
# update pointer to offset and to next free space
if isleaf:
free_ptr = tiff_file.align(ifd_offset + 2 + entry_count*12)
else:
offset_ptr = ifd_offset + 2 + entry_count*12
free_ptr = tiff_file.align(offset_ptr + 4)
offset_ptr = ifd_offset + 2 + entry_count*12
free_ptr = tiff_file.align(offset_ptr + 4)
# write any subdirectories present
for tag in [34665, 34853, 37500, 40965]: # EXIF, GPS, MakerNote, Interoperability
if tag in IFD:
# read original entry details (values contains subdirecttory)
field_type, value_count, values, value_offset = IFD[tag]
# write subdirectory at next available space
value_offset = free_ptr
free_ptr = self.write_directory(values, fid, value_offset, True)
sub_offset_ptr, free_ptr = self.write_directory(values, fid, value_offset)
# update entries for this subdirectory, based on field type, to write later
if field_type == 4:
IFD[tag] = (field_type, value_count, [value_offset], None)
Expand Down Expand Up @@ -682,10 +676,7 @@ def write_directory(self, IFD, fid, ifd_offset, isleaf=False):
for value in values:
tiff_file.write_float(value, fid, 8, self.little_endian)
# return updated pointers
if isleaf:
return free_ptr
else:
return offset_ptr, free_ptr
return offset_ptr, free_ptr

# write data to stream
def write(self, fid):
Expand Down Expand Up @@ -794,7 +785,7 @@ def get_memorymap_directory(IFD, prefix, parent=0):
# if this was a subdirectory, recurse
if isinstance(values, dict):
# add directory to memory map
length = 2+len(values)*12 # must be a leaf
length = 2 + len(values)*12 + 4
mmap += tiff_file.get_memorymap_directory(values, this_item, tag)
else:
# data segment length
Expand All @@ -810,8 +801,8 @@ def get_memorymap(self):
# work through all IFDs
for k, (IFD, ifd_offset, strips) in enumerate(self.data):
this_ifd = "IFD#%d" % k
# add entry for the directory itself (not a leaf)
mmap.append((ifd_offset, 2+len(IFD)*12+4, this_ifd))
# add entry for the directory itself
mmap.append((ifd_offset, 2 + len(IFD)*12 + 4, this_ifd))
# add content of IFD
mmap += tiff_file.get_memorymap_directory(IFD, this_ifd)
# add data strips if present
Expand Down

0 comments on commit 0428dd6

Please sign in to comment.