Beispiel #1
0
    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()
Beispiel #2
0
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