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)
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)
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
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
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)
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)
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)
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)
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
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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 )
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))
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)
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)
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)
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)