コード例 #1
0
class CARRenditionRaw(Model):
    fields = [
        ('magic', Parse.fixed("<4s")),
        ('reserved', Parse.fixed("<I")),
        ('length', Parse.fixed("<I")),
        ('binary', Parse.dynamic("length")),
    ]
コード例 #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)
コード例 #3
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 ""