mirror of
https://github.com/google/brotli.git
synced 2024-11-29 22:51:05 +00:00
Encoder fixes.
* Remove default constructors. * Initialize bit_cost in histogram.Clear(). * Check fseek result in FileSize. * Replace malloc in BrotliFileIn constructor with "new". * Catch bad_alloc in bro tool.
This commit is contained in:
parent
47835c6089
commit
2726b8a4f6
@ -339,6 +339,7 @@ std::vector<int> MoveToFrontTransform(const std::vector<int>& v) {
|
|||||||
std::vector<int> result(v.size());
|
std::vector<int> result(v.size());
|
||||||
for (int i = 0; i < v.size(); ++i) {
|
for (int i = 0; i < v.size(); ++i) {
|
||||||
int index = IndexOf(mtf, v[i]);
|
int index = IndexOf(mtf, v[i]);
|
||||||
|
assert(index >= 0);
|
||||||
result[i] = index;
|
result[i] = index;
|
||||||
MoveToFront(&mtf, index);
|
MoveToFront(&mtf, index);
|
||||||
}
|
}
|
||||||
|
@ -90,8 +90,6 @@ static inline void GetLengthCode(int insertlen, int copylen, int distancecode,
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct Command {
|
struct Command {
|
||||||
Command() {}
|
|
||||||
|
|
||||||
// distance_code is e.g. 0 for same-as-last short code, or 16 for offset 1.
|
// distance_code is e.g. 0 for same-as-last short code, or 16 for offset 1.
|
||||||
Command(int insertlen, int copylen, int copylen_code, int distance_code)
|
Command(int insertlen, int copylen, int copylen_code, int distance_code)
|
||||||
: insert_len_(insertlen), copy_len_(copylen) {
|
: insert_len_(insertlen), copy_len_(copylen) {
|
||||||
|
@ -39,15 +39,15 @@ namespace brotli {
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
void RecomputeDistancePrefixes(std::vector<Command>* cmds,
|
void RecomputeDistancePrefixes(Command* cmds, int num_commands,
|
||||||
int num_direct_distance_codes,
|
int num_direct_distance_codes,
|
||||||
int distance_postfix_bits) {
|
int distance_postfix_bits) {
|
||||||
if (num_direct_distance_codes == 0 &&
|
if (num_direct_distance_codes == 0 &&
|
||||||
distance_postfix_bits == 0) {
|
distance_postfix_bits == 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
for (int i = 0; i < cmds->size(); ++i) {
|
for (int i = 0; i < num_commands; ++i) {
|
||||||
Command* cmd = &(*cmds)[i];
|
Command* cmd = &cmds[i];
|
||||||
if (cmd->copy_len_ > 0 && cmd->cmd_prefix_ >= 128) {
|
if (cmd->copy_len_ > 0 && cmd->cmd_prefix_ >= 128) {
|
||||||
PrefixEncodeCopyDistance(cmd->DistanceCode(),
|
PrefixEncodeCopyDistance(cmd->DistanceCode(),
|
||||||
num_direct_distance_codes,
|
num_direct_distance_codes,
|
||||||
@ -104,7 +104,12 @@ bool WriteMetaBlockParallel(const BrotliParams& params,
|
|||||||
int num_literals = 0;
|
int num_literals = 0;
|
||||||
int max_backward_distance = (1 << params.lgwin) - 16;
|
int max_backward_distance = (1 << params.lgwin) - 16;
|
||||||
int dist_cache[4] = { -4, -4, -4, -4 };
|
int dist_cache[4] = { -4, -4, -4, -4 };
|
||||||
std::vector<Command> commands((input_size + 1) >> 1);
|
Command* commands = static_cast<Command*>(
|
||||||
|
malloc(sizeof(Command) * ((input_size + 1) >> 1)));
|
||||||
|
if (commands == 0) {
|
||||||
|
delete hashers;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
CreateBackwardReferences(
|
CreateBackwardReferences(
|
||||||
input_size, input_pos,
|
input_size, input_pos,
|
||||||
&input[0], mask,
|
&input[0], mask,
|
||||||
@ -114,16 +119,15 @@ bool WriteMetaBlockParallel(const BrotliParams& params,
|
|||||||
hash_type,
|
hash_type,
|
||||||
dist_cache,
|
dist_cache,
|
||||||
&last_insert_len,
|
&last_insert_len,
|
||||||
&commands[0],
|
commands,
|
||||||
&num_commands,
|
&num_commands,
|
||||||
&num_literals);
|
&num_literals);
|
||||||
delete hashers;
|
delete hashers;
|
||||||
commands.resize(num_commands);
|
|
||||||
if (last_insert_len > 0) {
|
if (last_insert_len > 0) {
|
||||||
commands.push_back(Command(last_insert_len));
|
commands[num_commands++] = Command(last_insert_len);
|
||||||
num_literals += last_insert_len;
|
num_literals += last_insert_len;
|
||||||
}
|
}
|
||||||
assert(!commands.empty());
|
assert(num_commands != 0);
|
||||||
|
|
||||||
// Build the meta-block.
|
// Build the meta-block.
|
||||||
MetaBlockSplit mb;
|
MetaBlockSplit mb;
|
||||||
@ -131,17 +135,17 @@ bool WriteMetaBlockParallel(const BrotliParams& params,
|
|||||||
params.mode == BrotliParams::MODE_FONT ? 12 : 0;
|
params.mode == BrotliParams::MODE_FONT ? 12 : 0;
|
||||||
int distance_postfix_bits = params.mode == BrotliParams::MODE_FONT ? 1 : 0;
|
int distance_postfix_bits = params.mode == BrotliParams::MODE_FONT ? 1 : 0;
|
||||||
int literal_context_mode = utf8_mode ? CONTEXT_UTF8 : CONTEXT_SIGNED;
|
int literal_context_mode = utf8_mode ? CONTEXT_UTF8 : CONTEXT_SIGNED;
|
||||||
RecomputeDistancePrefixes(&commands,
|
RecomputeDistancePrefixes(commands, num_commands,
|
||||||
num_direct_distance_codes,
|
num_direct_distance_codes,
|
||||||
distance_postfix_bits);
|
distance_postfix_bits);
|
||||||
if (params.quality <= 9) {
|
if (params.quality <= 9) {
|
||||||
BuildMetaBlockGreedy(&input[0], input_pos, mask,
|
BuildMetaBlockGreedy(&input[0], input_pos, mask,
|
||||||
&commands[0], commands.size(),
|
commands, num_commands,
|
||||||
&mb);
|
&mb);
|
||||||
} else {
|
} else {
|
||||||
BuildMetaBlock(&input[0], input_pos, mask,
|
BuildMetaBlock(&input[0], input_pos, mask,
|
||||||
prev_byte, prev_byte2,
|
prev_byte, prev_byte2,
|
||||||
&commands[0], commands.size(),
|
commands, num_commands,
|
||||||
literal_context_mode,
|
literal_context_mode,
|
||||||
&mb);
|
&mb);
|
||||||
}
|
}
|
||||||
@ -173,11 +177,13 @@ bool WriteMetaBlockParallel(const BrotliParams& params,
|
|||||||
num_direct_distance_codes,
|
num_direct_distance_codes,
|
||||||
distance_postfix_bits,
|
distance_postfix_bits,
|
||||||
literal_context_mode,
|
literal_context_mode,
|
||||||
&commands[0], commands.size(),
|
commands, num_commands,
|
||||||
mb,
|
mb,
|
||||||
&storage_ix, &storage[0])) {
|
&storage_ix, &storage[0])) {
|
||||||
|
free(commands);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
free(commands);
|
||||||
|
|
||||||
// If this is not the last meta-block, store an empty metadata
|
// 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.
|
// meta-block so that the meta-block will end at a byte boundary.
|
||||||
|
@ -29,7 +29,6 @@ namespace brotli {
|
|||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
struct HuffmanTree {
|
struct HuffmanTree {
|
||||||
HuffmanTree();
|
|
||||||
HuffmanTree(int count, int16_t left, int16_t right)
|
HuffmanTree(int count, int16_t left, int16_t right)
|
||||||
: total_count_(count),
|
: total_count_(count),
|
||||||
index_left_(left),
|
index_left_(left),
|
||||||
@ -40,8 +39,6 @@ struct HuffmanTree {
|
|||||||
int16_t index_right_or_value_;
|
int16_t index_right_or_value_;
|
||||||
};
|
};
|
||||||
|
|
||||||
HuffmanTree::HuffmanTree() {}
|
|
||||||
|
|
||||||
// Sort the root nodes, least popular first.
|
// Sort the root nodes, least popular first.
|
||||||
bool SortHuffmanTree(const HuffmanTree &v0, const HuffmanTree &v1) {
|
bool SortHuffmanTree(const HuffmanTree &v0, const HuffmanTree &v1) {
|
||||||
return v0.total_count_ < v1.total_count_;
|
return v0.total_count_ < v1.total_count_;
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
#define BROTLI_ENC_HISTOGRAM_H_
|
#define BROTLI_ENC_HISTOGRAM_H_
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <limits>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include "./command.h"
|
#include "./command.h"
|
||||||
@ -38,6 +39,7 @@ struct Histogram {
|
|||||||
void Clear() {
|
void Clear() {
|
||||||
memset(data_, 0, sizeof(data_));
|
memset(data_, 0, sizeof(data_));
|
||||||
total_count_ = 0;
|
total_count_ = 0;
|
||||||
|
bit_cost_ = std::numeric_limits<double>::infinity();
|
||||||
}
|
}
|
||||||
void Add(int val) {
|
void Add(int val) {
|
||||||
++data_[val];
|
++data_[val];
|
||||||
|
@ -89,18 +89,14 @@ const void* BrotliMemIn::Read(size_t n, size_t* output) {
|
|||||||
|
|
||||||
BrotliFileIn::BrotliFileIn(FILE* f, size_t max_read_size)
|
BrotliFileIn::BrotliFileIn(FILE* f, size_t max_read_size)
|
||||||
: f_(f),
|
: f_(f),
|
||||||
buf_(malloc(max_read_size)),
|
buf_(new char[max_read_size]),
|
||||||
buf_size_(max_read_size) {}
|
buf_size_(max_read_size) { }
|
||||||
|
|
||||||
BrotliFileIn::~BrotliFileIn() {
|
BrotliFileIn::~BrotliFileIn() {
|
||||||
if (buf_) free(buf_);
|
delete[] buf_;
|
||||||
}
|
}
|
||||||
|
|
||||||
const void* BrotliFileIn::Read(size_t n, size_t* bytes_read) {
|
const void* BrotliFileIn::Read(size_t n, size_t* bytes_read) {
|
||||||
if (buf_ == NULL) {
|
|
||||||
*bytes_read = 0;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
if (n > buf_size_) {
|
if (n > buf_size_) {
|
||||||
n = buf_size_;
|
n = buf_size_;
|
||||||
} else if (n == 0) {
|
} else if (n == 0) {
|
||||||
|
@ -110,7 +110,7 @@ class BrotliFileIn : public BrotliIn {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
FILE* f_;
|
FILE* f_;
|
||||||
void* buf_;
|
char* buf_;
|
||||||
size_t buf_size_;
|
size_t buf_size_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
11
tools/bro.cc
11
tools/bro.cc
@ -177,7 +177,10 @@ int64_t FileSize(char *path) {
|
|||||||
if (f == NULL) {
|
if (f == NULL) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
fseek(f, 0L, SEEK_END);
|
if (fseek(f, 0L, SEEK_END) != 0) {
|
||||||
|
fclose(f);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
int64_t retval = ftell(f);
|
int64_t retval = ftell(f);
|
||||||
fclose(f);
|
fclose(f);
|
||||||
return retval;
|
return retval;
|
||||||
@ -209,6 +212,7 @@ int main(int argc, char** argv) {
|
|||||||
brotli::BrotliParams params;
|
brotli::BrotliParams params;
|
||||||
params.lgwin = lgwin;
|
params.lgwin = lgwin;
|
||||||
params.quality = quality;
|
params.quality = quality;
|
||||||
|
try {
|
||||||
brotli::BrotliFileIn in(fin, 1 << 16);
|
brotli::BrotliFileIn in(fin, 1 << 16);
|
||||||
brotli::BrotliFileOut out(fout);
|
brotli::BrotliFileOut out(fout);
|
||||||
if (!BrotliCompress(params, &in, &out)) {
|
if (!BrotliCompress(params, &in, &out)) {
|
||||||
@ -216,6 +220,11 @@ int main(int argc, char** argv) {
|
|||||||
unlink(output_path);
|
unlink(output_path);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
} catch (std::bad_alloc&) {
|
||||||
|
fprintf(stderr, "not enough memory\n");
|
||||||
|
unlink(output_path);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (fclose(fin) != 0) {
|
if (fclose(fin) != 0) {
|
||||||
perror("fclose");
|
perror("fclose");
|
||||||
|
Loading…
Reference in New Issue
Block a user