示例#1
0
    def read(cls, fp, **kwargs):
        # NOTE: This is highly experimental and unstable.
        is_map, version, count_map = read_fmt('BHI', fp)
        assert version in (1, 4), 'Invalid version %d' % (version)

        if version == 1:
            count = bin(count_map).count('1')  # Bitmap = channel index?
        else:
            count = count_map

        if is_map:
            # This lookup format is never documented.
            data = [list(read_fmt('256B', fp)) for _ in range(count)]
        else:
            data = []
            for _ in range(count):
                point_count = read_fmt('H', fp)[0]
                assert 2 <= point_count and point_count <= 19, (
                    'Curves point count not in [2, 19]')
                points = [read_fmt('2H', fp) for i in range(point_count)]
                data.append(points)

        extra = None
        if version == 1:
            extra = CurvesExtraMarker.read(fp, is_map=is_map)

        return cls(is_map, version, count_map, data, extra)
示例#2
0
    def _read_body(cls, fp, length):
        top, left, bottom, right, background_color = read_fmt('4iB', fp)
        flags = MaskFlags.read(fp)

        # Order is based on tests. The specification is messed up here...

        # if length == 20:
        #     read_fmt('2x', fp)
        #     return cls(top, left, bottom, right, background_color, flags)

        real_flags, real_background_color = None, None
        real_top, real_left, real_bottom, real_right = None, None, None, None
        if length >= 36:
            real_flags = MaskFlags.read(fp)
            real_background_color = read_fmt('B', fp)[0]
            real_top, real_left, real_bottom, real_right = read_fmt('4i', fp)

        parameters = None
        if flags.parameters_applied:
            parameters = MaskParameters.read(fp)

        # logger.debug('    skipping %d' % (len(fp.read())))
        return cls(top, left, bottom, right, background_color, flags,
                   parameters, real_flags, real_background_color, real_top,
                   real_left, real_bottom, real_right)
示例#3
0
    def read(cls, fp, encoding='macroman', version=1):
        """Read the element from a file-like object.

        :param fp: file-like object
        :param encoding: encoding of the string
        :param version: psd file version
        :rtype: :py:class:`.LayerRecord`
        """
        start_pos = fp.tell()
        top, left, bottom, right, num_channels = read_fmt('4iH', fp)
        channel_info = [
            ChannelInfo.read(fp, version) for i in range(num_channels)
        ]
        signature, blend_mode, opacity, clipping = read_fmt('4s4sBB', fp)
        flags = LayerFlags.read(fp)

        data = read_length_block(fp, fmt='xI')
        logger.debug('  read layer record, len=%d' % (fp.tell() - start_pos))
        with io.BytesIO(data) as f:
            self = cls(top, left, bottom, right, channel_info, signature,
                       blend_mode, opacity, clipping, flags,
                       *cls._read_extra(f, encoding, version))

        # with io.BytesIO() as f:
        #     self._write_extra(f, encoding, version)
        #     assert data == f.getvalue()

        return self
示例#4
0
 def _read_body(cls, fp):
     rectangle = read_fmt('4i', fp)
     depth, max_channels = read_fmt('2I', fp)
     channels = []
     for _ in range(max_channels + 2):
         channels.append(FilterEffectChannel.read(fp))
     return rectangle, depth, max_channels, channels
示例#5
0
 def read(cls, fp, **kwargs):
     kind, version = read_fmt('4sI', fp)
     uuid = read_pascal_string(fp, 'macroman', padding=1)
     page, total_pages, anti_alias, layer_type = read_fmt('4I', fp)
     transform = read_fmt('8d', fp)
     warp = DescriptorBlock2.read(fp, padding=1)
     return cls(kind, version, uuid, page, total_pages, anti_alias,
                layer_type, transform, warp)
示例#6
0
 def read(cls, fp, is_map=False, **kwargs):
     if is_map:
         channel_id = read_fmt('H', fp)[0]
         points = list(read_fmt('256B', fp))
     else:
         channel_id, point_count = read_fmt('2H', fp)
         points = [read_fmt('2H', fp) for c in range(point_count)]
     return cls(channel_id, points)
示例#7
0
 def read(cls, fp):
     version = read_fmt('I', fp)[0]
     signature, blend_mode = read_fmt('4s4s', fp)
     assert signature == b'8BIM', 'Invalid signature %r' % (signature)
     color = Color.read(fp)
     opacity, enabled = read_fmt('2B', fp)
     native_color = Color.read(fp)
     return cls(version, blend_mode, color, opacity, enabled, native_color)
示例#8
0
    def read(cls, fp):
        """Read the element from a file-like object.

        :param fp: file-like object
        """
        unit, count = read_fmt('4sI', fp)
        values = list(read_fmt('%dd' % count, fp))
        return cls(unit, values)
示例#9
0
 def _read_body(cls, fp):
     # TODO: Check 4-byte = 2-byte int + 2-byte fraction?
     version, blur, intensity = read_fmt('III', fp)
     color = Color.read(fp)
     signature = read_fmt('4s', fp)[0]
     assert signature == b'8BIM', 'Invalid signature %r' % (signature)
     blend_mode = BlendMode(read_fmt('4s', fp)[0])
     enabled, opacity = read_fmt('2B', fp)
     return version, blur, intensity, color, blend_mode, enabled, opacity
示例#10
0
 def read(cls, fp, **kwargs):
     version, count = read_fmt('2H', fp)
     items = []
     for _ in range(count):
         signature = read_fmt('4s', fp)[0]
         assert signature == b'8BIM', 'Invalid signature %r' % (signature)
         ostype = EffectOSType(read_fmt('4s', fp)[0])
         kls = cls.EFFECT_TYPES.get(ostype)
         items.append((ostype, kls.frombytes(read_length_block(fp))))
     return cls(version=version, items=items)
示例#11
0
 def read(cls, fp):
     items = []
     length, operation, _unknown1, _unknown2, index, _unknown3 = read_fmt(
         'HhH2I10s', fp
     )
     for _ in range(length):
         selector = PathResourceID(read_fmt('H', fp)[0])
         kls = TYPES.get(selector)
         items.append(kls.read(fp))
     return cls(items=items, operation=operation, index=index,
                unknown1=_unknown1, unknown2=_unknown2, unknown3=_unknown3)
示例#12
0
 def read(cls, fp, **kwargs):
     major_version, minor_version, count = read_fmt('2HI', fp)
     items = []
     for _ in range(count):
         length = read_fmt('I', fp)[0] - 4
         if length > 0:
             with io.BytesIO(fp.read(length)) as f:
                 items.append(Annotation.read(f))
     return cls(major_version=major_version,
                minor_version=minor_version,
                items=items)
示例#13
0
 def read(cls, fp, **kwargs):
     id = read_fmt('H', fp)[0]
     try:
         id = ColorSpaceID(id)
     except ValueError:
         logger.info('Custom color space found: %d' % (id))
     if id == ColorSpaceID.LAB:
         values = read_fmt('4h', fp)
     else:
         values = read_fmt('4H', fp)
     return cls(id, values)
示例#14
0
 def read(cls, fp, **kwargs):
     version, enable = read_fmt('HBx', fp)
     assert version == 2, 'Invalid version %d' % (version)
     colorization = read_fmt('3h', fp)
     master = read_fmt('3h', fp)
     items = []
     for _ in range(6):
         range_values = read_fmt('4h', fp)
         settings_values = read_fmt('3h', fp)
         items.append([range_values, settings_values])
     return cls(version, enable, colorization, master, items)
示例#15
0
 def read(cls, fp, **kwargs):
     kind = SectionDivider(read_fmt('I', fp)[0])
     signature, key = None, None
     if is_readable(fp, 8):
         signature = read_fmt('4s', fp)[0]
         assert signature == b'8BIM', 'Invalid signature %r' % signature
         key = BlendMode(read_fmt('4s', fp)[0])
     sub_type = None
     if is_readable(fp, 4):
         sub_type = read_fmt('I', fp)[0]
     return cls(kind, signature=signature, key=key, sub_type=sub_type)
