Skip to content

Instantly share code, notes, and snippets.

@nitori
Last active July 24, 2017 21:29
Show Gist options
  • Save nitori/32fb25d7c2f17a6e298d to your computer and use it in GitHub Desktop.
Save nitori/32fb25d7c2f17a6e298d to your computer and use it in GitHub Desktop.
flif.py
import logging
from distutils import log
logging.basicConfig(level=logging.DEBUG)
log.set_verbosity(log.DEBUG)
from cffi import FFI
ffi = FFI()
SOURCE_CODE = """
typedef struct FLIF_IMAGE FLIF_IMAGE;
typedef struct FLIF_DECODER FLIF_DECODER;
FLIF_IMAGE* flif_create_image(uint32_t width, uint32_t height);
void flif_destroy_image(FLIF_IMAGE* image);
uint32_t flif_image_get_width(FLIF_IMAGE* image);
uint32_t flif_image_get_height(FLIF_IMAGE* image);
uint8_t flif_image_get_nb_channels(FLIF_IMAGE* image);
uint32_t flif_image_get_frame_delay(FLIF_IMAGE* image);
void flif_image_write_row_RGBA8(FLIF_IMAGE* image, uint32_t row, const void* buffer, size_t buffer_size_bytes);
void flif_image_read_row_RGBA8(FLIF_IMAGE* image, uint32_t row, void* buffer, size_t buffer_size_bytes);
void flif_free_memory(void* buffer);
FLIF_DECODER* flif_create_decoder();
int32_t flif_abort_decoder(FLIF_DECODER* decoder);
void flif_destroy_decoder(FLIF_DECODER* decoder);
void flif_decoder_set_quality(FLIF_DECODER* decoder, int32_t quality);
void flif_decoder_set_scale(FLIF_DECODER* decoder, uint32_t scale);
void flif_decoder_set_callback(FLIF_DECODER* decoder, uint32_t (*callback)(int32_t quality, int64_t bytes_read));
void flif_decoder_set_first_callback_quality(FLIF_DECODER* decoder, int32_t quality);
int32_t flif_decoder_decode_file(FLIF_DECODER* decoder, const char* filename);
int32_t flif_decoder_decode_memory(FLIF_DECODER* decoder, const void* buffer, size_t buffer_size_bytes);
size_t flif_decoder_num_images(FLIF_DECODER* decoder);
int32_t flif_decoder_num_loops(FLIF_DECODER* decoder);
FLIF_IMAGE* flif_decoder_get_image(FLIF_DECODER* decoder, size_t index);
"""
ffi.set_source(
'_libflif',
"""
#include <stdint.h>
#include <stddef.h>
""" + SOURCE_CODE,
libraries=['flif_dec'])
ffi.cdef(SOURCE_CODE)
if __name__ == '__main__':
ffi.compile()
from _libflif import ffi, lib
import io
decoder = lib.flif_create_decoder()
lib.flif_decoder_decode_file(decoder, b"test.flif")
img = lib.flif_decoder_get_image(decoder, 0)
width = lib.flif_image_get_width(img)
height = lib.flif_image_get_height(img)
channels = lib.flif_image_get_nb_channels(img)
buffer = ffi.new("char[]", width*4)
fp = io.BytesIO()
for i in range(height):
lib.flif_image_read_row_RGBA8(img, i, buffer, width*4)
fp.write(ffi.buffer(buffer))
from PIL import Image
im = Image.new('RGBA', (width, height))
im.frombytes(fp.getvalue())
if channels == 3:
im = im.convert('RGB')
im.show()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment