Added Brotli compress/decompress utilities and makefiles

This commit is contained in:
Roderick Sheeter
2013-11-19 14:32:56 -08:00
parent 1571db36a9
commit 437bbad370
29 changed files with 3267 additions and 135 deletions
+10
View File
@@ -0,0 +1,10 @@
#brotli/dec
include ../../shared.mk
OBJS = bit_reader.o decode.o huffman.o safe_malloc.o streams.o
all : $(OBJS)
clean :
rm -f $(OBJS)
+59 -62
View File
@@ -14,6 +14,7 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "./bit_reader.h"
#include "./context.h"
#include "./decode.h"
@@ -372,8 +373,8 @@ static void ReadInsertAndCopy(const HuffmanTree* tree,
} else {
*copy_dist = 0;
}
insert_code = (kInsertRangeLut[range_idx] << 3) + ((code >> 3) & 7);
copy_code = (kCopyRangeLut[range_idx] << 3) + (code & 7);
insert_code = kInsertRangeLut[range_idx] + ((code >> 3) & 7);
copy_code = kCopyRangeLut[range_idx] + (code & 7);
*insert_len = kInsertLengthPrefixCode[insert_code].offset;
insert_extra_bits = kInsertLengthPrefixCode[insert_code].nbits;
if (insert_extra_bits > 0) {
@@ -471,17 +472,11 @@ static int DecodeContextMap(int context_map_size,
return 1;
}
if (*num_htrees == context_map_size) {
int i;
for (i = 0; i < context_map_size; ++i) {
(*context_map)[i] = i;
}
return 1;
}
{
HuffmanTree tree_index_htree;
int use_rle_for_zeros = BrotliReadBits(br, 1);
int max_run_length_prefix = 0;
int i;
if (use_rle_for_zeros) {
max_run_length_prefix = BrotliReadBits(br, 4) + 1;
}
@@ -489,39 +484,26 @@ static int DecodeContextMap(int context_map_size,
&tree_index_htree, br)) {
return 0;
}
if (use_rle_for_zeros) {
int i;
for (i = 0; i < context_map_size;) {
int code;
if (!BrotliReadMoreInput(br)) {
printf("[DecodeContextMap] Unexpected end of input.\n");
ok = 0;
goto End;
}
code = ReadSymbol(&tree_index_htree, br);
if (code == 0) {
for (i = 0; i < context_map_size;) {
int code;
if (!BrotliReadMoreInput(br)) {
printf("[DecodeContextMap] Unexpected end of input.\n");
ok = 0;
goto End;
}
code = ReadSymbol(&tree_index_htree, br);
if (code == 0) {
(*context_map)[i] = 0;
++i;
} else if (code <= max_run_length_prefix) {
int reps = 1 + (1 << code) + BrotliReadBits(br, code);
while (--reps) {
(*context_map)[i] = 0;
++i;
} else if (code <= max_run_length_prefix) {
int reps = 1 + (1 << code) + BrotliReadBits(br, code);
while (--reps) {
(*context_map)[i] = 0;
++i;
}
} else {
(*context_map)[i] = code - max_run_length_prefix;
++i;
}
}
} else {
int i;
for (i = 0; i < context_map_size; ++i) {
if (!BrotliReadMoreInput(br)) {
printf("[DecodeContextMap] Unexpected end of input.\n");
ok = 0;
goto End;
}
(*context_map)[i] = ReadSymbol(&tree_index_htree, br);
} else {
(*context_map)[i] = code - max_run_length_prefix;
++i;
}
}
End:
@@ -640,6 +622,7 @@ int BrotliDecompress(BrotliInput input, BrotliOutput output) {
int input_size_bits = 0;
int input_end = 0;
int window_bits = 0;
size_t max_backward_distance;
size_t ringbuffer_size;
size_t ringbuffer_mask;
uint8_t* ringbuffer;
@@ -678,6 +661,7 @@ int BrotliDecompress(BrotliInput input, BrotliOutput output) {
} else {
window_bits = 16;
}
max_backward_distance = (1 << window_bits) - 16;
ringbuffer_size = 1 << window_bits;
ringbuffer_mask = ringbuffer_size - 1;
@@ -812,6 +796,7 @@ int BrotliDecompress(BrotliInput input, BrotliOutput output) {
int copy_length;
int distance_code;
int distance;
size_t max_distance;
uint8_t context;
int j;
const uint8_t* copy_src;
@@ -899,44 +884,56 @@ int BrotliDecompress(BrotliInput input, BrotliOutput output) {
dist_rb[dist_rb_idx & 3] = distance;
++dist_rb_idx;
}
BROTLI_LOG_UINT(distance);
if (pos < (size_t)distance || pos + copy_length > meta_block_end_pos) {
max_distance = max_backward_distance;
if (pos < max_distance) {
max_distance = pos;
}
if ((size_t)distance > max_distance) {
printf("Invalid backward reference. pos: %ld distance: %d "
"len: %d end: %lu\n", pos, distance, copy_length,
(unsigned long)meta_block_end_pos);
ok = 0;
goto End;
}
} else {
if (pos + copy_length > meta_block_end_pos) {
printf("Invalid backward reference. pos: %zu distance: %d "
"len: %d end: %zu\n", pos, distance, copy_length,
meta_block_end_pos);
ok = 0;
goto End;
}
copy_src = &ringbuffer[(pos - distance) & ringbuffer_mask];
copy_dst = &ringbuffer[pos & ringbuffer_mask];
copy_src = &ringbuffer[(pos - distance) & ringbuffer_mask];
copy_dst = &ringbuffer[pos & ringbuffer_mask];
#if (defined(__x86_64__) || defined(_M_X64))
if (copy_src + copy_length <= ringbuffer_end &&
copy_dst + copy_length < ringbuffer_end) {
if (copy_length <= 16 && distance >= 8) {
UNALIGNED_COPY64(copy_dst, copy_src);
UNALIGNED_COPY64(copy_dst + 8, copy_src + 8);
} else {
IncrementalCopyFastPath(copy_dst, copy_src, copy_length);
if (copy_src + copy_length <= ringbuffer_end &&
copy_dst + copy_length < ringbuffer_end) {
if (copy_length <= 16 && distance >= 8) {
UNALIGNED_COPY64(copy_dst, copy_src);
UNALIGNED_COPY64(copy_dst + 8, copy_src + 8);
} else {
IncrementalCopyFastPath(copy_dst, copy_src, copy_length);
}
pos += copy_length;
copy_length = 0;
}
pos += copy_length;
copy_length = 0;
}
#endif
for (j = 0; j < copy_length; ++j) {
ringbuffer[pos & ringbuffer_mask] =
ringbuffer[(pos - distance) & ringbuffer_mask];
if ((pos & ringbuffer_mask) == ringbuffer_mask) {
if (BrotliWrite(output, ringbuffer, ringbuffer_size) < 0) {
ok = 0;
goto End;
for (j = 0; j < copy_length; ++j) {
ringbuffer[pos & ringbuffer_mask] =
ringbuffer[(pos - distance) & ringbuffer_mask];
if ((pos & ringbuffer_mask) == ringbuffer_mask) {
if (BrotliWrite(output, ringbuffer, ringbuffer_size) < 0) {
ok = 0;
goto End;
}
}
++pos;
}
++pos;
}
// When we get here, we must have inserted at least one literal and made
+2 -6
View File
@@ -53,16 +53,12 @@ static const struct PrefixCodeRange kCopyLengthPrefixCode[] = {
{326, 8}, { 582, 9}, {1094, 10}, {2118, 24},
};
static const int kInsertAndCopyRangeLut[9] = {
0, 1, 4, 2, 3, 6, 5, 7, 8,
};
static const int kInsertRangeLut[9] = {
0, 0, 1, 1, 0, 2, 1, 2, 2,
0, 0, 8, 8, 0, 16, 8, 16, 16,
};
static const int kCopyRangeLut[9] = {
0, 1, 0, 1, 2, 0, 2, 1, 2,
0, 8, 0, 8, 16, 0, 16, 8, 16,
};
#endif // BROTLI_DEC_PREFIX_H_