def _read_channel_image_data(fp, layer, depth): """ Reads image data for all channels in a layer. """ channel_data = [] bytes_per_pixel = depth // 8 for channel in layer.channels: if channel.id == ChannelID.USER_LAYER_MASK: w, h = layer.mask_data.width(), layer.mask_data.height() else: w, h = layer.width(), layer.height() start_pos = fp.tell() compress_type = read_fmt("H", fp)[0] data = None if compress_type == Compression.RAW: data_size = w * h * bytes_per_pixel data = fp.read(data_size) elif compress_type == Compression.PACK_BITS: byte_counts = read_be_array("H", h, fp) data_size = sum(byte_counts) * bytes_per_pixel data = fp.read(data_size) elif compress_type == Compression.ZIP: data = zlib.decompress(fp.read(channel.length - 2)) elif compress_type == Compression.ZIP_WITH_PREDICTION: decompressed = zlib.decompress(fp.read(channel.length - 2)) data = compression.decode_prediction(decompressed, w, h, bytes_per_pixel) if data is None: return [] channel_data.append(ChannelData(compress_type, data)) remaining_bytes = channel.length - (fp.tell() - start_pos) - 2 if remaining_bytes > 0: fp.seek(remaining_bytes, 1) return channel_data
def test_prediction(fixture, width, height, depth): encoded = encode_prediction(fixture, width, height, depth) decoded = decode_prediction(encoded, width, height, depth) assert fixture == decoded
def _read_channel_image_data(fp, layer, depth): """ Reads image data for all channels in a layer. """ bytes_per_pixel = depth // 8 channel_data = [] for channel in layer.channels: logger.debug(" reading %s", channel) if channel.id == ChannelID.USER_LAYER_MASK: w, h = layer.mask_data.width(), layer.mask_data.height() elif channel.id == ChannelID.REAL_USER_LAYER_MASK: w, h = layer.mask_data.real_width(), layer.mask_data.real_height() else: w, h = layer.width(), layer.height() start_pos = fp.tell() compress_type = read_fmt("H", fp)[0] logger.debug(" start_pos=%s, compress_type=%s", start_pos, Compression.name_of(compress_type)) # read or calculate data size if compress_type == Compression.RAW: data_size = w * h * bytes_per_pixel logger.debug(' data size = %sx%sx%s=%s bytes', w, h, bytes_per_pixel, data_size) elif compress_type == Compression.PACK_BITS: byte_counts = read_be_array("H", h, fp) data_size = sum(byte_counts) logger.debug(' data size = %s bytes', data_size) elif compress_type in (Compression.ZIP, Compression.ZIP_WITH_PREDICTION): data_size = channel.length - 2 logger.debug(' data size = %s-2=%s bytes', channel.length, data_size) else: warnings.warn("Bad compression type %s" % compress_type) return [] # read the data itself if data_size > channel.length: warnings.warn("Incorrect data size: %s > %s" % (data_size, channel.length)) else: data = fp.read(data_size) if compress_type == Compression.ZIP: data = zlib.decompress(data) elif compress_type == Compression.ZIP_WITH_PREDICTION: data = zlib.decompress(data) data = compression.decode_prediction(data, w, h, bytes_per_pixel) if data is None: warnings.warn("Prediction decode failed!") return [] channel_data.append(ChannelData(compress_type, data)) remaining_length = channel.length - (fp.tell() - start_pos) if remaining_length > 0: fp.seek(remaining_length, 1) logger.debug(' skipping %s bytes', remaining_length) return channel_data
def _read_channel_image_data(fp, layer, depth): """ Reads image data for all channels in a layer. """ channel_data = [] bytes_per_pixel = depth // 8 for idx, channel in enumerate(layer.channels): logger.debug(" reading %s", channel) if channel.id == ChannelID.USER_LAYER_MASK: w, h = layer.mask_data.width(), layer.mask_data.height() elif channel.id == ChannelID.REAL_USER_LAYER_MASK: w, h = layer.mask_data.real_width(), layer.mask_data.real_height() else: w, h = layer.width(), layer.height() start_pos = fp.tell() compress_type = read_fmt("H", fp)[0] logger.debug(" start_pos=%s, compress_type=%s", start_pos, Compression.name_of(compress_type)) data = None # read data size if compress_type == Compression.RAW: data_size = w * h * bytes_per_pixel logger.debug(' data size = %sx%sx%s=%s bytes', w, h, bytes_per_pixel, data_size) elif compress_type == Compression.PACK_BITS: byte_counts = read_be_array("H", h, fp) data_size = sum(byte_counts) logger.debug(' data size = %s bytes', data_size) elif compress_type in (Compression.ZIP, Compression.ZIP_WITH_PREDICTION): data_size = channel.length - 2 logger.debug(' data size = %s-2=%s bytes', channel.length, data_size) else: warnings.warn("Bad compression type %s" % compress_type) return [] # read the data itself if data_size > channel.length: warnings.warn("Incorrect data size: %s > %s" % (data_size, channel.length)) else: raw_data = fp.read(data_size) if compress_type in (Compression.RAW, Compression.PACK_BITS): data = raw_data elif compress_type == Compression.ZIP: data = zlib.decompress(raw_data) elif compress_type == Compression.ZIP_WITH_PREDICTION: decompressed = zlib.decompress(raw_data) data = compression.decode_prediction(decompressed, w, h, bytes_per_pixel) if data is None: return [] channel_data.append(ChannelData(compress_type, data)) remaining_length = channel.length - (fp.tell() - start_pos) if remaining_length > 0: fp.seek(remaining_length, 1) logger.debug(' skipping %s bytes', remaining_length) return channel_data
def _read_channel_image_data(fp, layer, depth): """ Reads image data for all channels in a layer. """ channel_data = [] bytes_per_pixel = depth // 8 for idx, channel in enumerate(layer.channels): logger.debug(" reading %s", channel) if channel.id == ChannelID.USER_LAYER_MASK: w, h = layer.mask_data.width(), layer.mask_data.height() else: w, h = layer.width(), layer.height() start_pos = fp.tell() compress_type = read_fmt("H", fp)[0] logger.debug(" start_pos=%s, compress_type=%s", start_pos, Compression.name_of(compress_type)) data = None # read data size if compress_type == Compression.RAW: data_size = w * h * bytes_per_pixel logger.debug(' data size = %sx%sx%s=%s bytes', w, h, bytes_per_pixel, data_size) elif compress_type == Compression.PACK_BITS: byte_counts = read_be_array("H", h, fp) sum_counts = sum(byte_counts) data_size = sum_counts * bytes_per_pixel logger.debug(' data size = %sx%s=%s bytes', sum_counts, bytes_per_pixel, data_size) elif compress_type == Compression.ZIP: data_size = channel.length - 2 logger.debug(' data size = %s-2=%s bytes', channel.length, data_size) elif compress_type == Compression.ZIP_WITH_PREDICTION: data_size = channel.length - 2 logger.debug(' data size = %s-2=%s bytes', channel.length, data_size) else: warnings.warn("Bad compression type %s" % compress_type) return [] # read the data itself if data_size > channel.length: warnings.warn("Incorrect data size: %s > %s" % (data_size, channel.length)) else: raw_data = fp.read(data_size) if compress_type in (Compression.RAW, Compression.PACK_BITS): data = raw_data elif compress_type == Compression.ZIP: data = zlib.decompress(raw_data) elif compress_type == Compression.ZIP_WITH_PREDICTION: decompressed = zlib.decompress(raw_data) data = compression.decode_prediction(decompressed, w, h, bytes_per_pixel) if data is None: return [] channel_data.append(ChannelData(compress_type, data)) remaining_bytes = channel.length - (fp.tell() - start_pos) - 2 if remaining_bytes > 0: fp.seek(remaining_bytes, 1) logger.debug(' skipping %s bytes', remaining_bytes) return channel_data