Browse Source

add ifd builder (for testing), and make sure unknown enums are handled..

when I switched to the included enum, the unknown enum exception switched
from KeyError to ValueError, this now fixes that..
main
John-Mark Gurney 1 year ago
parent
commit
50c35a8a85
1 changed files with 62 additions and 2 deletions
  1. +62
    -2
      ui/medashare/metadata/crw.py

+ 62
- 2
ui/medashare/metadata/crw.py View File

@@ -619,6 +619,7 @@ class IFD(object):
if tag is None:
nextptr.append(res)
break

tag = self.getEnum(tag)
if tag in taghandlers:
res = taghandlers[tag](fh, endian, res, off)
@@ -639,7 +640,7 @@ class IFD(object):
def getEnum(self, key):
try:
return self.__enum(key)
except KeyError:
except ValueError:
return key

def __repr__(self):
@@ -919,6 +920,7 @@ def tiff_srational(endian, data):
return rational_dcomp(tiff_slong(endian, data))

tifftypes = {
# function to decode, length of an element
1: (tiff_bytes, 1),
2: (tiff_ascii, 1),
3: (tiff_short, 2),
@@ -1083,7 +1085,7 @@ def idcrw(fh):

if hlen == 0x2a:
#TIFF/CR2
hoff, idstr, ver, hlen = readstruct(fh, endian + "I2sHI")
hoff, idstr, ver, rawifdoff = readstruct(fh, endian + "I2sHI")
if not isjpeg and (hoff != 0x10 or idstr != b'CR' or ver != 2):
raise ValueError('normal TIFF, not a CR2')
nextoff = [ hoff ]
@@ -1180,6 +1182,64 @@ class _TestCRW(unittest.TestCase):
l.sort()
set(l)

@staticmethod
def ifd_builder(endian, off, entries):
'''Build an IFD. It is assumed to be rooted at off, but
will be returned as a bare string. To locate it properly,
something like:
file = b'\x00' * off + ifd_builder('<', off)

needs to be used. Obviously the prefix above is wrong and will
need to be a proper TIFF header and/or other IFDs.

The data will be added at the end.

entires is a list of tuples:
(tag, type, count, value)

Return value is a tuple of bytes, and offset of nextifd.
'''

entries = list(entries)
cnt = len(entries)

r = []

r.append(struct.pack(endian + 'H', cnt))

# offset + count + ifd entries + nextifd
extra = off + 2 + cnt * 12 + 4
sextra = extra
e = [] # extra values

for tag, _type, count, value in entries:
if len(value) <= 4:
r.append(struct.pack(endian + 'HHI', tag, _type, count) + value + b'\x00' * (4 - len(value)))
else:
r.append(struct.pack(endian + 'HHII', tag, _type, count, extra))
e.append(value)
extra += len(value)

r = b''.join(r)

nextoff = len(r) + off

assert len(r) + 4 == sextra - off

return r + b'\x00' * 4 + b''.join(e), len(r)

def test_unknown(self):
endian = '<'
off = 10

ifd, nextoff = self.ifd_builder(endian, off, [
(65000, 1, 4, b'\x10' * 4),
(65001, 1, 10, b'\x20' * 10)
])
fh = BytesIO(b'\x00' * 10 + ifd)

r = IFD(ExifTag, {}, fh, endian, off)

def test_bogus(self):
# make sure various bogus "files" raise an error



Loading…
Cancel
Save