Esempio n. 1
0
class CARRenditionRaw(Model):
    fields = [
        ('magic', Parse.fixed("<4s")),
        ('reserved', Parse.fixed("<I")),
        ('length', Parse.fixed("<I")),
        ('binary', Parse.dynamic("length")),
    ]
Esempio n. 2
0
class CARRenditionInfo(Model):
    fields = [
        ('magic', Parse.fixed("<I")),
        ('length', Parse.fixed("<I")),
        ('content', Parse.dynamic("length")),
    ]

    @cached_property
    def parsed(self):
        content = StringIO.StringIO(self.content)
        make_map = {
            1001: Parse.array_dynamic(model=CARRenditionSlice),
            1003: Parse.array_dynamic(model=CARRenditionMetric),
            1004: Parse.model(CARRenditionComposition),
            1005: Parse.model(CARRenditionUTI),
            1006: Parse.model(CARRenditionBitmapInfo),
            1007: Parse.model(CARRenditionBytesPerRow),
            1010: Parse.model(CARRenditionReference),
        }
        content_make = make_map.get(self.magic)
        return content_make(self, content) if content_make else None

    def __str__(self):
        return "<CARRenditionInfo magic=%s, length=%s, parsed=%s>" % \
            (self.magic, self.length, self.parsed)
Esempio n. 3
0
class CARRenditionMetadata(Model):
    fields = [
        ('modification_date', Parse.fixed("<I")),
        ('layout_raw', Parse.fixed("<H")),
        ('reserved', Parse.fixed("<H")),
        ('name', Parse.terminated("\x00", fixed=128)),
    ]
Esempio n. 4
0
class CARRenditionSlice(Model):
    fields = [
        ('x', Parse.fixed("<I")),
        ('y', Parse.fixed("<I")),
        ('width', Parse.fixed("<I")),
        ('height', Parse.fixed("<I")),
    ]
Esempio n. 5
0
class CARKeyFormat(Model):
    fields = [
        ('magic', Parse.fixed(">4s")),
        ('reserved', Parse.fixed("<I")),
        ('num_identifiers', Parse.fixed("<I")),
        ('identifiers',
         Parse.array(model=CARKeyFormatIdentifier, count="num_identifiers")),
    ]
Esempio n. 6
0
class BOMPath(Model):
    fields = [
        ('is_leaf', Parse.fixed(">H")),
        ('count', Parse.fixed(">H")),
        ('forward', Parse.fixed(">I")),
        ('backwards', Parse.fixed(">I")),
        ('indexes', Parse.array(model=BOMPathIndex, count="count")),
    ]
Esempio n. 7
0
class CARHeader(Model):
    def _uuid(self, stream):
        content, = struct.unpack("<16s", stream.read(16))
        return content.encode("hex")

    fields = [
        ('magic', Parse.fixed(">4s")),
        ('ui_version', Parse.fixed("<I")),
        ('storage_version', Parse.fixed("<I")),
        ('storage_timestamp', Parse.fixed("<I")),
        ('rendition_count', Parse.fixed("<I")),
        ('file_creator', Parse.terminated("\n", fixed=128)),
        ('other_creator', Parse.terminated("\x00", fixed=256)),
        ('uuid', _uuid),
        ('associated_checksum', Parse.fixed("<I")),
        ('schema_version', Parse.fixed("<I")),
        ('color_space_id', Parse.fixed("<I")),
        ('key_semantics', Parse.fixed("<I")),
    ]

    def dump(self):
        print "Magic: %s" % self.magic
        print "UI version: %x" % self.ui_version
        print "Storage version: %x" % self.storage_version
        print "Storage Timestamp: %d" % self.storage_timestamp
        print "Rendition Count: %x" % self.rendition_count
        print "Creator: %s" % self.file_creator
        print "Other Creator: %s" % self.other_creator
        print "UUID: %s" % self.uuid
        print "Associated Checksum: %x" % self.associated_checksum
        print "Schema Version: %d" % self.schema_version
        print "Color space ID: %d" % self.color_space_id
        print "Key Semantics: %d" % self.key_semantics
