* 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:
Eugene Kliuchnikov 2016-08-22 13:28:22 +02:00
parent 2e0d3214c2
commit 801f5f37ee
65 changed files with 319 additions and 1041 deletions

20
BUILD
View File

@ -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",

View File

@ -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" {

View File

@ -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
View 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_ */

View File

@ -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)

View File

@ -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)

View File

@ -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,

View File

@ -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) {

View File

@ -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)

View File

@ -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)

View File

@ -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) */

View File

@ -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;

View File

@ -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;

View File

@ -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)

View File

@ -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;
}

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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(&params, 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(&params, 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 */

View File

@ -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_ */

View File

@ -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)

View File

@ -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" {

View File

@ -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" */

View File

@ -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(&params);
params.lgblock = ComputeLgBlock(&params);
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(&params,
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 */

View File

@ -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_ */

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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;

View File

@ -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;

View File

@ -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"

View File

@ -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"

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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"

View File

@ -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"

View File

@ -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)))

View File

@ -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)

View File

@ -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

View File

@ -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"

View File

@ -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)

View File

@ -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" {

View File

@ -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 */

View File

@ -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_ */

View File

@ -8,7 +8,7 @@
#include "./utf8_util.h"
#include "../common/types.h"
#include "../public/types.h"
#if defined(__cplusplus) || defined(c_plusplus)
extern "C" {

View File

@ -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)

View File

@ -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)

View File

@ -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
View 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
View 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
View 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_ */

View File

@ -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>