4 * Functions too long to declare as inline in comp.h.
6 * Copyright (C) 2012 Eric Biggers
8 * wimlib - Library for working with WIM files
10 * This library is free software; you can redistribute it and/or modify it under
11 * the terms of the GNU Lesser General Public License as published by the Free
12 * Software Foundation; either version 2.1 of the License, or (at your option) any
15 * This library is distributed in the hope that it will be useful, but WITHOUT ANY
16 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
17 * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public License along
20 * with this library; if not, write to the Free Software Foundation, Inc., 59
21 * Temple Place, Suite 330, Boston, MA 02111-1307 USA
26 static inline void flush_bits(struct output_bitstream *ostream)
28 *(u16*)ostream->bit_output = to_le16(ostream->bitbuf);
29 ostream->bit_output = ostream->next_bit_output;
30 ostream->next_bit_output = ostream->output;
32 ostream->num_bytes_remaining -= 2;
35 /* Writes @num_bits bits, given by the @num_bits least significant bits of
36 * @bits, to the output @ostream. */
37 int bitstream_put_bits(struct output_bitstream *ostream, output_bitbuf_t bits,
42 wimlib_assert(num_bits <= 16);
43 if (num_bits <= ostream->free_bits) {
44 ostream->bitbuf = (ostream->bitbuf << num_bits) | bits;
45 ostream->free_bits -= num_bits;
48 if (ostream->num_bytes_remaining + (ostream->output -
49 ostream->bit_output) < 2)
52 /* It is tricky to output the bits correctly. The correct way
53 * is to output little-endian 2-byte words, such that the bits
54 * in the SECOND byte logically precede those in the FIRST byte.
55 * While the byte order is little-endian, the bit order is
56 * big-endian; the first bit in a byte is the high-order one.
57 * Any multi-bit numbers are in bit-big-endian form, so the
58 * low-order bit of a multi-bit number is the LAST bit to be
60 rem_bits = num_bits - ostream->free_bits;
61 ostream->bitbuf <<= ostream->free_bits;
62 ostream->bitbuf |= bits >> rem_bits;
64 ostream->free_bits = 16 - rem_bits;
65 ostream->bitbuf = bits;
71 /* Flushes any remaining bits in the output buffer to the output byte stream. */
72 int flush_output_bitstream(struct output_bitstream *ostream)
74 if (ostream->num_bytes_remaining + (ostream->output -
75 ostream->bit_output) < 2)
77 if (ostream->free_bits != 16) {
78 ostream->bitbuf <<= ostream->free_bits;
84 /* Initializes an output bit buffer to write its output to the memory location
85 * pointer to by @data. */
86 void init_output_bitstream(struct output_bitstream *ostream, void *data,
90 ostream->free_bits = 16;
91 ostream->bit_output = (u8*)data;
92 ostream->next_bit_output = (u8*)data + 2;
93 ostream->output = (u8*)data + 4;
94 ostream->num_bytes_remaining = num_bytes - 4;