Esempio n. 8
0
class CARFacet(Model):
    custom = ['name']
    fields = [
        ('x', Parse.fixed("<H")),
        ('y', Parse.fixed("<H")),
        ('attributes_count', Parse.fixed("<H")),
        ('attributes_raw',
         Parse.array(model=CARFacetAttribute, count="attributes_count")),
    ]

    def dump(self):
        print "Facet: %s" % self.name
        for attribute, value in self.attributes.iteritems():
            print "[%.2d] %s = %s" % \
                (attribute.identifier_raw, attribute.identifier, value)
Esempio n. 9
0
class CARRenditionReference(Model):
    fields = [
        ('magic', Parse.fixed("<4s")),
        ('padding', Parse.fixed("<I")),
        ('x', Parse.fixed("<I")),
        ('y', Parse.fixed("<I")),
        ('width', Parse.fixed("<I")),
        ('height', Parse.fixed("<I")),
        ('layout', Parse.fixed("<H")),
        ('key_length', Parse.fixed("<H")),
    ]
Esempio n. 10
0
class CARKeyFormatIdentifier(Model):
    fields = [
        ('identifier_raw', Parse.fixed("<I")),
    ]

    def __eq__(self, other):
        return self.identifier_raw == other.identifier_raw

    @property
    def identifier(self):
        return CAR_ATTRIBUTE_BY_ID.get(self.identifier_raw, "unknown")
Esempio n. 11
0
class BOMHeader(Model):
    fields = [
        ('magic', Parse.fixed(">8s")),
        ('version', Parse.fixed(">I")),
        ('block_count', Parse.fixed(">I")),
        ('index_offset', Parse.fixed(">I")),
        ('index_size', Parse.fixed(">I")),
        ('table_offset', Parse.fixed(">I")),
        ('table_size', Parse.fixed(">I")),
    ]
Esempio n. 12
0
class BOMTree(Model):
    def iterate(self, stream_index):
        if self.magic != "tree" or self.version != 1:
            raise BOMInvalidTreeType("Invalid tree type %s" % self)

        path = BOMPath.make(stream_index(self.child).stream)
        if not path.is_leaf:
            index = path.indexes[0]
            path = BOMPath.make(stream_index(index.value_index).stream)

        while path:
            for index in path.indexes:
                stream, block = stream_index(index.key_index)
                key = stream.read(block.size)
                stream, block = stream_index(index.value_index)
                value = stream.read(block.size)
                yield key, value

            if not path.forward:
                break

            path = BOMPath.make(stream_index(path.forward).stream)

    custom = ["name"]
    fields = [
        ('magic', Parse.fixed(">4s")),
        ('version', Parse.fixed(">I")),
        ('child', Parse.fixed(">I")),
        ('block_size', Parse.fixed(">I")),
        ('path_count', Parse.fixed(">I")),
        ('unknown', Parse.fixed(">b")),
    ]
Esempio n. 13
0
class CARFacetAttribute(Model):
    fields = [
        ('identifier', Parse.fixed("<H")),
        ('value', Parse.fixed("<H")),
    ]
Esempio n. 14
0
class CARRenditionBytesPerRow(Model):
    fields = [
        ('bytes_per_row', Parse.fixed("<I")),
    ]
Esempio n. 15
0
class CARRenditionBitmapInfo(Model):
    fields = [
        ('exif_orientation', Parse.fixed("<I")),
    ]
Esempio n. 16
0
class CARRenditionUTI(Model):
    fields = [
        ('length', Parse.fixed("<I")),
        ('uti', Parse.fixed("<1s")),
    ]
Esempio n. 17
0
class BOMPathIndex(Model):
    fields = [
        ('value_index', Parse.fixed(">I")),
        ('key_index', Parse.fixed(">I")),
    ]
Esempio n. 18
0
class BOMExtendedMetadata(Model):
    fields = [
        ('magic', Parse.fixed(">4s")),
        ('contents', Parse.terminated("\x00", fixed=768)),
        ('creator', Parse.terminated("\n", fixed=256)),
    ]
Esempio n. 19
0
class CARRenditionFlag(Model):
    fields = [
        ('flags', Parse.fixed("<B")),
        ('reserved', Parse.fixed("<3s")),
    ]
