Blame |
Last modification |
View Log
| RSS feed
package test.util;
import java.nio.BufferUnderflowException;
import uk.me.parabola.imgfmt.app.ImgFileReader;
public class BitReaderLR
{
private final ImgFileReader reader
;
private final long readerStart
;
private long bitPosition
;
private final int maxLen
;
public BitReaderLR
(ImgFileReader reader,
int maxLen
) {
this.
reader = reader
;
readerStart = reader.
position();
this.
maxLen = maxLen
;
}
public int get1
() {
int off =
(int) (bitPosition
% 8);
reader.
position(readerStart +
(bitPosition
>> 3));
int b = reader.
get1u();
bitPosition++
;
return b
>> (7 - off
) & 0x1
;
}
/**
* Read n bits.
* @param n number of bits (1 .. 32)
* @return an int containing the bits
*/
public int get
(final int n
) {
if (n
< 1 || n
> 32)
throw new IllegalArgumentException("n must be between 1 .. 32");
if (maxLen
> 0 && bitPosition + n
> maxLen
<< 3) {
throw new BufferUnderflowException();
}
int off =
(int) (bitPosition
% 8);
reader.
position(readerStart +
(bitPosition
>> 3));
int res =
0;
int bitsToRead = n + off
;
while (bitsToRead
> 0) {
res
<<=
8;
res |= reader.
get1u();
bitsToRead -=
8;
}
res
>>= -bitsToRead
;
res
&=
(1 << n
) -
1; // mask out the top bits
bitPosition += n
;
return res
;
}
public long getBitPosition
() {
return bitPosition
;
}
public void setBitPosition
(long pos
) {
if (pos
< 0)
throw new IllegalArgumentException("pos must be >= 0");
bitPosition = pos
;
reader.
position(readerStart +
((bitPosition +
7) >> 3));
}
public boolean hasRemaining
() {
return maxLen
<=
0 ||
(bitPosition
>> 3) < maxLen
;
}
public void flush
() {
if (maxLen
>=
0)
reader.
position(readerStart + maxLen
);
}
}