- Some support for dng:
- Read SubIFDs and tags, TODO: read image data in SubIFD - Read ExifIFDs and tags - Maximize size of blocks in bar - Properly read and print srationals
This commit is contained in:
2
setup.py
2
setup.py
@@ -6,7 +6,7 @@ with open("README.md", "r") as fh:
|
||||
setuptools.setup(
|
||||
name="tiffexplore",
|
||||
packages=["tiffexplore"],
|
||||
version="2021.06.2",
|
||||
version="2021.07.0",
|
||||
author="Wim Pomp",
|
||||
author_email="wimpomp@gmail.com",
|
||||
description="Explore a tiff structure.",
|
||||
|
||||
@@ -131,14 +131,14 @@ class Bar(PaintBox):
|
||||
self.drawText(qp, (0, value[0], 125, value[1]), ('_'.join(('{}',) * len(key))).format(*key).lower())
|
||||
qp.end()
|
||||
|
||||
def get_bar(self):
|
||||
min_size = 10
|
||||
scale = 100
|
||||
def get_bar(self, scale=100, min_size=10, max_size=1000):
|
||||
bar = tiffread.assignments()
|
||||
pos = 0
|
||||
for item in self.tiff.addresses.get_assignments():
|
||||
key, value = item[0]
|
||||
size = value[1] // scale if value[1] // scale >= min_size else min_size
|
||||
size = value[1] // scale
|
||||
if not (min_size <= size <= max_size):
|
||||
size = min_size if size < min_size else max_size
|
||||
if not (key[0].lower() == 'empty' and value[1] == 1):
|
||||
if key[0].lower() == 'empty':
|
||||
bar[('empty', value[0] + value[1] // 2)] = (pos, size)
|
||||
@@ -148,7 +148,6 @@ class Bar(PaintBox):
|
||||
else:
|
||||
bar[key] = (pos, size)
|
||||
pos += size
|
||||
|
||||
bar.max_addr = pos
|
||||
return bar
|
||||
|
||||
@@ -179,18 +178,21 @@ class Bar(PaintBox):
|
||||
if key[0].lower() == 'ifd':
|
||||
text.append(f'Number of tags: {self.tiff.nTags[key[1]]}\n')
|
||||
text.extend([self.tiff.fmt_tag(k, v)+'\n' for k, v in self.tiff.tags[key[1]].items()])
|
||||
if key[1] < len(self.tiff.offsets) - 1:
|
||||
if not isinstance(key[1], str):
|
||||
text.append(f'Next ifd offset: {self.tiff.offsets[key[1] + 1]}')
|
||||
if key[0].lower() == 'tagdata':
|
||||
text.append('\n' + self.tiff.fmt_tag(key[2], self.tiff.tags[key[1]][key[2]]))
|
||||
if key[0].lower() == 'image':
|
||||
im = self.tiff.asarray(key[1], key[2])
|
||||
if im is not None:
|
||||
text.append(f'\nStrip size: {im.shape}')
|
||||
text.append(f'Data type: {im.dtype}')
|
||||
text.append(f'Min, max: {im.min()}, {im.max()}')
|
||||
text.append(f'Mean, std: {im.mean()}, {im.std()}')
|
||||
self.parent.setImage(im)
|
||||
try:
|
||||
im = self.tiff.asarray(key[1], key[2])
|
||||
if im is not None:
|
||||
text.append(f'\nStrip size: {im.shape}')
|
||||
text.append(f'Data type: {im.dtype}')
|
||||
text.append(f'Min, max: {im.min()}, {im.max()}')
|
||||
text.append(f'Mean, std: {im.mean()}, {im.std()}')
|
||||
self.parent.setImage(im)
|
||||
except Exception:
|
||||
pass
|
||||
else:
|
||||
self.parent.setImage()
|
||||
self.parent.properties.setText('\n'.join(text))
|
||||
@@ -227,7 +229,7 @@ class App(QtWidgets.QMainWindow, UiMainWindow):
|
||||
|
||||
def openDialog(self):
|
||||
file, _ = QtWidgets.QFileDialog.getOpenFileName(self,
|
||||
"Open config file", "", "TIFF Files (*.tif *.tiff);;All Files (*)",
|
||||
"Open config file", "", "TIFF Files (*.tif *.tiff);;DNG files (*.dng);;All Files (*)",
|
||||
options=(QtWidgets.QFileDialog.Options() | QtWidgets.QFileDialog.DontUseNativeDialog))
|
||||
self.open(file)
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ import tifffile
|
||||
import numpy as np
|
||||
from traceback import format_exc
|
||||
|
||||
ifdcodes = {330: 'sub', 34665: 'exif', 34853: 'gps', 40965: 'inter'}
|
||||
|
||||
class tiff():
|
||||
def __init__(self, file):
|
||||
@@ -12,24 +13,39 @@ class tiff():
|
||||
self.tiff = tifffile.TiffFile(self.file)
|
||||
except Exception:
|
||||
self.tiff = None
|
||||
self.tags = []
|
||||
self.tags = {}
|
||||
self.get_file_len()
|
||||
self.addresses = assignments(len(self))
|
||||
self.offsets = []
|
||||
self.nTags = []
|
||||
self.nTags = {}
|
||||
self.tagsread = set()
|
||||
try:
|
||||
self.offsets = [self.read_header()]
|
||||
i = 0
|
||||
idx = 0
|
||||
while 0 < self.offsets[-1] < len(self):
|
||||
self.offsets.append(self.read_ifd(self.offsets[-1], i))
|
||||
i += 1
|
||||
for i, tags in enumerate(self.tags):
|
||||
if 273 in tags and 279 in tags:
|
||||
for j, a in enumerate(zip(tags[273][-1], tags[279][-1])):
|
||||
self.addresses[('image', i, j)] = a
|
||||
self.offsets.append(self.read_ifd(self.offsets[-1], idx))
|
||||
idx += 1
|
||||
self.readtags()
|
||||
except Exception:
|
||||
print(format_exc())
|
||||
|
||||
def readtags(self):
|
||||
while len(set(self.tags.keys()) - self.tagsread):
|
||||
for idx in set(self.tags.keys()) - self.tagsread:
|
||||
tags = self.tags[idx]
|
||||
if idx not in self.tagsread:
|
||||
if 273 in tags and 279 in tags:
|
||||
for i, a in enumerate(zip(tags[273][-1], tags[279][-1])):
|
||||
self.addresses[('image', idx, i)] = a
|
||||
for code, id in ifdcodes.items():
|
||||
if code in tags:
|
||||
if len(tags[code][3]) == 1:
|
||||
self.offsets.append(self.read_ifd(tags[code][3][0], f'{id}_{idx}'))
|
||||
else:
|
||||
for i, offset in enumerate(tags[code][3]):
|
||||
self.offsets.append(self.read_ifd(offset, f'{id}_{idx}_{i}'))
|
||||
self.tagsread.add(idx)
|
||||
|
||||
@staticmethod
|
||||
def fmt_tag(code, value):
|
||||
text = [f'Code: {code}']
|
||||
@@ -42,8 +58,8 @@ class tiff():
|
||||
pass
|
||||
text.append(f'address: {value[1]}')
|
||||
text.append(f'count: {value[2]}')
|
||||
if value[0] == 5:
|
||||
text.append(f'value: [{", ".join(["/".join([str(w) for w in v[::-1]]) for v in value[3]])}]')
|
||||
if value[0] in (5, 10):
|
||||
text.append(f'value: [{", ".join(["-" * (sum([w<0 for w in v]) % 2) + "/".join([str(abs(w)) for w in v[::-1]]) for v in value[3]])}]')
|
||||
else:
|
||||
text.append(f'value: {value[3]}')
|
||||
return '\n'.join(text)
|
||||
@@ -85,8 +101,8 @@ class tiff():
|
||||
"""
|
||||
self.fh.seek(offset)
|
||||
nTags = struct.unpack(self.byteorder + self.tagnoformat, self.fh.read(struct.calcsize(self.tagnoformat)))[0]
|
||||
self.nTags.append(nTags)
|
||||
self.tags.append({})
|
||||
self.nTags[idx] = nTags
|
||||
self.tags[idx] = {}
|
||||
assert nTags < 4096, 'Too many tags'
|
||||
|
||||
length = 8 if self.bigtiff else 2
|
||||
@@ -115,7 +131,7 @@ class tiff():
|
||||
value = self.fh.read(count)
|
||||
elif ttype == 2:
|
||||
value = self.fh.read(count).decode('ascii').rstrip('\x00')
|
||||
elif ttype == 5:
|
||||
elif ttype in (5, 10):
|
||||
value = [struct.unpack(self.byteorder + dtype, self.fh.read(dtypelen)) for _ in range(count)]
|
||||
else:
|
||||
value = [struct.unpack(self.byteorder + dtype, self.fh.read(dtypelen))[0] for _ in range(count)]
|
||||
@@ -124,7 +140,7 @@ class tiff():
|
||||
self.fh.seek(cp)
|
||||
except Exception:
|
||||
print(format_exc())
|
||||
self.tags[-1][code] = (ttype, caddr, dtypelen*count, value)
|
||||
self.tags[idx][code] = (ttype, caddr, dtypelen*count, value)
|
||||
|
||||
self.fh.seek(offset + struct.calcsize(self.tagnoformat) + self.tagsize * nTags)
|
||||
nifd = struct.unpack(self.byteorder + self.offsetformat, self.fh.read(self.offsetsize))[0]
|
||||
|
||||
Reference in New Issue
Block a user