package org.jcodec.common.io;
import java.lang.IllegalArgumentException;
import java.nio.ByteBuffer;
/**
* This class is part of JCodec ( www.jcodec.org ) This software is distributed
* under FreeBSD License
*
* Bitstream writer
*
* @author The JCodec project
*
*/
public class BitWriter {
private final ByteBuffer buf;
private int curInt;
private int _curBit;
private int initPos;
public BitWriter(ByteBuffer buf) {
this.buf = buf;
initPos = buf.position();
}
public BitWriter fork() {
BitWriter fork = new BitWriter(buf.duplicate());
fork._curBit = this._curBit;
fork.curInt = this.curInt;
fork.initPos = this.initPos;
return fork;
}
public void flush() {
int toWrite = (_curBit + 7) >> 3;
for (int i = 0; i < toWrite; i++) {
buf.put((byte) (curInt >>> 24));
curInt <<= 8;
}
}
private final void putInt(int i) {
buf.put((byte) (i >>> 24));
buf.put((byte) (i >> 16));
buf.put((byte) (i >> 8));
buf.put((byte) i);
}
public final void writeNBit(int value, int n) {
if (n > 32)
throw new IllegalArgumentException("Max 32 bit to write");
if (n == 0)
return;
value &= -1 >>> (32 - n);
if (32 - _curBit >= n) {
curInt |= value << (32 - _curBit - n);
_curBit += n;
if (_curBit == 32) {
putInt(curInt);
_curBit = 0;
curInt = 0;
}
} else {
int secPart = n - (32 - _curBit);
curInt |= value >>> secPart;
putInt(curInt);
curInt = value << (32 - secPart);
_curBit = secPart;
}
}
public void write1Bit(int bit) {
curInt |= bit << (32 - _curBit - 1);
++_curBit;
if (_curBit == 32) {
putInt(curInt);
_curBit = 0;
curInt = 0;
}
}
public int curBit() {
return _curBit & 0x7;
}
public int position() {
return ((buf.position() - initPos) << 3) + _curBit;
}
public ByteBuffer getBuffer() {
return buf;
}
}