/* This file is part of jpcsp. Jpcsp is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. Jpcsp is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Jpcsp. If not, see <http://www.gnu.org/licenses/>. */ package jpcsp.media.codec.util; import jpcsp.Memory; public class BitReader implements IBitReader { private Memory mem; private int addr; private int initialAddr; private int initialSize; private int size; private int bits; private int value; private int direction; public BitReader(int addr, int size) { this.addr = addr; this.size = size; initialAddr = addr; initialSize = size; mem = Memory.getInstance(); bits = 0; direction = 1; } @Override public boolean readBool() { return read1() != 0; } @Override public int read1() { if (bits <= 0) { value = mem.read8(addr); addr += direction; size--; bits = 8; } int bit = value >> 7; bits--; value = (value << 1) & 0xFF; return bit; } @Override public int read(int n) { int read; if (n <= bits) { read = value >> (8 - n); bits -= n; value = (value << n) & 0xFF; } else { read = 0; for (; n > 0; n--) { read = (read << 1) + read1(); } } return read; } public int readByte() { if (bits == 8) { bits = 0; return value; } if (bits > 0) { skip(bits); } int read = mem.read8(addr); addr += direction; size--; return read; } public int getBitsLeft() { return (size << 3) + bits; } public int getBytesRead() { int bytesRead = addr - initialAddr; if (bits == 8) { bytesRead--; } return bytesRead; } public int getBitsRead() { return (addr - initialAddr) * 8 - bits; } @Override public int peek(int n) { int read = read(n); skip(-n); return read; } @Override public void skip(int n) { bits -= n; if (n >= 0) { while (bits < 0) { addr += direction; size--; bits += 8; } } else { while (bits > 8) { addr -= direction; size++; bits -= 8; } } if (bits > 0) { value = mem.read8(addr - direction); value = (value << (8 - bits)) & 0xFF; } } public void seek(int n) { addr = initialAddr + n; size = initialSize - n; bits = 0; } public void setDirection(int direction) { this.direction = direction; bits = 0; } public void byteAlign() { if (bits > 0 && bits < 8) { skip(bits); } } @Override public String toString() { return String.format("BitReader addr=0x%08X, bits=%d, size=0x%X, bits read %d", addr, bits, size, getBitsRead()); } }