X-Git-Url: https://wimlib.net/git/?a=blobdiff_plain;f=src%2Fcomp.c;h=559abbe4016a57801f7f089914dd33c73656be0c;hb=d0e7f039e4ab206b9fd973c983e3fb841fcd2bf2;hp=c18dbd091f47c3baf2221ed9c72c412f4898abe4;hpb=81ea19151423fa87b8698dd3fa8a5274066a76c2;p=wimlib diff --git a/src/comp.c b/src/comp.c index c18dbd09..559abbe4 100644 --- a/src/comp.c +++ b/src/comp.c @@ -1,24 +1,26 @@ /* * comp.c * - * Functions too long to declare as inline in comp.h. - * + * Functions used for compression. + */ + +/* * Copyright (C) 2012 Eric Biggers * - * wimlib - Library for working with WIM files + * This file is part of wimlib, a library for working with WIM files. * - * This library is free software; you can redistribute it and/or modify it under - * the terms of the GNU Lesser General Public License as published by the Free - * Software Foundation; either version 2.1 of the License, or (at your option) any - * later version. + * wimlib is free software; you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free + * Software Foundation; either version 3 of the License, or (at your option) + * any later version. * - * This library is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A - * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + * wimlib is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. * - * You should have received a copy of the GNU Lesser General Public License along - * with this library; if not, write to the Free Software Foundation, Inc., 59 - * Temple Place, Suite 330, Boston, MA 02111-1307 USA + * You should have received a copy of the GNU General Public License + * along with wimlib; if not, see http://www.gnu.org/licenses/. */ #include "comp.h" @@ -27,7 +29,7 @@ static inline void flush_bits(struct output_bitstream *ostream) { - *(u16*)ostream->bit_output = to_le16(ostream->bitbuf); + *(u16*)ostream->bit_output = cpu_to_le16(ostream->bitbuf); ostream->bit_output = ostream->next_bit_output; ostream->next_bit_output = ostream->output; ostream->output += 2; @@ -36,7 +38,7 @@ static inline void flush_bits(struct output_bitstream *ostream) /* Writes @num_bits bits, given by the @num_bits least significant bits of * @bits, to the output @ostream. */ -int bitstream_put_bits(struct output_bitstream *ostream, output_bitbuf_t bits, +int bitstream_put_bits(struct output_bitstream *ostream, output_bitbuf_t bits, uint num_bits) { uint rem_bits; @@ -47,7 +49,7 @@ int bitstream_put_bits(struct output_bitstream *ostream, output_bitbuf_t bits, ostream->free_bits -= num_bits; } else { - if (ostream->num_bytes_remaining + (ostream->output - + if (ostream->num_bytes_remaining + (ostream->output - ostream->bit_output) < 2) return 1; @@ -73,7 +75,7 @@ int bitstream_put_bits(struct output_bitstream *ostream, output_bitbuf_t bits, /* Flushes any remaining bits in the output buffer to the output byte stream. */ int flush_output_bitstream(struct output_bitstream *ostream) { - if (ostream->num_bytes_remaining + (ostream->output - + if (ostream->num_bytes_remaining + (ostream->output - ostream->bit_output) < 2) return 1; if (ostream->free_bits != 16) { @@ -85,9 +87,11 @@ int flush_output_bitstream(struct output_bitstream *ostream) /* Initializes an output bit buffer to write its output to the memory location * pointer to by @data. */ -void init_output_bitstream(struct output_bitstream *ostream, void *data, +void init_output_bitstream(struct output_bitstream *ostream, void *data, uint num_bytes) { + wimlib_assert(num_bytes >= 4); + ostream->bitbuf = 0; ostream->free_bits = 16; ostream->bit_output = (u8*)data; @@ -164,7 +168,7 @@ static void huffman_tree_compute_path_lengths(HuffmanNode *node, u16 cur_len) } } -/* Creates a canonical Huffman code from an array of symbol frequencies. +/* Creates a canonical Huffman code from an array of symbol frequencies. * * The algorithm used is similar to the well-known algorithm that builds a * Huffman tree using a minheap. In that algorithm, the leaf nodes are @@ -215,12 +219,12 @@ static void huffman_tree_compute_path_lengths(HuffmanNode *node, u16 cur_len) * codewords for each symbol will be written. * * @codewords: An array of @num_syms short integers into which the - * codewords for each symbol will be written. The first - * lens[i] bits of codewords[i] will contain the codeword + * codewords for each symbol will be written. The first + * lens[i] bits of codewords[i] will contain the codeword * for symbol i. */ -void make_canonical_huffman_code(uint num_syms, uint max_codeword_len, - const u32 freq_tab[], u8 lens[], +void make_canonical_huffman_code(uint num_syms, uint max_codeword_len, + const u32 freq_tab[], u8 lens[], u16 codewords[]) { /* We require at least 2 possible symbols in the alphabet to produce a @@ -299,7 +303,7 @@ void make_canonical_huffman_code(uint num_syms, uint max_codeword_len, * most num_used_symbols - 1 intermediate nodes when creating a Huffman * code. This is because if there were at least num_used_symbols nodes, * the code would be suboptimal because there would be at least one - * unnecessary intermediate node. + * unnecessary intermediate node. * * The worst case (greatest number of intermediate nodes) would be if * all the intermediate nodes were chained together. This results in @@ -346,7 +350,7 @@ try_building_tree_again: while (1) { /* Lowest frequency node. */ - HuffmanNode *f1 = NULL; + HuffmanNode *f1 = NULL; /* Second lowest frequency node. */ HuffmanNode *f2 = NULL; @@ -355,14 +359,14 @@ try_building_tree_again: * the remaining leaves or from the intermediate nodes. * */ - if (cur_leaf != end_leaf && (cur_inode == next_inode || + if (cur_leaf != end_leaf && (cur_inode == next_inode || cur_leaf->freq <= cur_inode->freq)) { f1 = (HuffmanNode*)cur_leaf++; } else if (cur_inode != next_inode) { f1 = cur_inode++; } - if (cur_leaf != end_leaf && (cur_inode == next_inode || + if (cur_leaf != end_leaf && (cur_inode == next_inode || cur_leaf->freq <= cur_inode->freq)) { f2 = (HuffmanNode*)cur_leaf++; } else if (cur_inode != next_inode) { @@ -401,7 +405,7 @@ try_building_tree_again: if (leaves[i].freq > 1) leaves[i].freq >>= 1; goto try_building_tree_again; - } + } next_inode++; }