mirror of
https://github.com/google/brotli.git
synced 2024-11-08 13:20:05 +00:00
Use C-style comments in the brotli decoder.
This commit is contained in:
parent
29bb7cb1af
commit
b8a1008569
@ -1,18 +1,19 @@
|
||||
// Copyright 2013 Google Inc. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// Bit reading helpers
|
||||
/* Copyright 2013 Google Inc. All Rights Reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
Bit reading helpers
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
@ -44,5 +45,5 @@ int BrotliInitBitReader(BrotliBitReader* const br, BrotliInput input) {
|
||||
}
|
||||
|
||||
#if defined(__cplusplus) || defined(c_plusplus)
|
||||
} // extern "C"
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
@ -1,18 +1,19 @@
|
||||
// Copyright 2013 Google Inc. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// Bit reading helpers
|
||||
/* Copyright 2013 Google Inc. All Rights Reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
Bit reading helpers
|
||||
*/
|
||||
|
||||
#ifndef BROTLI_DEC_BIT_READER_H_
|
||||
#define BROTLI_DEC_BIT_READER_H_
|
||||
@ -38,26 +39,26 @@ static const uint32_t kBitMask[BROTLI_MAX_NUM_BIT_READ] = {
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
// Input byte buffer, consist of a ringbuffer and a "slack" region where
|
||||
// bytes from the start of the ringbuffer are copied.
|
||||
/* Input byte buffer, consist of a ringbuffer and a "slack" region where */
|
||||
/* bytes from the start of the ringbuffer are copied. */
|
||||
uint8_t buf_[BROTLI_IBUF_SIZE];
|
||||
BrotliInput input_; // input callback
|
||||
uint64_t val_; // pre-fetched bits
|
||||
size_t pos_; // byte position in stream
|
||||
int bit_pos_; // current bit-reading position in val_
|
||||
size_t end_pos_; // current end position in stream
|
||||
int eos_; // input stream is finished
|
||||
BrotliInput input_; /* input callback */
|
||||
uint64_t val_; /* pre-fetched bits */
|
||||
size_t pos_; /* byte position in stream */
|
||||
int bit_pos_; /* current bit-reading position in val_ */
|
||||
size_t end_pos_; /* current end position in stream */
|
||||
int eos_; /* input stream is finished */
|
||||
} BrotliBitReader;
|
||||
|
||||
int BrotliInitBitReader(BrotliBitReader* const br, BrotliInput input);
|
||||
|
||||
// Return the prefetched bits, so they can be looked up.
|
||||
/* Return the prefetched bits, so they can be looked up. */
|
||||
static BROTLI_INLINE uint32_t BrotliPrefetchBits(BrotliBitReader* const br) {
|
||||
return (uint32_t)(br->val_ >> br->bit_pos_);
|
||||
}
|
||||
|
||||
// For jumping over a number of bits in the bit stream when accessed with
|
||||
// BrotliPrefetchBits and BrotliFillBitWindow.
|
||||
/* For jumping over a number of bits in the bit stream when accessed with */
|
||||
/* BrotliPrefetchBits and BrotliFillBitWindow. */
|
||||
static BROTLI_INLINE void BrotliSetBitPos(BrotliBitReader* const br, int val) {
|
||||
#ifdef BROTLI_DECODE_DEBUG
|
||||
int n_bits = val - br->bit_pos_;
|
||||
@ -68,7 +69,7 @@ static BROTLI_INLINE void BrotliSetBitPos(BrotliBitReader* const br, int val) {
|
||||
br->bit_pos_ = val;
|
||||
}
|
||||
|
||||
// Reload up to 64 bits byte-by-byte
|
||||
/* Reload up to 64 bits byte-by-byte */
|
||||
static BROTLI_INLINE void ShiftBytes(BrotliBitReader* const br) {
|
||||
while (br->bit_pos_ >= 8) {
|
||||
br->val_ >>= 8;
|
||||
@ -78,17 +79,18 @@ static BROTLI_INLINE void ShiftBytes(BrotliBitReader* const br) {
|
||||
}
|
||||
}
|
||||
|
||||
// Fills up the input ringbuffer by calling the input callback.
|
||||
//
|
||||
// Does nothing if there are at least 32 bytes present after current position.
|
||||
//
|
||||
// Returns 0 if either:
|
||||
// - the input callback returned an error, or
|
||||
// - there is no more input and the position is past the end of the stream.
|
||||
//
|
||||
// After encountering the end of the input stream, 32 additional zero bytes are
|
||||
// copied to the ringbuffer, therefore it is safe to call this function after
|
||||
// every 32 bytes of input is read.
|
||||
/* Fills up the input ringbuffer by calling the input callback.
|
||||
|
||||
Does nothing if there are at least 32 bytes present after current position.
|
||||
|
||||
Returns 0 if either:
|
||||
- the input callback returned an error, or
|
||||
- there is no more input and the position is past the end of the stream.
|
||||
|
||||
After encountering the end of the input stream, 32 additional zero bytes are
|
||||
copied to the ringbuffer, therefore it is safe to call this function after
|
||||
every 32 bytes of input is read.
|
||||
*/
|
||||
static BROTLI_INLINE int BrotliReadMoreInput(BrotliBitReader* const br) {
|
||||
if (br->pos_ + 32 < br->end_pos_) {
|
||||
return 1;
|
||||
@ -102,7 +104,7 @@ static BROTLI_INLINE int BrotliReadMoreInput(BrotliBitReader* const br) {
|
||||
}
|
||||
if (bytes_read < BROTLI_READ_SIZE) {
|
||||
br->eos_ = 1;
|
||||
// Store 32 bytes of zero after the stream end.
|
||||
/* Store 32 bytes of zero after the stream end. */
|
||||
#if (defined(__x86_64__) || defined(_M_X64))
|
||||
*(uint64_t*)(dst + bytes_read) = 0;
|
||||
*(uint64_t*)(dst + bytes_read + 8) = 0;
|
||||
@ -113,7 +115,7 @@ static BROTLI_INLINE int BrotliReadMoreInput(BrotliBitReader* const br) {
|
||||
#endif
|
||||
}
|
||||
if (dst == br->buf_) {
|
||||
// Copy the head of the ringbuffer to the slack region.
|
||||
/* Copy the head of the ringbuffer to the slack region. */
|
||||
#if (defined(__x86_64__) || defined(_M_X64))
|
||||
UNALIGNED_COPY64(br->buf_ + BROTLI_IBUF_SIZE - 32, br->buf_);
|
||||
UNALIGNED_COPY64(br->buf_ + BROTLI_IBUF_SIZE - 24, br->buf_ + 8);
|
||||
@ -128,14 +130,14 @@ static BROTLI_INLINE int BrotliReadMoreInput(BrotliBitReader* const br) {
|
||||
}
|
||||
}
|
||||
|
||||
// Advances the Read buffer by 5 bytes to make room for reading next 24 bits.
|
||||
/* Advances the Read buffer by 5 bytes to make room for reading next 24 bits. */
|
||||
static BROTLI_INLINE void BrotliFillBitWindow(BrotliBitReader* const br) {
|
||||
if (br->bit_pos_ >= 40) {
|
||||
#if (defined(__x86_64__) || defined(_M_X64))
|
||||
br->val_ >>= 40;
|
||||
br->bit_pos_ -= 40;
|
||||
// The expression below needs a little-endian arch to work correctly.
|
||||
// This gives a large speedup for decoding speed.
|
||||
/* The expression below needs a little-endian arch to work correctly. */
|
||||
/* This gives a large speedup for decoding speed. */
|
||||
br->val_ |= *(const uint64_t*)(
|
||||
br->buf_ + (br->pos_ & BROTLI_IBUF_MASK)) << 24;
|
||||
br->pos_ += 5;
|
||||
@ -145,8 +147,8 @@ static BROTLI_INLINE void BrotliFillBitWindow(BrotliBitReader* const br) {
|
||||
}
|
||||
}
|
||||
|
||||
// Reads the specified number of bits from Read Buffer.
|
||||
// Requires that n_bits is positive.
|
||||
/* Reads the specified number of bits from Read Buffer. */
|
||||
/* Requires that n_bits is positive. */
|
||||
static BROTLI_INLINE uint32_t BrotliReadBits(
|
||||
BrotliBitReader* const br, int n_bits) {
|
||||
uint32_t val;
|
||||
@ -161,7 +163,7 @@ static BROTLI_INLINE uint32_t BrotliReadBits(
|
||||
}
|
||||
|
||||
#if defined(__cplusplus) || defined(c_plusplus)
|
||||
} // extern "C"
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif // BROTLI_DEC_BIT_READER_H_
|
||||
#endif /* BROTLI_DEC_BIT_READER_H_ */
|
||||
|
249
dec/context.h
249
dec/context.h
@ -1,107 +1,108 @@
|
||||
// Copyright 2013 Google Inc. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// Lookup table to map the previous two bytes to a context id.
|
||||
//
|
||||
// There are four different context modeling modes defined here:
|
||||
// CONTEXT_LSB6: context id is the least significant 6 bits of the last byte,
|
||||
// CONTEXT_MSB6: context id is the most significant 6 bits of the last byte,
|
||||
// CONTEXT_UTF8: second-order context model tuned for UTF8-encoded text,
|
||||
// CONTEXT_SIGNED: second-order context model tuned for signed integers.
|
||||
//
|
||||
// The context id for the UTF8 context model is calculated as follows. If p1
|
||||
// and p2 are the previous two bytes, we calcualte the context as
|
||||
//
|
||||
// context = kContextLookup[p1] | kContextLookup[p2 + 256].
|
||||
//
|
||||
// If the previous two bytes are ASCII characters (i.e. < 128), this will be
|
||||
// equivalent to
|
||||
//
|
||||
// context = 4 * context1(p1) + context2(p2),
|
||||
//
|
||||
// where context1 is based on the previous byte in the following way:
|
||||
//
|
||||
// 0 : non-ASCII control
|
||||
// 1 : \t, \n, \r
|
||||
// 2 : space
|
||||
// 3 : other punctuation
|
||||
// 4 : " '
|
||||
// 5 : %
|
||||
// 6 : ( < [ {
|
||||
// 7 : ) > ] }
|
||||
// 8 : , ; :
|
||||
// 9 : .
|
||||
// 10 : =
|
||||
// 11 : number
|
||||
// 12 : upper-case vowel
|
||||
// 13 : upper-case consonant
|
||||
// 14 : lower-case vowel
|
||||
// 15 : lower-case consonant
|
||||
//
|
||||
// and context2 is based on the second last byte:
|
||||
//
|
||||
// 0 : control, space
|
||||
// 1 : punctuation
|
||||
// 2 : upper-case letter, number
|
||||
// 3 : lower-case letter
|
||||
//
|
||||
// If the last byte is ASCII, and the second last byte is not (in a valid UTF8
|
||||
// stream it will be a continuation byte, value between 128 and 191), the
|
||||
// context is the same as if the second last byte was an ASCII control or space.
|
||||
//
|
||||
// If the last byte is a UTF8 lead byte (value >= 192), then the next byte will
|
||||
// be a continuation byte and the context id is 2 or 3 depending on the LSB of
|
||||
// the last byte and to a lesser extent on the second last byte if it is ASCII.
|
||||
//
|
||||
// If the last byte is a UTF8 continuation byte, the second last byte can be:
|
||||
// - continuation byte: the next byte is probably ASCII or lead byte (assuming
|
||||
// 4-byte UTF8 characters are rare) and the context id is 0 or 1.
|
||||
// - lead byte (192 - 207): next byte is ASCII or lead byte, context is 0 or 1
|
||||
// - lead byte (208 - 255): next byte is continuation byte, context is 2 or 3
|
||||
//
|
||||
// The possible value combinations of the previous two bytes, the range of
|
||||
// context ids and the type of the next byte is summarized in the table below:
|
||||
//
|
||||
// |--------\-----------------------------------------------------------------|
|
||||
// | \ Last byte |
|
||||
// | Second \---------------------------------------------------------------|
|
||||
// | last byte \ ASCII | cont. byte | lead byte |
|
||||
// | \ (0-127) | (128-191) | (192-) |
|
||||
// |=============|===================|=====================|==================|
|
||||
// | ASCII | next: ASCII/lead | not valid | next: cont. |
|
||||
// | (0-127) | context: 4 - 63 | | context: 2 - 3 |
|
||||
// |-------------|-------------------|---------------------|------------------|
|
||||
// | cont. byte | next: ASCII/lead | next: ASCII/lead | next: cont. |
|
||||
// | (128-191) | context: 4 - 63 | context: 0 - 1 | context: 2 - 3 |
|
||||
// |-------------|-------------------|---------------------|------------------|
|
||||
// | lead byte | not valid | next: ASCII/lead | not valid |
|
||||
// | (192-207) | | context: 0 - 1 | |
|
||||
// |-------------|-------------------|---------------------|------------------|
|
||||
// | lead byte | not valid | next: cont. | not valid |
|
||||
// | (208-) | | context: 2 - 3 | |
|
||||
// |-------------|-------------------|---------------------|------------------|
|
||||
//
|
||||
// The context id for the signed context mode is calculated as:
|
||||
//
|
||||
// context = (kContextLookup[512 + p1] << 3) | kContextLookup[512 + p2].
|
||||
//
|
||||
// For any context modeling modes, the context ids can be calculated by |-ing
|
||||
// together two lookups from one table using context model dependent offsets:
|
||||
//
|
||||
// context = kContextLookup[offset1 + p1] | kContextLookup[offset2 + p2].
|
||||
//
|
||||
// where offset1 and offset2 are dependent on the context mode.
|
||||
/* Copyright 2013 Google Inc. All Rights Reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
Lookup table to map the previous two bytes to a context id.
|
||||
|
||||
There are four different context modeling modes defined here:
|
||||
CONTEXT_LSB6: context id is the least significant 6 bits of the last byte,
|
||||
CONTEXT_MSB6: context id is the most significant 6 bits of the last byte,
|
||||
CONTEXT_UTF8: second-order context model tuned for UTF8-encoded text,
|
||||
CONTEXT_SIGNED: second-order context model tuned for signed integers.
|
||||
|
||||
The context id for the UTF8 context model is calculated as follows. If p1
|
||||
and p2 are the previous two bytes, we calcualte the context as
|
||||
|
||||
context = kContextLookup[p1] | kContextLookup[p2 + 256].
|
||||
|
||||
If the previous two bytes are ASCII characters (i.e. < 128), this will be
|
||||
equivalent to
|
||||
|
||||
context = 4 * context1(p1) + context2(p2),
|
||||
|
||||
where context1 is based on the previous byte in the following way:
|
||||
|
||||
0 : non-ASCII control
|
||||
1 : \t, \n, \r
|
||||
2 : space
|
||||
3 : other punctuation
|
||||
4 : " '
|
||||
5 : %
|
||||
6 : ( < [ {
|
||||
7 : ) > ] }
|
||||
8 : , ; :
|
||||
9 : .
|
||||
10 : =
|
||||
11 : number
|
||||
12 : upper-case vowel
|
||||
13 : upper-case consonant
|
||||
14 : lower-case vowel
|
||||
15 : lower-case consonant
|
||||
|
||||
and context2 is based on the second last byte:
|
||||
|
||||
0 : control, space
|
||||
1 : punctuation
|
||||
2 : upper-case letter, number
|
||||
3 : lower-case letter
|
||||
|
||||
If the last byte is ASCII, and the second last byte is not (in a valid UTF8
|
||||
stream it will be a continuation byte, value between 128 and 191), the
|
||||
context is the same as if the second last byte was an ASCII control or space.
|
||||
|
||||
If the last byte is a UTF8 lead byte (value >= 192), then the next byte will
|
||||
be a continuation byte and the context id is 2 or 3 depending on the LSB of
|
||||
the last byte and to a lesser extent on the second last byte if it is ASCII.
|
||||
|
||||
If the last byte is a UTF8 continuation byte, the second last byte can be:
|
||||
- continuation byte: the next byte is probably ASCII or lead byte (assuming
|
||||
4-byte UTF8 characters are rare) and the context id is 0 or 1.
|
||||
- lead byte (192 - 207): next byte is ASCII or lead byte, context is 0 or 1
|
||||
- lead byte (208 - 255): next byte is continuation byte, context is 2 or 3
|
||||
|
||||
The possible value combinations of the previous two bytes, the range of
|
||||
context ids and the type of the next byte is summarized in the table below:
|
||||
|
||||
|--------\-----------------------------------------------------------------|
|
||||
| \ Last byte |
|
||||
| Second \---------------------------------------------------------------|
|
||||
| last byte \ ASCII | cont. byte | lead byte |
|
||||
| \ (0-127) | (128-191) | (192-) |
|
||||
|=============|===================|=====================|==================|
|
||||
| ASCII | next: ASCII/lead | not valid | next: cont. |
|
||||
| (0-127) | context: 4 - 63 | | context: 2 - 3 |
|
||||
|-------------|-------------------|---------------------|------------------|
|
||||
| cont. byte | next: ASCII/lead | next: ASCII/lead | next: cont. |
|
||||
| (128-191) | context: 4 - 63 | context: 0 - 1 | context: 2 - 3 |
|
||||
|-------------|-------------------|---------------------|------------------|
|
||||
| lead byte | not valid | next: ASCII/lead | not valid |
|
||||
| (192-207) | | context: 0 - 1 | |
|
||||
|-------------|-------------------|---------------------|------------------|
|
||||
| lead byte | not valid | next: cont. | not valid |
|
||||
| (208-) | | context: 2 - 3 | |
|
||||
|-------------|-------------------|---------------------|------------------|
|
||||
|
||||
The context id for the signed context mode is calculated as:
|
||||
|
||||
context = (kContextLookup[512 + p1] << 3) | kContextLookup[512 + p2].
|
||||
|
||||
For any context modeling modes, the context ids can be calculated by |-ing
|
||||
together two lookups from one table using context model dependent offsets:
|
||||
|
||||
context = kContextLookup[offset1 + p1] | kContextLookup[offset2 + p2].
|
||||
|
||||
where offset1 and offset2 are dependent on the context mode.
|
||||
*/
|
||||
|
||||
#ifndef BROTLI_DEC_CONTEXT_H_
|
||||
#define BROTLI_DEC_CONTEXT_H_
|
||||
@ -115,11 +116,10 @@ enum ContextType {
|
||||
CONTEXT_SIGNED = 3
|
||||
};
|
||||
|
||||
// Common context lookup table for all context modes.
|
||||
/* Common context lookup table for all context modes. */
|
||||
static const uint8_t kContextLookup[1792] = {
|
||||
// CONTEXT_UTF8, last byte.
|
||||
//
|
||||
// ASCII range.
|
||||
/* CONTEXT_UTF8, last byte. */
|
||||
/* ASCII range. */
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 0, 0, 4, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
8, 12, 16, 12, 12, 20, 12, 16, 24, 28, 12, 12, 32, 12, 36, 12,
|
||||
@ -128,19 +128,18 @@ static const uint8_t kContextLookup[1792] = {
|
||||
52, 52, 52, 52, 52, 48, 52, 52, 52, 52, 52, 24, 12, 28, 12, 12,
|
||||
12, 56, 60, 60, 60, 56, 60, 60, 60, 56, 60, 60, 60, 60, 60, 56,
|
||||
60, 60, 60, 60, 60, 56, 60, 60, 60, 60, 60, 24, 12, 28, 12, 0,
|
||||
// UTF8 continuation byte range.
|
||||
/* UTF8 continuation byte range. */
|
||||
0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
|
||||
0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
|
||||
0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
|
||||
0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
|
||||
// UTF8 lead byte range.
|
||||
/* UTF8 lead byte range. */
|
||||
2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3,
|
||||
2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3,
|
||||
2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3,
|
||||
2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3,
|
||||
// CONTEXT_UTF8 second last byte.
|
||||
//
|
||||
// ASCII range.
|
||||
/* CONTEXT_UTF8 second last byte. */
|
||||
/* ASCII range. */
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
@ -149,17 +148,17 @@ static const uint8_t kContextLookup[1792] = {
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1,
|
||||
1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
|
||||
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 1, 1, 1, 0,
|
||||
// UTF8 continuation byte range.
|
||||
/* UTF8 continuation byte range. */
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
// UTF8 lead byte range.
|
||||
/* UTF8 lead byte range. */
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
// CONTEXT_SIGNED, second last byte.
|
||||
/* CONTEXT_SIGNED, second last byte. */
|
||||
0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
@ -176,7 +175,7 @@ static const uint8_t kContextLookup[1792] = {
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7,
|
||||
// CONTEXT_SIGNED, last byte, same as the above values shifted by 3 bits.
|
||||
/* CONTEXT_SIGNED, last byte, same as the above values shifted by 3 bits. */
|
||||
0, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
||||
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
|
||||
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
|
||||
@ -193,7 +192,7 @@ static const uint8_t kContextLookup[1792] = {
|
||||
40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
|
||||
40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
|
||||
48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 56,
|
||||
// CONTEXT_LSB6, last byte.
|
||||
/* CONTEXT_LSB6, last byte. */
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
|
||||
16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
|
||||
32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
|
||||
@ -210,7 +209,7 @@ static const uint8_t kContextLookup[1792] = {
|
||||
16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
|
||||
32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
|
||||
48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
|
||||
// CONTEXT_MSB6, last byte.
|
||||
/* CONTEXT_MSB6, last byte. */
|
||||
0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3,
|
||||
4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7,
|
||||
8, 8, 8, 8, 9, 9, 9, 9, 10, 10, 10, 10, 11, 11, 11, 11,
|
||||
@ -227,7 +226,7 @@ static const uint8_t kContextLookup[1792] = {
|
||||
52, 52, 52, 52, 53, 53, 53, 53, 54, 54, 54, 54, 55, 55, 55, 55,
|
||||
56, 56, 56, 56, 57, 57, 57, 57, 58, 58, 58, 58, 59, 59, 59, 59,
|
||||
60, 60, 60, 60, 61, 61, 61, 61, 62, 62, 62, 62, 63, 63, 63, 63,
|
||||
// CONTEXT_{M,L}SB6, second last byte,
|
||||
/* CONTEXT_{M,L}SB6, second last byte, */
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
@ -247,14 +246,14 @@ static const uint8_t kContextLookup[1792] = {
|
||||
};
|
||||
|
||||
static const int kContextLookupOffsets[8] = {
|
||||
// CONTEXT_LSB6
|
||||
/* CONTEXT_LSB6 */
|
||||
1024, 1536,
|
||||
// CONTEXT_MSB6
|
||||
/* CONTEXT_MSB6 */
|
||||
1280, 1536,
|
||||
// CONTEXT_UTF8
|
||||
/* CONTEXT_UTF8 */
|
||||
0, 256,
|
||||
// CONTEXT_SIGNED
|
||||
/* CONTEXT_SIGNED */
|
||||
768, 512,
|
||||
};
|
||||
|
||||
#endif // BROTLI_DEC_CONTEXT_H_
|
||||
#endif /* BROTLI_DEC_CONTEXT_H_ */
|
||||
|
122
dec/decode.c
122
dec/decode.c
@ -1,16 +1,17 @@
|
||||
// Copyright 2013 Google Inc. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
/* Copyright 2013 Google Inc. All Rights Reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
@ -67,7 +68,7 @@ static BROTLI_INLINE int DecodeWindowBits(BrotliBitReader* br) {
|
||||
}
|
||||
}
|
||||
|
||||
// Decodes a number in the range [0..255], by reading 1 - 11 bits.
|
||||
/* Decodes a number in the range [0..255], by reading 1 - 11 bits. */
|
||||
static BROTLI_INLINE int DecodeVarLenUint8(BrotliBitReader* br) {
|
||||
if (BrotliReadBits(br, 1)) {
|
||||
int nbits = BrotliReadBits(br, 3);
|
||||
@ -102,7 +103,7 @@ static void DecodeMetaBlockLength(BrotliBitReader* br,
|
||||
}
|
||||
}
|
||||
|
||||
// Decodes the next Huffman code from bit-stream.
|
||||
/* Decodes the next Huffman code from bit-stream. */
|
||||
static BROTLI_INLINE int ReadSymbol(const HuffmanTree* tree,
|
||||
BrotliBitReader* br) {
|
||||
uint32_t bits;
|
||||
@ -113,7 +114,7 @@ static BROTLI_INLINE int ReadSymbol(const HuffmanTree* tree,
|
||||
BrotliFillBitWindow(br);
|
||||
bits = BrotliPrefetchBits(br);
|
||||
bitpos = br->bit_pos_;
|
||||
// Check if we find the bit combination from the Huffman lookup table.
|
||||
/* Check if we find the bit combination from the Huffman lookup table. */
|
||||
lut_ix = bits & (HUFF_LUT - 1);
|
||||
lut_bits = tree->lut_bits_[lut_ix];
|
||||
if (lut_bits <= HUFF_LUT_BITS) {
|
||||
@ -124,7 +125,7 @@ static BROTLI_INLINE int ReadSymbol(const HuffmanTree* tree,
|
||||
bitpos += HUFF_LUT_BITS;
|
||||
bits >>= HUFF_LUT_BITS;
|
||||
|
||||
// Decode the value from a binary tree.
|
||||
/* Decode the value from a binary tree. */
|
||||
assert(node != NULL);
|
||||
do {
|
||||
node = HuffmanTreeNextNode(node, bits & 1);
|
||||
@ -249,7 +250,7 @@ static int ReadHuffmanCode(int alphabet_size,
|
||||
}
|
||||
simple_code = BrotliReadBits(br, 1);
|
||||
BROTLI_LOG_UINT(simple_code);
|
||||
if (simple_code) { // Read symbols, codes & code lengths directly.
|
||||
if (simple_code) { /* Read symbols, codes & code lengths directly. */
|
||||
int i;
|
||||
int max_bits_counter = alphabet_size - 1;
|
||||
int max_bits = 0;
|
||||
@ -282,7 +283,7 @@ static int ReadHuffmanCode(int alphabet_size,
|
||||
break;
|
||||
}
|
||||
BROTLI_LOG_UINT(num_symbols);
|
||||
} else { // Decode Huffman-coded code lengths.
|
||||
} else { /* Decode Huffman-coded code lengths. */
|
||||
int i;
|
||||
uint8_t code_length_code_lengths[CODE_LENGTH_CODES] = { 0 };
|
||||
const int num_codes = BrotliReadBits(br, 4) + 3;
|
||||
@ -421,7 +422,7 @@ static void InverseMoveToFrontTransform(uint8_t* v, int v_len) {
|
||||
}
|
||||
}
|
||||
|
||||
// Contains a collection of huffman trees with the same alphabet size.
|
||||
/* Contains a collection of huffman trees with the same alphabet size. */
|
||||
typedef struct {
|
||||
int alphabet_size;
|
||||
int num_htrees;
|
||||
@ -539,36 +540,37 @@ static BROTLI_INLINE void DecodeBlockType(const HuffmanTree* trees,
|
||||
++(*index);
|
||||
}
|
||||
|
||||
// Copy len bytes from src to dst. It can write up to ten extra bytes
|
||||
// after the end of the copy.
|
||||
//
|
||||
// The main part of this loop is a simple copy of eight bytes at a time until
|
||||
// we've copied (at least) the requested amount of bytes. However, if dst and
|
||||
// src are less than eight bytes apart (indicating a repeating pattern of
|
||||
// length < 8), we first need to expand the pattern in order to get the correct
|
||||
// results. For instance, if the buffer looks like this, with the eight-byte
|
||||
// <src> and <dst> patterns marked as intervals:
|
||||
//
|
||||
// abxxxxxxxxxxxx
|
||||
// [------] src
|
||||
// [------] dst
|
||||
//
|
||||
// a single eight-byte copy from <src> to <dst> will repeat the pattern once,
|
||||
// after which we can move <dst> two bytes without moving <src>:
|
||||
//
|
||||
// ababxxxxxxxxxx
|
||||
// [------] src
|
||||
// [------] dst
|
||||
//
|
||||
// and repeat the exercise until the two no longer overlap.
|
||||
//
|
||||
// This allows us to do very well in the special case of one single byte
|
||||
// repeated many times, without taking a big hit for more general cases.
|
||||
//
|
||||
// The worst case of extra writing past the end of the match occurs when
|
||||
// dst - src == 1 and len == 1; the last copy will read from byte positions
|
||||
// [0..7] and write to [4..11], whereas it was only supposed to write to
|
||||
// position 1. Thus, ten excess bytes.
|
||||
/* Copy len bytes from src to dst. It can write up to ten extra bytes
|
||||
after the end of the copy.
|
||||
|
||||
The main part of this loop is a simple copy of eight bytes at a time until
|
||||
we've copied (at least) the requested amount of bytes. However, if dst and
|
||||
src are less than eight bytes apart (indicating a repeating pattern of
|
||||
length < 8), we first need to expand the pattern in order to get the correct
|
||||
results. For instance, if the buffer looks like this, with the eight-byte
|
||||
<src> and <dst> patterns marked as intervals:
|
||||
|
||||
abxxxxxxxxxxxx
|
||||
[------] src
|
||||
[------] dst
|
||||
|
||||
a single eight-byte copy from <src> to <dst> will repeat the pattern once,
|
||||
after which we can move <dst> two bytes without moving <src>:
|
||||
|
||||
ababxxxxxxxxxx
|
||||
[------] src
|
||||
[------] dst
|
||||
|
||||
and repeat the exercise until the two no longer overlap.
|
||||
|
||||
This allows us to do very well in the special case of one single byte
|
||||
repeated many times, without taking a big hit for more general cases.
|
||||
|
||||
The worst case of extra writing past the end of the match occurs when
|
||||
dst - src == 1 and len == 1; the last copy will read from byte positions
|
||||
[0..7] and write to [4..11], whereas it was only supposed to write to
|
||||
position 1. Thus, ten excess bytes.
|
||||
*/
|
||||
static BROTLI_INLINE void IncrementalCopyFastPath(
|
||||
uint8_t* dst, const uint8_t* src, int len) {
|
||||
if (src < dst) {
|
||||
@ -631,11 +633,11 @@ int BrotliDecompress(BrotliInput input, BrotliOutput output) {
|
||||
size_t ringbuffer_mask;
|
||||
uint8_t* ringbuffer;
|
||||
uint8_t* ringbuffer_end;
|
||||
// This ring buffer holds a few past copy distances that will be used by
|
||||
// some special distance codes.
|
||||
/* This ring buffer holds a few past copy distances that will be used by */
|
||||
/* some special distance codes. */
|
||||
int dist_rb[4] = { 16, 15, 11, 4 };
|
||||
size_t dist_rb_idx = 0;
|
||||
// The previous 2 bytes used for context.
|
||||
/* The previous 2 bytes used for context. */
|
||||
uint8_t prev_byte1 = 0;
|
||||
uint8_t prev_byte2 = 0;
|
||||
HuffmanTreeGroup hgroup[3];
|
||||
@ -649,7 +651,7 @@ int BrotliDecompress(BrotliInput input, BrotliOutput output) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Decode window size.
|
||||
/* Decode window size. */
|
||||
window_bits = DecodeWindowBits(&br);
|
||||
max_backward_distance = (1ULL << window_bits) - 16;
|
||||
|
||||
@ -877,8 +879,8 @@ int BrotliDecompress(BrotliInput input, BrotliOutput output) {
|
||||
&br);
|
||||
}
|
||||
|
||||
// Convert the distance code to the actual distance by possibly looking
|
||||
// up past distnaces from the ringbuffer.
|
||||
/* Convert the distance code to the actual distance by possibly looking */
|
||||
/* up past distnaces from the ringbuffer. */
|
||||
distance = TranslateShortCodes(distance_code, dist_rb, dist_rb_idx);
|
||||
if (distance_code > 0) {
|
||||
dist_rb[dist_rb_idx & 3] = distance;
|
||||
@ -937,9 +939,9 @@ int BrotliDecompress(BrotliInput input, BrotliOutput output) {
|
||||
}
|
||||
}
|
||||
|
||||
// When we get here, we must have inserted at least one literal and made
|
||||
// a copy of at least length two, therefore accessing the last 2 bytes is
|
||||
// valid.
|
||||
/* When we get here, we must have inserted at least one literal and */
|
||||
/* made a copy of at least length two, therefore accessing the last 2 */
|
||||
/* bytes is valid. */
|
||||
prev_byte1 = ringbuffer[(pos - 1) & ringbuffer_mask];
|
||||
prev_byte2 = ringbuffer[(pos - 2) & ringbuffer_mask];
|
||||
}
|
||||
@ -962,5 +964,5 @@ int BrotliDecompress(BrotliInput input, BrotliOutput output) {
|
||||
}
|
||||
|
||||
#if defined(__cplusplus) || defined(c_plusplus)
|
||||
} // extern "C"
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
53
dec/decode.h
53
dec/decode.h
@ -1,18 +1,19 @@
|
||||
// Copyright 2013 Google Inc. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// API for Brotli decompression
|
||||
/* Copyright 2013 Google Inc. All Rights Reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
API for Brotli decompression
|
||||
*/
|
||||
|
||||
#ifndef BROTLI_DEC_DECODE_H_
|
||||
#define BROTLI_DEC_DECODE_H_
|
||||
@ -24,28 +25,28 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// Sets *decoded_size to the decompressed size of the given encoded stream.
|
||||
// Returns 1 on success, 0 on failure.
|
||||
/* Sets *decoded_size to the decompressed size of the given encoded stream. */
|
||||
/* Returns 1 on success, 0 on failure. */
|
||||
int BrotliDecompressedSize(size_t encoded_size,
|
||||
const uint8_t* encoded_buffer,
|
||||
size_t* decoded_size);
|
||||
|
||||
// Decompresses the data in encoded_buffer into decoded_buffer, and sets
|
||||
// *decoded_size to the decompressed length.
|
||||
// Returns 0 if there was either a bit stream error or memory allocation error,
|
||||
// and 1 otherwise.
|
||||
// If decoded size is zero, returns 1 and keeps decoded_buffer unchanged.
|
||||
/* Decompresses the data in encoded_buffer into decoded_buffer, and sets */
|
||||
/* *decoded_size to the decompressed length. */
|
||||
/* Returns 0 if there was either a bit stream error or memory allocation */
|
||||
/* error, and 1 otherwise. */
|
||||
/* If decoded size is zero, returns 1 and keeps decoded_buffer unchanged. */
|
||||
int BrotliDecompressBuffer(size_t encoded_size,
|
||||
const uint8_t* encoded_buffer,
|
||||
size_t* decoded_size,
|
||||
uint8_t* decoded_buffer);
|
||||
|
||||
// Same as above, but uses the specified input and output callbacks instead of
|
||||
// reading from and writing to pre-allocated memory buffers.
|
||||
/* Same as above, but uses the specified input and output callbacks instead */
|
||||
/* of reading from and writing to pre-allocated memory buffers. */
|
||||
int BrotliDecompress(BrotliInput input, BrotliOutput output);
|
||||
|
||||
#if defined(__cplusplus) || defined(c_plusplus)
|
||||
} // extern "C"
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif // BROTLI_DEC_DECODE_H_
|
||||
#endif /* BROTLI_DEC_DECODE_H_ */
|
||||
|
@ -1,18 +1,19 @@
|
||||
// Copyright 2013 Google Inc. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// Utilities for building and looking up Huffman trees.
|
||||
/* Copyright 2013 Google Inc. All Rights Reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
Utilities for building and looking up Huffman trees.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
@ -28,7 +29,7 @@ extern "C" {
|
||||
#define MAX_ALLOWED_CODE_LENGTH 15
|
||||
|
||||
static void TreeNodeInit(HuffmanTreeNode* const node) {
|
||||
node->children_ = -1; // means: 'unassigned so far'
|
||||
node->children_ = -1; /* means: 'unassigned so far' */
|
||||
}
|
||||
|
||||
static int NodeIsEmpty(const HuffmanTreeNode* const node) {
|
||||
@ -52,15 +53,15 @@ static void AssignChildren(HuffmanTree* const tree,
|
||||
static int TreeInit(HuffmanTree* const tree, int num_leaves) {
|
||||
assert(tree != NULL);
|
||||
if (num_leaves == 0) return 0;
|
||||
// We allocate maximum possible nodes in the tree at once.
|
||||
// Note that a Huffman tree is a full binary tree; and in a full binary tree
|
||||
// with L leaves, the total number of nodes N = 2 * L - 1.
|
||||
/* We allocate maximum possible nodes in the tree at once. */
|
||||
/* Note that a Huffman tree is a full binary tree; and in a full binary */
|
||||
/* tree with L leaves, the total number of nodes N = 2 * L - 1. */
|
||||
tree->max_nodes_ = 2 * num_leaves - 1;
|
||||
assert(tree->max_nodes_ < (1 << 16)); // limit for the lut_jump_ table
|
||||
assert(tree->max_nodes_ < (1 << 16)); /* limit for the lut_jump_ table */
|
||||
tree->root_ = (HuffmanTreeNode*)BrotliSafeMalloc((uint64_t)tree->max_nodes_,
|
||||
sizeof(*tree->root_));
|
||||
if (tree->root_ == NULL) return 0;
|
||||
TreeNodeInit(tree->root_); // Initialize root.
|
||||
TreeNodeInit(tree->root_); /* Initialize root. */
|
||||
tree->num_nodes_ = 1;
|
||||
memset(tree->lut_bits_, 255, sizeof(tree->lut_bits_));
|
||||
memset(tree->lut_jump_, 0, sizeof(tree->lut_jump_));
|
||||
@ -76,9 +77,9 @@ void BrotliHuffmanTreeRelease(HuffmanTree* const tree) {
|
||||
}
|
||||
}
|
||||
|
||||
// Utility: converts Huffman code lengths to corresponding Huffman codes.
|
||||
// 'huff_codes' should be pre-allocated.
|
||||
// Returns false in case of error (memory allocation, invalid codes).
|
||||
/* Utility: converts Huffman code lengths to corresponding Huffman codes. */
|
||||
/* 'huff_codes' should be pre-allocated. */
|
||||
/* Returns false in case of error (memory allocation, invalid codes). */
|
||||
static int HuffmanCodeLengthsToCodes(const uint8_t* const code_lengths,
|
||||
int code_lengths_size,
|
||||
int* const huff_codes) {
|
||||
@ -93,7 +94,7 @@ static int HuffmanCodeLengthsToCodes(const uint8_t* const code_lengths,
|
||||
assert(code_lengths_size > 0);
|
||||
assert(huff_codes != NULL);
|
||||
|
||||
// Calculate max code length.
|
||||
/* Calculate max code length. */
|
||||
for (symbol = 0; symbol < code_lengths_size; ++symbol) {
|
||||
if (code_lengths[symbol] > max_code_length) {
|
||||
max_code_length = code_lengths[symbol];
|
||||
@ -101,23 +102,24 @@ static int HuffmanCodeLengthsToCodes(const uint8_t* const code_lengths,
|
||||
}
|
||||
if (max_code_length > MAX_ALLOWED_CODE_LENGTH) return 0;
|
||||
|
||||
// Calculate code length histogram.
|
||||
/* Calculate code length histogram. */
|
||||
for (symbol = 0; symbol < code_lengths_size; ++symbol) {
|
||||
++code_length_hist[code_lengths[symbol]];
|
||||
}
|
||||
code_length_hist[0] = 0;
|
||||
|
||||
// Calculate the initial values of 'next_codes' for each code length.
|
||||
// next_codes[code_len] denotes the code to be assigned to the next symbol
|
||||
// of code length 'code_len'.
|
||||
/* Calculate the initial values of 'next_codes' for each code length. */
|
||||
/* next_codes[code_len] denotes the code to be assigned to the next symbol */
|
||||
/* of code length 'code_len'. */
|
||||
curr_code = 0;
|
||||
next_codes[0] = -1; // Unused, as code length = 0 implies code doesn't exist.
|
||||
next_codes[0] = -1; /* Unused, as code length = 0 implies */
|
||||
/* code doesn't exist. */
|
||||
for (code_len = 1; code_len <= max_code_length; ++code_len) {
|
||||
curr_code = (curr_code + code_length_hist[code_len - 1]) << 1;
|
||||
next_codes[code_len] = curr_code;
|
||||
}
|
||||
|
||||
// Get symbols.
|
||||
/* Get symbols. */
|
||||
for (symbol = 0; symbol < code_lengths_size; ++symbol) {
|
||||
if (code_lengths[symbol] > 0) {
|
||||
huff_codes[symbol] = next_codes[code_lengths[symbol]]++;
|
||||
@ -169,10 +171,10 @@ static int TreeAddSymbol(HuffmanTree* const tree,
|
||||
return 0;
|
||||
}
|
||||
if (NodeIsEmpty(node)) {
|
||||
if (IsFull(tree)) return 0; // error: too many symbols.
|
||||
if (IsFull(tree)) return 0; /* error: too many symbols. */
|
||||
AssignChildren(tree, node);
|
||||
} else if (!HuffmanTreeNodeIsNotLeaf(node)) {
|
||||
return 0; // leaf is already occupied.
|
||||
return 0; /* leaf is already occupied. */
|
||||
}
|
||||
node += node->children_ + ((code >> code_length) & 1);
|
||||
if (--step == 0) {
|
||||
@ -180,11 +182,11 @@ static int TreeAddSymbol(HuffmanTree* const tree,
|
||||
}
|
||||
}
|
||||
if (NodeIsEmpty(node)) {
|
||||
node->children_ = 0; // turn newly created node into a leaf.
|
||||
node->children_ = 0; /* turn newly created node into a leaf. */
|
||||
} else if (HuffmanTreeNodeIsNotLeaf(node)) {
|
||||
return 0; // trying to assign a symbol to already used code.
|
||||
return 0; /* trying to assign a symbol to already used code. */
|
||||
}
|
||||
node->symbol_ = symbol; // Add symbol in this node.
|
||||
node->symbol_ = symbol; /* Add symbol in this node. */
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -198,30 +200,30 @@ int BrotliHuffmanTreeBuildImplicit(HuffmanTree* const tree,
|
||||
assert(tree != NULL);
|
||||
assert(code_lengths != NULL);
|
||||
|
||||
// Find out number of symbols and the root symbol.
|
||||
/* Find out number of symbols and the root symbol. */
|
||||
for (symbol = 0; symbol < code_lengths_size; ++symbol) {
|
||||
if (code_lengths[symbol] > 0) {
|
||||
// Note: code length = 0 indicates non-existent symbol.
|
||||
/* Note: code length = 0 indicates non-existent symbol. */
|
||||
++num_symbols;
|
||||
root_symbol = symbol;
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize the tree. Will fail for num_symbols = 0
|
||||
/* Initialize the tree. Will fail for num_symbols = 0 */
|
||||
if (!TreeInit(tree, num_symbols)) return 0;
|
||||
|
||||
// Build tree.
|
||||
if (num_symbols == 1) { // Trivial case.
|
||||
/* Build tree. */
|
||||
if (num_symbols == 1) { /* Trivial case. */
|
||||
const int max_symbol = code_lengths_size;
|
||||
if (root_symbol < 0 || root_symbol >= max_symbol) {
|
||||
BrotliHuffmanTreeRelease(tree);
|
||||
return 0;
|
||||
}
|
||||
return TreeAddSymbol(tree, root_symbol, 0, 0);
|
||||
} else { // Normal case.
|
||||
} else { /* Normal case. */
|
||||
int ok = 0;
|
||||
|
||||
// Get Huffman codes from the code lengths.
|
||||
/* Get Huffman codes from the code lengths. */
|
||||
int* const codes =
|
||||
(int*)BrotliSafeMalloc((uint64_t)code_lengths_size, sizeof(*codes));
|
||||
if (codes == NULL) goto End;
|
||||
@ -230,7 +232,7 @@ int BrotliHuffmanTreeBuildImplicit(HuffmanTree* const tree,
|
||||
goto End;
|
||||
}
|
||||
|
||||
// Add symbols one-by-one.
|
||||
/* Add symbols one-by-one. */
|
||||
for (symbol = 0; symbol < code_lengths_size; ++symbol) {
|
||||
if (code_lengths[symbol] > 0) {
|
||||
if (!TreeAddSymbol(tree, symbol, codes[symbol], code_lengths[symbol])) {
|
||||
@ -248,5 +250,5 @@ int BrotliHuffmanTreeBuildImplicit(HuffmanTree* const tree,
|
||||
}
|
||||
|
||||
#if defined(__cplusplus) || defined(c_plusplus)
|
||||
} // extern "C"
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
@ -1,18 +1,19 @@
|
||||
// Copyright 2013 Google Inc. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// Utilities for building and looking up Huffman trees.
|
||||
/* Copyright 2013 Google Inc. All Rights Reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
Utilities for building and looking up Huffman trees.
|
||||
*/
|
||||
|
||||
#ifndef BROTLI_DEC_HUFFMAN_H_
|
||||
#define BROTLI_DEC_HUFFMAN_H_
|
||||
@ -24,51 +25,51 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// A node of a Huffman tree.
|
||||
/* A node of a Huffman tree. */
|
||||
typedef struct {
|
||||
int symbol_;
|
||||
int children_; // delta offset to both children (contiguous) or 0 if leaf.
|
||||
int children_; /* delta offset to both children (contiguous) or 0 if leaf. */
|
||||
} HuffmanTreeNode;
|
||||
|
||||
// Huffman Tree.
|
||||
/* Huffman Tree. */
|
||||
#define HUFF_LUT_BITS 7
|
||||
#define HUFF_LUT (1U << HUFF_LUT_BITS)
|
||||
typedef struct HuffmanTree HuffmanTree;
|
||||
struct HuffmanTree {
|
||||
// Fast lookup for short bit lengths.
|
||||
/* Fast lookup for short bit lengths. */
|
||||
uint8_t lut_bits_[HUFF_LUT];
|
||||
int16_t lut_symbol_[HUFF_LUT];
|
||||
int16_t lut_jump_[HUFF_LUT];
|
||||
// Complete tree for lookups.
|
||||
HuffmanTreeNode* root_; // all the nodes, starting at root.
|
||||
int max_nodes_; // max number of nodes
|
||||
int num_nodes_; // number of currently occupied nodes
|
||||
/* Complete tree for lookups. */
|
||||
HuffmanTreeNode* root_; /* all the nodes, starting at root. */
|
||||
int max_nodes_; /* max number of nodes */
|
||||
int num_nodes_; /* number of currently occupied nodes */
|
||||
};
|
||||
|
||||
// Returns true if the given node is not a leaf of the Huffman tree.
|
||||
/* Returns true if the given node is not a leaf of the Huffman tree. */
|
||||
static BROTLI_INLINE int HuffmanTreeNodeIsNotLeaf(
|
||||
const HuffmanTreeNode* const node) {
|
||||
return node->children_;
|
||||
}
|
||||
|
||||
// Go down one level. Most critical function. 'right_child' must be 0 or 1.
|
||||
/* Go down one level. Most critical function. 'right_child' must be 0 or 1. */
|
||||
static BROTLI_INLINE const HuffmanTreeNode* HuffmanTreeNextNode(
|
||||
const HuffmanTreeNode* node, int right_child) {
|
||||
return node + node->children_ + right_child;
|
||||
}
|
||||
|
||||
// Releases the nodes of the Huffman tree.
|
||||
// Note: It does NOT free 'tree' itself.
|
||||
/* Releases the nodes of the Huffman tree. */
|
||||
/* Note: It does NOT free 'tree' itself. */
|
||||
void BrotliHuffmanTreeRelease(HuffmanTree* const tree);
|
||||
|
||||
// Builds Huffman tree assuming code lengths are implicitly in symbol order.
|
||||
// Returns false in case of error (invalid tree or memory error).
|
||||
/* Builds Huffman tree assuming code lengths are implicitly in symbol order. */
|
||||
/* Returns false in case of error (invalid tree or memory error). */
|
||||
int BrotliHuffmanTreeBuildImplicit(HuffmanTree* const tree,
|
||||
const uint8_t* const code_lengths,
|
||||
int code_lengths_size);
|
||||
|
||||
#if defined(__cplusplus) || defined(c_plusplus)
|
||||
} // extern "C"
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif // BROTLI_DEC_HUFFMAN_H_
|
||||
#endif /* BROTLI_DEC_HUFFMAN_H_ */
|
||||
|
39
dec/prefix.h
39
dec/prefix.h
@ -1,25 +1,26 @@
|
||||
// Copyright 2013 Google Inc. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// Lookup tables to map prefix codes to value ranges. This is used during
|
||||
// decoding of the block lengths, literal insertion lengths and copy lengths.
|
||||
/* Copyright 2013 Google Inc. All Rights Reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
Lookup tables to map prefix codes to value ranges. This is used during
|
||||
decoding of the block lengths, literal insertion lengths and copy lengths.
|
||||
*/
|
||||
|
||||
#ifndef BROTLI_DEC_PREFIX_H_
|
||||
#define BROTLI_DEC_PREFIX_H_
|
||||
|
||||
// Represents the range of values belonging to a prefix code:
|
||||
// [offset, offset + 2^nbits)
|
||||
/* Represents the range of values belonging to a prefix code: */
|
||||
/* [offset, offset + 2^nbits) */
|
||||
struct PrefixCodeRange {
|
||||
int offset;
|
||||
int nbits;
|
||||
@ -61,4 +62,4 @@ static const int kCopyRangeLut[9] = {
|
||||
0, 8, 0, 8, 16, 0, 16, 8, 16,
|
||||
};
|
||||
|
||||
#endif // BROTLI_DEC_PREFIX_H_
|
||||
#endif /* BROTLI_DEC_PREFIX_H_ */
|
||||
|
@ -1,18 +1,19 @@
|
||||
// Copyright 2013 Google Inc. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// Size-checked memory allocation.
|
||||
/* Copyright 2013 Google Inc. All Rights Reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
Size-checked memory allocation.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "./safe_malloc.h"
|
||||
@ -21,7 +22,7 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// Returns 0 in case of overflow of nmemb * size.
|
||||
/* Returns 0 in case of overflow of nmemb * size. */
|
||||
static int CheckSizeArgumentsOverflow(uint64_t nmemb, size_t size) {
|
||||
const uint64_t total_size = nmemb * size;
|
||||
if (nmemb == 0) return 1;
|
||||
@ -37,5 +38,5 @@ void* BrotliSafeMalloc(uint64_t nmemb, size_t size) {
|
||||
}
|
||||
|
||||
#if defined(__cplusplus) || defined(c_plusplus)
|
||||
} // extern "C"
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
@ -1,18 +1,19 @@
|
||||
// Copyright 2013 Google Inc. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// Size-checked memory allocation.
|
||||
/* Copyright 2013 Google Inc. All Rights Reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
Size-checked memory allocation.
|
||||
*/
|
||||
|
||||
#ifndef BROTLI_UTILS_UTILS_H_
|
||||
#define BROTLI_UTILS_UTILS_H_
|
||||
@ -25,19 +26,20 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// This is the maximum memory amount that we will ever try to allocate.
|
||||
/* This is the maximum memory amount that we will ever try to allocate. */
|
||||
#define BROTLI_MAX_ALLOCABLE_MEMORY (1ULL << 40)
|
||||
|
||||
// size-checking safe malloc/calloc: verify that the requested size is not too
|
||||
// large, or return NULL. You don't need to call these for constructs like
|
||||
// malloc(sizeof(foo)), but only if there's font-dependent size involved
|
||||
// somewhere (like: malloc(decoded_size * sizeof(*something))). That's why this
|
||||
// safe malloc() borrows the signature from calloc(), pointing at the dangerous
|
||||
// underlying multiply involved.
|
||||
/* size-checking safe malloc/calloc: verify that the requested size is not too
|
||||
large, or return NULL. You don't need to call these for constructs like
|
||||
malloc(sizeof(foo)), but only if there's font-dependent size involved
|
||||
somewhere (like: malloc(decoded_size * sizeof(*something))). That's why this
|
||||
safe malloc() borrows the signature from calloc(), pointing at the dangerous
|
||||
underlying multiply involved.
|
||||
*/
|
||||
void* BrotliSafeMalloc(uint64_t nmemb, size_t size);
|
||||
|
||||
#if defined(__cplusplus) || defined(c_plusplus)
|
||||
} // extern "C"
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* BROTLI_UTILS_UTILS_H_ */
|
||||
|
@ -1,18 +1,19 @@
|
||||
// Copyright 2013 Google Inc. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// Functions for streaming input and output.
|
||||
/* Copyright 2013 Google Inc. All Rights Reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
Functions for streaming input and output.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#ifndef _WIN32
|
||||
@ -112,5 +113,5 @@ BrotliOutput BrotliFileOutput(FILE* f) {
|
||||
|
||||
|
||||
#if defined(__cplusplus) || defined(c_plusplus)
|
||||
} // extern "C"
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
@ -1,18 +1,19 @@
|
||||
// Copyright 2013 Google Inc. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// Functions for streaming input and output.
|
||||
/* Copyright 2013 Google Inc. All Rights Reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
Functions for streaming input and output.
|
||||
*/
|
||||
|
||||
#ifndef BROTLI_DEC_STREAMS_H_
|
||||
#define BROTLI_DEC_STREAMS_H_
|
||||
@ -24,79 +25,79 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// Function pointer type used to read len bytes into buf. Returns the
|
||||
// number of bytes read or -1 on error.
|
||||
/* Function pointer type used to read len bytes into buf. Returns the */
|
||||
/* number of bytes read or -1 on error. */
|
||||
typedef int (*BrotliInputFunction)(void* data, uint8_t* buf, size_t len);
|
||||
|
||||
// Input callback function with associated data.
|
||||
/* Input callback function with associated data. */
|
||||
typedef struct {
|
||||
BrotliInputFunction cb_;
|
||||
void* data_;
|
||||
} BrotliInput;
|
||||
|
||||
// Reads len bytes into buf, using the in callback.
|
||||
/* Reads len bytes into buf, using the in callback. */
|
||||
static BROTLI_INLINE int BrotliRead(BrotliInput in, uint8_t* buf, size_t len) {
|
||||
return in.cb_(in.data_, buf, len);
|
||||
}
|
||||
|
||||
// Function pointer type used to write len bytes into buf. Returns the
|
||||
// number of bytes written or -1 on error.
|
||||
/* Function pointer type used to write len bytes into buf. Returns the */
|
||||
/* number of bytes written or -1 on error. */
|
||||
typedef int (*BrotliOutputFunction)(void* data, const uint8_t* buf, size_t len);
|
||||
|
||||
// Output callback function with associated data.
|
||||
/* Output callback function with associated data. */
|
||||
typedef struct {
|
||||
BrotliOutputFunction cb_;
|
||||
void* data_;
|
||||
} BrotliOutput;
|
||||
|
||||
// Writes len bytes into buf, using the out callback.
|
||||
/* Writes len bytes into buf, using the out callback. */
|
||||
static BROTLI_INLINE int BrotliWrite(BrotliOutput out,
|
||||
const uint8_t* buf, size_t len) {
|
||||
return out.cb_(out.data_, buf, len);
|
||||
}
|
||||
|
||||
// Memory region with position.
|
||||
/* Memory region with position. */
|
||||
typedef struct {
|
||||
const uint8_t* buffer;
|
||||
size_t length;
|
||||
size_t pos;
|
||||
} BrotliMemInput;
|
||||
|
||||
// Input callback where *data is a BrotliMemInput struct.
|
||||
/* Input callback where *data is a BrotliMemInput struct. */
|
||||
int BrotliMemInputFunction(void* data, uint8_t* buf, size_t count);
|
||||
|
||||
// Returns an input callback that wraps the given memory region.
|
||||
/* Returns an input callback that wraps the given memory region. */
|
||||
BrotliInput BrotliInitMemInput(const uint8_t* buffer, size_t length,
|
||||
BrotliMemInput* mem_input);
|
||||
|
||||
// Output buffer with position.
|
||||
/* Output buffer with position. */
|
||||
typedef struct {
|
||||
uint8_t* buffer;
|
||||
size_t length;
|
||||
size_t pos;
|
||||
} BrotliMemOutput;
|
||||
|
||||
// Output callback where *data is a BrotliMemOutput struct.
|
||||
/* Output callback where *data is a BrotliMemOutput struct. */
|
||||
int BrotliMemOutputFunction(void* data, const uint8_t* buf, size_t count);
|
||||
|
||||
// Returns an output callback that wraps the given memory region.
|
||||
/* Returns an output callback that wraps the given memory region. */
|
||||
BrotliOutput BrotliInitMemOutput(uint8_t* buffer, size_t length,
|
||||
BrotliMemOutput* mem_output);
|
||||
|
||||
// Input callback that reads from standard input.
|
||||
/* Input callback that reads from standard input. */
|
||||
int BrotliStdinInputFunction(void* data, uint8_t* buf, size_t count);
|
||||
BrotliInput BrotliStdinInput();
|
||||
|
||||
// Output callback that writes to standard output.
|
||||
/* Output callback that writes to standard output. */
|
||||
int BrotliStdoutOutputFunction(void* data, const uint8_t* buf, size_t count);
|
||||
BrotliOutput BrotliStdoutOutput();
|
||||
|
||||
// Output callback that writes to a file.
|
||||
/* Output callback that writes to a file. */
|
||||
int BrotliFileOutputFunction(void* data, const uint8_t* buf, size_t count);
|
||||
BrotliOutput BrotliFileOutput(FILE* f);
|
||||
|
||||
#if defined(__cplusplus) || defined(c_plusplus)
|
||||
} // extern "C"
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif // BROTLI_DEC_STREAMS_H_
|
||||
#endif /* BROTLI_DEC_STREAMS_H_ */
|
||||
|
35
dec/types.h
35
dec/types.h
@ -1,23 +1,24 @@
|
||||
// Copyright 2013 Google Inc. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// Common types
|
||||
/* Copyright 2013 Google Inc. All Rights Reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
Common types
|
||||
*/
|
||||
|
||||
#ifndef BROTLI_DEC_TYPES_H_
|
||||
#define BROTLI_DEC_TYPES_H_
|
||||
|
||||
#include <stddef.h> // for size_t
|
||||
#include <stddef.h> /* for size_t */
|
||||
|
||||
#ifndef _MSC_VER
|
||||
#include <inttypes.h>
|
||||
@ -38,4 +39,4 @@ typedef long long int int64_t;
|
||||
#define BROTLI_INLINE __forceinline
|
||||
#endif /* _MSC_VER */
|
||||
|
||||
#endif // BROTLI_DEC_TYPES_H_
|
||||
#endif /* BROTLI_DEC_TYPES_H_ */
|
||||
|
Loading…
Reference in New Issue
Block a user