| | |
| | import os |
| | import sys |
| |
|
| | from cffi import FFI |
| | ffi = FFI() |
| |
|
| | USE_SHARED_BROTLI = os.environ.get("USE_SHARED_BROTLI") |
| | if USE_SHARED_BROTLI != "1": |
| | libraries = ['libbrotli'] |
| | else: |
| | libraries = ['brotlienc', 'brotlidec'] |
| |
|
| | if 'win32' not in str(sys.platform).lower(): |
| | libraries.append('stdc++') |
| |
|
| |
|
| | ffi.set_source( |
| | "_brotlicffi", |
| | """#include <brotli/decode.h> |
| | #include <brotli/encode.h> |
| | """, |
| | libraries=libraries, |
| | include_dirs=["libbrotli/c", "libbrotli/c/include", "libbrotli/c/common"] |
| | ) |
| |
|
| | 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); |
| | |
| | /* 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); |
| | |
| | /* 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() |
| |
|