示例#16
0
 def read(cls, fp, **kwargs):
     is_written = read_fmt('I', fp)[0]
     if is_written == 0:
         return cls(is_written=is_written)
     data = read_length_block(fp, fmt='Q')
     if len(data) == 0:
         return cls(is_written=is_written)
     with io.BytesIO(data) as f:
         compression = read_fmt('H', f)[0]
         data = f.read()
     return cls(is_written, compression, data)
示例#17
0
 def read(cls, fp, **kwargs):
     kind, is_open, flags, optional_blocks = read_fmt('4s2BH', fp)
     icon_location = read_fmt('4i', fp)
     popup_location = read_fmt('4i', fp)
     color = Color.read(fp)
     author = read_pascal_string(fp, 'macroman', padding=2)
     name = read_pascal_string(fp, 'macroman', padding=2)
     mod_date = read_pascal_string(fp, 'macroman', padding=2)
     length, marker = read_fmt('I4s', fp)
     data = read_length_block(fp)
     return cls(kind, is_open, flags, optional_blocks, icon_location,
                popup_location, color, author, name, mod_date, marker, data)
示例#18
0
    def read(cls, fp):
        """Read the element from a file-like object.

        :param fp: file-like object
        :rtype: :py:class:`.MaskParameters`
        """
        parameters = read_fmt('B', fp)[0]
        return cls(
            read_fmt('B', fp)[0] if bool(parameters & 1) else None,
            read_fmt('d', fp)[0] if bool(parameters & 2) else None,
            read_fmt('B', fp)[0] if bool(parameters & 4) else None,
            read_fmt('d', fp)[0] if bool(parameters & 8) else None)
示例#19
0
 def read(cls, fp, **kwargs):
     is_written = read_fmt('I', fp)[0]
     if is_written == 0:
         return cls(is_written=is_written)
     length = read_fmt('I', fp)[0]
     if length == 0:
         return cls(is_written=is_written)
     depth = read_fmt('I', fp)[0]
     rectangle = read_fmt('4I', fp)
     pixel_depth, compression = read_fmt('HB', fp)
     data = fp.read(length - 23)
     return cls(is_written, depth, rectangle, pixel_depth, compression,
                data)
示例#20
0
    def read(cls, fp):
        is_written = read_fmt('B', fp)[0]
        if not is_written:
            return cls(is_written=is_written)

        rectangle = read_fmt('4i', fp)
        compression = 0
        data = b''
        with io.BytesIO(read_length_block(fp, fmt='Q')) as f:
            compression = read_fmt('H', f)[0]
            data = f.read()

        return cls(is_written, rectangle, compression, data)
示例#21
0
    def read(cls, fp, **kwargs):
        version = read_fmt('I', fp)[0]
        assert version == 3, 'Invalid version %d' % (version)

        data = read_length_block(fp)
        with io.BytesIO(data) as f:
            rectangle = read_fmt('4I', f)
            num_channels = read_fmt('I', f)[0]
            channels = []
            for _ in range(num_channels + 2):
                channels.append(VirtualMemoryArray.read(f))

        return cls(version, rectangle, channels)
示例#22
0
 def read(cls, fp, **kwargs):
     version = read_fmt('H', fp)[0]
     assert version in (2, 3), 'Invalid version %d' % (version)
     if version == 3:
         xyz = read_fmt('3I', fp)
         color_space = None
         color_components = None
     else:
         xyz = None
         color_space = read_fmt('H', fp)[0]
         color_components = read_fmt('4H', fp)
     density, luminosity = read_fmt('IB', fp)
     return cls(version, xyz, color_space, color_components, density,
                luminosity)
示例#23
0
 def read(cls, fp):
     slice_id, group_id, origin = read_fmt('3I', fp)
     associated_id = read_fmt('I', fp)[0] if origin == 1 else None
     name = read_unicode_string(fp)
     slice_type = read_fmt('I', fp)[0]
     bbox = read_fmt('4I', fp)
     url = read_unicode_string(fp)
     target = read_unicode_string(fp)
     message = read_unicode_string(fp)
     alt_tag = read_unicode_string(fp)
     cell_is_html = read_fmt('?', fp)[0]
     cell_text = read_unicode_string(fp)
     horizontal_align, vertical_align = read_fmt('2I', fp)
     alpha, red, green, blue = read_fmt('4B', fp)
     data = None
     if is_readable(fp, 4):
         # There is no easy distinction between descriptor block and
         # next slice v6 item here...
         current_position = fp.tell()
         version = read_fmt('I', fp)[0]
         fp.seek(-4, 1)
         if version == 16:
             try:
                 data = DescriptorBlock.read(fp)
             except ValueError:
                 logger.debug('Failed to read DescriptorBlock')
                 fp.seek(current_position)
     return cls(slice_id, group_id, origin, associated_id, name, slice_type,
                bbox, url, target, message, alt_tag, cell_is_html,
                cell_text, horizontal_align, vertical_align, alpha, red,
                green, blue, data)
示例#24
0
    def read(cls, fp, **kwargs):
        version = read_fmt('H', fp)[0]
        assert version == 2, 'Invalid version %d' % (version)
        items = [LevelRecord.read(fp) for _ in range(29)]

        extra_version = None
        if is_readable(fp, 6):
            signature, extra_version = read_fmt('4sH', fp)
            assert signature == b'Lvls', 'Invalid signature %r' % (signature)
            assert extra_version == 3, 'Invalid extra version %d' % (
                extra_version)
            count = read_fmt('H', fp)[0]
            items += [LevelRecord.read(fp) for _ in range(count - 29)]

        return cls(version=version, extra_version=extra_version, items=items)
示例#25
0
 def read(cls, fp):
     # TODO: Check 4-byte = 2-byte int + 2-byte fraction?
     version, blur, intensity, angle, distance = read_fmt(
         'IIIiI', fp
     )
     color = Color.read(fp)
     signature = read_fmt('4s', fp)[0]
     assert signature == b'8BIM', 'Invalid signature %r' % (signature)
     blend_mode = BlendMode(read_fmt('4s', fp)[0])
     enabled, use_global_angle, opacity = read_fmt('3B', fp)
     native_color = Color.read(fp)
     return cls(
         version, blur, intensity, angle, distance, color, blend_mode,
         enabled, use_global_angle, opacity, native_color
     )
示例#26
0
    def read(cls, fp):
        """Read the element from a file-like object.

        :param fp: file-like object
        """
        items_count = read_fmt('I', fp)[0]
        return cls(items_count=items_count, **cls._read_body(fp))
示例#27
0
 def read(cls, fp):
     items = []
     while is_readable(fp, 26):
         selector = PathResourceID(read_fmt('H', fp)[0])
         kls = TYPES.get(selector)
         items.append(kls.read(fp))
     return cls(items)
示例#28
0
    def read(cls, fp, encoding='macroman'):
        """Read the element from a file-like object.

        :param fp: file-like object
        :rtype: :py:class:`.ImageResource`
        """
        signature, key = read_fmt('4sH', fp)
        try:
            key = ImageResourceID(key)
        except ValueError:
            logger.warning('Unknown image resource %d' % (key))
        name = read_pascal_string(fp, encoding, padding=2)
        raw_data = read_length_block(fp, padding=2)
        if key in TYPES:
            data = TYPES[key].frombytes(raw_data)
            # try:
            #     _raw_data = data.tobytes(padding=1)
            #     assert _raw_data == raw_data, '%r vs %r' % (
            #         _raw_data, raw_data
            #     )
            # except AssertionError as e:
            #     logger.error(e)
            #     raise
        else:
            data = raw_data
        return cls(signature, key, name, data)
示例#29
0
    def read(cls, fp):
        """Read the element from a file-like object.

        :param fp: file-like object
        """
        unit, value = read_fmt('4sd', fp)
        return cls(unit=UnitFloatType(unit), value=value)
示例#30
0
 def _read_body(cls, fp, encoding, version):
     start_pos = fp.tell()
     layer_count = read_fmt('h', fp)[0]
     layer_records = LayerRecords.read(fp, layer_count, encoding, version)
     logger.debug('  read layer records, len=%d' % (fp.tell() - start_pos))
     channel_image_data = ChannelImageData.read(fp, layer_records)
     return cls(layer_count, layer_records, channel_image_data)