// Copyright (c) the JPEG XL Project Authors. All rights reserved. // // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file.
// num = alphabet size // depths = symbol depths
Status StoreHuffmanTree(const uint8_t* depths, size_t num, BitWriter* writer) { // Write the Huffman tree into the compact representation.
std::unique_ptr<uint8_t[]> arena(new uint8_t[2 * num]);
uint8_t* huffman_tree = arena.get();
uint8_t* huffman_tree_extra_bits = arena.get() + num;
size_t huffman_tree_size = 0;
WriteHuffmanTree(depths, num, &huffman_tree_size, huffman_tree,
huffman_tree_extra_bits);
// Calculate the statistics of the Huffman tree in the compact representation.
uint32_t huffman_tree_histogram[kCodeLengthCodes] = {0}; for (size_t i = 0; i < huffman_tree_size; ++i) {
++huffman_tree_histogram[huffman_tree[i]];
}
int num_codes = 0; int code = 0; for (int i = 0; i < kCodeLengthCodes; ++i) { if (huffman_tree_histogram[i]) { if (num_codes == 0) {
code = i;
num_codes = 1;
} elseif (num_codes == 1) {
num_codes = 2; break;
}
}
}
// Calculate another Huffman tree to use for compressing both the // earlier Huffman tree with.
uint8_t code_length_bitdepth[kCodeLengthCodes] = {0};
uint16_t code_length_bitdepth_symbols[kCodeLengthCodes] = {0};
CreateHuffmanTree(&huffman_tree_histogram[0], kCodeLengthCodes, 5,
&code_length_bitdepth[0]);
ConvertBitDepthsToSymbols(code_length_bitdepth, kCodeLengthCodes,
&code_length_bitdepth_symbols[0]);
// Now, we have all the data, let's start storing it
StoreHuffmanTreeOfHuffmanTreeToBitMask(num_codes, code_length_bitdepth,
writer);
if (num_codes == 1) {
code_length_bitdepth[code] = 0;
}
// Store the real huffman tree now.
JXL_RETURN_IF_ERROR(StoreHuffmanTreeToBitMask(
huffman_tree_size, huffman_tree, huffman_tree_extra_bits,
&code_length_bitdepth[0], code_length_bitdepth_symbols, writer)); returntrue;
}
} // namespace
Status BuildAndStoreHuffmanTree(const uint32_t* histogram, const size_t length,
uint8_t* depth, uint16_t* bits,
BitWriter* writer) {
size_t count = 0;
size_t s4[4] = {0}; for (size_t i = 0; i < length; i++) { if (histogram[i]) { if (count < 4) {
s4[count] = i;
} elseif (count > 4) { break;
}
count++;
}
}
if (count <= 1) { // Output symbol bits and depths are initialized with 0, nothing to do.
writer->Write(4, 1);
writer->Write(max_bits, s4[0]); returntrue;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.