forked from sox_ng/sox_ng
From https://github.com/jafingerhut/lpc10 -> lpc10-1.6/lpc55-C which now has proper copyright
114 lines
3.1 KiB
C
114 lines
3.1 KiB
C
/*
|
|
* Copyright 2006 John Andrew Fingerhut (andy.fingerhut@gmail.com)
|
|
*
|
|
* Released under the BSD 3-Clause "New" or "Revised" License
|
|
*
|
|
* https://spdx.org/licenses/BSD-3-Clause.html
|
|
* SPDX Full name: BSD 3-Clause "New" or "Revised" License
|
|
* SPDX Identifier: name BSD-3-Clause
|
|
*
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include "lpc10.h"
|
|
|
|
|
|
/*
|
|
|
|
Write the bits in bits[0] through bits[len-1] to file f, in "packed"
|
|
format.
|
|
|
|
bits is expected to be an array of len integer values, where each
|
|
integer is 0 to represent a 0 bit, and any other value represents a 1
|
|
bit. This bit string is written to the file f in the form of several
|
|
8 bit characters. If len is not a multiple of 8, then the last
|
|
character is padded with 0 bits -- the padding is in the least
|
|
significant bits of the last byte. The 8 bit characters are "filled"
|
|
in order from most significant bit to least significant.
|
|
|
|
*/
|
|
|
|
void
|
|
write_bits(FILE *f, INT32 *bits, int len)
|
|
{
|
|
int i; /* generic loop variable */
|
|
unsigned char mask; /* The next bit position within the
|
|
variable "data" to place the next
|
|
bit. */
|
|
unsigned char data; /* The contents of the next byte to
|
|
place in the output. */
|
|
|
|
/* Fill in the array bits.
|
|
* The first compressed output bit will be the most significant
|
|
* bit of the byte, so initialize mask to 0x80. The next byte of
|
|
* compressed data is initially 0, and the desired bits will be
|
|
* turned on below.
|
|
*/
|
|
mask = 0x80;
|
|
data = 0;
|
|
|
|
for (i = 0; i < len; i++) {
|
|
/* Turn on the next bit of output data, if necessary. */
|
|
if (bits[i]) {
|
|
data |= mask;
|
|
}
|
|
/*
|
|
* If the byte data is full, determined by mask becoming 0,
|
|
* then write the byte to the output file, and reinitialize
|
|
* data and mask for the next output byte. Also add the byte
|
|
* if (i == len-1), because if len is not a multiple of 8,
|
|
* then mask won't yet be 0. */
|
|
mask >>= 1;
|
|
if ((mask == 0) || (i == len-1)) {
|
|
putc(data, f);
|
|
data = 0;
|
|
mask = 0x80;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
Read bits from file f into bits[0] through bits[len-1], in "packed"
|
|
format.
|
|
|
|
Read ceiling(len/8) characters from file f, if that many are available
|
|
to read, otherwise read to the end of the file. The first character's
|
|
8 bits, in order from MSB to LSB, are used to fill bits[0] through
|
|
bits[7]. The second character's bits are used to fill bits[8] through
|
|
bits[15], and so on. If ceiling(len/8) characters are available to
|
|
read, and len is not a multiple of 8, then some of the least
|
|
significant bits of the last character read are completely ignored.
|
|
Every entry of bits[] that is modified is changed to either a 0 or a
|
|
1.
|
|
|
|
The number of bits successfully read is returned, and is always in the
|
|
range 0 to len, inclusive. If it is less than len, it will always be
|
|
a multiple of 8.
|
|
|
|
*/
|
|
|
|
int
|
|
read_bits(FILE *f, INT32 *bits, int len)
|
|
{
|
|
int i; /* generic loop variable */
|
|
int c = 0;
|
|
|
|
/* Unpack the array bits into coded_frame. */
|
|
for (i = 0; i < len; i++) {
|
|
if (i % 8 == 0) {
|
|
c = getc(f);
|
|
if (c == EOF) {
|
|
return (i);
|
|
}
|
|
}
|
|
if (c & (0x80 >> (i & 7))) {
|
|
bits[i] = 1;
|
|
} else {
|
|
bits[i] = 0;
|
|
}
|
|
}
|
|
return (len);
|
|
}
|