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 BitWriterBuffer {
6dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu
7dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu    private ByteBuffer buffer;
8dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu    int initialPos;
9dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu    int position = 0;
10dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu
11dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu    public BitWriterBuffer(ByteBuffer buffer) {
12dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        this.buffer = buffer;
13dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        this.initialPos = buffer.position();
14dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu    }
15dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu
16dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu    public void writeBits(int i, int numBits) {
17dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        assert i <= ((1 << numBits)-1): String.format("Trying to write a value bigger (%s) than the number bits (%s) allows. " +
18dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu                "Please mask the value before writing it and make your code is really working as intended.", i, (1<<numBits)-1);
19dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu
20dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        int left = 8 - position % 8;
21dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        if (numBits <= left) {
22dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu            int current = (buffer.get(initialPos + position / 8));
23dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu            current = current < 0 ? current + 256 : current;
24dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu            current += i << (left - numBits);
25dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu            buffer.put(initialPos + position / 8, (byte) (current > 127 ? current - 256 : current));
26dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu            position += numBits;
27dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        } else {
28dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu            int bitsSecondWrite = numBits - left;
29dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu            writeBits(i >> bitsSecondWrite, left);
30dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu            writeBits(i & (1 << bitsSecondWrite) - 1, bitsSecondWrite);
31dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        }
32dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu        buffer.position(initialPos + position / 8 + ((position % 8 > 0) ? 1 : 0));
33dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu    }
34dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu
35dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu
36dd9eb897ee7c7b507cbdcf80263bb4b5de6966bfTeng-Hui Zhu}
37