- More info

- Show multiplane frames
- More error proof
This commit is contained in:
Wim Pomp
2021-06-17 18:22:54 +02:00
parent b91190ffd5
commit 68aca10cb7
3 changed files with 74 additions and 52 deletions

View File

@@ -6,7 +6,7 @@ with open("README.md", "r") as fh:
setuptools.setup(
name="tiffexplore",
packages=["tiffexplore"],
version="2021.06.0",
version="2021.06.1",
author="Wim Pomp",
author_email="wimpomp@gmail.com",
description="Explore a tiff structure.",

View File

@@ -33,11 +33,13 @@ class UiMainWindow(object):
self.middlecolumn = QtWidgets.QVBoxLayout(self.middlecolumnWidget)
self.middlecolumn.setContentsMargins(0, 0, 0, 0)
self.properties = QtWidgets.QTextEdit(self.centralwidget)
self.properties.setReadOnly(True)
self.middlecolumn.addWidget(self.properties)
self.rightcolumnWidget = QtWidgets.QWidget()
self.rightcolumn = QtWidgets.QVBoxLayout(self.rightcolumnWidget)
self.rightcolumn.setContentsMargins(0, 0, 0, 0)
self.binary = QtWidgets.QTextEdit(self.rightcolumnWidget)
self.binary.setReadOnly(True)
self.rightcolumn.addWidget(self.binary)
self.image = QtWidgets.QLabel(self.rightcolumnWidget)
self.image.setMinimumWidth(200)
@@ -165,24 +167,27 @@ class Bar(PaintBox):
text.append('')
text.append(f'Adresses: {addr[0]} - {sum(addr)}')
text.append(f'Length: {addr[1]}')
text.append('')
if key[0].lower() == 'header':
text.append(f'File size: {len(self.tiff)}')
text.append(f'\nFile size: {len(self.tiff)}')
text.append(f'Byte order: {self.tiff.byteorder}')
text.append(f'Big tiff: {self.tiff.bigtiff}')
text.append(f'Tag size: {self.tiff.tagsize}')
text.append(f'Tag number format: {self.tiff.tagnoformat}')
text.append(f'Offset size: {self.tiff.offsetsize}')
text.append(f'Offset format: {self.tiff.offsetformat}')
text.append(f'First ifd offset: {self.tiff.offset}')
text.append(f'First ifd offset: {self.tiff.offsets[0]}')
if key[0].lower() == 'ifd':
text.extend([f'{k}: {v}' for k, v in self.tiff.tags[key[1]].items()])
if key[1] < self.tiff.nifds-1:
text.append(f'Next ifd offset: {self.tiff.addresses[("ifd", key[1] + 1)][0]}')
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:
text.append(f'Next ifd offset: {self.tiff.offsets[key[1] + 1]}')
if key[0].lower() == 'tagdata':
text.append(f'{key[2]}: {self.tiff.tags[key[1]][key[2]]}')
text.append('\n' + self.tiff.fmt_tag(key[2], self.tiff.tags[key[1]][key[2]]))
if key[0].lower() == 'image':
self.parent.setImage(key[1], key[2])
im = self.tiff.asarray(key[1], key[2])
text.append(f'\nStrip size: {im.shape}')
text.append(f'Data type: {im.dtype}')
self.parent.setImage(im)
else:
self.parent.setImage()
self.parent.properties.setText('\n'.join(text))
@@ -204,9 +209,9 @@ class App(QtWidgets.QMainWindow, UiMainWindow):
def setImage(self, *args):
if len(args):
im = self.tiff.asarray(*args)
im = args[0]
if im.ndim == 3:
im = im[0]
im = im.transpose(2, 0, 1).reshape((im.shape[0]*im.shape[2], im.shape[1]))
if im.max() - im.min() > 0:
im = (255 * ((im - im.min()) / (im.max() - im.min()))).astype('uint8')
shape = im.shape

View File

@@ -1,6 +1,7 @@
import struct
import tifffile
import numpy as np
from traceback import format_exc
class tiff():
@@ -11,16 +12,31 @@ class tiff():
self.tags = []
self.get_file_len()
self.addresses = assignments(len(self))
nifd = self.read_header()
i = 0
while nifd:
nifd = self.read_ifd(nifd, i)
i += 1
self.nifds = i
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 = []
self.nTags = []
try:
self.offsets = [self.read_header()]
i = 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
except Exception:
print(format_exc())
@staticmethod
def fmt_tag(code, value):
text = [f'Code: {code}']
if code in tifffile.TIFF.TAGS:
text[-1] += f'; {tifffile.TIFF.TAGS[code]}'
text.append(f'data format: {value[0]}; {tifffile.TIFF.DATA_FORMATS.get(value[0])}')
text.append(f'address: {value[1]}')
text.append(f'count: {value[2]}')
text.append(f'value: {value[3]}')
return '\n'.join(text)
def get_file_len(self):
self.fh.seek(0, 2)
@@ -58,49 +74,50 @@ class tiff():
"""
self.fh.seek(offset)
nTags = struct.unpack(self.byteorder + self.tagnoformat, self.fh.read(struct.calcsize(self.tagnoformat)))[0]
# print('Found {} tags'.format(nTags))
self.nTags.append(nTags)
self.tags.append({})
assert nTags < 4096, 'Too many tags'
length = 8 if self.bigtiff else 2
length += nTags * self.tagsize + self.offsetsize
tags = {}
for i in range(nTags):
pos = offset + struct.calcsize(self.tagnoformat) + self.tagsize * i
self.fh.seek(pos)
code, ttype, caddr, dtypelen, count, value = 0, 0, 0, 0, 0, [0]
try:
self.fh.seek(offset + struct.calcsize(self.tagnoformat) + self.tagsize * i)
code, ttype = struct.unpack(self.byteorder + 'HH', self.fh.read(4))
count = struct.unpack(self.byteorder + self.offsetformat, self.fh.read(self.offsetsize))[0]
dtype = tifffile.TIFF.DATA_FORMATS[ttype]
dtypelen = struct.calcsize(dtype)
code, ttype = struct.unpack(self.byteorder + 'HH', self.fh.read(4))
count = struct.unpack(self.byteorder + self.offsetformat, self.fh.read(self.offsetsize))[0]
dtype = tifffile.TIFF.DATA_FORMATS[ttype]
dtypelen = struct.calcsize(dtype)
toolong = struct.calcsize(dtype) * count > self.offsetsize
if toolong:
caddr = struct.unpack(self.byteorder + self.offsetformat, self.fh.read(self.offsetsize))[0]
self.addresses[('tagdata', idx, code)] = (caddr, dtypelen * count)
cp = self.fh.tell()
self.fh.seek(caddr)
else:
caddr = self.fh.tell()
toolong = struct.calcsize(dtype) * count > self.offsetsize
if toolong:
caddr = struct.unpack(self.byteorder + self.offsetformat, self.fh.read(self.offsetsize))[0]
self.addresses[('tagdata', idx, code)] = (caddr, dtypelen * count)
cp = self.fh.tell()
self.fh.seek(caddr)
else:
caddr = self.fh.tell()
if ttype == 1:
value = self.fh.read(count)
elif ttype == 2:
value = self.fh.read(count).decode('ascii').rstrip('\x00')
elif ttype == 5:
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)]
if ttype == 1:
value = self.fh.read(count)
elif ttype == 2:
value = self.fh.read(count).decode('ascii').rstrip('\x00')
elif ttype == 5:
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)]
if toolong:
self.fh.seek(cp)
if toolong:
self.fh.seek(cp)
except Exception:
print(format_exc())
self.tags[-1][code] = (ttype, caddr, dtypelen*count, value)
tags[code] = (ttype, caddr, dtypelen*count, value)
nifd = struct.unpack(self.byteorder + self.tagnoformat, self.fh.read(struct.calcsize(self.tagnoformat)))[0]
self.fh.seek(offset)
self.fh.seek(offset + struct.calcsize(self.tagnoformat) + self.tagsize * nTags)
nifd = struct.unpack(self.byteorder + self.offsetformat, self.fh.read(self.offsetsize))[0]
self.addresses[('ifd', idx)] = (offset, 2 * struct.calcsize(self.tagnoformat) + nTags * self.tagsize)
self.tags.append(tags)
return nifd
def __getitem__(self, item):