Merge remote-tracking branch 'upstream/master'

This commit is contained in:
Zoltan Szabadka 2016-05-26 11:52:48 +02:00
commit d34ff954e4
5 changed files with 240 additions and 162 deletions

File diff suppressed because it is too large Load Diff

View File

@ -28,6 +28,53 @@ typedef enum {
BROTLI_RESULT_NEEDS_MORE_OUTPUT = 3 BROTLI_RESULT_NEEDS_MORE_OUTPUT = 3
} BrotliResult; } BrotliResult;
typedef enum {
BROTLI_NO_ERROR = 0,
/* Same as BrotliResult values */
BROTLI_SUCCESS = 1,
BROTLI_NEEDS_MORE_INPUT = 2,
BROTLI_NEEDS_MORE_OUTPUT = 3,
/* Errors caused by invalid input */
BROTLI_ERROR_FORMAT_EXUBERANT_NIBBLE = -1,
BROTLI_ERROR_FORMAT_RESERVED = -2,
BROTLI_ERROR_FORMAT_EXUBERANT_META_NIBBLE = -3,
BROTLI_ERROR_FORMAT_SIMPLE_HUFFMAN_ALPHABET = -4,
BROTLI_ERROR_FORMAT_SIMPLE_HUFFMAN_SAME = -5,
BROTLI_ERROR_FORMAT_CL_SPACE = -6,
BROTLI_ERROR_FORMAT_HUFFMAN_SPACE = -7,
BROTLI_ERROR_FORMAT_CONTEXT_MAP_REPEAT = -8,
BROTLI_ERROR_FORMAT_BLOCK_LENGTH_1 = -9,
BROTLI_ERROR_FORMAT_BLOCK_LENGTH_2 = -10,
BROTLI_ERROR_FORMAT_TRANSFORM = -11,
BROTLI_ERROR_FORMAT_DICTIONARY = -12,
BROTLI_ERROR_FORMAT_WINDOW_BITS = -13,
BROTLI_ERROR_FORMAT_PADDING_1 = -14,
BROTLI_ERROR_FORMAT_PADDING_2 = -15,
/* -16..-20 codes are reserved */
/* Memory allocation problems */
BROTLI_ERROR_ALLOC_CONTEXT_MODES = -21,
BROTLI_ERROR_ALLOC_TREE_GROUPS = -22, /* Literal, insert, distance */
/* -23..-24 codes are reserved for distinct tree groups */
BROTLI_ERROR_ALLOC_CONTEXT_MAP = -25,
BROTLI_ERROR_ALLOC_RING_BUFFER_1 = -26,
BROTLI_ERROR_ALLOC_RING_BUFFER_2 = -27,
/* -28..-29 codes are reserved for dynamic ringbuffer allocation */
BROTLI_ERROR_ALLOC_BLOCK_TYPE_TREES = -30,
/* "Impossible" states */
BROTLI_ERROR_UNREACHABLE_1 = -31,
BROTLI_ERROR_UNREACHABLE_2 = -32,
BROTLI_ERROR_UNREACHABLE_3 = -33,
BROTLI_ERROR_UNREACHABLE_4 = -34,
BROTLI_ERROR_UNREACHABLE_5 = -35,
BROTLI_ERROR_UNREACHABLE_6 = -36
} BrotliErrorCode;
#define BROTLI_LAST_ERROR_CODE BROTLI_ERROR_UNREACHABLE_6
/* Creates the instance of BrotliState and initializes it. |alloc_func| and /* Creates the instance of BrotliState and initializes it. |alloc_func| and
|free_func| MUST be both zero or both non-zero. In the case they are both |free_func| MUST be both zero or both non-zero. In the case they are both
zero, default memory allocators are used. |opaque| is passed to |alloc_func| zero, default memory allocators are used. |opaque| is passed to |alloc_func|
@ -98,6 +145,10 @@ int BrotliStateIsStreamStart(const BrotliState* s);
produced all of the output, and 0 otherwise. */ produced all of the output, and 0 otherwise. */
int BrotliStateIsStreamEnd(const BrotliState* s); int BrotliStateIsStreamEnd(const BrotliState* s);
/* Returns detailed error code after BrotliDecompressStream returns
BROTLI_RESULT_ERROR. */
BrotliErrorCode BrotliGetErrorCode(const BrotliState* s);
#if defined(__cplusplus) || defined(c_plusplus) #if defined(__cplusplus) || defined(c_plusplus)
} /* extern "C" */ } /* extern "C" */
#endif #endif

View File

@ -120,6 +120,8 @@ struct BrotliStateStruct {
int ringbuffer_mask; int ringbuffer_mask;
int dist_rb_idx; int dist_rb_idx;
int dist_rb[4]; int dist_rb[4];
int error_code;
uint32_t sub_loop_counter;
uint8_t* ringbuffer; uint8_t* ringbuffer;
uint8_t* ringbuffer_end; uint8_t* ringbuffer_end;
HuffmanCode* htree_command; HuffmanCode* htree_command;
@ -128,8 +130,6 @@ struct BrotliStateStruct {
uint8_t* context_map_slice; uint8_t* context_map_slice;
uint8_t* dist_context_map_slice; uint8_t* dist_context_map_slice;
uint32_t sub_loop_counter;
/* This ring buffer holds a few past copy distances that will be used by */ /* This ring buffer holds a few past copy distances that will be used by */
/* some special distance codes. */ /* some special distance codes. */
HuffmanTreeGroup literal_hgroup; HuffmanTreeGroup literal_hgroup;

View File

@ -442,7 +442,8 @@ BrotliCompressor::BrotliCompressor(BrotliParams params)
large_table_(NULL), large_table_(NULL),
cmd_code_numbits_(0), cmd_code_numbits_(0),
command_buf_(NULL), command_buf_(NULL),
literal_buf_(NULL) { literal_buf_(NULL),
is_last_block_emitted_(0) {
// Sanitize params. // Sanitize params.
params_.quality = std::max(0, params_.quality); params_.quality = std::max(0, params_.quality);
if (params_.lgwin < kMinWindowBits) { if (params_.lgwin < kMinWindowBits) {
@ -583,6 +584,10 @@ bool BrotliCompressor::WriteBrotliData(const bool is_last,
const uint8_t* data = ringbuffer_->start(); const uint8_t* data = ringbuffer_->start();
const uint32_t mask = ringbuffer_->mask(); const uint32_t mask = ringbuffer_->mask();
/* Adding more blocks after "last" block is forbidden. */
if (is_last_block_emitted_) return false;
if (is_last) is_last_block_emitted_ = 1;
if (delta > input_block_size()) { if (delta > input_block_size()) {
return false; return false;
} }

View File

@ -180,6 +180,8 @@ class BrotliCompressor {
// Command and literal buffers for quality 1. // Command and literal buffers for quality 1.
uint32_t* command_buf_; uint32_t* command_buf_;
uint8_t* literal_buf_; uint8_t* literal_buf_;
int is_last_block_emitted_;
}; };
// Compresses the data in input_buffer into encoded_buffer, and sets // Compresses the data in input_buffer into encoded_buffer, and sets