- More info
- Show multiplane frames - More error proof
This commit is contained in:
2
setup.py
2
setup.py
@@ -6,7 +6,7 @@ with open("README.md", "r") as fh:
|
|||||||
setuptools.setup(
|
setuptools.setup(
|
||||||
name="tiffexplore",
|
name="tiffexplore",
|
||||||
packages=["tiffexplore"],
|
packages=["tiffexplore"],
|
||||||
version="2021.06.0",
|
version="2021.06.1",
|
||||||
author="Wim Pomp",
|
author="Wim Pomp",
|
||||||
author_email="wimpomp@gmail.com",
|
author_email="wimpomp@gmail.com",
|
||||||
description="Explore a tiff structure.",
|
description="Explore a tiff structure.",
|
||||||
|
|||||||
@@ -33,11 +33,13 @@ class UiMainWindow(object):
|
|||||||
self.middlecolumn = QtWidgets.QVBoxLayout(self.middlecolumnWidget)
|
self.middlecolumn = QtWidgets.QVBoxLayout(self.middlecolumnWidget)
|
||||||
self.middlecolumn.setContentsMargins(0, 0, 0, 0)
|
self.middlecolumn.setContentsMargins(0, 0, 0, 0)
|
||||||
self.properties = QtWidgets.QTextEdit(self.centralwidget)
|
self.properties = QtWidgets.QTextEdit(self.centralwidget)
|
||||||
|
self.properties.setReadOnly(True)
|
||||||
self.middlecolumn.addWidget(self.properties)
|
self.middlecolumn.addWidget(self.properties)
|
||||||
self.rightcolumnWidget = QtWidgets.QWidget()
|
self.rightcolumnWidget = QtWidgets.QWidget()
|
||||||
self.rightcolumn = QtWidgets.QVBoxLayout(self.rightcolumnWidget)
|
self.rightcolumn = QtWidgets.QVBoxLayout(self.rightcolumnWidget)
|
||||||
self.rightcolumn.setContentsMargins(0, 0, 0, 0)
|
self.rightcolumn.setContentsMargins(0, 0, 0, 0)
|
||||||
self.binary = QtWidgets.QTextEdit(self.rightcolumnWidget)
|
self.binary = QtWidgets.QTextEdit(self.rightcolumnWidget)
|
||||||
|
self.binary.setReadOnly(True)
|
||||||
self.rightcolumn.addWidget(self.binary)
|
self.rightcolumn.addWidget(self.binary)
|
||||||
self.image = QtWidgets.QLabel(self.rightcolumnWidget)
|
self.image = QtWidgets.QLabel(self.rightcolumnWidget)
|
||||||
self.image.setMinimumWidth(200)
|
self.image.setMinimumWidth(200)
|
||||||
@@ -165,24 +167,27 @@ class Bar(PaintBox):
|
|||||||
text.append('')
|
text.append('')
|
||||||
text.append(f'Adresses: {addr[0]} - {sum(addr)}')
|
text.append(f'Adresses: {addr[0]} - {sum(addr)}')
|
||||||
text.append(f'Length: {addr[1]}')
|
text.append(f'Length: {addr[1]}')
|
||||||
text.append('')
|
|
||||||
if key[0].lower() == 'header':
|
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'Byte order: {self.tiff.byteorder}')
|
||||||
text.append(f'Big tiff: {self.tiff.bigtiff}')
|
text.append(f'Big tiff: {self.tiff.bigtiff}')
|
||||||
text.append(f'Tag size: {self.tiff.tagsize}')
|
text.append(f'Tag size: {self.tiff.tagsize}')
|
||||||
text.append(f'Tag number format: {self.tiff.tagnoformat}')
|
text.append(f'Tag number format: {self.tiff.tagnoformat}')
|
||||||
text.append(f'Offset size: {self.tiff.offsetsize}')
|
text.append(f'Offset size: {self.tiff.offsetsize}')
|
||||||
text.append(f'Offset format: {self.tiff.offsetformat}')
|
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':
|
if key[0].lower() == 'ifd':
|
||||||
text.extend([f'{k}: {v}' for k, v in self.tiff.tags[key[1]].items()])
|
text.append(f'Number of tags: {self.tiff.nTags[key[1]]}\n')
|
||||||
if key[1] < self.tiff.nifds-1:
|
text.extend([self.tiff.fmt_tag(k, v)+'\n' for k, v in self.tiff.tags[key[1]].items()])
|
||||||
text.append(f'Next ifd offset: {self.tiff.addresses[("ifd", key[1] + 1)][0]}')
|
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':
|
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':
|
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:
|
else:
|
||||||
self.parent.setImage()
|
self.parent.setImage()
|
||||||
self.parent.properties.setText('\n'.join(text))
|
self.parent.properties.setText('\n'.join(text))
|
||||||
@@ -204,9 +209,9 @@ class App(QtWidgets.QMainWindow, UiMainWindow):
|
|||||||
|
|
||||||
def setImage(self, *args):
|
def setImage(self, *args):
|
||||||
if len(args):
|
if len(args):
|
||||||
im = self.tiff.asarray(*args)
|
im = args[0]
|
||||||
if im.ndim == 3:
|
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:
|
if im.max() - im.min() > 0:
|
||||||
im = (255 * ((im - im.min()) / (im.max() - im.min()))).astype('uint8')
|
im = (255 * ((im - im.min()) / (im.max() - im.min()))).astype('uint8')
|
||||||
shape = im.shape
|
shape = im.shape
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import struct
|
import struct
|
||||||
import tifffile
|
import tifffile
|
||||||
import numpy as np
|
import numpy as np
|
||||||
|
from traceback import format_exc
|
||||||
|
|
||||||
|
|
||||||
class tiff():
|
class tiff():
|
||||||
@@ -11,16 +12,31 @@ class tiff():
|
|||||||
self.tags = []
|
self.tags = []
|
||||||
self.get_file_len()
|
self.get_file_len()
|
||||||
self.addresses = assignments(len(self))
|
self.addresses = assignments(len(self))
|
||||||
nifd = self.read_header()
|
self.offsets = []
|
||||||
i = 0
|
self.nTags = []
|
||||||
while nifd:
|
try:
|
||||||
nifd = self.read_ifd(nifd, i)
|
self.offsets = [self.read_header()]
|
||||||
i += 1
|
i = 0
|
||||||
self.nifds = i
|
while 0 < self.offsets[-1] < len(self):
|
||||||
for i, tags in enumerate(self.tags):
|
self.offsets.append(self.read_ifd(self.offsets[-1], i))
|
||||||
if 273 in tags and 279 in tags:
|
i += 1
|
||||||
for j, a in enumerate(zip(tags[273][-1], tags[279][-1])):
|
for i, tags in enumerate(self.tags):
|
||||||
self.addresses[('image', i, j)] = a
|
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):
|
def get_file_len(self):
|
||||||
self.fh.seek(0, 2)
|
self.fh.seek(0, 2)
|
||||||
@@ -58,49 +74,50 @@ class tiff():
|
|||||||
"""
|
"""
|
||||||
self.fh.seek(offset)
|
self.fh.seek(offset)
|
||||||
nTags = struct.unpack(self.byteorder + self.tagnoformat, self.fh.read(struct.calcsize(self.tagnoformat)))[0]
|
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'
|
assert nTags < 4096, 'Too many tags'
|
||||||
|
|
||||||
length = 8 if self.bigtiff else 2
|
length = 8 if self.bigtiff else 2
|
||||||
length += nTags * self.tagsize + self.offsetsize
|
length += nTags * self.tagsize + self.offsetsize
|
||||||
|
|
||||||
tags = {}
|
|
||||||
for i in range(nTags):
|
for i in range(nTags):
|
||||||
pos = offset + struct.calcsize(self.tagnoformat) + self.tagsize * i
|
code, ttype, caddr, dtypelen, count, value = 0, 0, 0, 0, 0, [0]
|
||||||
self.fh.seek(pos)
|
try:
|
||||||
|
self.fh.seek(offset + struct.calcsize(self.tagnoformat) + self.tagsize * i)
|
||||||
|
|
||||||
code, ttype = struct.unpack(self.byteorder + 'HH', self.fh.read(4))
|
code, ttype = struct.unpack(self.byteorder + 'HH', self.fh.read(4))
|
||||||
count = struct.unpack(self.byteorder + self.offsetformat, self.fh.read(self.offsetsize))[0]
|
count = struct.unpack(self.byteorder + self.offsetformat, self.fh.read(self.offsetsize))[0]
|
||||||
dtype = tifffile.TIFF.DATA_FORMATS[ttype]
|
dtype = tifffile.TIFF.DATA_FORMATS[ttype]
|
||||||
dtypelen = struct.calcsize(dtype)
|
dtypelen = struct.calcsize(dtype)
|
||||||
|
|
||||||
toolong = struct.calcsize(dtype) * count > self.offsetsize
|
toolong = struct.calcsize(dtype) * count > self.offsetsize
|
||||||
if toolong:
|
if toolong:
|
||||||
caddr = struct.unpack(self.byteorder + self.offsetformat, self.fh.read(self.offsetsize))[0]
|
caddr = struct.unpack(self.byteorder + self.offsetformat, self.fh.read(self.offsetsize))[0]
|
||||||
self.addresses[('tagdata', idx, code)] = (caddr, dtypelen * count)
|
self.addresses[('tagdata', idx, code)] = (caddr, dtypelen * count)
|
||||||
cp = self.fh.tell()
|
cp = self.fh.tell()
|
||||||
self.fh.seek(caddr)
|
self.fh.seek(caddr)
|
||||||
else:
|
else:
|
||||||
caddr = self.fh.tell()
|
caddr = self.fh.tell()
|
||||||
|
|
||||||
if ttype == 1:
|
if ttype == 1:
|
||||||
value = self.fh.read(count)
|
value = self.fh.read(count)
|
||||||
elif ttype == 2:
|
elif ttype == 2:
|
||||||
value = self.fh.read(count).decode('ascii').rstrip('\x00')
|
value = self.fh.read(count).decode('ascii').rstrip('\x00')
|
||||||
elif ttype == 5:
|
elif ttype == 5:
|
||||||
value = [struct.unpack(self.byteorder + dtype, self.fh.read(dtypelen)) for _ in range(count)]
|
value = [struct.unpack(self.byteorder + dtype, self.fh.read(dtypelen)) for _ in range(count)]
|
||||||
else:
|
else:
|
||||||
value = [struct.unpack(self.byteorder + dtype, self.fh.read(dtypelen))[0] for _ in range(count)]
|
value = [struct.unpack(self.byteorder + dtype, self.fh.read(dtypelen))[0] for _ in range(count)]
|
||||||
|
|
||||||
if toolong:
|
if toolong:
|
||||||
self.fh.seek(cp)
|
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)
|
self.fh.seek(offset + struct.calcsize(self.tagnoformat) + self.tagsize * nTags)
|
||||||
|
nifd = struct.unpack(self.byteorder + self.offsetformat, self.fh.read(self.offsetsize))[0]
|
||||||
nifd = struct.unpack(self.byteorder + self.tagnoformat, self.fh.read(struct.calcsize(self.tagnoformat)))[0]
|
|
||||||
self.fh.seek(offset)
|
|
||||||
self.addresses[('ifd', idx)] = (offset, 2 * struct.calcsize(self.tagnoformat) + nTags * self.tagsize)
|
self.addresses[('ifd', idx)] = (offset, 2 * struct.calcsize(self.tagnoformat) + nTags * self.tagsize)
|
||||||
self.tags.append(tags)
|
|
||||||
return nifd
|
return nifd
|
||||||
|
|
||||||
def __getitem__(self, item):
|
def __getitem__(self, item):
|
||||||
|
|||||||
Reference in New Issue
Block a user