def decode(self, color_mode=WebPColorMode.RGBA): dec_config = WebPDecoderConfig.new() dec_config.read_features(self) if color_mode == WebPColorMode.RGBA \ or color_mode == WebPColorMode.bgrA \ or color_mode == WebPColorMode.BGRA \ or color_mode == WebPColorMode.rgbA \ or color_mode == WebPColorMode.ARGB \ or color_mode == WebPColorMode.Argb: bytes_per_pixel = 4 elif color_mode == WebPColorMode.RGB \ or color_mode == WebPColorMode.BGR: bytes_per_pixel = 3 elif color_mode == WebPColorMode.RGB_565 \ or color_mode == WebPColorMode.RGBA_4444 \ or color_mode == WebPColorMode.rgbA_4444: bytes_per_pixel = 2 else: raise WebPError('unsupported color mode: {}'.format(str(color_mode))) arr = np.empty((dec_config.input.height, dec_config.input.width, bytes_per_pixel), dtype=np.uint8) dec_config.output.colorspace = color_mode.value dec_config.output.u.RGBA.rgba = ffi.cast('uint8_t*', ffi.from_buffer(arr)) dec_config.output.u.RGBA.size = arr.size dec_config.output.u.RGBA.stride = dec_config.input.width * bytes_per_pixel dec_config.output.is_external_memory = 1 if lib.WebPDecode(self.ptr.bytes, self.size, dec_config.ptr) != lib.VP8_STATUS_OK: raise WebPError('failed to decode') lib.WebPFreeDecBuffer(ffi.addressof(dec_config.ptr, 'output')) return arr
def encode(self, config=None): if config is None: config = WebPConfig.new() writer = WebPMemoryWriter.new() self.ptr.writer = ffi.addressof(lib, 'WebPMemoryWrite') self.ptr.custom_ptr = writer.ptr if lib.WebPEncode(config.ptr, self.ptr) == 0: raise WebPError('encoding error: ' + self.ptr.error_code) return writer.to_webp_data()
def read_features(self, webp_data): input_ptr = ffi.addressof(self.ptr, 'input') if lib.WebPGetFeatures(webp_data.ptr.bytes, webp_data.size, input_ptr) != lib.VP8_STATUS_OK: raise WebPError('failed to read features')