Spaces:
Running
Running
# -*- coding: utf-8 -*- | |
import sys | |
from cffi import FFI | |
ffi = FFI() | |
libraries = ['libbrotli'] | |
if 'win32' not in str(sys.platform).lower(): | |
libraries.append('stdc++') | |
ffi.set_source( | |
"_brotli", | |
"""#include <brotli/decode.h> | |
#include <brotli/encode.h> | |
""", | |
libraries=libraries, | |
include_dirs=["libbrotli", "libbrotli/include"] | |
) | |
ffi.cdef(""" | |
/* common/types.h */ | |
typedef bool BROTLI_BOOL; | |
#define BROTLI_TRUE ... | |
#define BROTLI_FALSE ... | |
/* dec/state.h */ | |
/* Allocating function pointer. Function MUST return 0 in the case of | |
failure. Otherwise it MUST return a valid pointer to a memory region of | |
at least size length. Neither items nor size are allowed to be 0. | |
opaque argument is a pointer provided by client and could be used to | |
bind function to specific object (memory pool). */ | |
typedef void* (*brotli_alloc_func)(void* opaque, size_t size); | |
/* Deallocating function pointer. Function SHOULD be no-op in the case the | |
address is 0. */ | |
typedef void (*brotli_free_func)(void* opaque, void* address); | |
/* dec/decode.h */ | |
typedef enum { | |
/* Decoding error, e.g. corrupt input or memory allocation problem */ | |
BROTLI_DECODER_RESULT_ERROR = 0, | |
/* Decoding successfully completed */ | |
BROTLI_DECODER_RESULT_SUCCESS = 1, | |
/* Partially done; should be called again with more input */ | |
BROTLI_DECODER_RESULT_NEEDS_MORE_INPUT = 2, | |
/* Partially done; should be called again with more output */ | |
BROTLI_DECODER_RESULT_NEEDS_MORE_OUTPUT = 3 | |
} BrotliDecoderResult; | |
typedef enum {...} BrotliDecoderErrorCode; | |
typedef ... BrotliDecoderState; | |
/* Creates the instance of BrotliDecoderState and initializes it. | |
|alloc_func| and |free_func| MUST be both zero or both non-zero. In the | |
case they are both zero, default memory allocators are used. |opaque| is | |
passed to |alloc_func| and |free_func| when they are called. */ | |
BrotliDecoderState* BrotliDecoderCreateInstance(brotli_alloc_func, | |
brotli_free_func, | |
void *); | |
/* Deinitializes and frees BrotliDecoderState instance. */ | |
void BrotliDecoderDestroyInstance(BrotliDecoderState* state); | |
/* Decompresses the data. Supports partial input and output. | |
Must be called with an allocated input buffer in |*next_in| and an | |
allocated output buffer in |*next_out|. The values |*available_in| and | |
|*available_out| must specify the allocated size in |*next_in| and | |
|*next_out| respectively. | |
After each call, |*available_in| will be decremented by the amount of | |
input bytes consumed, and the |*next_in| pointer will be incremented by | |
that amount. Similarly, |*available_out| will be decremented by the | |
amount of output bytes written, and the |*next_out| pointer will be | |
incremented by that amount. |total_out|, if it is not a null-pointer, | |
will be set to the number of bytes decompressed since the last state | |
initialization. | |
Input is never overconsumed, so |next_in| and |available_in| could be | |
passed to the next consumer after decoding is complete. */ | |
BrotliDecoderResult BrotliDecoderDecompressStream(BrotliDecoderState* s, | |
size_t* available_in, | |
const uint8_t** next_in, | |
size_t* available_out, | |
uint8_t** next_out, | |
size_t* total_out); | |
/* Fills the new state with a dictionary for LZ77, warming up the | |
ringbuffer, e.g. for custom static dictionaries for data formats. | |
Not to be confused with the built-in transformable dictionary of Brotli. | |
|size| should be less or equal to 2^24 (16MiB), otherwise the dictionary | |
will be ignored. The dictionary must exist in memory until decoding is | |
done and is owned by the caller. To use: | |
1) Allocate and initialize state with BrotliCreateInstance | |
2) Use BrotliSetCustomDictionary | |
3) Use BrotliDecompressStream | |
4) Clean up and free state with BrotliDestroyState | |
*/ | |
void BrotliDecoderSetCustomDictionary( | |
BrotliDecoderState* s, size_t size, const uint8_t* dict); | |
/* Returns true, if decoder has some unconsumed output. | |
Otherwise returns false. */ | |
BROTLI_BOOL BrotliDecoderHasMoreOutput(const BrotliDecoderState* s); | |
/* Returns true, if decoder has already received some input bytes. | |
Otherwise returns false. */ | |
BROTLI_BOOL BrotliDecoderIsUsed(const BrotliDecoderState* s); | |
/* Returns true, if decoder is in a state where we reached the end of the | |
input and produced all of the output; returns false otherwise. */ | |
BROTLI_BOOL BrotliDecoderIsFinished(const BrotliDecoderState* s); | |
/* Returns detailed error code after BrotliDecompressStream returns | |
BROTLI_DECODER_RESULT_ERROR. */ | |
BrotliDecoderErrorCode BrotliDecoderGetErrorCode( | |
const BrotliDecoderState* s); | |
const char* BrotliDecoderErrorString(BrotliDecoderErrorCode c); | |
/* enc/encode.h */ | |
typedef ... BrotliEncoderState; | |
typedef enum BrotliEncoderParameter { | |
BROTLI_PARAM_MODE = 0, | |
/* Controls the compression-speed vs compression-density tradeoffs. The | |
higher the quality, the slower the compression. Range is 0 to 11. */ | |
BROTLI_PARAM_QUALITY = 1, | |
/* Base 2 logarithm of the sliding window size. Range is 10 to 24. */ | |
BROTLI_PARAM_LGWIN = 2, | |
/* Base 2 logarithm of the maximum input block size. Range is 16 to 24. | |
If set to 0, the value will be set based on the quality. */ | |
BROTLI_PARAM_LGBLOCK = 3 | |
} BrotliEncoderParameter; | |
typedef enum BrotliEncoderMode { | |
/* Default compression mode. The compressor does not know anything in | |
advance about the properties of the input. */ | |
BROTLI_MODE_GENERIC = 0, | |
/* Compression mode for UTF-8 format text input. */ | |
BROTLI_MODE_TEXT = 1, | |
/* Compression mode used in WOFF 2.0. */ | |
BROTLI_MODE_FONT = 2 | |
} BrotliEncoderMode; | |
int BROTLI_DEFAULT_QUALITY = 11; | |
int BROTLI_DEFAULT_WINDOW = 22; | |
#define BROTLI_DEFAULT_MODE ... | |
typedef enum BrotliEncoderOperation { | |
BROTLI_OPERATION_PROCESS = 0, | |
/* Request output stream to flush. Performed when input stream is | |
depleted and there is enough space in output stream. */ | |
BROTLI_OPERATION_FLUSH = 1, | |
/* Request output stream to finish. Performed when input stream is | |
depleted and there is enough space in output stream. */ | |
BROTLI_OPERATION_FINISH = 2 | |
} BrotliEncoderOperation; | |
/* Creates the instance of BrotliEncoderState and initializes it. | |
|alloc_func| and |free_func| MUST be both zero or both non-zero. In the | |
case they are both zero, default memory allocators are used. |opaque| is | |
passed to |alloc_func| and |free_func| when they are called. */ | |
BrotliEncoderState* BrotliEncoderCreateInstance(brotli_alloc_func, | |
brotli_free_func, | |
void *); | |
/* Deinitializes and frees BrotliEncoderState instance. */ | |
void BrotliEncoderDestroyInstance(BrotliEncoderState* state); | |
/* Compresses the data in |input_buffer| into |encoded_buffer|, and sets | |
|*encoded_size| to the compressed length. | |
BROTLI_DEFAULT_QUALITY, BROTLI_DEFAULT_WINDOW and BROTLI_DEFAULT_MODE | |
should be used as |quality|, |lgwin| and |mode| if there are no specific | |
requirements to encoder speed and compression ratio. | |
If compression fails, |*encoded_size| is set to 0. | |
If BrotliEncoderMaxCompressedSize(|input_size|) is not zero, then | |
|*encoded_size| is never set to the bigger value. | |
Returns false if there was an error and true otherwise. */ | |
BROTLI_BOOL BrotliEncoderCompress(int quality, | |
int lgwin, | |
BrotliEncoderMode mode, | |
size_t input_size, | |
const uint8_t* input_buffer, | |
size_t* encoded_size, | |
uint8_t* encoded_buffer); | |
BROTLI_BOOL BrotliEncoderCompressStream(BrotliEncoderState* s, | |
BrotliEncoderOperation op, | |
size_t* available_in, | |
const uint8_t** next_in, | |
size_t* available_out, | |
uint8_t** next_out, | |
size_t* total_out); | |
BROTLI_BOOL BrotliEncoderSetParameter(BrotliEncoderState* state, | |
BrotliEncoderParameter p, | |
uint32_t value); | |
/* Fills the new state with a dictionary for LZ77, warming up the | |
ringbuffer, e.g. for custom static dictionaries for data formats. | |
Not to be confused with the built-in transformable dictionary of Brotli. | |
To decode, use BrotliSetCustomDictionary() of the decoder with the same | |
dictionary. */ | |
void BrotliEncoderSetCustomDictionary(BrotliEncoderState* state, | |
size_t size, | |
const uint8_t* dict); | |
/* Check if encoder is in "finished" state, i.e. no more input is | |
acceptable and no more output will be produced. | |
Works only with BrotliEncoderCompressStream workflow. | |
Returns 1 if stream is finished and 0 otherwise. */ | |
BROTLI_BOOL BrotliEncoderIsFinished(BrotliEncoderState* s); | |
/* Check if encoder has more output bytes in internal buffer. | |
Works only with BrotliEncoderCompressStream workflow. | |
Returns 1 if has more output (in internal buffer) and 0 otherwise. */ | |
BROTLI_BOOL BrotliEncoderHasMoreOutput(BrotliEncoderState* s); | |
""") | |
if __name__ == '__main__': | |
ffi.compile() | |