--- /dev/null
+/*\r
+ * 11/19/04 1.0 moved to LGPL.\r
+ * \r
+ * 12/12/99 0.0.7 Implementation stores single bits \r
+ * as ints for better performance. mdm@techie.com.\r
+ *\r
+ * 02/28/99 0.0 Java Conversion by E.B, javalayer@javazoom.net\r
+ *\r
+ * Adapted from the public c code by Jeff Tsay.\r
+ *\r
+ *-----------------------------------------------------------------------\r
+ * This program is free software; you can redistribute it and/or modify\r
+ * it under the terms of the GNU Library General Public License as published\r
+ * by the Free Software Foundation; either version 2 of the License, or\r
+ * (at your option) any later version.\r
+ *\r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU Library General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU Library General Public\r
+ * License along with this program; if not, write to the Free Software\r
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.\r
+ *----------------------------------------------------------------------\r
+ */\r
+\r
+package javazoom.jl.decoder;\r
+ \r
+/**\r
+ * Implementation of Bit Reservoir for Layer III.\r
+ * <p>\r
+ * The implementation stores single bits as a word in the buffer. If\r
+ * a bit is set, the corresponding word in the buffer will be non-zero.\r
+ * If a bit is clear, the corresponding word is zero. Although this\r
+ * may seem waseful, this can be a factor of two quicker than \r
+ * packing 8 bits to a byte and extracting. \r
+ * <p> \r
+ */\r
+\r
+// REVIEW: there is no range checking, so buffer underflow or overflow\r
+// can silently occur.\r
+final class BitReserve\r
+{\r
+ /**\r
+ * Size of the internal buffer to store the reserved bits.\r
+ * Must be a power of 2. And x8, as each bit is stored as a single\r
+ * entry.\r
+ */\r
+ private static final int BUFSIZE = 4096*8;\r
+ \r
+ /**\r
+ * Mask that can be used to quickly implement the\r
+ * modulus operation on BUFSIZE.\r
+ */\r
+ private static final int BUFSIZE_MASK = BUFSIZE-1;\r
+ \r
+ private int offset, totbit, buf_byte_idx;\r
+ private final int[] buf = new int[BUFSIZE];\r
+ private int buf_bit_idx;\r
+ \r
+ BitReserve()\r
+ {\r
+ \r
+ offset = 0;\r
+ totbit = 0;\r
+ buf_byte_idx = 0; \r
+ }\r
+ \r
+ \r
+ /**\r
+ * Return totbit Field.\r
+ */\r
+ public int hsstell() \r
+ { \r
+ return(totbit); \r
+ }\r
+\r
+ /**\r
+ * Read a number bits from the bit stream.\r
+ * @param N the number of\r
+ */\r
+ public int hgetbits(int N)\r
+ {\r
+ totbit += N;\r
+ \r
+ int val = 0;\r
+ \r
+ int pos = buf_byte_idx;\r
+ if (pos+N < BUFSIZE)\r
+ {\r
+ while (N-- > 0)\r
+ {\r
+ val <<= 1;\r
+ val |= ((buf[pos++]!=0) ? 1 : 0); \r
+ }\r
+ }\r
+ else\r
+ { \r
+ while (N-- > 0)\r
+ {\r
+ val <<= 1; \r
+ val |= ((buf[pos]!=0) ? 1 : 0);\r
+ pos = (pos+1) & BUFSIZE_MASK;\r
+ } \r
+ } \r
+ buf_byte_idx = pos;\r
+ return val;\r
+ }\r
+ \r
+ \r
+ \r
+ /**\r
+ * Read 1 bit from the bit stream.\r
+ */\r
+/*\r
+ public int hget1bit_old()\r
+ {\r
+ int val;\r
+ totbit++;\r
+ if (buf_bit_idx == 0)\r
+ {\r
+ buf_bit_idx = 8;\r
+ buf_byte_idx++; \r
+ }\r
+ // BUFSIZE = 4096 = 2^12, so\r
+ // buf_byte_idx%BUFSIZE == buf_byte_idx & 0xfff\r
+ val = buf[buf_byte_idx & BUFSIZE_MASK] & putmask[buf_bit_idx];\r
+ buf_bit_idx--;\r
+ val = val >>> buf_bit_idx;\r
+ return val; \r
+ }\r
+ */\r
+ /**\r
+ * Returns next bit from reserve.\r
+ * @returns 0 if next bit is reset, or 1 if next bit is set.\r
+ */\r
+ public int hget1bit()\r
+ { \r
+ totbit++; \r
+ int val = buf[buf_byte_idx];\r
+ buf_byte_idx = (buf_byte_idx+1) & BUFSIZE_MASK;\r
+ return val;\r
+ }\r
+ \r
+ /**\r
+ * Retrieves bits from the reserve. \r
+ */\r
+/* \r
+ public int readBits(int[] out, int len)\r
+ {\r
+ if (buf_bit_idx == 0)\r
+ {\r
+ buf_bit_idx = 8;\r
+ buf_byte_idx++;\r
+ current = buf[buf_byte_idx & BUFSIZE_MASK];\r
+ } \r
+ \r
+ \r
+ \r
+ // save total number of bits returned\r
+ len = buf_bit_idx;\r
+ buf_bit_idx = 0;\r
+ \r
+ int b = current;\r
+ int count = len-1;\r
+ \r
+ while (count >= 0)\r
+ {\r
+ out[count--] = (b & 0x1);\r
+ b >>>= 1;\r
+ }\r
+ \r
+ totbit += len;\r
+ return len;\r
+ }\r
+ */\r
+ \r
+ /**\r
+ * Write 8 bits into the bit stream.\r
+ */\r
+ public void hputbuf(int val)\r
+ { \r
+ int ofs = offset;\r
+ buf[ofs++] = val & 0x80;\r
+ buf[ofs++] = val & 0x40;\r
+ buf[ofs++] = val & 0x20;\r
+ buf[ofs++] = val & 0x10;\r
+ buf[ofs++] = val & 0x08;\r
+ buf[ofs++] = val & 0x04;\r
+ buf[ofs++] = val & 0x02;\r
+ buf[ofs++] = val & 0x01;\r
+ \r
+ if (ofs==BUFSIZE)\r
+ offset = 0;\r
+ else\r
+ offset = ofs;\r
+ \r
+ }\r
+ \r
+ /**\r
+ * Rewind N bits in Stream.\r
+ */\r
+ public void rewindNbits(int N)\r
+ {\r
+ totbit -= N; \r
+ buf_byte_idx -= N;\r
+ if (buf_byte_idx<0)\r
+ buf_byte_idx += BUFSIZE;\r
+ }\r
+ \r
+ /**\r
+ * Rewind N bytes in Stream.\r
+ */\r
+ public void rewindNbytes(int N)\r
+ {\r
+ int bits = (N << 3);\r
+ totbit -= bits;\r
+ buf_byte_idx -= bits; \r
+ if (buf_byte_idx<0)\r
+ buf_byte_idx += BUFSIZE;\r
+ }\r
+}\r