Esempio n. 20
0
class CARRendition(Model):
    RESIZE_MODE_FIXED = "Fixed Size"
    RESIZE_MODE_TILE = "Tile"
    RESIZE_MODE_SCALE = "Scale"
    RESIZE_MODE_HUNIFORM_VSCALE = "Horizontal Uniform; Vertical Scale"
    RESIZE_MODE_HSCALE_VUNIFORM = "Horizontal Scale; Vertical Uniform"

    @classmethod
    def make_from_buffer(cls, buffer, **kwargs):
        stream = StringIO.StringIO(buffer)
        return cls.make(stream, **kwargs)

    fields = [
        ('magic', Parse.fixed("<4s")),
        ('version', Parse.fixed("<I")),
        ('flags', Parse.model(CARRenditionFlag)),
        ('width', Parse.fixed("<I")),
        ('height', Parse.fixed("<I")),
        ('scale_factor', Parse.fixed("<I")),
        ('pixel_format', Parse.fixed("<4s")),
        ('color_space_id', Parse.fixed("<B")),
        ('reserved', Parse.fixed("<3s")),
        ('modification_date', Parse.fixed("<I")),
        ('layout_raw', Parse.fixed("<H")),
        ('reserved', Parse.fixed("<H")),
        ('name', Parse.terminated("\x00", fixed=128)),
        ('info_len', Parse.fixed("<I")),
        ('bitmap_count', Parse.fixed("<I")),
        ('reserved', Parse.fixed("<I")),
        ('payload_size', Parse.fixed("<I")),
        ('info', Parse.array_fixed(model=CARRenditionInfo, size='info_len')),
        ('content', Parse.dynamic("payload_size")),
    ]

    @cached_property
    def raw(self):
        if len(self.content):
            return CARRenditionRaw.make_from_buffer(self.content)

    @cached_property
    def layout(self):
        return CAR_RENDITION_LAYOUT_BY_ID.get(self.layout_raw, "unknown")

    @cached_property
    def is_resizable(self):
        return 25 >= self.layout_raw >= 20 and len(self.slices) > 1

    @cached_property
    def slices(self):
        return filter(lambda x: x.parsed is CARRenditionSlice, self.info)

    @cached_property
    def resize_mode(self):
        mode_map = {
            "one_part_tile":
            CARRendition.RESIZE_MODE_TILE,
            "three_part_horizontal_tile":
            CARRendition.RESIZE_MODE_TILE,
            "three_part_vertical_tile":
            CARRendition.RESIZE_MODE_TILE,
            "nine_part_tile":
            CARRendition.RESIZE_MODE_TILE,
            "one_part_scale":
            CARRendition.RESIZE_MODE_SCALE,
            "three_part_horizontal_scale":
            CARRendition.RESIZE_MODE_SCALE,
            "three_part_vertical_scale":
            CARRendition.RESIZE_MODE_SCALE,
            "nine_part_scale":
            CARRendition.RESIZE_MODE_SCALE,
            "nine_part_horizontal_uniform_vertical_scale":
            CARRendition.RESIZE_MODE_HUNIFORM_VSCALE,
            "nine_part_horizontal_uniform_vertical_scale":
            CARRendition.RESIZE_MODE_HSCALE_VUNIFORM,
        }
        return mode_map.get(self.layout, CARRendition.RESIZE_MODE_FIXED)

    def dump(self):
        print "Rendition: %s" % self.name
        print "Width: %d" % self.width
        print "Height: %d" % self.height
        print "Scale: %f" % (self.scale_factor / 100.0)
        print "Layout: %s" % self.layout_raw
        print "Resizable: %d" % self.is_resizable
        print "Payload size: %d" % self.payload_size
        if self.is_resizable:
            for i, slice in enumerate(self.slices):
                print "Slice %d: (%u, %u) %u x %u" % \
                    (i, slice.x, slice.y, slice.width, slice.height)

        print "Resize mode: %s" % self.resize_mode
        print "Attributes:"
        for attribute, value in self.attributes.iteritems():
            print "[%.2d] %s = %s" % \
                (attribute.identifier_raw, attribute.identifier, value)

        print ""
Esempio n. 21
0
class CARRenditionMetric(Model):
    fields = [
        ('width', Parse.fixed("<I")),
        ('height', Parse.fixed("<I")),
    ]
Esempio n. 22
0
class CARRenditionComposition(Model):
    fields = [
        ('blend_mode', Parse.fixed("<I")),
        ('opacity', Parse.fixed("<f")),
    ]
Esempio n. 23
0
class BOMBlock(Model):
    fields = [
        ('index', Parse.fixed(">I")),
        ('size', Parse.fixed(">I")),
    ]