/* Copyright 2013 Google Inc. All Rights Reserved.
Distributed under MIT license.
See file LICENSE for detail or copy at https://opensource.org/licenses/MIT
*/
#include <brotli/decode.h>
#include <stdlib.h> /* free, malloc */
#include <string.h> /* memcpy, memset */
#include "../common/constants.h"
#include "../common/context.h"
#include "../common/dictionary.h"
#include "../common/platform.h"
#include "../common/shared_dictionary_internal.h"
#include "../common/transform.h"
#include "../common/version.h"
#include "bit_reader.h"
#include "huffman.h"
#include "prefix.h"
#include "state.h"
#if defined(BROTLI_TARGET_NEON)
#include <arm_neon.h>
#endif
#if defined(__cplusplus) || defined(c_plusplus)
extern "C" {
#endif
#define BROTLI_FAILURE(CODE) (BROTLI_DUMP(), CODE)
#define BROTLI_LOG_UINT(name) \
BROTLI_LOG(("[%s] %s = %lu\n", __func__, #name, (unsigned long)(name)))
#define BROTLI_LOG_ARRAY_INDEX(array_name, idx) \
BROTLI_LOG(("[%s] %s[%lu] = %lu\n", __func__, #array_name, \
(unsigned long)(idx), (unsigned long)array_name[idx]))
#define HUFFMAN_TABLE_BITS 8U
#define HUFFMAN_TABLE_MASK 0xFF
/* We need the slack region for the following reasons:
- doing up to two 16-byte copies for fast backward copying
- inserting transformed dictionary word:
255 prefix + 32 base + 255 suffix */
static const brotli_reg_t kRingBufferWriteAheadSlack = 542;
static const uint8_t kCodeLengthCodeOrder[BROTLI_CODE_LENGTH_CODES] = {
1, 2, 3, 4, 0, 5, 17, 6, 16, 7, 8, 9, 10, 11, 12, 13, 14, 15,
};
/* Static prefix code for the complex code length code lengths. */
static const uint8_t kCodeLengthPrefixLength[16] = {
2, 2, 2, 3, 2, 2, 2, 4, 2, 2, 2, 3, 2, 2, 2, 4,
};
static const uint8_t kCodeLengthPrefixValue[16] = {
0, 4, 3, 2, 0, 4, 3, 1, 0, 4, 3, 2, 0, 4, 3, 5,
};
BROTLI_BOOL BrotliDecoderSetParameter(
BrotliDecoderState* state, BrotliDecoderParameter p, uint32_t value) {
if (state->state != BROTLI_STATE_UNINITED) return BROTLI_FALSE;
switch (p) {
case BROTLI_DECODER_PARAM_DISABLE_RING_BUFFER_REALLOCATION:
state->canny_ringbuffer_allocation = !!value ? 0 : 1;
return BROTLI_TRUE;
case BROTLI_DECODER_PARAM_LARGE_WINDOW:
state->large_window = TO_BROTLI_BOOL(!!value);
return BROTLI_TRUE;
default: return BROTLI_FALSE;
}
}
BrotliDecoderState* BrotliDecoderCreateInstance(
brotli_alloc_func alloc_func, brotli_free_func free_func, void* opaque) {
BrotliDecoderState* state = 0;
if (!alloc_func && !free_func) {
state = (BrotliDecoderState*)malloc(sizeof(BrotliDecoderState));
} else if (alloc_func && free_func) {
state = (BrotliDecoderState*)alloc_func(opaque, sizeof(BrotliDecoderState));
}
if (state == 0) {
BROTLI_DUMP();
return 0;
}
if (!BrotliDecoderStateInit(state, alloc_func, free_func, opaque)) {
BROTLI_DUMP();
if (!alloc_func && !free_func) {
free(state);
} else if (alloc_func && free_func) {
free_func(opaque, state);
}
return 0;
}
return state;
}
/* Deinitializes and frees BrotliDecoderState instance. */
void BrotliDecoderDestroyInstance(BrotliDecoderState* state) {
if (!state) {
return;
} else {
brotli_free_func free_func = state->free_func;
void* opaque = state->memory_manager_opaque;
BrotliDecoderStateCleanup(state);
free_func(opaque, state);
}
}
/* Saves error code and converts it to BrotliDecoderResult. */
static BROTLI_NOINLINE BrotliDecoderResult SaveErrorCode(
BrotliDecoderState* s, BrotliDecoderErrorCode e, size_t consumed_input) {
s->error_code = (int)e;
s->used_input += consumed_input;
if ((s->buffer_length != 0) && (s->br.next_in == s->br.last_in)) {
/* If internal buffer is depleted at last, reset it. */
s->buffer_length = 0;
}
switch (e) {
case BROTLI_DECODER_SUCCESS:
return BROTLI_DECODER_RESULT_SUCCESS;
case BROTLI_DECODER_NEEDS_MORE_INPUT:
return BROTLI_DECODER_RESULT_NEEDS_MORE_INPUT;
case BROTLI_DECODER_NEEDS_MORE_OUTPUT:
return BROTLI_DECODER_RESULT_NEEDS_MORE_OUTPUT;
default:
return BROTLI_DECODER_RESULT_ERROR;
}
}
/* Decodes WBITS by reading 1 - 7 bits, or 0x11 for "Large Window Brotli".
Precondition: bit-reader accumulator has at least 8 bits. */
static BrotliDecoderErrorCode DecodeWindowBits(BrotliDecoderState* s,
BrotliBitReader* br) {
brotli_reg_t n;
BROTLI_BOOL large_window = s->large_window;
s->large_window = BROTLI_FALSE;
BrotliTakeBits(br, 1, &n);
if (n == 0) {
s->window_bits = 16;
return BROTLI_DECODER_SUCCESS;
}
BrotliTakeBits(br, 3, &n);
if (n != 0) {
s->window_bits = (17u + n) & 63u;
return BROTLI_DECODER_SUCCESS;
}
BrotliTakeBits(br, 3, &n);
if (n == 1) {
if (large_window) {
BrotliTakeBits(br, 1, &n);
if (n == 1) {
return BROTLI_FAILURE(BROTLI_DECODER_ERROR_FORMAT_WINDOW_BITS);
}
s->large_window = BROTLI_TRUE;
return BROTLI_DECODER_SUCCESS;
} else {
return BROTLI_FAILURE(BROTLI_DECODER_ERROR_FORMAT_WINDOW_BITS);
}
}
if (n != 0) {
|