def __init__(self, parent, br=None): self.parent = parent self.br = br self.tags = TiffTags() self.tag = None self.type = None self.count = None self.offset = None self.directory = None if br: self._load()
class TiffDirectoryEntry(object): # XXX Tiff 3.0 types, 6.0 has more, but I don't need them yet BYTE = 1 ASCII = 2 SHORT = 3 LONG = 4 RATIONAL = 5 STRING = 0 LENGTH = 1 FORMAT = 2 types = { BYTE: ("byte", 1, "s"), ASCII: ("ascii", 1, "s"), SHORT: ("short", 2, "H"), LONG: ("long", 4, "L"), RATIONAL: ("rational", 8, "LL"), } def __init__(self, parent, br=None): self.parent = parent self.br = br self.tags = TiffTags() self.tag = None self.type = None self.count = None self.offset = None self.directory = None if br: self._load() def __repr__(self): return "TiffDirectoryEntry(parent={}, tag={}, type={}, count={}, offset={})".format( self.parent.offset, self._tagstr(self.tag), self._typestr(self.type), self.count, self.offset ) def __str__(self): return self.__repr__() def _typestr(self, type): if type in self.types: return self.types[type][self.STRING] return "unknown" def _tagstr(self, tag): name = self.tags.getTagName(tag) if name: return name return hex(tag) def _load(self): self.tag = self.br.read() self.type = self.br.read() self.count = self.br.read(4, "I") self.offset = self.br.read(4, "I") def read(self): if not self.br: return None # To save time and space the Value Offset contains the Value instead of pointing to # the Value if and only if the Value fits into 4 bytes. If the Value is shorter than 4 # bytes, it is left-justified within the 4-byte Value Offset, i.e., stored in the lowernumbered # bytes. Whether the Value fits within 4 bytes is determined by the Type # and Count of the field. if not self.type in self.types.keys(): return None if self.types[self.type][self.LENGTH] * self.count <= 4: return self.offset self.br.seek(self.offset) if self.type in (TiffDirectoryEntry.BYTE, TiffDirectoryEntry.ASCII): return self.br.read(self.types[self.type][self.LENGTH], self.types[self.type][self.FORMAT], self.count) if self.type in (TiffDirectoryEntry.SHORT, TiffDirectoryEntry.LONG): return self.br.read( self.types[self.type][self.LENGTH], self.types[self.type][self.FORMAT], self.count, True ) elif self.type == TiffDirectoryEntry.RATIONAL: values = () for i in range(0, self.count): numerator, denominator = self.br.read(self.types[self.type][self.LENGTH], "LL", 1, True) values += ((numerator, denominator),) return values