1dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhupackage com.googlecode.mp4parser.boxes.mp4.objectdescriptors;
2dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu
3dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhuimport java.nio.ByteBuffer;
4dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu
5dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhupublic class BitReaderBuffer {
6dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu
7dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu    private ByteBuffer buffer;
8dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu    int initialPos;
9dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu    int position;
10dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu
11dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu    public BitReaderBuffer(ByteBuffer buffer) {
12dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        this.buffer = buffer;
13dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        initialPos = buffer.position();
14dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu    }
15dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu
16dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu    public int readBits(int i) {
17dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        byte b = buffer.get(initialPos + position / 8);
18dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        int v = b < 0 ? b + 256 : b;
19dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        int left = 8 - position % 8;
20dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        int rc;
21dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        if (i <= left) {
22dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu            rc = (v << (position % 8) & 0xFF) >> ((position % 8) + (left - i));
23dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu            position += i;
24dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        } else {
25dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu            int now = left;
26dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu            int then = i - left;
27dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu            rc = readBits(now);
28dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu            rc = rc << then;
29dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu            rc += readBits(then);
30dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        }
31dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        buffer.position(initialPos + (int) Math.ceil((double) position / 8));
32dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        return rc;
33dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu    }
34dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu
35dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu    public int getPosition() {
36dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        return position;
37dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu    }
38dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu
39dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu    public int byteSync() {
40dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        int left = 8 - position % 8;
41dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        if (left == 8) {
42dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu            left = 0;
43dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        }
44dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        readBits(left);
45dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        return left;
46dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu    }
47dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu
48dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu    public int remainingBits() {
49dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        return buffer.limit() * 8 - position;
50dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu    }
51dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu}
52