mirror of
https://github.com/google/brotli.git
synced 2024-11-27 11:53:33 +08:00
* rename macros with preceding underscore
* add Brotli*TakeOutput methods * * flushing now doesn't require additional call * add Brotli*Version methods * moved public headers to 'public' directory * removed C++ API * do not assume STDC_VERSION is defined
This commit is contained in:
parent
2e0d3214c2
commit
801f5f37ee
20
BUILD
20
BUILD
@ -21,6 +21,11 @@ STRICT_C_OPTIONS = [
|
||||
"-Wsign-compare",
|
||||
]
|
||||
|
||||
filegroup(
|
||||
name = "public_headers",
|
||||
srcs = glob(["public/*.h"]),
|
||||
)
|
||||
|
||||
filegroup(
|
||||
name = "common_headers",
|
||||
srcs = glob(["common/*.h"]),
|
||||
@ -54,14 +59,20 @@ filegroup(
|
||||
cc_library(
|
||||
name = "brotli_common",
|
||||
srcs = [":common_sources"],
|
||||
hdrs = [":common_headers"],
|
||||
hdrs = [
|
||||
":common_headers",
|
||||
":public_headers",
|
||||
],
|
||||
copts = STRICT_C_OPTIONS,
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "brotli_dec",
|
||||
srcs = [":dec_sources"],
|
||||
hdrs = [":dec_headers"],
|
||||
hdrs = [
|
||||
":dec_headers",
|
||||
":public_headers",
|
||||
],
|
||||
copts = STRICT_C_OPTIONS,
|
||||
deps = [
|
||||
":brotli_common",
|
||||
@ -71,7 +82,10 @@ cc_library(
|
||||
cc_library(
|
||||
name = "brotli_enc",
|
||||
srcs = [":enc_sources"],
|
||||
hdrs = [":enc_headers"],
|
||||
hdrs = [
|
||||
":enc_headers",
|
||||
":public_headers",
|
||||
],
|
||||
copts = STRICT_C_OPTIONS,
|
||||
deps = [
|
||||
":brotli_common",
|
||||
|
@ -9,7 +9,7 @@
|
||||
#ifndef BROTLI_COMMON_DICTIONARY_H_
|
||||
#define BROTLI_COMMON_DICTIONARY_H_
|
||||
|
||||
#include "./types.h"
|
||||
#include "../public/types.h"
|
||||
|
||||
#if defined(__cplusplus) || defined(c_plusplus)
|
||||
extern "C" {
|
||||
|
@ -87,7 +87,7 @@ OR:
|
||||
|
||||
#ifndef _MSC_VER
|
||||
#if defined(__cplusplus) || !defined(__STRICT_ANSI__) || \
|
||||
__STDC_VERSION__ >= 199901L
|
||||
(defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L)
|
||||
#define BROTLI_INLINE inline ATTRIBUTE_ALWAYS_INLINE
|
||||
#else
|
||||
#define BROTLI_INLINE
|
||||
|
19
common/version.h
Executable file
19
common/version.h
Executable file
@ -0,0 +1,19 @@
|
||||
/* Copyright 2016 Google Inc. All Rights Reserved.
|
||||
|
||||
Distributed under MIT license.
|
||||
See file LICENSE for detail or copy at https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
/* Version definition. */
|
||||
|
||||
#ifndef BROTLI_COMMON_VERSION_H_
|
||||
#define BROTLI_COMMON_VERSION_H_
|
||||
|
||||
/* This macro should only be used when library is compiled together with client.
|
||||
If library is dynamically linked, use BrotliDecoderVersion and
|
||||
BrotliEncoderVersion methods. */
|
||||
|
||||
/* Semantic version, claculated as (MAJOR << 24) | (MINOR << 12) | PATCH */
|
||||
#define BROTLI_VERSION 0x1000000
|
||||
|
||||
#endif /* BROTLI_COMMON_VERSION_H_ */
|
@ -8,7 +8,7 @@
|
||||
|
||||
#include "./bit_reader.h"
|
||||
|
||||
#include "../common/types.h"
|
||||
#include "../public/types.h"
|
||||
#include "./port.h"
|
||||
|
||||
#if defined(__cplusplus) || defined(c_plusplus)
|
||||
|
@ -11,7 +11,7 @@
|
||||
|
||||
#include <string.h> /* memcpy */
|
||||
|
||||
#include "../common/types.h"
|
||||
#include "../public/types.h"
|
||||
#include "./port.h"
|
||||
|
||||
#if defined(__cplusplus) || defined(c_plusplus)
|
||||
|
@ -99,7 +99,7 @@
|
||||
#ifndef BROTLI_DEC_CONTEXT_H_
|
||||
#define BROTLI_DEC_CONTEXT_H_
|
||||
|
||||
#include "../common/types.h"
|
||||
#include "../public/types.h"
|
||||
|
||||
enum ContextType {
|
||||
CONTEXT_LSB6 = 0,
|
||||
|
68
dec/decode.c
68
dec/decode.c
@ -4,7 +4,7 @@
|
||||
See file LICENSE for detail or copy at https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#include "./decode.h"
|
||||
#include "../public/decode.h"
|
||||
|
||||
#ifdef __ARM_NEON__
|
||||
#include <arm_neon.h>
|
||||
@ -15,6 +15,7 @@
|
||||
|
||||
#include "../common/constants.h"
|
||||
#include "../common/dictionary.h"
|
||||
#include "../common/version.h"
|
||||
#include "./bit_reader.h"
|
||||
#include "./context.h"
|
||||
#include "./huffman.h"
|
||||
@ -181,7 +182,7 @@ static BrotliDecoderErrorCode BROTLI_NOINLINE DecodeMetaBlockLength(
|
||||
if (!BrotliSafeReadBits(br, 1, &bits)) {
|
||||
return BROTLI_DECODER_NEEDS_MORE_INPUT;
|
||||
}
|
||||
s->is_last_metablock = (uint8_t)bits;
|
||||
s->is_last_metablock = bits ? 1 : 0;
|
||||
s->meta_block_remaining_len = 0;
|
||||
s->is_uncompressed = 0;
|
||||
s->is_metadata = 0;
|
||||
@ -238,7 +239,7 @@ static BrotliDecoderErrorCode BROTLI_NOINLINE DecodeMetaBlockLength(
|
||||
if (!BrotliSafeReadBits(br, 1, &bits)) {
|
||||
return BROTLI_DECODER_NEEDS_MORE_INPUT;
|
||||
}
|
||||
s->is_uncompressed = (uint8_t)bits;
|
||||
s->is_uncompressed = bits ? 1 : 0;
|
||||
}
|
||||
++s->meta_block_remaining_len;
|
||||
s->substate_metablock_header = BROTLI_STATE_METABLOCK_HEADER_NONE;
|
||||
@ -1185,8 +1186,14 @@ static BrotliDecoderErrorCode BROTLI_NOINLINE WriteRingBuffer(
|
||||
if (s->meta_block_remaining_len < 0) {
|
||||
return BROTLI_FAILURE(BROTLI_DECODER_ERROR_FORMAT_BLOCK_LENGTH_1);
|
||||
}
|
||||
if (next_out && !*next_out) {
|
||||
*next_out = start;
|
||||
} else {
|
||||
if (next_out) {
|
||||
memcpy(*next_out, start, num_written);
|
||||
*next_out += num_written;
|
||||
}
|
||||
}
|
||||
*available_out -= num_written;
|
||||
BROTLI_LOG_UINT(to_write);
|
||||
BROTLI_LOG_UINT(num_written);
|
||||
@ -1195,14 +1202,21 @@ static BrotliDecoderErrorCode BROTLI_NOINLINE WriteRingBuffer(
|
||||
if (num_written < to_write) {
|
||||
return BROTLI_DECODER_NEEDS_MORE_OUTPUT;
|
||||
}
|
||||
|
||||
if (s->pos >= s->ringbuffer_size) {
|
||||
s->pos -= s->ringbuffer_size;
|
||||
s->rb_roundtrips++;
|
||||
s->should_wrap_ringbuffer = (size_t)s->pos != 0 ? 1 : 0;
|
||||
}
|
||||
return BROTLI_DECODER_SUCCESS;
|
||||
}
|
||||
|
||||
static void BROTLI_NOINLINE WrapRingBuffer(BrotliDecoderState* s) {
|
||||
if (s->should_wrap_ringbuffer) {
|
||||
memcpy(s->ringbuffer, s->ringbuffer_end, (size_t)s->pos);
|
||||
s->should_wrap_ringbuffer = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Allocates ringbuffer.
|
||||
|
||||
s->ringbuffer_size MUST be updated by BrotliCalculateRingBufferSize before
|
||||
@ -1871,6 +1885,11 @@ BrotliDecoderResult BrotliDecoderDecompressStream(
|
||||
size_t* available_out, uint8_t** next_out, size_t* total_out) {
|
||||
BrotliDecoderErrorCode result = BROTLI_DECODER_SUCCESS;
|
||||
BrotliBitReader* br = &s->br;
|
||||
if (*available_out && (!next_out || !*next_out)) {
|
||||
return SaveErrorCode(
|
||||
s, BROTLI_FAILURE(BROTLI_DECODER_ERROR_INVALID_ARGUMENTS));
|
||||
}
|
||||
if (!*available_out) next_out = 0;
|
||||
if (s->buffer_length == 0) { /* Just connect bit reader to input stream. */
|
||||
br->avail_in = *available_in;
|
||||
br->next_in = *next_in;
|
||||
@ -2206,9 +2225,9 @@ BrotliDecoderResult BrotliDecoderDecompressStream(
|
||||
if (result != BROTLI_DECODER_SUCCESS) {
|
||||
break;
|
||||
}
|
||||
WrapRingBuffer(s);
|
||||
s->max_distance = s->max_backward_distance;
|
||||
if (s->state == BROTLI_STATE_COMMAND_POST_WRITE_1) {
|
||||
memcpy(s->ringbuffer, s->ringbuffer_end, (size_t)s->pos);
|
||||
if (s->meta_block_remaining_len == 0) {
|
||||
/* Next metablock, if any */
|
||||
s->state = BROTLI_STATE_METABLOCK_DONE;
|
||||
@ -2278,13 +2297,36 @@ BROTLI_BOOL BrotliDecoderHasMoreOutput(const BrotliDecoderState* s) {
|
||||
s->ringbuffer != 0 && UnwrittenBytes(s, BROTLI_FALSE) != 0);
|
||||
}
|
||||
|
||||
const uint8_t* BrotliDecoderTakeOutput(BrotliDecoderState* s, size_t* size) {
|
||||
uint8_t* result = 0;
|
||||
size_t available_out = *size ? *size : 1u << 24;
|
||||
size_t requested_out = available_out;
|
||||
BrotliDecoderErrorCode status;
|
||||
if (s->ringbuffer == 0) {
|
||||
*size = 0;
|
||||
return 0;
|
||||
}
|
||||
WrapRingBuffer(s);
|
||||
status = WriteRingBuffer(s, &available_out, &result, 0);
|
||||
if (status == BROTLI_DECODER_SUCCESS ||
|
||||
status == BROTLI_DECODER_NEEDS_MORE_OUTPUT) {
|
||||
*size = requested_out - available_out;
|
||||
} else {
|
||||
/* This might happen if previous decoder error code was ignored. */
|
||||
*size = 0;
|
||||
result = 0;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
BROTLI_BOOL BrotliDecoderIsUsed(const BrotliDecoderState* s) {
|
||||
return TO_BROTLI_BOOL(s->state != BROTLI_STATE_UNINITED ||
|
||||
BrotliGetAvailableBits(&s->br) != 0);
|
||||
}
|
||||
|
||||
BROTLI_BOOL BrotliDecoderIsFinished(const BrotliDecoderState* s) {
|
||||
return TO_BROTLI_BOOL(s->state == BROTLI_STATE_DONE);
|
||||
return TO_BROTLI_BOOL(s->state == BROTLI_STATE_DONE) &&
|
||||
!BrotliDecoderHasMoreOutput(s);
|
||||
}
|
||||
|
||||
BrotliDecoderErrorCode BrotliDecoderGetErrorCode(const BrotliDecoderState* s) {
|
||||
@ -2293,16 +2335,20 @@ BrotliDecoderErrorCode BrotliDecoderGetErrorCode(const BrotliDecoderState* s) {
|
||||
|
||||
const char* BrotliDecoderErrorString(BrotliDecoderErrorCode c) {
|
||||
switch (c) {
|
||||
#define _BROTLI_ERROR_CODE_CASE(PREFIX, NAME, CODE) \
|
||||
#define BROTLI_ERROR_CODE_CASE_(PREFIX, NAME, CODE) \
|
||||
case BROTLI_DECODER ## PREFIX ## NAME: return #NAME;
|
||||
#define _BROTLI_NOTHING
|
||||
BROTLI_DECODER_ERROR_CODES_LIST(_BROTLI_ERROR_CODE_CASE, _BROTLI_NOTHING)
|
||||
#undef _BROTLI_ERROR_CODE_CASE
|
||||
#undef _BROTLI_NOTHING
|
||||
#define BROTLI_NOTHING_
|
||||
BROTLI_DECODER_ERROR_CODES_LIST(BROTLI_ERROR_CODE_CASE_, BROTLI_NOTHING_)
|
||||
#undef BROTLI_ERROR_CODE_CASE_
|
||||
#undef BROTLI_NOTHING_
|
||||
default: return "INVALID";
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t BrotliDecoderVersion() {
|
||||
return BROTLI_VERSION;
|
||||
}
|
||||
|
||||
/* DEPRECATED >>> */
|
||||
BrotliState* BrotliCreateState(
|
||||
brotli_alloc_func alloc, brotli_free_func free, void* opaque) {
|
||||
|
@ -11,7 +11,7 @@
|
||||
#include <string.h> /* memcpy, memset */
|
||||
|
||||
#include "../common/constants.h"
|
||||
#include "../common/types.h"
|
||||
#include "../public/types.h"
|
||||
#include "./port.h"
|
||||
|
||||
#if defined(__cplusplus) || defined(c_plusplus)
|
||||
|
@ -9,7 +9,7 @@
|
||||
#ifndef BROTLI_DEC_HUFFMAN_H_
|
||||
#define BROTLI_DEC_HUFFMAN_H_
|
||||
|
||||
#include "../common/types.h"
|
||||
#include "../public/types.h"
|
||||
#include "./port.h"
|
||||
|
||||
#if defined(__cplusplus) || defined(c_plusplus)
|
||||
|
@ -12,7 +12,7 @@
|
||||
#define BROTLI_DEC_PREFIX_H_
|
||||
|
||||
#include "../common/constants.h"
|
||||
#include "../common/types.h"
|
||||
#include "../public/types.h"
|
||||
|
||||
/* Represents the range of values belonging to a prefix code: */
|
||||
/* [offset, offset + 2^nbits) */
|
||||
|
@ -8,7 +8,7 @@
|
||||
|
||||
#include <stdlib.h> /* free, malloc */
|
||||
|
||||
#include "../common/types.h"
|
||||
#include "../public/types.h"
|
||||
#include "./huffman.h"
|
||||
|
||||
#if defined(__cplusplus) || defined(c_plusplus)
|
||||
@ -80,6 +80,7 @@ void BrotliDecoderStateInitWithCustomAllocators(BrotliDecoderState* s,
|
||||
s->custom_dict_size = 0;
|
||||
|
||||
s->is_last_metablock = 0;
|
||||
s->should_wrap_ringbuffer = 0;
|
||||
s->window_bits = 0;
|
||||
s->max_distance = 0;
|
||||
s->dist_rb[0] = 16;
|
||||
|
11
dec/state.h
11
dec/state.h
@ -10,7 +10,7 @@
|
||||
#define BROTLI_DEC_STATE_H_
|
||||
|
||||
#include "../common/constants.h"
|
||||
#include "../common/types.h"
|
||||
#include "../public/types.h"
|
||||
#include "./bit_reader.h"
|
||||
#include "./huffman.h"
|
||||
#include "./port.h"
|
||||
@ -209,10 +209,11 @@ struct BrotliDecoderStateStruct {
|
||||
BrotliRunningDecodeUint8State substate_decode_uint8;
|
||||
BrotliRunningReadBlockLengthState substate_read_block_length;
|
||||
|
||||
uint8_t is_last_metablock;
|
||||
uint8_t is_uncompressed;
|
||||
uint8_t is_metadata;
|
||||
uint8_t size_nibbles;
|
||||
unsigned int is_last_metablock : 1;
|
||||
unsigned int is_uncompressed : 1;
|
||||
unsigned int is_metadata : 1;
|
||||
unsigned int should_wrap_ringbuffer : 1;
|
||||
unsigned int size_nibbles : 8;
|
||||
uint32_t window_bits;
|
||||
|
||||
uint32_t num_literal_htrees;
|
||||
|
@ -9,7 +9,7 @@
|
||||
#ifndef BROTLI_DEC_TRANSFORM_H_
|
||||
#define BROTLI_DEC_TRANSFORM_H_
|
||||
|
||||
#include "../common/types.h"
|
||||
#include "../public/types.h"
|
||||
#include "./port.h"
|
||||
|
||||
#if defined(__cplusplus) || defined(c_plusplus)
|
||||
|
@ -12,7 +12,7 @@
|
||||
#include <string.h> /* memcpy, memset */
|
||||
|
||||
#include "../common/constants.h"
|
||||
#include "../common/types.h"
|
||||
#include "../public/types.h"
|
||||
#include "./command.h"
|
||||
#include "./fast_log.h"
|
||||
#include "./find_match_length.h"
|
||||
@ -873,14 +873,14 @@ void BrotliCreateBackwardReferences(MemoryManager* m,
|
||||
}
|
||||
|
||||
switch (ChooseHasher(params)) {
|
||||
#define _CASE(N) \
|
||||
#define CASE_(N) \
|
||||
case N: \
|
||||
CreateBackwardReferencesH ## N(m, num_bytes, position, is_last, \
|
||||
ringbuffer, ringbuffer_mask, params, hashers->h ## N, dist_cache, \
|
||||
last_insert_len, commands, num_commands, num_literals); \
|
||||
break;
|
||||
FOR_GENERIC_HASHERS(_CASE)
|
||||
#undef _CASE
|
||||
FOR_GENERIC_HASHERS(CASE_)
|
||||
#undef CASE_
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -9,7 +9,7 @@
|
||||
#ifndef BROTLI_ENC_BACKWARD_REFERENCES_H_
|
||||
#define BROTLI_ENC_BACKWARD_REFERENCES_H_
|
||||
|
||||
#include "../common/types.h"
|
||||
#include "../public/types.h"
|
||||
#include "./command.h"
|
||||
#include "./hash.h"
|
||||
#include "./memory.h"
|
||||
|
@ -9,7 +9,7 @@
|
||||
#include "./bit_cost.h"
|
||||
|
||||
#include "../common/constants.h"
|
||||
#include "../common/types.h"
|
||||
#include "../public/types.h"
|
||||
#include "./fast_log.h"
|
||||
#include "./histogram.h"
|
||||
#include "./port.h"
|
||||
|
@ -9,7 +9,7 @@
|
||||
#ifndef BROTLI_ENC_BIT_COST_H_
|
||||
#define BROTLI_ENC_BIT_COST_H_
|
||||
|
||||
#include "../common/types.h"
|
||||
#include "../public/types.h"
|
||||
#include "./fast_log.h"
|
||||
#include "./histogram.h"
|
||||
#include "./port.h"
|
||||
|
@ -9,7 +9,7 @@
|
||||
#ifndef BROTLI_ENC_BLOCK_SPLITTER_H_
|
||||
#define BROTLI_ENC_BLOCK_SPLITTER_H_
|
||||
|
||||
#include "../common/types.h"
|
||||
#include "../public/types.h"
|
||||
#include "./command.h"
|
||||
#include "./memory.h"
|
||||
#include "./port.h"
|
||||
|
@ -13,7 +13,7 @@
|
||||
#include <string.h> /* memcpy, memset */
|
||||
|
||||
#include "../common/constants.h"
|
||||
#include "../common/types.h"
|
||||
#include "../public/types.h"
|
||||
#include "./context.h"
|
||||
#include "./entropy_encode.h"
|
||||
#include "./entropy_encode_static.h"
|
||||
|
@ -16,7 +16,7 @@
|
||||
#ifndef BROTLI_ENC_BROTLI_BIT_STREAM_H_
|
||||
#define BROTLI_ENC_BROTLI_BIT_STREAM_H_
|
||||
|
||||
#include "../common/types.h"
|
||||
#include "../public/types.h"
|
||||
#include "./command.h"
|
||||
#include "./context.h"
|
||||
#include "./entropy_encode.h"
|
||||
|
@ -8,7 +8,7 @@
|
||||
|
||||
#include "./cluster.h"
|
||||
|
||||
#include "../common/types.h"
|
||||
#include "../public/types.h"
|
||||
#include "./bit_cost.h" /* BrotliPopulationCost */
|
||||
#include "./fast_log.h"
|
||||
#include "./histogram.h"
|
||||
|
@ -9,7 +9,7 @@
|
||||
#ifndef BROTLI_ENC_CLUSTER_H_
|
||||
#define BROTLI_ENC_CLUSTER_H_
|
||||
|
||||
#include "../common/types.h"
|
||||
#include "../public/types.h"
|
||||
#include "./histogram.h"
|
||||
#include "./memory.h"
|
||||
#include "./port.h"
|
||||
|
@ -9,7 +9,7 @@
|
||||
#ifndef BROTLI_ENC_COMMAND_H_
|
||||
#define BROTLI_ENC_COMMAND_H_
|
||||
|
||||
#include "../common/types.h"
|
||||
#include "../public/types.h"
|
||||
#include "../common/port.h"
|
||||
#include "./fast_log.h"
|
||||
#include "./prefix.h"
|
||||
|
@ -16,7 +16,7 @@
|
||||
|
||||
#include <string.h> /* memcmp, memcpy, memset */
|
||||
|
||||
#include "../common/types.h"
|
||||
#include "../public/types.h"
|
||||
#include "./brotli_bit_stream.h"
|
||||
#include "./entropy_encode.h"
|
||||
#include "./fast_log.h"
|
||||
|
@ -12,7 +12,7 @@
|
||||
#ifndef BROTLI_ENC_COMPRESS_FRAGMENT_H_
|
||||
#define BROTLI_ENC_COMPRESS_FRAGMENT_H_
|
||||
|
||||
#include "../common/types.h"
|
||||
#include "../public/types.h"
|
||||
#include "./memory.h"
|
||||
#include "./port.h"
|
||||
|
||||
|
@ -14,7 +14,7 @@
|
||||
|
||||
#include <string.h> /* memcmp, memcpy, memset */
|
||||
|
||||
#include "../common/types.h"
|
||||
#include "../public/types.h"
|
||||
#include "./bit_cost.h"
|
||||
#include "./brotli_bit_stream.h"
|
||||
#include "./entropy_encode.h"
|
||||
|
@ -13,7 +13,7 @@
|
||||
#ifndef BROTLI_ENC_COMPRESS_FRAGMENT_TWO_PASS_H_
|
||||
#define BROTLI_ENC_COMPRESS_FRAGMENT_TWO_PASS_H_
|
||||
|
||||
#include "../common/types.h"
|
||||
#include "../public/types.h"
|
||||
#include "./memory.h"
|
||||
#include "./port.h"
|
||||
|
||||
|
@ -1,139 +0,0 @@
|
||||
/* Copyright 2016 Google Inc. All Rights Reserved.
|
||||
|
||||
Distributed under MIT license.
|
||||
See file LICENSE for detail or copy at https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
/* Brotli compressor API C++ wrapper and utilities. */
|
||||
|
||||
#include "./compressor.h"
|
||||
|
||||
#include <cstdlib> /* exit */
|
||||
|
||||
namespace brotli {
|
||||
|
||||
static void SetParams(const BrotliParams* from, BrotliEncoderState* to) {
|
||||
BrotliEncoderMode mode = BROTLI_MODE_GENERIC;
|
||||
if (from->mode == BrotliParams::MODE_TEXT) {
|
||||
mode = BROTLI_MODE_TEXT;
|
||||
} else if (from->mode == BrotliParams::MODE_FONT) {
|
||||
mode = BROTLI_MODE_FONT;
|
||||
}
|
||||
BrotliEncoderSetParameter(to, BROTLI_PARAM_MODE, (uint32_t)mode);
|
||||
BrotliEncoderSetParameter(to, BROTLI_PARAM_QUALITY, (uint32_t)from->quality);
|
||||
BrotliEncoderSetParameter(to, BROTLI_PARAM_LGWIN, (uint32_t)from->lgwin);
|
||||
BrotliEncoderSetParameter(to, BROTLI_PARAM_LGBLOCK, (uint32_t)from->lgblock);
|
||||
}
|
||||
|
||||
BrotliCompressor::BrotliCompressor(BrotliParams params) {
|
||||
state_ = BrotliEncoderCreateInstance(0, 0, 0);
|
||||
if (state_ == 0) std::exit(EXIT_FAILURE); /* OOM */
|
||||
SetParams(¶ms, state_);
|
||||
}
|
||||
|
||||
BrotliCompressor::~BrotliCompressor(void) {
|
||||
BrotliEncoderDestroyInstance(state_);
|
||||
}
|
||||
|
||||
bool BrotliCompressor::WriteMetaBlock(const size_t input_size,
|
||||
const uint8_t* input_buffer,
|
||||
const bool is_last, size_t* encoded_size,
|
||||
uint8_t* encoded_buffer) {
|
||||
return !!BrotliEncoderWriteMetaBlock(state_, input_size, input_buffer,
|
||||
TO_BROTLI_BOOL(is_last), encoded_size,
|
||||
encoded_buffer);
|
||||
}
|
||||
|
||||
bool BrotliCompressor::WriteMetadata(const size_t input_size,
|
||||
const uint8_t* input_buffer,
|
||||
const bool is_last, size_t* encoded_size,
|
||||
uint8_t* encoded_buffer) {
|
||||
return !!BrotliEncoderWriteMetadata(state_, input_size, input_buffer,
|
||||
TO_BROTLI_BOOL(is_last), encoded_size,
|
||||
encoded_buffer);
|
||||
}
|
||||
|
||||
bool BrotliCompressor::FinishStream(size_t* encoded_size,
|
||||
uint8_t* encoded_buffer) {
|
||||
return !!BrotliEncoderFinishStream(state_, encoded_size, encoded_buffer);
|
||||
}
|
||||
|
||||
void BrotliCompressor::CopyInputToRingBuffer(const size_t input_size,
|
||||
const uint8_t* input_buffer) {
|
||||
BrotliEncoderCopyInputToRingBuffer(state_, input_size, input_buffer);
|
||||
}
|
||||
|
||||
bool BrotliCompressor::WriteBrotliData(const bool is_last,
|
||||
const bool force_flush, size_t* out_size,
|
||||
uint8_t** output) {
|
||||
return !!BrotliEncoderWriteData(state_, TO_BROTLI_BOOL(is_last),
|
||||
TO_BROTLI_BOOL(force_flush), out_size, output);
|
||||
}
|
||||
|
||||
void BrotliCompressor::BrotliSetCustomDictionary(size_t size,
|
||||
const uint8_t* dict) {
|
||||
BrotliEncoderSetCustomDictionary(state_, size, dict);
|
||||
}
|
||||
|
||||
int BrotliCompressBuffer(BrotliParams params, size_t input_size,
|
||||
const uint8_t* input_buffer, size_t* encoded_size,
|
||||
uint8_t* encoded_buffer) {
|
||||
return BrotliEncoderCompress(params.quality, params.lgwin,
|
||||
(BrotliEncoderMode)params.mode, input_size, input_buffer,
|
||||
encoded_size, encoded_buffer);
|
||||
}
|
||||
|
||||
int BrotliCompress(BrotliParams params, BrotliIn* in, BrotliOut* out) {
|
||||
return BrotliCompressWithCustomDictionary(0, 0, params, in, out);
|
||||
}
|
||||
|
||||
int BrotliCompressWithCustomDictionary(size_t dictsize, const uint8_t* dict,
|
||||
BrotliParams params, BrotliIn* in,
|
||||
BrotliOut* out) {
|
||||
const size_t kOutputBufferSize = 65536;
|
||||
uint8_t* output_buffer;
|
||||
bool result = true;
|
||||
size_t available_in = 0;
|
||||
const uint8_t* next_in = NULL;
|
||||
size_t total_out = 0;
|
||||
bool end_of_input = false;
|
||||
BrotliEncoderState* s;
|
||||
|
||||
s = BrotliEncoderCreateInstance(0, 0, 0);
|
||||
if (!s) return 0;
|
||||
SetParams(¶ms, s);
|
||||
BrotliEncoderSetCustomDictionary(s, dictsize, dict);
|
||||
output_buffer = new uint8_t[kOutputBufferSize];
|
||||
|
||||
while (true) {
|
||||
if (available_in == 0 && !end_of_input) {
|
||||
next_in = reinterpret_cast<const uint8_t*>(
|
||||
in->Read(BrotliEncoderInputBlockSize(s), &available_in));
|
||||
if (!next_in) {
|
||||
end_of_input = true;
|
||||
available_in = 0;
|
||||
} else if (available_in == 0) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
size_t available_out = kOutputBufferSize;
|
||||
uint8_t* next_out = output_buffer;
|
||||
result = !!BrotliEncoderCompressStream(
|
||||
s, end_of_input ? BROTLI_OPERATION_FINISH : BROTLI_OPERATION_PROCESS,
|
||||
&available_in, &next_in, &available_out, &next_out, &total_out);
|
||||
if (!result) break;
|
||||
size_t used_output = kOutputBufferSize - available_out;
|
||||
if (used_output != 0) {
|
||||
result = out->Write(output_buffer, used_output);
|
||||
if (!result) break;
|
||||
}
|
||||
if (BrotliEncoderIsFinished(s)) break;
|
||||
}
|
||||
|
||||
delete[] output_buffer;
|
||||
BrotliEncoderDestroyInstance(s);
|
||||
return result ? 1 : 0;
|
||||
}
|
||||
|
||||
|
||||
} /* namespace brotli */
|
161
enc/compressor.h
161
enc/compressor.h
@ -1,161 +0,0 @@
|
||||
/* Copyright 2016 Google Inc. All Rights Reserved.
|
||||
|
||||
Distributed under MIT license.
|
||||
See file LICENSE for detail or copy at https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
/* C++ API for Brotli compression. */
|
||||
|
||||
#ifndef BROTLI_ENC_COMPRESSOR_H_
|
||||
#define BROTLI_ENC_COMPRESSOR_H_
|
||||
|
||||
#include "./encode.h"
|
||||
#include "./streams.h"
|
||||
|
||||
namespace brotli {
|
||||
|
||||
static const int kMinWindowBits = kBrotliMinWindowBits;
|
||||
static const int kMaxWindowBits = kBrotliMaxWindowBits;
|
||||
static const int kMinInputBlockBits = kBrotliMinInputBlockBits;
|
||||
static const int kMaxInputBlockBits = kBrotliMaxInputBlockBits;
|
||||
|
||||
struct BrotliParams {
|
||||
BrotliParams(void)
|
||||
: mode(MODE_GENERIC),
|
||||
quality(11),
|
||||
lgwin(22),
|
||||
lgblock(0),
|
||||
enable_dictionary(true),
|
||||
enable_transforms(false),
|
||||
greedy_block_split(false),
|
||||
enable_context_modeling(true) {}
|
||||
|
||||
enum Mode {
|
||||
/* Default compression mode. The compressor does not know anything in
|
||||
advance about the properties of the input. */
|
||||
MODE_GENERIC = 0,
|
||||
/* Compression mode for UTF-8 format text input. */
|
||||
MODE_TEXT = 1,
|
||||
/* Compression mode used in WOFF 2.0. */
|
||||
MODE_FONT = 2
|
||||
};
|
||||
Mode mode;
|
||||
|
||||
/* Controls the compression-speed vs compression-density tradeoffs. The higher
|
||||
the |quality|, the slower the compression. Range is 0 to 11. */
|
||||
int quality;
|
||||
/* Base 2 logarithm of the sliding window size. Range is 10 to 24. */
|
||||
int lgwin;
|
||||
/* 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. */
|
||||
int lgblock;
|
||||
|
||||
/* These settings are deprecated and will be ignored.
|
||||
All speed vs. size compromises are controlled by the |quality| param. */
|
||||
bool enable_dictionary;
|
||||
bool enable_transforms;
|
||||
bool greedy_block_split;
|
||||
bool enable_context_modeling;
|
||||
};
|
||||
|
||||
/* An instance can not be reused for multiple brotli streams. */
|
||||
class BrotliCompressor {
|
||||
public:
|
||||
explicit BrotliCompressor(BrotliParams params);
|
||||
~BrotliCompressor(void);
|
||||
|
||||
/* The maximum input size that can be processed at once. */
|
||||
size_t input_block_size(void) const {
|
||||
return BrotliEncoderInputBlockSize(state_);
|
||||
}
|
||||
|
||||
/* Encodes the data in |input_buffer| as a meta-block and writes it to
|
||||
|encoded_buffer| (|*encoded_size should| be set to the size of
|
||||
|encoded_buffer|) and sets |*encoded_size| to the number of bytes that
|
||||
was written. The |input_size| must not be greater than input_block_size().
|
||||
Returns false if there was an error and true otherwise. */
|
||||
bool WriteMetaBlock(const size_t input_size,
|
||||
const uint8_t* input_buffer,
|
||||
const bool is_last,
|
||||
size_t* encoded_size,
|
||||
uint8_t* encoded_buffer);
|
||||
|
||||
/* Writes a metadata meta-block containing the given input to encoded_buffer.
|
||||
|*encoded_size| should be set to the size of the encoded_buffer.
|
||||
Sets |*encoded_size| to the number of bytes that was written.
|
||||
Note that the given input data will not be part of the sliding window and
|
||||
thus no backward references can be made to this data from subsequent
|
||||
metablocks. |input_size| must not be greater than 2^24 and provided
|
||||
|*encoded_size| must not be less than |input_size| + 6.
|
||||
Returns false if there was an error and true otherwise. */
|
||||
bool WriteMetadata(const size_t input_size,
|
||||
const uint8_t* input_buffer,
|
||||
const bool is_last,
|
||||
size_t* encoded_size,
|
||||
uint8_t* encoded_buffer);
|
||||
|
||||
/* Writes a zero-length meta-block with end-of-input bit set to the
|
||||
internal output buffer and copies the output buffer to |encoded_buffer|
|
||||
(|*encoded_size| should be set to the size of |encoded_buffer|) and sets
|
||||
|*encoded_size| to the number of bytes written.
|
||||
Returns false if there was an error and true otherwise. */
|
||||
bool FinishStream(size_t* encoded_size, uint8_t* encoded_buffer);
|
||||
|
||||
/* Copies the given input data to the internal ring buffer of the compressor.
|
||||
No processing of the data occurs at this time and this function can be
|
||||
called multiple times before calling WriteBrotliData() to process the
|
||||
accumulated input. At most input_block_size() bytes of input data can be
|
||||
copied to the ring buffer, otherwise the next WriteBrotliData() will fail.
|
||||
*/
|
||||
void CopyInputToRingBuffer(const size_t input_size,
|
||||
const uint8_t* input_buffer);
|
||||
|
||||
/* Processes the accumulated input data and sets |*out_size| to the length of
|
||||
the new output meta-block, or to zero if no new output meta-block has been
|
||||
created (in this case the processed input data is buffered internally).
|
||||
If |*out_size| is positive, |*output| points to the start of the output
|
||||
data. If |is_last| or |force_flush| is true, an output meta-block is always
|
||||
created. However, until |is_last| is true encoder may retain up to 7 bits
|
||||
of the last byte of output. To force encoder to dump the remaining bits
|
||||
use WriteMetadata() to append an empty meta-data block.
|
||||
Returns false if the size of the input data is larger than
|
||||
input_block_size(). */
|
||||
bool WriteBrotliData(const bool is_last, const bool force_flush,
|
||||
size_t* out_size, uint8_t** output);
|
||||
|
||||
/* 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 BrotliSetCustomDictionary(size_t size, const uint8_t* dict);
|
||||
|
||||
/* No-op, but we keep it here for API backward-compatibility. */
|
||||
void WriteStreamHeader(void) {}
|
||||
|
||||
private:
|
||||
BrotliEncoderState* state_;
|
||||
};
|
||||
|
||||
/* Compresses the data in |input_buffer| into |encoded_buffer|, and sets
|
||||
|*encoded_size| to the compressed length.
|
||||
Returns 0 if there was an error and 1 otherwise. */
|
||||
int BrotliCompressBuffer(BrotliParams params,
|
||||
size_t input_size,
|
||||
const uint8_t* input_buffer,
|
||||
size_t* encoded_size,
|
||||
uint8_t* encoded_buffer);
|
||||
|
||||
/* Same as above, but uses the specified input and output classes instead
|
||||
of reading from and writing to pre-allocated memory buffers. */
|
||||
int BrotliCompress(BrotliParams params, BrotliIn* in, BrotliOut* out);
|
||||
|
||||
/* Before compressing the data, sets a custom LZ77 dictionary with
|
||||
BrotliCompressor::BrotliSetCustomDictionary. */
|
||||
int BrotliCompressWithCustomDictionary(size_t dictsize, const uint8_t* dict,
|
||||
BrotliParams params,
|
||||
BrotliIn* in, BrotliOut* out);
|
||||
|
||||
} /* namespace brotli */
|
||||
|
||||
#endif /* BROTLI_ENC_COMPRESSOR_H_ */
|
@ -9,7 +9,7 @@
|
||||
#ifndef BROTLI_ENC_CONTEXT_H_
|
||||
#define BROTLI_ENC_CONTEXT_H_
|
||||
|
||||
#include "../common/types.h"
|
||||
#include "../public/types.h"
|
||||
#include "../common/port.h"
|
||||
|
||||
#if defined(__cplusplus) || defined(c_plusplus)
|
||||
|
@ -9,7 +9,7 @@
|
||||
#ifndef BROTLI_ENC_DICTIONARY_HASH_H_
|
||||
#define BROTLI_ENC_DICTIONARY_HASH_H_
|
||||
|
||||
#include "../common/types.h"
|
||||
#include "../public/types.h"
|
||||
|
||||
#if defined(__cplusplus) || defined(c_plusplus)
|
||||
extern "C" {
|
||||
|
100
enc/encode.c
100
enc/encode.c
@ -6,11 +6,12 @@
|
||||
|
||||
/* Implementation of Brotli compressor. */
|
||||
|
||||
#include "./encode.h"
|
||||
#include "../public/encode.h"
|
||||
|
||||
#include <stdlib.h> /* free, malloc */
|
||||
#include <string.h> /* memcpy, memset */
|
||||
|
||||
#include "../common/version.h"
|
||||
#include "./backward_references.h"
|
||||
#include "./bit_cost.h"
|
||||
#include "./brotli_bit_stream.h"
|
||||
@ -801,7 +802,7 @@ BROTLI_BOOL BrotliEncoderWriteData(
|
||||
*out_size = 0;
|
||||
return BROTLI_TRUE;
|
||||
}
|
||||
storage = GetBrotliStorage(s, 2 * bytes + 500);
|
||||
storage = GetBrotliStorage(s, 2 * bytes + 502);
|
||||
if (BROTLI_IS_OOM(m)) return BROTLI_FALSE;
|
||||
storage[0] = s->last_byte_;
|
||||
table = GetHashTable(s, s->params.quality, bytes, &table_size);
|
||||
@ -908,7 +909,7 @@ BROTLI_BOOL BrotliEncoderWriteData(
|
||||
{
|
||||
const uint32_t metablock_size =
|
||||
(uint32_t)(s->input_pos_ - s->last_flush_pos_);
|
||||
uint8_t* storage = GetBrotliStorage(s, 2 * metablock_size + 500);
|
||||
uint8_t* storage = GetBrotliStorage(s, 2 * metablock_size + 502);
|
||||
size_t storage_ix = s->last_byte_bits_;
|
||||
if (BROTLI_IS_OOM(m)) return BROTLI_FALSE;
|
||||
storage[0] = s->last_byte_;
|
||||
@ -941,26 +942,6 @@ BROTLI_BOOL BrotliEncoderWriteData(
|
||||
}
|
||||
}
|
||||
|
||||
BROTLI_BOOL BrotliEncoderWriteMetaBlock(
|
||||
BrotliEncoderState* s, const size_t input_size, const uint8_t* input_buffer,
|
||||
const BROTLI_BOOL is_last, size_t* encoded_size, uint8_t* encoded_buffer) {
|
||||
size_t out_size = 0;
|
||||
uint8_t* output;
|
||||
int result;
|
||||
if (!EnsureInitialized(s)) return BROTLI_FALSE;
|
||||
BrotliEncoderCopyInputToRingBuffer(s, input_size, input_buffer);
|
||||
result = BrotliEncoderWriteData(
|
||||
s, is_last, /* force_flush */ BROTLI_TRUE, &out_size, &output);
|
||||
if (!result || out_size > *encoded_size) {
|
||||
return BROTLI_FALSE;
|
||||
}
|
||||
if (out_size > 0) {
|
||||
memcpy(encoded_buffer, output, out_size);
|
||||
}
|
||||
*encoded_size = out_size;
|
||||
return BROTLI_TRUE;
|
||||
}
|
||||
|
||||
BROTLI_BOOL BrotliEncoderWriteMetadata(
|
||||
BrotliEncoderState* s, const size_t input_size, const uint8_t* input_buffer,
|
||||
const BROTLI_BOOL is_last, size_t* encoded_size, uint8_t* encoded_buffer) {
|
||||
@ -1000,13 +981,6 @@ BROTLI_BOOL BrotliEncoderWriteMetadata(
|
||||
return BROTLI_TRUE;
|
||||
}
|
||||
|
||||
BROTLI_BOOL BrotliEncoderFinishStream(
|
||||
BrotliEncoderState* s, size_t* encoded_size, uint8_t* encoded_buffer) {
|
||||
if (!EnsureInitialized(s)) return BROTLI_FALSE;
|
||||
return BrotliEncoderWriteMetaBlock(
|
||||
s, 0, NULL, 1, encoded_size, encoded_buffer);
|
||||
}
|
||||
|
||||
static BROTLI_BOOL BrotliCompressBufferQuality10(
|
||||
int lgwin, size_t input_size, const uint8_t* input_buffer,
|
||||
size_t* encoded_size, uint8_t* encoded_buffer) {
|
||||
@ -1165,7 +1139,7 @@ static BROTLI_BOOL BrotliCompressBufferQuality10(
|
||||
BrotliOptimizeHistograms(num_direct_distance_codes,
|
||||
distance_postfix_bits,
|
||||
&mb);
|
||||
storage = BROTLI_ALLOC(m, uint8_t, 2 * metablock_size + 500);
|
||||
storage = BROTLI_ALLOC(m, uint8_t, 2 * metablock_size + 502);
|
||||
if (BROTLI_IS_OOM(m)) goto oom;
|
||||
storage[0] = last_byte;
|
||||
BrotliStoreMetaBlock(m, input_buffer, metablock_start, metablock_size,
|
||||
@ -1336,15 +1310,23 @@ fallback:
|
||||
static void InjectBytePaddingBlock(BrotliEncoderState* s) {
|
||||
uint32_t seal = s->last_byte_;
|
||||
size_t seal_bits = s->last_byte_bits_;
|
||||
uint8_t* destination;
|
||||
s->last_byte_ = 0;
|
||||
s->last_byte_bits_ = 0;
|
||||
/* is_last = 0, data_nibbles = 11, reseved = 0, meta_nibbles = 00 */
|
||||
seal |= 0x6u << seal_bits;
|
||||
seal_bits += 6;
|
||||
s->flush_buf_[0] = (uint8_t)seal;
|
||||
if (seal_bits > 8) s->flush_buf_[1] = (uint8_t)(seal >> 8);
|
||||
s->next_out_ = s->flush_buf_;
|
||||
s->available_out_ = (seal_bits + 7) >> 3;
|
||||
/* If we have already created storage, then append to it.
|
||||
Storage is valid until next block is being compressed. */
|
||||
if (s->next_out_) {
|
||||
destination = s->next_out_ + s->available_out_;
|
||||
} else {
|
||||
destination = s->flush_buf_;
|
||||
s->next_out_ = destination;
|
||||
}
|
||||
destination[0] = (uint8_t)seal;
|
||||
if (seal_bits > 8) destination[1] = (uint8_t)(seal >> 8);
|
||||
s->available_out_ += (seal_bits + 7) >> 3;
|
||||
}
|
||||
|
||||
static BROTLI_BOOL BrotliEncoderCompressStreamFast(
|
||||
@ -1384,10 +1366,8 @@ static BROTLI_BOOL BrotliEncoderCompressStreamFast(
|
||||
}
|
||||
|
||||
while (BROTLI_TRUE) {
|
||||
if (s->available_out_ == 0 &&
|
||||
s->stream_state_ == BROTLI_STREAM_FLUSH_REQUESTED) {
|
||||
s->stream_state_ = BROTLI_STREAM_PROCESSING;
|
||||
if (s->last_byte_bits_ == 0) break;
|
||||
if (s->stream_state_ == BROTLI_STREAM_FLUSH_REQUESTED &&
|
||||
s->last_byte_bits_ != 0) {
|
||||
InjectBytePaddingBlock(s);
|
||||
continue;
|
||||
}
|
||||
@ -1416,7 +1396,7 @@ static BROTLI_BOOL BrotliEncoderCompressStreamFast(
|
||||
(*available_in == block_size) && (op == BROTLI_OPERATION_FINISH);
|
||||
BROTLI_BOOL force_flush =
|
||||
(*available_in == block_size) && (op == BROTLI_OPERATION_FLUSH);
|
||||
size_t max_out_size = 2 * block_size + 500;
|
||||
size_t max_out_size = 2 * block_size + 502;
|
||||
BROTLI_BOOL inplace = BROTLI_TRUE;
|
||||
uint8_t* storage = NULL;
|
||||
size_t storage_ix = s->last_byte_bits_;
|
||||
@ -1430,7 +1410,7 @@ static BROTLI_BOOL BrotliEncoderCompressStreamFast(
|
||||
if (max_out_size <= *available_out) {
|
||||
storage = *next_out;
|
||||
} else {
|
||||
inplace = 0;
|
||||
inplace = BROTLI_FALSE;
|
||||
storage = GetBrotliStorage(s, max_out_size);
|
||||
if (BROTLI_IS_OOM(m)) return BROTLI_FALSE;
|
||||
}
|
||||
@ -1475,6 +1455,11 @@ static BROTLI_BOOL BrotliEncoderCompressStreamFast(
|
||||
}
|
||||
BROTLI_FREE(m, tmp_command_buf);
|
||||
BROTLI_FREE(m, tmp_literal_buf);
|
||||
if (s->stream_state_ == BROTLI_STREAM_FLUSH_REQUESTED &&
|
||||
s->available_out_ == 0) {
|
||||
s->stream_state_ = BROTLI_STREAM_PROCESSING;
|
||||
s->next_out_ = 0;
|
||||
}
|
||||
return BROTLI_TRUE;
|
||||
}
|
||||
|
||||
@ -1504,10 +1489,8 @@ BROTLI_BOOL BrotliEncoderCompressStream(
|
||||
continue;
|
||||
}
|
||||
|
||||
if (s->available_out_ == 0 &&
|
||||
s->stream_state_ == BROTLI_STREAM_FLUSH_REQUESTED) {
|
||||
s->stream_state_ = BROTLI_STREAM_PROCESSING;
|
||||
if (s->last_byte_bits_ == 0) break;
|
||||
if (s->stream_state_ == BROTLI_STREAM_FLUSH_REQUESTED &&
|
||||
s->last_byte_bits_ != 0) {
|
||||
InjectBytePaddingBlock(s);
|
||||
continue;
|
||||
}
|
||||
@ -1544,6 +1527,11 @@ BROTLI_BOOL BrotliEncoderCompressStream(
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (s->stream_state_ == BROTLI_STREAM_FLUSH_REQUESTED &&
|
||||
s->available_out_ == 0) {
|
||||
s->stream_state_ = BROTLI_STREAM_PROCESSING;
|
||||
s->next_out_ = 0;
|
||||
}
|
||||
return BROTLI_TRUE;
|
||||
}
|
||||
|
||||
@ -1556,6 +1544,28 @@ BROTLI_BOOL BrotliEncoderHasMoreOutput(BrotliEncoderState* s) {
|
||||
return TO_BROTLI_BOOL(s->available_out_ != 0);
|
||||
}
|
||||
|
||||
const uint8_t* BrotliEncoderTakeOutput(BrotliEncoderState* s, size_t* size) {
|
||||
size_t consumed_size = s->available_out_;
|
||||
uint8_t* result = s->next_out_;
|
||||
if (*size) {
|
||||
consumed_size = BROTLI_MIN(size_t, *size, s->available_out_);
|
||||
}
|
||||
if (consumed_size) {
|
||||
s->next_out_ += consumed_size;
|
||||
s->available_out_ -= consumed_size;
|
||||
s->total_out_ += consumed_size;
|
||||
*size = consumed_size;
|
||||
} else {
|
||||
*size = 0;
|
||||
result = 0;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
uint32_t BrotliEncoderVersion(void) {
|
||||
return BROTLI_VERSION;
|
||||
}
|
||||
|
||||
|
||||
#if defined(__cplusplus) || defined(c_plusplus)
|
||||
} /* extern "C" */
|
||||
|
@ -1,289 +0,0 @@
|
||||
/* Copyright 2013 Google Inc. All Rights Reserved.
|
||||
|
||||
Distributed under MIT license.
|
||||
See file LICENSE for detail or copy at https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
/* Implementation of parallel Brotli compressor. */
|
||||
|
||||
#include "./encode_parallel.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "./backward_references.h"
|
||||
#include "./brotli_bit_stream.h"
|
||||
#include "./context.h"
|
||||
#include "./entropy_encode.h"
|
||||
#include "./fast_log.h"
|
||||
#include "./hash.h"
|
||||
#include "./metablock.h"
|
||||
#include "./port.h"
|
||||
#include "./prefix.h"
|
||||
#include "./quality.h"
|
||||
#include "./utf8_util.h"
|
||||
|
||||
namespace brotli {
|
||||
|
||||
namespace {
|
||||
|
||||
static void RecomputeDistancePrefixes(Command* cmds, size_t num_commands,
|
||||
uint32_t num_direct_distance_codes,
|
||||
uint32_t distance_postfix_bits) {
|
||||
if (num_direct_distance_codes == 0 &&
|
||||
distance_postfix_bits == 0) {
|
||||
return;
|
||||
}
|
||||
for (size_t i = 0; i < num_commands; ++i) {
|
||||
Command* cmd = &cmds[i];
|
||||
if (CommandCopyLen(cmd) && cmd->cmd_prefix_ >= 128) {
|
||||
PrefixEncodeCopyDistance(CommandDistanceCode(cmd),
|
||||
num_direct_distance_codes,
|
||||
distance_postfix_bits,
|
||||
&cmd->dist_prefix_,
|
||||
&cmd->dist_extra_);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Returns 1 on success, otherwise 0. */
|
||||
int WriteMetaBlockParallel(const BrotliEncoderParams* params,
|
||||
const uint32_t input_size,
|
||||
const uint8_t* input_buffer,
|
||||
const uint32_t prefix_size,
|
||||
const uint8_t* prefix_buffer,
|
||||
const int is_first,
|
||||
const int is_last,
|
||||
size_t* encoded_size,
|
||||
uint8_t* encoded_buffer) {
|
||||
if (input_size == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
MemoryManager memory_manager;
|
||||
MemoryManager* m = &memory_manager;
|
||||
BrotliInitMemoryManager(m, 0, 0, 0);
|
||||
|
||||
uint8_t* storage;
|
||||
size_t storage_ix;
|
||||
uint8_t first_byte;
|
||||
size_t first_byte_bits;
|
||||
size_t output_size;
|
||||
uint32_t num_direct_distance_codes;
|
||||
uint32_t distance_postfix_bits;
|
||||
ContextType literal_context_mode;
|
||||
size_t last_insert_len = 0;
|
||||
size_t num_commands = 0;
|
||||
size_t num_literals = 0;
|
||||
int dist_cache[4] = { -4, -4, -4, -4 };
|
||||
Command* commands;
|
||||
Hashers* hashers;
|
||||
int use_utf8_mode;
|
||||
uint8_t prev_byte;
|
||||
uint8_t prev_byte2;
|
||||
const uint32_t mask = BROTLI_UINT32_MAX >> 1;
|
||||
|
||||
/* Copy prefix + next input block into a continuous area. */
|
||||
uint32_t input_pos = prefix_size;
|
||||
/* CreateBackwardReferences reads up to 3 bytes past the end of input if the
|
||||
mask points past the end of input.
|
||||
FindMatchLengthWithLimit could do another 8 bytes look-forward. */
|
||||
uint8_t* input = BROTLI_ALLOC(m, uint8_t, prefix_size + input_size + 4 + 8);
|
||||
if (BROTLI_IS_OOM(m)) goto oom;
|
||||
memcpy(input, prefix_buffer, prefix_size);
|
||||
memcpy(input + input_pos, input_buffer, input_size);
|
||||
/* Since we don't have a ringbuffer, masking is a no-op.
|
||||
We use one less bit than the full range because some of the code uses
|
||||
mask + 1 as the size of the ringbuffer. */
|
||||
|
||||
prev_byte = input_pos > 0 ? input[(input_pos - 1) & mask] : 0;
|
||||
prev_byte2 = input_pos > 1 ? input[(input_pos - 2) & mask] : 0;
|
||||
|
||||
/* Decide about UTF8 mode. */
|
||||
static const double kMinUTF8Ratio = 0.75;
|
||||
use_utf8_mode = BrotliIsMostlyUTF8(
|
||||
input, input_pos, mask, input_size, kMinUTF8Ratio);
|
||||
|
||||
/* Initialize hashers. */
|
||||
hashers = BROTLI_ALLOC(m, Hashers, 1);
|
||||
if (BROTLI_IS_OOM(m)) goto oom;
|
||||
InitHashers(hashers);
|
||||
HashersSetup(m, hashers, ChooseHasher(params));
|
||||
if (BROTLI_IS_OOM(m)) goto oom;
|
||||
|
||||
/* Compute backward references. */
|
||||
commands = BROTLI_ALLOC(m, Command, ((input_size + 1) >> 1));
|
||||
if (BROTLI_IS_OOM(m)) goto oom;
|
||||
BrotliCreateBackwardReferences(m, input_size, input_pos,
|
||||
TO_BROTLI_BOOL(is_last), input, mask, params,
|
||||
hashers, dist_cache, &last_insert_len, commands, &num_commands,
|
||||
&num_literals);
|
||||
if (BROTLI_IS_OOM(m)) goto oom;
|
||||
DestroyHashers(m, hashers);
|
||||
BROTLI_FREE(m, hashers);
|
||||
if (last_insert_len > 0) {
|
||||
InitInsertCommand(&commands[num_commands++], last_insert_len);
|
||||
num_literals += last_insert_len;
|
||||
}
|
||||
assert(num_commands != 0);
|
||||
|
||||
/* Build the meta-block. */
|
||||
MetaBlockSplit mb;
|
||||
InitMetaBlockSplit(&mb);
|
||||
num_direct_distance_codes = params->mode == BROTLI_MODE_FONT ? 12 : 0;
|
||||
distance_postfix_bits = params->mode == BROTLI_MODE_FONT ? 1 : 0;
|
||||
literal_context_mode = use_utf8_mode ? CONTEXT_UTF8 : CONTEXT_SIGNED;
|
||||
RecomputeDistancePrefixes(commands, num_commands,
|
||||
num_direct_distance_codes,
|
||||
distance_postfix_bits);
|
||||
if (params->quality < MIN_QUALITY_FOR_HQ_BLOCK_SPLITTING) {
|
||||
BrotliBuildMetaBlockGreedy(m, input, input_pos, mask,
|
||||
commands, num_commands,
|
||||
&mb);
|
||||
if (BROTLI_IS_OOM(m)) goto oom;
|
||||
} else {
|
||||
BrotliBuildMetaBlock(m, input, input_pos, mask, params,
|
||||
prev_byte, prev_byte2,
|
||||
commands, num_commands,
|
||||
literal_context_mode,
|
||||
&mb);
|
||||
if (BROTLI_IS_OOM(m)) goto oom;
|
||||
}
|
||||
|
||||
/* Set up the temporary output storage. */
|
||||
storage = BROTLI_ALLOC(m, uint8_t, 2 * input_size + 500);
|
||||
if (BROTLI_IS_OOM(m)) goto oom;
|
||||
first_byte = 0;
|
||||
first_byte_bits = 0;
|
||||
if (is_first) {
|
||||
if (params->lgwin == 16) {
|
||||
first_byte = 0;
|
||||
first_byte_bits = 1;
|
||||
} else if (params->lgwin == 17) {
|
||||
first_byte = 1;
|
||||
first_byte_bits = 7;
|
||||
} else {
|
||||
first_byte = static_cast<uint8_t>(((params->lgwin - 17) << 1) | 1);
|
||||
first_byte_bits = 4;
|
||||
}
|
||||
}
|
||||
storage[0] = static_cast<uint8_t>(first_byte);
|
||||
storage_ix = first_byte_bits;
|
||||
|
||||
/* Store the meta-block to the temporary output. */
|
||||
BrotliStoreMetaBlock(m, input, input_pos, input_size, mask,
|
||||
prev_byte, prev_byte2,
|
||||
TO_BROTLI_BOOL(is_last),
|
||||
num_direct_distance_codes,
|
||||
distance_postfix_bits,
|
||||
literal_context_mode,
|
||||
commands, num_commands,
|
||||
&mb,
|
||||
&storage_ix, storage);
|
||||
if (BROTLI_IS_OOM(m)) goto oom;
|
||||
DestroyMetaBlockSplit(m, &mb);
|
||||
BROTLI_FREE(m, commands);
|
||||
|
||||
/* If this is not the last meta-block, store an empty metadata
|
||||
meta-block so that the meta-block will end at a byte boundary. */
|
||||
if (!is_last) {
|
||||
BrotliStoreSyncMetaBlock(&storage_ix, storage);
|
||||
}
|
||||
|
||||
/* If the compressed data is too large, fall back to an uncompressed
|
||||
meta-block. */
|
||||
output_size = storage_ix >> 3;
|
||||
if (input_size + 4 < output_size) {
|
||||
storage[0] = static_cast<uint8_t>(first_byte);
|
||||
storage_ix = first_byte_bits;
|
||||
BrotliStoreUncompressedMetaBlock(
|
||||
TO_BROTLI_BOOL(is_last), input, input_pos, mask, input_size,
|
||||
&storage_ix, storage);
|
||||
output_size = storage_ix >> 3;
|
||||
}
|
||||
|
||||
/* Copy the temporary output with size-check to the output. */
|
||||
if (output_size > *encoded_size) {
|
||||
BROTLI_FREE(m, storage);
|
||||
BROTLI_FREE(m, input);
|
||||
return 0;
|
||||
}
|
||||
memcpy(encoded_buffer, storage, output_size);
|
||||
*encoded_size = output_size;
|
||||
BROTLI_FREE(m, storage);
|
||||
BROTLI_FREE(m, input);
|
||||
return 1;
|
||||
|
||||
oom:
|
||||
BrotliWipeOutMemoryManager(m);
|
||||
return 0;
|
||||
}
|
||||
|
||||
} /* namespace */
|
||||
|
||||
int BrotliCompressBufferParallel(BrotliParams compressor_params,
|
||||
size_t input_size,
|
||||
const uint8_t* input_buffer,
|
||||
size_t* encoded_size,
|
||||
uint8_t* encoded_buffer) {
|
||||
if (*encoded_size == 0) {
|
||||
/* Output buffer needs at least one byte. */
|
||||
return 0;
|
||||
} else if (input_size == 0) {
|
||||
encoded_buffer[0] = 6;
|
||||
*encoded_size = 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
BrotliEncoderParams params;
|
||||
params.mode = (BrotliEncoderMode)compressor_params.mode;
|
||||
params.quality = compressor_params.quality;
|
||||
params.lgwin = compressor_params.lgwin;
|
||||
params.lgblock = compressor_params.lgblock;
|
||||
|
||||
SanitizeParams(¶ms);
|
||||
params.lgblock = ComputeLgBlock(¶ms);
|
||||
size_t max_input_block_size = 1 << params.lgblock;
|
||||
size_t max_prefix_size = 1u << params.lgwin;
|
||||
|
||||
std::vector<std::vector<uint8_t> > compressed_pieces;
|
||||
|
||||
/* Compress block-by-block independently. */
|
||||
for (size_t pos = 0; pos < input_size; ) {
|
||||
uint32_t input_block_size = static_cast<uint32_t>(
|
||||
BROTLI_MIN(size_t, max_input_block_size, input_size - pos));
|
||||
uint32_t prefix_size =
|
||||
static_cast<uint32_t>(BROTLI_MIN(size_t, max_prefix_size, pos));
|
||||
size_t out_size = input_block_size + (input_block_size >> 3) + 1024;
|
||||
std::vector<uint8_t> out(out_size);
|
||||
if (!WriteMetaBlockParallel(¶ms,
|
||||
input_block_size,
|
||||
&input_buffer[pos],
|
||||
prefix_size,
|
||||
&input_buffer[pos - prefix_size],
|
||||
(pos == 0) ? 1 : 0,
|
||||
(pos + input_block_size == input_size) ? 1 : 0,
|
||||
&out_size,
|
||||
&out[0])) {
|
||||
return 0;
|
||||
}
|
||||
out.resize(out_size);
|
||||
compressed_pieces.push_back(out);
|
||||
pos += input_block_size;
|
||||
}
|
||||
|
||||
/* Piece together the output. */
|
||||
size_t out_pos = 0;
|
||||
for (size_t i = 0; i < compressed_pieces.size(); ++i) {
|
||||
const std::vector<uint8_t>& out = compressed_pieces[i];
|
||||
if (out_pos + out.size() > *encoded_size) {
|
||||
return 0;
|
||||
}
|
||||
memcpy(&encoded_buffer[out_pos], &out[0], out.size());
|
||||
out_pos += out.size();
|
||||
}
|
||||
*encoded_size = out_pos;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
} /* namespace brotli */
|
@ -1,27 +0,0 @@
|
||||
/* Copyright 2013 Google Inc. All Rights Reserved.
|
||||
|
||||
Distributed under MIT license.
|
||||
See file LICENSE for detail or copy at https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
/* API for parallel Brotli compression
|
||||
Note that this is only a proof of concept currently and not part of the
|
||||
final API yet. */
|
||||
|
||||
#ifndef BROTLI_ENC_ENCODE_PARALLEL_H_
|
||||
#define BROTLI_ENC_ENCODE_PARALLEL_H_
|
||||
|
||||
#include "../common/types.h"
|
||||
#include "./compressor.h"
|
||||
|
||||
namespace brotli {
|
||||
|
||||
int BrotliCompressBufferParallel(BrotliParams params,
|
||||
size_t input_size,
|
||||
const uint8_t* input_buffer,
|
||||
size_t* encoded_size,
|
||||
uint8_t* encoded_buffer);
|
||||
|
||||
} /* namespace brotli */
|
||||
|
||||
#endif /* BROTLI_ENC_ENCODE_PARALLEL_H_ */
|
@ -11,7 +11,7 @@
|
||||
#include <string.h> /* memset */
|
||||
|
||||
#include "../common/constants.h"
|
||||
#include "../common/types.h"
|
||||
#include "../public/types.h"
|
||||
#include "./port.h"
|
||||
|
||||
#if defined(__cplusplus) || defined(c_plusplus)
|
||||
|
@ -9,7 +9,7 @@
|
||||
#ifndef BROTLI_ENC_ENTROPY_ENCODE_H_
|
||||
#define BROTLI_ENC_ENTROPY_ENCODE_H_
|
||||
|
||||
#include "../common/types.h"
|
||||
#include "../public/types.h"
|
||||
#include "./port.h"
|
||||
|
||||
#if defined(__cplusplus) || defined(c_plusplus)
|
||||
|
@ -11,7 +11,7 @@
|
||||
|
||||
#include "../common/constants.h"
|
||||
#include "../common/port.h"
|
||||
#include "../common/types.h"
|
||||
#include "../public/types.h"
|
||||
#include "./write_bits.h"
|
||||
|
||||
#if defined(__cplusplus) || defined(c_plusplus)
|
||||
|
@ -11,7 +11,7 @@
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#include "../common/types.h"
|
||||
#include "../public/types.h"
|
||||
#include "../common/port.h"
|
||||
|
||||
#if defined(__cplusplus) || defined(c_plusplus)
|
||||
|
@ -9,7 +9,7 @@
|
||||
#ifndef BROTLI_ENC_FIND_MATCH_LENGTH_H_
|
||||
#define BROTLI_ENC_FIND_MATCH_LENGTH_H_
|
||||
|
||||
#include "../common/types.h"
|
||||
#include "../public/types.h"
|
||||
#include "./port.h"
|
||||
|
||||
#if defined(__cplusplus) || defined(c_plusplus)
|
||||
|
44
enc/hash.h
44
enc/hash.h
@ -14,7 +14,7 @@
|
||||
|
||||
#include "../common/constants.h"
|
||||
#include "../common/dictionary.h"
|
||||
#include "../common/types.h"
|
||||
#include "../public/types.h"
|
||||
#include "./dictionary_hash.h"
|
||||
#include "./fast_log.h"
|
||||
#include "./find_match_length.h"
|
||||
@ -639,29 +639,29 @@ static BROTLI_INLINE void FN(StitchToPreviousBlock)(HashToBinaryTree* self,
|
||||
#define FOR_ALL_HASHERS(H) FOR_GENERIC_HASHERS(H) H(10)
|
||||
|
||||
typedef struct Hashers {
|
||||
#define _MEMBER(N) H ## N* h ## N;
|
||||
FOR_ALL_HASHERS(_MEMBER)
|
||||
#undef _MEMBER
|
||||
#define MEMBER_(N) H ## N* h ## N;
|
||||
FOR_ALL_HASHERS(MEMBER_)
|
||||
#undef MEMBER_
|
||||
} Hashers;
|
||||
|
||||
static BROTLI_INLINE void InitHashers(Hashers* self) {
|
||||
#define _INIT(N) self->h ## N = 0;
|
||||
FOR_ALL_HASHERS(_INIT)
|
||||
#undef _INIT
|
||||
#define INIT_(N) self->h ## N = 0;
|
||||
FOR_ALL_HASHERS(INIT_)
|
||||
#undef INIT_
|
||||
}
|
||||
|
||||
static BROTLI_INLINE void DestroyHashers(MemoryManager* m, Hashers* self) {
|
||||
if (self->h10) CleanupH10(m, self->h10);
|
||||
#define _CLEANUP(N) BROTLI_FREE(m, self->h ## N)
|
||||
FOR_ALL_HASHERS(_CLEANUP)
|
||||
#undef _CLEANUP
|
||||
#define CLEANUP_(N) BROTLI_FREE(m, self->h ## N)
|
||||
FOR_ALL_HASHERS(CLEANUP_)
|
||||
#undef CLEANUP_
|
||||
}
|
||||
|
||||
static BROTLI_INLINE void HashersReset(Hashers* self, int type) {
|
||||
switch (type) {
|
||||
#define _RESET(N) case N: ResetH ## N(self->h ## N); break;
|
||||
FOR_ALL_HASHERS(_RESET)
|
||||
#undef _RESET
|
||||
#define RESET_(N) case N: ResetH ## N(self->h ## N); break;
|
||||
FOR_ALL_HASHERS(RESET_)
|
||||
#undef RESET_
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
@ -669,9 +669,9 @@ static BROTLI_INLINE void HashersReset(Hashers* self, int type) {
|
||||
static BROTLI_INLINE void HashersSetup(
|
||||
MemoryManager* m, Hashers* self, int type) {
|
||||
switch (type) {
|
||||
#define _SETUP(N) case N: self->h ## N = BROTLI_ALLOC(m, H ## N, 1); break;
|
||||
FOR_ALL_HASHERS(_SETUP)
|
||||
#undef _SETUP
|
||||
#define SETUP_(N) case N: self->h ## N = BROTLI_ALLOC(m, H ## N, 1); break;
|
||||
FOR_ALL_HASHERS(SETUP_)
|
||||
#undef SETUP_
|
||||
default: break;
|
||||
}
|
||||
if (BROTLI_IS_OOM(m)) return;
|
||||
@ -679,7 +679,7 @@ static BROTLI_INLINE void HashersSetup(
|
||||
HashersReset(self, type);
|
||||
}
|
||||
|
||||
#define _WARMUP_HASH(N) \
|
||||
#define WARMUP_HASH_(N) \
|
||||
static BROTLI_INLINE void WarmupHashH ## N(MemoryManager* m, \
|
||||
const BrotliEncoderParams* params, const size_t size, const uint8_t* dict, \
|
||||
H ## N* hasher) { \
|
||||
@ -691,8 +691,8 @@ static BROTLI_INLINE void WarmupHashH ## N(MemoryManager* m, \
|
||||
StoreH ## N(hasher, dict, ~(size_t)0, i); \
|
||||
} \
|
||||
}
|
||||
FOR_ALL_HASHERS(_WARMUP_HASH)
|
||||
#undef _WARMUP_HASH
|
||||
FOR_ALL_HASHERS(WARMUP_HASH_)
|
||||
#undef WARMUP_HASH_
|
||||
|
||||
/* Custom LZ77 window. */
|
||||
static BROTLI_INLINE void HashersPrependCustomDictionary(
|
||||
@ -700,10 +700,10 @@ static BROTLI_INLINE void HashersPrependCustomDictionary(
|
||||
const size_t size, const uint8_t* dict) {
|
||||
int hasher_type = ChooseHasher(params);
|
||||
switch (hasher_type) {
|
||||
#define _PREPEND(N) \
|
||||
#define PREPEND_(N) \
|
||||
case N: WarmupHashH ## N(m, params, size, dict, self->h ## N); break;
|
||||
FOR_ALL_HASHERS(_PREPEND)
|
||||
#undef _PREPEND
|
||||
FOR_ALL_HASHERS(PREPEND_)
|
||||
#undef PREPEND_
|
||||
default: break;
|
||||
}
|
||||
if (BROTLI_IS_OOM(m)) return;
|
||||
|
@ -172,6 +172,7 @@ static BROTLI_INLINE BROTLI_BOOL FN(FindLongestMatch)(
|
||||
const size_t backward =
|
||||
(size_t)(distance_cache[idx] + kDistanceCacheOffset[i]);
|
||||
size_t prev_ix = (cur_ix - backward);
|
||||
/* For distance code 0 we want to consider 2-byte matches. */
|
||||
if (i > 0 && self->tiny_hash[(uint16_t)prev_ix] != tiny_hash) continue;
|
||||
if (prev_ix >= cur_ix || backward > max_backward) {
|
||||
continue;
|
||||
|
@ -12,7 +12,7 @@
|
||||
#include <string.h> /* memset */
|
||||
|
||||
#include "../common/constants.h"
|
||||
#include "../common/types.h"
|
||||
#include "../public/types.h"
|
||||
#include "./block_splitter.h"
|
||||
#include "./command.h"
|
||||
#include "./context.h"
|
||||
|
@ -9,7 +9,7 @@
|
||||
|
||||
#include "./literal_cost.h"
|
||||
|
||||
#include "../common/types.h"
|
||||
#include "../public/types.h"
|
||||
#include "./fast_log.h"
|
||||
#include "./port.h"
|
||||
#include "./utf8_util.h"
|
||||
|
@ -10,7 +10,7 @@
|
||||
#ifndef BROTLI_ENC_LITERAL_COST_H_
|
||||
#define BROTLI_ENC_LITERAL_COST_H_
|
||||
|
||||
#include "../common/types.h"
|
||||
#include "../public/types.h"
|
||||
#include "./port.h"
|
||||
|
||||
#if defined(__cplusplus) || defined(c_plusplus)
|
||||
|
@ -13,7 +13,7 @@
|
||||
#include <stdlib.h> /* exit, free, malloc */
|
||||
#include <string.h> /* memcpy */
|
||||
|
||||
#include "../common/types.h"
|
||||
#include "../public/types.h"
|
||||
#include "./port.h"
|
||||
|
||||
#if defined(__cplusplus) || defined(c_plusplus)
|
||||
|
@ -9,7 +9,7 @@
|
||||
#ifndef BROTLI_ENC_MEMORY_H_
|
||||
#define BROTLI_ENC_MEMORY_H_
|
||||
|
||||
#include "../common/types.h"
|
||||
#include "../public/types.h"
|
||||
#include "./port.h"
|
||||
|
||||
#if defined(__cplusplus) || defined(c_plusplus)
|
||||
|
@ -10,7 +10,7 @@
|
||||
#include "./metablock.h"
|
||||
|
||||
#include "../common/constants.h"
|
||||
#include "../common/types.h"
|
||||
#include "../public/types.h"
|
||||
#include "./bit_cost.h"
|
||||
#include "./block_splitter.h"
|
||||
#include "./cluster.h"
|
||||
|
@ -10,7 +10,7 @@
|
||||
#ifndef BROTLI_ENC_METABLOCK_H_
|
||||
#define BROTLI_ENC_METABLOCK_H_
|
||||
|
||||
#include "../common/types.h"
|
||||
#include "../public/types.h"
|
||||
#include "./block_splitter.h"
|
||||
#include "./command.h"
|
||||
#include "./context.h"
|
||||
|
13
enc/port.h
13
enc/port.h
@ -13,7 +13,7 @@
|
||||
#include <string.h> /* memcpy */
|
||||
|
||||
#include "../common/port.h"
|
||||
#include "../common/types.h"
|
||||
#include "../public/types.h"
|
||||
|
||||
#if defined OS_LINUX || defined OS_CYGWIN
|
||||
#include <endian.h>
|
||||
@ -128,7 +128,8 @@ static BROTLI_INLINE void BROTLI_UNALIGNED_STORE64(void *p, uint64_t v) {
|
||||
|
||||
#endif
|
||||
|
||||
#if !defined(__cplusplus) && !defined(c_plusplus) && __STDC_VERSION__ >= 199901L
|
||||
#if !defined(__cplusplus) && !defined(c_plusplus) && \
|
||||
(defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L)
|
||||
#define BROTLI_RESTRICT restrict
|
||||
#elif BROTLI_GCC_VERSION > 295 || defined(__llvm__)
|
||||
#define BROTLI_RESTRICT __restrict
|
||||
@ -136,12 +137,12 @@ static BROTLI_INLINE void BROTLI_UNALIGNED_STORE64(void *p, uint64_t v) {
|
||||
#define BROTLI_RESTRICT
|
||||
#endif
|
||||
|
||||
#define _TEMPLATE(T) \
|
||||
#define TEMPLATE_(T) \
|
||||
static BROTLI_INLINE T brotli_min_ ## T (T a, T b) { return a < b ? a : b; } \
|
||||
static BROTLI_INLINE T brotli_max_ ## T (T a, T b) { return a > b ? a : b; }
|
||||
_TEMPLATE(double) _TEMPLATE(float) _TEMPLATE(int)
|
||||
_TEMPLATE(size_t) _TEMPLATE(uint32_t) _TEMPLATE(uint8_t)
|
||||
#undef _TEMPLATE
|
||||
TEMPLATE_(double) TEMPLATE_(float) TEMPLATE_(int)
|
||||
TEMPLATE_(size_t) TEMPLATE_(uint32_t) TEMPLATE_(uint8_t)
|
||||
#undef TEMPLATE_
|
||||
#define BROTLI_MIN(T, A, B) (brotli_min_ ## T((A), (B)))
|
||||
#define BROTLI_MAX(T, A, B) (brotli_max_ ## T((A), (B)))
|
||||
|
||||
|
@ -12,7 +12,7 @@
|
||||
|
||||
#include "../common/constants.h"
|
||||
#include "../common/port.h"
|
||||
#include "../common/types.h"
|
||||
#include "../public/types.h"
|
||||
#include "./fast_log.h"
|
||||
|
||||
#if defined(__cplusplus) || defined(c_plusplus)
|
||||
|
@ -10,7 +10,7 @@
|
||||
#ifndef BROTLI_ENC_QUALITY_H_
|
||||
#define BROTLI_ENC_QUALITY_H_
|
||||
|
||||
#include "./encode.h"
|
||||
#include "../public/encode.h"
|
||||
|
||||
#define FAST_ONE_PASS_COMPRESSION_QUALITY 0
|
||||
#define FAST_TWO_PASS_COMPRESSION_QUALITY 1
|
||||
|
@ -11,7 +11,7 @@
|
||||
|
||||
#include <string.h> /* memcpy */
|
||||
|
||||
#include "../common/types.h"
|
||||
#include "../public/types.h"
|
||||
#include "./memory.h"
|
||||
#include "./port.h"
|
||||
#include "./quality.h"
|
||||
|
@ -9,7 +9,7 @@
|
||||
#ifndef BROTLI_ENC_STATIC_DICT_H_
|
||||
#define BROTLI_ENC_STATIC_DICT_H_
|
||||
|
||||
#include "../common/types.h"
|
||||
#include "../public/types.h"
|
||||
#include "./port.h"
|
||||
|
||||
#if defined(__cplusplus) || defined(c_plusplus)
|
||||
|
@ -9,7 +9,7 @@
|
||||
#ifndef BROTLI_ENC_STATIC_DICT_LUT_H_
|
||||
#define BROTLI_ENC_STATIC_DICT_LUT_H_
|
||||
|
||||
#include "../common/types.h"
|
||||
#include "../public/types.h"
|
||||
|
||||
#if defined(__cplusplus) || defined(c_plusplus)
|
||||
extern "C" {
|
||||
|
114
enc/streams.cc
114
enc/streams.cc
@ -1,114 +0,0 @@
|
||||
/* Copyright 2009 Google Inc. All Rights Reserved.
|
||||
|
||||
Distributed under MIT license.
|
||||
See file LICENSE for detail or copy at https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
/* Convience routines to make Brotli I/O classes from some memory containers and
|
||||
files. */
|
||||
|
||||
#include "./streams.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h> /* memcpy */
|
||||
|
||||
namespace brotli {
|
||||
|
||||
BrotliMemOut::BrotliMemOut(void* buf, size_t len)
|
||||
: buf_(buf),
|
||||
len_(len),
|
||||
pos_(0) {}
|
||||
|
||||
void BrotliMemOut::Reset(void* buf, size_t len) {
|
||||
buf_ = buf;
|
||||
len_ = len;
|
||||
pos_ = 0;
|
||||
}
|
||||
|
||||
/* Brotli output routine: copy n bytes to the output buffer. */
|
||||
bool BrotliMemOut::Write(const void *buf, size_t n) {
|
||||
if (n + pos_ > len_)
|
||||
return false;
|
||||
char* p = reinterpret_cast<char*>(buf_) + pos_;
|
||||
memcpy(p, buf, n);
|
||||
pos_ += n;
|
||||
return true;
|
||||
}
|
||||
|
||||
BrotliStringOut::BrotliStringOut(std::string* buf, size_t max_size)
|
||||
: buf_(buf),
|
||||
max_size_(max_size) {
|
||||
assert(buf->empty());
|
||||
}
|
||||
|
||||
void BrotliStringOut::Reset(std::string* buf, size_t max_size) {
|
||||
buf_ = buf;
|
||||
max_size_ = max_size;
|
||||
}
|
||||
|
||||
/* Brotli output routine: add n bytes to a string. */
|
||||
bool BrotliStringOut::Write(const void *buf, size_t n) {
|
||||
if (buf_->size() + n > max_size_)
|
||||
return false;
|
||||
buf_->append(static_cast<const char*>(buf), n);
|
||||
return true;
|
||||
}
|
||||
|
||||
BrotliMemIn::BrotliMemIn(const void* buf, size_t len)
|
||||
: buf_(buf),
|
||||
len_(len),
|
||||
pos_(0) {}
|
||||
|
||||
void BrotliMemIn::Reset(const void* buf, size_t len) {
|
||||
buf_ = buf;
|
||||
len_ = len;
|
||||
pos_ = 0;
|
||||
}
|
||||
|
||||
/* Brotli input routine: read the next chunk of memory. */
|
||||
const void* BrotliMemIn::Read(size_t n, size_t* output) {
|
||||
if (pos_ == len_) {
|
||||
return NULL;
|
||||
}
|
||||
if (n > len_ - pos_)
|
||||
n = len_ - pos_;
|
||||
const char* p = reinterpret_cast<const char*>(buf_) + pos_;
|
||||
pos_ += n;
|
||||
*output = n;
|
||||
return p;
|
||||
}
|
||||
|
||||
BrotliFileIn::BrotliFileIn(FILE* f, size_t max_read_size)
|
||||
: f_(f),
|
||||
buf_(new char[max_read_size]),
|
||||
buf_size_(max_read_size) { }
|
||||
|
||||
BrotliFileIn::~BrotliFileIn(void) {
|
||||
delete[] buf_;
|
||||
}
|
||||
|
||||
const void* BrotliFileIn::Read(size_t n, size_t* bytes_read) {
|
||||
if (n > buf_size_) {
|
||||
n = buf_size_;
|
||||
} else if (n == 0) {
|
||||
return feof(f_) ? NULL : buf_;
|
||||
}
|
||||
*bytes_read = fread(buf_, 1, n, f_);
|
||||
if (*bytes_read == 0) {
|
||||
return NULL;
|
||||
} else {
|
||||
return buf_;
|
||||
}
|
||||
}
|
||||
|
||||
BrotliFileOut::BrotliFileOut(FILE* f) : f_(f) {}
|
||||
|
||||
bool BrotliFileOut::Write(const void* buf, size_t n) {
|
||||
if (fwrite(buf, n, 1, f_) != 1) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
} /* namespace brotli */
|
121
enc/streams.h
121
enc/streams.h
@ -1,121 +0,0 @@
|
||||
/* Copyright 2009 Google Inc. All Rights Reserved.
|
||||
|
||||
Distributed under MIT license.
|
||||
See file LICENSE for detail or copy at https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
/* Input and output classes for streaming brotli compression. */
|
||||
|
||||
#ifndef BROTLI_ENC_STREAMS_H_
|
||||
#define BROTLI_ENC_STREAMS_H_
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string>
|
||||
|
||||
#include "../common/types.h"
|
||||
|
||||
namespace brotli {
|
||||
|
||||
/* Input interface for the compression routines. */
|
||||
class BrotliIn {
|
||||
public:
|
||||
virtual ~BrotliIn(void) {}
|
||||
|
||||
/* Return a pointer to the next block of input of at most n bytes.
|
||||
Return the actual length in *nread.
|
||||
At end of data, return NULL. Don't return NULL if there is more data
|
||||
to read, even if called with n == 0.
|
||||
Read will only be called if some of its bytes are needed. */
|
||||
virtual const void* Read(size_t n, size_t* nread) = 0;
|
||||
};
|
||||
|
||||
/* Output interface for the compression routines. */
|
||||
class BrotliOut {
|
||||
public:
|
||||
virtual ~BrotliOut(void) {}
|
||||
|
||||
/* Write n bytes of data from buf.
|
||||
Return true if all written, false otherwise. */
|
||||
virtual bool Write(const void *buf, size_t n) = 0;
|
||||
};
|
||||
|
||||
/* Adapter class to make BrotliIn objects from raw memory. */
|
||||
class BrotliMemIn : public BrotliIn {
|
||||
public:
|
||||
BrotliMemIn(const void* buf, size_t len);
|
||||
|
||||
void Reset(const void* buf, size_t len);
|
||||
|
||||
/* returns the amount of data consumed */
|
||||
size_t position(void) const { return pos_; }
|
||||
|
||||
const void* Read(size_t n, size_t* OUTPUT);
|
||||
|
||||
private:
|
||||
const void* buf_; /* start of input buffer */
|
||||
size_t len_; /* length of input */
|
||||
size_t pos_; /* current read position within input */
|
||||
};
|
||||
|
||||
/* Adapter class to make BrotliOut objects from raw memory. */
|
||||
class BrotliMemOut : public BrotliOut {
|
||||
public:
|
||||
BrotliMemOut(void* buf, size_t len);
|
||||
|
||||
void Reset(void* buf, size_t len);
|
||||
|
||||
/* returns the amount of data written */
|
||||
size_t position(void) const { return pos_; }
|
||||
|
||||
bool Write(const void* buf, size_t n);
|
||||
|
||||
private:
|
||||
void* buf_; /* start of output buffer */
|
||||
size_t len_; /* length of output */
|
||||
size_t pos_; /* current write position within output */
|
||||
};
|
||||
|
||||
/* Adapter class to make BrotliOut objects from a string. */
|
||||
class BrotliStringOut : public BrotliOut {
|
||||
public:
|
||||
/* Create a writer that appends its data to buf.
|
||||
buf->size() will grow to at most max_size
|
||||
buf is expected to be empty when constructing BrotliStringOut. */
|
||||
BrotliStringOut(std::string* buf, size_t max_size);
|
||||
|
||||
void Reset(std::string* buf, size_t max_len);
|
||||
|
||||
bool Write(const void* buf, size_t n);
|
||||
|
||||
private:
|
||||
std::string* buf_; /* start of output buffer */
|
||||
size_t max_size_; /* max length of output */
|
||||
};
|
||||
|
||||
/* Adapter class to make BrotliIn object from a file. */
|
||||
class BrotliFileIn : public BrotliIn {
|
||||
public:
|
||||
BrotliFileIn(FILE* f, size_t max_read_size);
|
||||
~BrotliFileIn(void);
|
||||
|
||||
const void* Read(size_t n, size_t* bytes_read);
|
||||
|
||||
private:
|
||||
FILE* f_;
|
||||
char* buf_;
|
||||
size_t buf_size_;
|
||||
};
|
||||
|
||||
/* Adapter class to make BrotliOut object from a file. */
|
||||
class BrotliFileOut : public BrotliOut {
|
||||
public:
|
||||
explicit BrotliFileOut(FILE* f);
|
||||
|
||||
bool Write(const void* buf, size_t n);
|
||||
private:
|
||||
FILE* f_;
|
||||
};
|
||||
|
||||
} /* namespace brotli */
|
||||
|
||||
#endif /* BROTLI_ENC_STREAMS_H_ */
|
@ -8,7 +8,7 @@
|
||||
|
||||
#include "./utf8_util.h"
|
||||
|
||||
#include "../common/types.h"
|
||||
#include "../public/types.h"
|
||||
|
||||
#if defined(__cplusplus) || defined(c_plusplus)
|
||||
extern "C" {
|
||||
|
@ -9,7 +9,7 @@
|
||||
#ifndef BROTLI_ENC_UTF8_UTIL_H_
|
||||
#define BROTLI_ENC_UTF8_UTIL_H_
|
||||
|
||||
#include "../common/types.h"
|
||||
#include "../public/types.h"
|
||||
#include "./port.h"
|
||||
|
||||
#if defined(__cplusplus) || defined(c_plusplus)
|
||||
|
@ -12,7 +12,7 @@
|
||||
#include <assert.h>
|
||||
#include <stdio.h> /* printf */
|
||||
|
||||
#include "../common/types.h"
|
||||
#include "../public/types.h"
|
||||
#include "./port.h"
|
||||
|
||||
#if defined(__cplusplus) || defined(c_plusplus)
|
||||
|
12
premake5.lua
12
premake5.lua
@ -28,38 +28,38 @@ configuration { "macosx" }
|
||||
project "brotli_common"
|
||||
kind "SharedLib"
|
||||
language "C"
|
||||
files { "common/**.h", "common/**.c" }
|
||||
files { "common/**.h", "common/**.c", "public/**.h" }
|
||||
|
||||
project "brotli_common_static"
|
||||
kind "StaticLib"
|
||||
targetname "brotli_common"
|
||||
language "C"
|
||||
files { "common/**.h", "common/**.c" }
|
||||
files { "common/**.h", "common/**.c", "public/**.h" }
|
||||
|
||||
project "brotli_dec"
|
||||
kind "SharedLib"
|
||||
language "C"
|
||||
files { "dec/**.h", "dec/**.c" }
|
||||
files { "dec/**.h", "dec/**.c", "public/**.h" }
|
||||
links "brotli_common"
|
||||
|
||||
project "brotli_dec_static"
|
||||
kind "StaticLib"
|
||||
targetname "brotli_dec"
|
||||
language "C"
|
||||
files { "dec/**.h", "dec/**.c" }
|
||||
files { "dec/**.h", "dec/**.c", "public/**.h" }
|
||||
links "brotli_common_static"
|
||||
|
||||
project "brotli_enc"
|
||||
kind "SharedLib"
|
||||
language "C"
|
||||
files { "enc/**.h", "enc/**.c" }
|
||||
files { "enc/**.h", "enc/**.c", "public/**.h" }
|
||||
links "brotli_common"
|
||||
|
||||
project "brotli_enc_static"
|
||||
kind "StaticLib"
|
||||
targetname "brotli_enc"
|
||||
language "C"
|
||||
files { "enc/**.h", "enc/**.c" }
|
||||
files { "enc/**.h", "enc/**.c", "public/**.h" }
|
||||
links "brotli_common_static"
|
||||
|
||||
project "bro"
|
||||
|
56
dec/decode.h → public/decode.h
Normal file → Executable file
56
dec/decode.h → public/decode.h
Normal file → Executable file
@ -9,7 +9,7 @@
|
||||
#ifndef BROTLI_DEC_DECODE_H_
|
||||
#define BROTLI_DEC_DECODE_H_
|
||||
|
||||
#include "../common/types.h"
|
||||
#include "./types.h"
|
||||
|
||||
#if defined(__cplusplus) || defined(c_plusplus)
|
||||
extern "C" {
|
||||
@ -52,7 +52,9 @@ typedef enum {
|
||||
BROTLI_ERROR_CODE(_ERROR_FORMAT_, PADDING_1, -14) SEPARATOR \
|
||||
BROTLI_ERROR_CODE(_ERROR_FORMAT_, PADDING_2, -15) SEPARATOR \
|
||||
\
|
||||
/* -16..-20 codes are reserved */ \
|
||||
/* -16..-19 codes are reserved */ \
|
||||
\
|
||||
BROTLI_ERROR_CODE(_ERROR_, INVALID_ARGUMENTS, -20) SEPARATOR \
|
||||
\
|
||||
/* Memory allocation problems */ \
|
||||
BROTLI_ERROR_CODE(_ERROR_ALLOC_, CONTEXT_MODES, -21) SEPARATOR \
|
||||
@ -69,12 +71,12 @@ typedef enum {
|
||||
BROTLI_ERROR_CODE(_ERROR_, UNREACHABLE, -31)
|
||||
|
||||
typedef enum {
|
||||
#define _BROTLI_COMMA ,
|
||||
#define _BROTLI_ERROR_CODE_ENUM_ITEM(PREFIX, NAME, CODE) \
|
||||
#define BROTLI_COMMA_ ,
|
||||
#define BROTLI_ERROR_CODE_ENUM_ITEM_(PREFIX, NAME, CODE) \
|
||||
BROTLI_DECODER ## PREFIX ## NAME = CODE
|
||||
BROTLI_DECODER_ERROR_CODES_LIST(_BROTLI_ERROR_CODE_ENUM_ITEM, _BROTLI_COMMA)
|
||||
#undef _BROTLI_ERROR_CODE_ENUM_ITEM
|
||||
#undef _BROTLI_COMMA
|
||||
BROTLI_DECODER_ERROR_CODES_LIST(BROTLI_ERROR_CODE_ENUM_ITEM_, BROTLI_COMMA_)
|
||||
#undef BROTLI_ERROR_CODE_ENUM_ITEM_
|
||||
#undef BROTLI_COMMA_
|
||||
} BrotliDecoderErrorCode;
|
||||
|
||||
#define BROTLI_LAST_ERROR_CODE BROTLI_DECODER_ERROR_UNREACHABLE
|
||||
@ -92,14 +94,17 @@ void BrotliDecoderDestroyInstance(BrotliDecoderState* state);
|
||||
/* Decompresses the data in |encoded_buffer| into |decoded_buffer|, and sets
|
||||
|*decoded_size| to the decompressed length. */
|
||||
BrotliDecoderResult BrotliDecoderDecompress(
|
||||
size_t encoded_size, const uint8_t* encoded_buffer, size_t* decoded_size,
|
||||
uint8_t* decoded_buffer);
|
||||
size_t encoded_size,
|
||||
const uint8_t encoded_buffer[BROTLI_ARRAY_PARAM(encoded_size)],
|
||||
size_t* decoded_size,
|
||||
uint8_t decoded_buffer[BROTLI_ARRAY_PARAM(*decoded_size)]);
|
||||
|
||||
/* 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.
|
||||
must specify the allocated size in |*next_in| and |*next_out| respectively;
|
||||
when |*available_out| is 0, |next_out| is allowed to be NULL.
|
||||
|
||||
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
|
||||
@ -126,12 +131,28 @@ BrotliDecoderResult BrotliDecoderDecompressStream(
|
||||
4) Clean up and free state with BrotliDestroyState
|
||||
*/
|
||||
void BrotliDecoderSetCustomDictionary(
|
||||
BrotliDecoderState* s, size_t size, const uint8_t* dict);
|
||||
BrotliDecoderState* s, size_t size,
|
||||
const uint8_t dict[BROTLI_ARRAY_PARAM(size)]);
|
||||
|
||||
/* Returns true, if decoder has some unconsumed output.
|
||||
Otherwise returns false. */
|
||||
BROTLI_BOOL BrotliDecoderHasMoreOutput(const BrotliDecoderState* s);
|
||||
|
||||
/* Returns pointer to internal output buffer.
|
||||
Set |size| to zero, to request all the continous output produced by decoder
|
||||
so far. Otherwise no more than |size| bytes output will be provided.
|
||||
After return |size| contains the size of output buffer region available for
|
||||
reading. |size| bytes of output are considered consumed for all consecutive
|
||||
calls to the instance methods; returned pointer becomes invalidated as well.
|
||||
|
||||
This method is created to make language bindings easier and more efficient:
|
||||
1. push data to DecompressStream, until "needs more output" is reported
|
||||
2. use TakeOutput to peek bytes and copy to language-specific entity
|
||||
Also this could be useful if there is an output stream that is able to
|
||||
consume all the provided data (e.g. when data is saved to file system).
|
||||
*/
|
||||
const uint8_t* BrotliDecoderTakeOutput(BrotliDecoderState* s, size_t* size);
|
||||
|
||||
/* Returns true, if decoder has already received some input bytes.
|
||||
Otherwise returns false. */
|
||||
BROTLI_BOOL BrotliDecoderIsUsed(const BrotliDecoderState* s);
|
||||
@ -146,6 +167,9 @@ BrotliDecoderErrorCode BrotliDecoderGetErrorCode(const BrotliDecoderState* s);
|
||||
|
||||
const char* BrotliDecoderErrorString(BrotliDecoderErrorCode c);
|
||||
|
||||
/* Decoder version. Look at BROTLI_VERSION for more information. */
|
||||
uint32_t BrotliDecoderVersion(void);
|
||||
|
||||
/* DEPRECATED >>> */
|
||||
typedef enum {
|
||||
BROTLI_RESULT_ERROR = 0,
|
||||
@ -154,12 +178,12 @@ typedef enum {
|
||||
BROTLI_RESULT_NEEDS_MORE_OUTPUT = 3
|
||||
} BrotliResult;
|
||||
typedef enum {
|
||||
#define _BROTLI_COMMA ,
|
||||
#define _BROTLI_ERROR_CODE_ENUM_ITEM(PREFIX, NAME, CODE) \
|
||||
#define BROTLI_COMMA_ ,
|
||||
#define BROTLI_ERROR_CODE_ENUM_ITEM_(PREFIX, NAME, CODE) \
|
||||
BROTLI ## PREFIX ## NAME = CODE
|
||||
BROTLI_DECODER_ERROR_CODES_LIST(_BROTLI_ERROR_CODE_ENUM_ITEM, _BROTLI_COMMA)
|
||||
#undef _BROTLI_ERROR_CODE_ENUM_ITEM
|
||||
#undef _BROTLI_COMMA
|
||||
BROTLI_DECODER_ERROR_CODES_LIST(BROTLI_ERROR_CODE_ENUM_ITEM_, BROTLI_COMMA_)
|
||||
#undef BROTLI_ERROR_CODE_ENUM_ITEM_
|
||||
#undef BROTLI_COMMA_
|
||||
} BrotliErrorCode;
|
||||
typedef struct BrotliStateStruct BrotliState;
|
||||
BrotliState* BrotliCreateState(
|
48
enc/encode.h → public/encode.h
Normal file → Executable file
48
enc/encode.h → public/encode.h
Normal file → Executable file
@ -9,7 +9,7 @@
|
||||
#ifndef BROTLI_ENC_ENCODE_H_
|
||||
#define BROTLI_ENC_ENCODE_H_
|
||||
|
||||
#include "../common/types.h"
|
||||
#include "./types.h"
|
||||
|
||||
#if defined(__cplusplus) || defined(c_plusplus)
|
||||
extern "C" {
|
||||
@ -75,19 +75,10 @@ BrotliEncoderState* BrotliEncoderCreateInstance(brotli_alloc_func alloc_func,
|
||||
|
||||
/* Deinitializes and frees BrotliEncoderState instance. */
|
||||
void BrotliEncoderDestroyInstance(BrotliEncoderState* state);
|
||||
|
||||
/* The maximum input size that can be processed at once. */
|
||||
size_t BrotliEncoderInputBlockSize(BrotliEncoderState* state);
|
||||
|
||||
/* Encodes the data in |input_buffer| as a meta-block and writes it to
|
||||
|encoded_buffer| (|*encoded_size should| be set to the size of
|
||||
|encoded_buffer|) and sets |*encoded_size| to the number of bytes that
|
||||
was written. The |input_size| must not be greater than input_block_size().
|
||||
Returns false if there was an error and true otherwise. */
|
||||
BROTLI_BOOL BrotliEncoderWriteMetaBlock(
|
||||
BrotliEncoderState* state, const size_t input_size,
|
||||
const uint8_t* input_buffer, const BROTLI_BOOL is_last,
|
||||
size_t* encoded_size, uint8_t* encoded_buffer);
|
||||
|
||||
/* Writes a metadata meta-block containing the given input to encoded_buffer.
|
||||
|*encoded_size| should be set to the size of the encoded_buffer.
|
||||
Sets |*encoded_size| to the number of bytes that was written.
|
||||
@ -101,14 +92,6 @@ BROTLI_BOOL BrotliEncoderWriteMetadata(
|
||||
const uint8_t* input_buffer, const BROTLI_BOOL is_last,
|
||||
size_t* encoded_size, uint8_t* encoded_buffer);
|
||||
|
||||
/* Writes a zero-length meta-block with end-of-input bit set to the
|
||||
internal output buffer and copies the output buffer to |encoded_buffer|
|
||||
(|*encoded_size| should be set to the size of |encoded_buffer|) and sets
|
||||
|*encoded_size| to the number of bytes written.
|
||||
Returns false if there was an error and true otherwise. */
|
||||
BROTLI_BOOL BrotliEncoderFinishStream(
|
||||
BrotliEncoderState* state, size_t* encoded_size, uint8_t* encoded_buffer);
|
||||
|
||||
/* Copies the given input data to the internal ring buffer of the compressor.
|
||||
No processing of the data occurs at this time and this function can be
|
||||
called multiple times before calling WriteBrotliData() to process the
|
||||
@ -138,8 +121,9 @@ BROTLI_BOOL BrotliEncoderWriteData(
|
||||
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);
|
||||
void BrotliEncoderSetCustomDictionary(
|
||||
BrotliEncoderState* state, size_t size,
|
||||
const uint8_t dict[BROTLI_ARRAY_PARAM(size)]);
|
||||
|
||||
/* Returns buffer size that is large enough to contain BrotliEncoderCompress
|
||||
output for any input.
|
||||
@ -157,7 +141,9 @@ size_t BrotliEncoderMaxCompressedSize(size_t input_size);
|
||||
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);
|
||||
const uint8_t input_buffer[BROTLI_ARRAY_PARAM(input_size)],
|
||||
size_t* encoded_size,
|
||||
uint8_t encoded_buffer[BROTLI_ARRAY_PARAM(*encoded_size)]);
|
||||
|
||||
/* Progressively compress input stream and push produced bytes to output stream.
|
||||
Internally workflow consists of 3 tasks:
|
||||
@ -213,6 +199,24 @@ BROTLI_BOOL BrotliEncoderIsFinished(BrotliEncoderState* s);
|
||||
Returns 1 if has more output (in internal buffer) and 0 otherwise. */
|
||||
BROTLI_BOOL BrotliEncoderHasMoreOutput(BrotliEncoderState* s);
|
||||
|
||||
/* Returns pointer to internal output buffer.
|
||||
Set |size| to zero, to request all the continous output produced by encoder
|
||||
so far. Otherwise no more than |size| bytes output will be provided.
|
||||
After return |size| contains the size of output buffer region available for
|
||||
reading. |size| bytes of output are considered consumed for all consecutive
|
||||
calls to the instance methods; returned pointer becomes invalidated as well.
|
||||
|
||||
This method is created to make language bindings easier and more efficient:
|
||||
1. push input data to CompressStream, until HasMoreOutput becomes true
|
||||
2. use TakeOutput to peek bytes and copy to language-specific entity
|
||||
Also this could be useful if there is an output stream that is able to
|
||||
consume all the provided data (e.g. when data is saved to file system).
|
||||
*/
|
||||
const uint8_t* BrotliEncoderTakeOutput(BrotliEncoderState* s, size_t* size);
|
||||
|
||||
|
||||
/* Encoder version. Look at BROTLI_VERSION for more information. */
|
||||
uint32_t BrotliEncoderVersion(void);
|
||||
|
||||
#if defined(__cplusplus) || defined(c_plusplus)
|
||||
} /* extern "C" */
|
10
common/types.h → public/types.h
Normal file → Executable file
10
common/types.h → public/types.h
Normal file → Executable file
@ -25,7 +25,8 @@ typedef __int64 int64_t;
|
||||
#endif /* defined(_MSC_VER) && (_MSC_VER < 1600) */
|
||||
|
||||
#if (!defined(_MSC_VER) || (_MSC_VER >= 1800)) && \
|
||||
(defined(__cplusplus) || (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L))
|
||||
(defined(__cplusplus) || \
|
||||
(defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L))
|
||||
#include <stdbool.h>
|
||||
#define BROTLI_BOOL bool
|
||||
#define BROTLI_TRUE true
|
||||
@ -55,4 +56,11 @@ typedef void* (*brotli_alloc_func)(void* opaque, size_t size);
|
||||
address is 0. */
|
||||
typedef void (*brotli_free_func)(void* opaque, void* address);
|
||||
|
||||
#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && \
|
||||
!defined(__cplusplus)
|
||||
#define BROTLI_ARRAY_PARAM(L) L
|
||||
#else
|
||||
#define BROTLI_ARRAY_PARAM(L)
|
||||
#endif
|
||||
|
||||
#endif /* BROTLI_COMMON_TYPES_H_ */
|
@ -14,8 +14,8 @@
|
||||
#include <sys/types.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "../dec/decode.h"
|
||||
#include "../enc/encode.h"
|
||||
#include "../public/decode.h"
|
||||
#include "../public/encode.h"
|
||||
|
||||
#if !defined(_WIN32)
|
||||
#include <unistd.h>
|
||||
|
Loading…
Reference in New Issue
Block a user