org.freehep.util.io.BitOutputStream Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of freehep-io Show documentation
Show all versions of freehep-io Show documentation
FreeHEP extension to the java.io library
// Copyright 2001-2003, FreeHEP.
package org.freehep.util.io;
import java.io.IOException;
import java.io.OutputStream;
/**
* Class to write bits to a Stream, allowing for byte synchronization. Signed,
* Unsigned, Booleans and Floats can be written.
*
* @author Mark Donszelmann
* @author Charles Loomis
* @version $Id: src/main/java/org/freehep/util/io/BitOutputStream.java
* 96b41b903496 2005/11/21 19:50:18 duns $
*/
public class BitOutputStream extends CompressableOutputStream implements
FinishableOutputStream {
private int bits;
private int bitPos;
/**
* Create a Bit output stream from given stream
*
* @param out
* stream to write to
*/
public BitOutputStream(OutputStream out) {
super(out);
bits = 0;
bitPos = 0;
}
@Override
public void finish() throws IOException {
flushByte();
if (out instanceof FinishableOutputStream) {
((FinishableOutputStream) out).finish();
}
}
@Override
public void close() throws IOException {
finish();
super.close();
}
/**
* A utility method to flush the next byte
*
* @throws IOException
* if write fails
*/
protected void flushByte() throws IOException {
if (bitPos == 0) {
return;
}
write(bits);
bits = 0;
bitPos = 0;
}
/**
* A utility to force the next write to be byte-aligned.
*
* @throws IOException
* if write fails
*/
public void byteAlign() throws IOException {
flushByte();
}
/**
* Write a bit to the output stream. A 1-bit is true; a 0-bit is false.
*
* @param bit
* value to write
* @throws IOException
* if write fails
*/
public void writeBitFlag(boolean bit) throws IOException {
writeUBits((bit) ? 1 : 0, 1);
}
/**
* Write a signed value of n-bits to the output stream.
*
* @param value
* value to write
* @param n
* number of bits to write
* @throws IOException
* if write fails
*/
public void writeSBits(long value, int n) throws IOException {
long tmp = value & 0x7FFFFFFF;
if (value < 0) {
tmp |= (1L << (n - 1));
}
writeUBits(tmp, n);
}
/**
* Write a float value of n-bits to the stream.
*
* @param value
* value to write
* @param n
* number of bits to write
* @throws IOException
* if write fails
*/
public void writeFBits(float value, int n) throws IOException {
if (n == 0) {
return;
}
long tmp = (long) (value * 0x10000);
writeSBits(tmp, n);
}
/**
* Write an unsigned value of n-bits to the output stream.
*
* @param value
* value to write
* @param n
* number of bits to write
* @throws IOException
* if write fails
*/
public void writeUBits(long value, int n) throws IOException {
if (n == 0) {
return;
}
if (bitPos == 0) {
bitPos = 8;
}
int bitNum = n;
while (bitNum > 0) {
while ((bitPos > 0) && (bitNum > 0)) {
long or = (value & (1L << (bitNum - 1)));
int shift = bitPos - bitNum;
if (shift < 0) {
or >>= -shift;
} else {
or <<= shift;
}
bits |= or;
bitNum--;
bitPos--;
}
if (bitPos == 0) {
write(bits);
bits = 0;
if (bitNum > 0) {
bitPos = 8;
}
}
}
}
/**
* calculates the minumum number of bits necessary to write number.
*
* @param number
* number
* @return minimum number of bits to store number
*/
public static int minBits(float number) {
return minBits((int) number, true) + 16;
}
/**
* @param number
* value to calculate bits for
* @return number of bits needed to store value
*/
public static int minBits(long number) {
return minBits(number, number < 0);
}
/**
* @param number
* value to calculate bits for
* @param signed
* true if the value if signed (< 0)
* @return number of bits needed to store value
*/
public static int minBits(long number, boolean signed) {
number = Math.abs(number);
long x = 1;
int i;
for (i = 1; i <= 64; i++) {
x <<= 1;
if (x > number) {
break;
}
}
return i + ((signed) ? 1 : 0);
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy