Browse Source

fix string to follow the standard, other minor fixes..

fixing strings let me drop some special handlers..

Use BytesIO instead of fileoff so less code to maintain..  Maybe
want to just use bytes instead?
main
John-Mark Gurney 1 year ago
parent
commit
67d44c1e95
1 changed files with 26 additions and 34 deletions
  1. +26
    -34
      ui/medashare/metadata/crw.py

+ 26
- 34
ui/medashare/metadata/crw.py View File

@@ -15,7 +15,7 @@ import struct
# CRW: https://web.archive.org/web/20081230095207/http://xyrion.org/ciff/CIFFspecV1R04.pdf
# CR2: https://web.archive.org/web/20230404015346/http://lclevy.free.fr/cr2/
# JPEG: https://www.w3.org/Graphics/JPEG/itu-t81.pdf
# JFIF: http://www.w3.org/Graphics/JPEG/jfif3.pdf
# JFIF: https://www.w3.org/Graphics/JPEG/jfif3.pdf
# EXIF: https://www.cipa.jp/std/documents/e/DC-X008-Translation-2019-E.pdf
#
# Exif Tags:
@@ -407,11 +407,7 @@ class CanonMakerNote(enum.IntEnum):
PictureStylePC = 0x4009

canonmakernotehandlers = {
CanonMakerNote.FirmwareVersion: lambda fh, endian, res, off:
tuple(res.split(b'\x00', 1)),
CanonMakerNote.Lens: lambda fh, endian, res, off:
res.split(b'\x00', 1)[0],
}
}

# Needed by Exif
class TIFFResolutionUnit(enum.IntEnum):
@@ -892,10 +888,16 @@ def tiff_bytes(endian, data):
return map(ord, data)

def tiff_ascii(endian, data):
if data[-1] != '\x00':
return data # XXX - Canon MakerNote requires this.
#raise ValueError, 'string does not terminate with NUL'
return data[:-1]
if data[-2:] == b'\x00\x00':
# multipl strings
return [ x.decode('ASCII') for x in data[:-2].split(b'\x00') ]

if data[-1] != 0:
#print('d:', repr(data))
#raise ValueError('string does not terminate with NUL')
return data

return data[:-1].decode('ascii')

def tiff_short(endian, data):
return struct.unpack(endian + 'H' * (len(data) // 2), data)
@@ -922,10 +924,15 @@ tifftypes = {
4: (tiff_long, 4),
5: (tiff_rational, 8),

#6: sbyte

# Exif Types
7: (lambda x, y: y, 1), # byte string
#8: sshort
9: (tiff_slong, 4),
10: (tiff_srational, 8),
#11: single float
#12: double float
}

TIFF_IFD_CNT = 'H'
@@ -942,6 +949,7 @@ def tiff_ifd(fh, endian, off):
for i in range(cnt):
tag, ttype, length, valoff = entries[i *
TIFF_IFD_ENTRY_CNT:(i + 1) * TIFF_IFD_ENTRY_CNT]
#print('t:', repr(tag), repr(ttype), repr(length), repr(valoff))
typefun, typequantum = tifftypes[ttype]
blength = length * typequantum
if blength <= 4:
@@ -1021,26 +1029,6 @@ def getendian(val):

return endian

class fileoff:
'''A wrapper around a file object that pretends it
starts at off.
'''

def __init__(self, fh, off):
self.fh = fh
self.off = off

def seek(self, arg, whence=0):
if whence == 0:
arg += self.off
return self.fh.seek(arg, whence)

def read(self, *args):
return self.fh.read(*args)

def tell(self):
return self.th.tell() - self.off

def idcrw(fh):
fh.seek(0)
isjpeg = False
@@ -1059,6 +1047,7 @@ def idcrw(fh):
while True:
fh.seek(pos)
data = fh.read(10)
marklen = int.from_bytes(data[2:4], 'big')
if data == b'':
raise ValueError('unexpected end of file')

@@ -1068,14 +1057,14 @@ def idcrw(fh):

if data[:2] != b'\xff\xe1' or data[4:10] != b'Exif\x00\x00':
# Skip over marker
pos += 2 + int.from_bytes(data[2:4], 'big')
pos += 2 + marklen
continue

# required due to coverage bug
if True: #pragma: no cover
break

fh = fileoff(fh, fh.tell())
fh = BytesIO(fh.read(marklen - 8))
endian = getendian(fh.read(2))
isjpeg = True

@@ -1235,6 +1224,7 @@ class _TestCRW(unittest.TestCase):
self.assertEqual(ci[0][TIFFTag.ExifIFDPointer][ExifTag.ExposureTime][0], Fraction(1, 200))

#print(repr(ci))
#print(repr(ci[0][TIFFTag.ExifIFDPointer][ExifTag.MakerNote][CanonMakerNote.SerialInfo]))

def test_jpegexif(self):
with open(self.fixtures / 'exif.jpeg', 'rb') as fp:
@@ -1242,5 +1232,7 @@ class _TestCRW(unittest.TestCase):

self.assertEqual(ci[0][TIFFTag.ExifIFDPointer][ExifTag.ISOSpeedRatings][0], 100)
self.assertEqual(ci[0][TIFFTag.ExifIFDPointer][ExifTag.UserComment], b'UNICODE\x00' + 'abc123สวัสดี'.encode('utf-16-be'))
self.assertEqual(ci[0][TIFFTag.ExifIFDPointer][ExifTag.LensMake], b'Random Lens Maker\x00')
self.assertEqual(ci[0][TIFFTag.ImageDescription], b'Some comment\x00')
self.assertEqual(ci[0][TIFFTag.ExifIFDPointer][ExifTag.LensMake], 'Random Lens Maker')
self.assertEqual(ci[0][TIFFTag.ImageDescription], 'Some comment')

#print(repr(ci))

Loading…
Cancel
Save