annotated
[IRC.git] / Robust / src / Tests / ssJava / mp3decoder / BitReserve.java
1 /*\r
2  * 11/19/04                     1.0 moved to LGPL.\r
3  * \r
4  * 12/12/99 0.0.7       Implementation stores single bits \r
5  *                                      as ints for better performance. mdm@techie.com.\r
6  *\r
7  * 02/28/99 0.0     Java Conversion by E.B, javalayer@javazoom.net\r
8  *\r
9  *                  Adapted from the public c code by Jeff Tsay.\r
10  *\r
11  *-----------------------------------------------------------------------\r
12  *   This program is free software; you can redistribute it and/or modify\r
13  *   it under the terms of the GNU Library General Public License as published\r
14  *   by the Free Software Foundation; either version 2 of the License, or\r
15  *   (at your option) any later version.\r
16  *\r
17  *   This program is distributed in the hope that it will be useful,\r
18  *   but WITHOUT ANY WARRANTY; without even the implied warranty of\r
19  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
20  *   GNU Library General Public License for more details.\r
21  *\r
22  *   You should have received a copy of the GNU Library General Public\r
23  *   License along with this program; if not, write to the Free Software\r
24  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.\r
25  *----------------------------------------------------------------------\r
26  */\r
27         \r
28 /**\r
29  * Implementation of Bit Reservoir for Layer III.\r
30  * <p>\r
31  * The implementation stores single bits as a word in the buffer. If\r
32  * a bit is set, the corresponding word in the buffer will be non-zero.\r
33  * If a bit is clear, the corresponding word is zero. Although this\r
34  * may seem waseful, this can be a factor of two quicker than \r
35  * packing 8 bits to a byte and extracting. \r
36  * <p> \r
37  */\r
38 \r
39 // REVIEW: there is no range checking, so buffer underflow or overflow\r
40 // can silently occur.\r
41 @LATTICE("SH<V,V<T,TOT<OFF,OFF<T,SH*,TOT*,OFF*")\r
42 @METHODDEFAULT("OUT<V,V<C,C<IN,C*,THISLOC=V,GLOBALLOC=V")\r
43 final class BitReserve\r
44 {\r
45    /**\r
46     * Size of the internal buffer to store the reserved bits.\r
47     * Must be a power of 2. And x8, as each bit is stored as a single\r
48     * entry.\r
49     */\r
50     @LOC("T") private static final int BUFSIZE = 4096*8;\r
51         \r
52         /**\r
53          * Mask that can be used to quickly implement the\r
54          * modulus operation on BUFSIZE.\r
55          */\r
56     @LOC("V") private static final int BUFSIZE_MASK = BUFSIZE-1;\r
57         \r
58     @LOC("OFF") private int offset;\r
59     @LOC("TOT") private int totbit;\r
60     @LOC("SH") private int buf_byte_idx;\r
61     @LOC("V") private final int[] buf;\r
62     @LOC("T") private int buf_bit_idx;\r
63         \r
64    BitReserve()\r
65    {      \r
66       offset = 0;\r
67       totbit = 0;\r
68       buf_byte_idx = 0;\r
69       buf = new int[BUFSIZE];\r
70    }\r
71       \r
72    \r
73    /**\r
74     * Return totbit Field.\r
75         */\r
76 \r
77    @RETURNLOC("OUT")\r
78    public int hsstell() \r
79    { \r
80            return(totbit); \r
81    }\r
82 \r
83    /**\r
84     * Read a number bits from the bit stream.\r
85     * @param N the number of\r
86         */\r
87    @LATTICE("OUT<SH,SH<THIS,THIS<C,C<GLOBAL,C*,SH*,THISLOC=THIS,GLOBALLOC=GLOBAL")\r
88    @RETURNLOC("OUT") \r
89    public int hgetbits(@LOC("C") int N)\r
90    {\r
91          totbit += N;\r
92          \r
93          @LOC("SH") int val = 0;\r
94          \r
95          @LOC("THIS,BitReserve.SH") int pos = buf_byte_idx;\r
96          if (pos+N < BUFSIZE)\r
97          {\r
98                 while (N-- > 0)\r
99                 {\r
100                         val <<= 1;\r
101                         val |= ((buf[pos++]!=0) ? 1 : 0);                \r
102                 }\r
103         }\r
104          else\r
105          {       \r
106                  while (N-- > 0)\r
107                 {\r
108                          val <<= 1;                      \r
109                          val |= ((buf[pos]!=0) ? 1 : 0);\r
110                          pos = (pos+1) & BUFSIZE_MASK;\r
111                 }                \r
112          }      \r
113          buf_byte_idx = pos;\r
114          return val;\r
115    }\r
116    \r
117          \r
118    \r
119    /**\r
120     * Read 1 bit from the bit stream.\r
121         */\r
122 /*\r
123    public int hget1bit_old()\r
124    {\r
125           int val;\r
126           totbit++;\r
127           if (buf_bit_idx == 0)\r
128           {\r
129          buf_bit_idx = 8;\r
130              buf_byte_idx++;             \r
131           }\r
132       // BUFSIZE = 4096 = 2^12, so\r
133       // buf_byte_idx%BUFSIZE == buf_byte_idx & 0xfff\r
134       val = buf[buf_byte_idx & BUFSIZE_MASK] & putmask[buf_bit_idx];\r
135       buf_bit_idx--;\r
136           val = val >>> buf_bit_idx;\r
137       return val;   \r
138    }\r
139  */\r
140    /**\r
141     * Returns next bit from reserve.\r
142     * @returns 0 if next bit is reset, or 1 if next bit is set.\r
143     */\r
144    @RETURNLOC("OUT")\r
145    public int hget1bit()\r
146    {      \r
147       totbit++;   \r
148       @LOC("OUT") int val = buf[buf_byte_idx];\r
149       buf_byte_idx = (buf_byte_idx+1) & BUFSIZE_MASK;\r
150       return val;\r
151    }\r
152    \r
153    /**\r
154     * Retrieves bits from the reserve.     \r
155     */\r
156 /*   \r
157    public int readBits(int[] out, int len)\r
158    {\r
159                 if (buf_bit_idx == 0)\r
160                 {\r
161                    buf_bit_idx = 8;\r
162                    buf_byte_idx++;\r
163                    current = buf[buf_byte_idx & BUFSIZE_MASK];\r
164                 }      \r
165                 \r
166                 \r
167                 \r
168                 // save total number of bits returned\r
169                 len = buf_bit_idx;\r
170                 buf_bit_idx = 0;\r
171                   \r
172                 int b = current;\r
173                 int count = len-1;\r
174                   \r
175                 while (count >= 0)\r
176                 {\r
177                     out[count--] = (b & 0x1);\r
178                     b >>>= 1;\r
179                 }\r
180           \r
181                 totbit += len;\r
182                 return len;\r
183    }\r
184   */\r
185    \r
186    /**\r
187     * Write 8 bits into the bit stream.\r
188         */\r
189    @LATTICE("OUT<THIS,THIS<IN,THISLOC=THIS,GLOBALLOC=IN")\r
190    public void hputbuf(@LOC("IN") int val)\r
191    {      \r
192            @LOC("THIS,BitReserve.OFF") int ofs = offset;\r
193            buf[ofs++] = val & 0x80;\r
194            buf[ofs++] = val & 0x40;\r
195            buf[ofs++] = val & 0x20;\r
196            buf[ofs++] = val & 0x10;\r
197            buf[ofs++] = val & 0x08;\r
198            buf[ofs++] = val & 0x04;\r
199            buf[ofs++] = val & 0x02;\r
200            buf[ofs++] = val & 0x01;\r
201            \r
202            if (ofs==BUFSIZE)\r
203                         offset = 0;\r
204            else\r
205                         offset = ofs;\r
206            \r
207    }\r
208  \r
209    /**\r
210     * Rewind N bits in Stream.\r
211         */\r
212    public void rewindNbits(int N)\r
213    {\r
214           totbit -= N;            \r
215           buf_byte_idx -= N;\r
216           if (buf_byte_idx<0)\r
217                   buf_byte_idx += BUFSIZE;\r
218    }\r
219         \r
220    /**\r
221     * Rewind N bytes in Stream.\r
222         */\r
223    @LATTICE("THIS<BIT,BIT<N,THISLOC=THIS,GLOBALLOC=N")\r
224    public void rewindNbytes(@LOC("N") int N)\r
225    {\r
226           @LOC("BIT") int bits = (N << 3);\r
227           totbit -= bits;\r
228           buf_byte_idx -= bits;   \r
229           if (buf_byte_idx<0)\r
230                   buf_byte_idx += BUFSIZE;\r
231    }\r
232 }\r