Subversion Repositories display

Rev

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);
        }      
       
}