corrade-vassal – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 vero 1 /*
2 * CVS identifier:
3 *
4 * $Id: BitToByteOutput.java,v 1.16 2001/10/17 16:56:59 grosbois Exp $
5 *
6 * Class: BitToByteOutput
7 *
8 * Description: Adapter to perform bit based output on a byte
9 * based one.
10 *
11 *
12 *
13 * COPYRIGHT:
14 *
15 * This software module was originally developed by Raphaël Grosbois and
16 * Diego Santa Cruz (Swiss Federal Institute of Technology-EPFL); Joel
17 * Askelöf (Ericsson Radio Systems AB); and Bertrand Berthelot, David
18 * Bouchard, Félix Henry, Gerard Mozelle and Patrice Onno (Canon Research
19 * Centre France S.A) in the course of development of the JPEG2000
20 * standard as specified by ISO/IEC 15444 (JPEG 2000 Standard). This
21 * software module is an implementation of a part of the JPEG 2000
22 * Standard. Swiss Federal Institute of Technology-EPFL, Ericsson Radio
23 * Systems AB and Canon Research Centre France S.A (collectively JJ2000
24 * Partners) agree not to assert against ISO/IEC and users of the JPEG
25 * 2000 Standard (Users) any of their rights under the copyright, not
26 * including other intellectual property rights, for this software module
27 * with respect to the usage by ISO/IEC and Users of this software module
28 * or modifications thereof for use in hardware or software products
29 * claiming conformance to the JPEG 2000 Standard. Those intending to use
30 * this software module in hardware or software products are advised that
31 * their use may infringe existing patents. The original developers of
32 * this software module, JJ2000 Partners and ISO/IEC assume no liability
33 * for use of this software module or modifications thereof. No license
34 * or right to this software module is granted for non JPEG 2000 Standard
35 * conforming products. JJ2000 Partners have full right to use this
36 * software module for his/her own purpose, assign or donate this
37 * software module to any third party and to inhibit third parties from
38 * using this software module for non JPEG 2000 Standard conforming
39 * products. This copyright notice must be included in all copies or
40 * derivative works of this software module.
41 *
42 * Copyright (c) 1999/2000 JJ2000 Partners.
43 * */
44 using System;
45 using CSJ2K.j2k.io;
46 namespace CSJ2K.j2k.entropy.encoder
47 {
48  
49 /// <summary> This class provides an adapter to perform bit based output on byte based
50 /// output objects that inherit from a 'ByteOutputBuffer' class. This class
51 /// implements the bit stuffing policy needed for the 'selective arithmetic
52 /// coding bypass' mode of the entropy coder. This class also delays the output
53 /// of a trailing 0xFF, since they are synthetized be the decoder.
54 ///
55 /// </summary>
56 class BitToByteOutput
57 {
58 /// <summary> Set the flag according to whether or not the predictable termination is
59 /// requested.
60 ///
61 /// </summary>
62 /// <param name="isPredTerm">Whether or not predictable termination is requested.
63 ///
64 /// </param>
65 virtual internal bool PredTerm
66 {
67 set
68 {
69 this.isPredTerm = value;
70 }
71  
72 }
73  
74 /// <summary>Whether or not predictable termination is requested. This value is
75 /// important when the last byte before termination is an 0xFF
76 /// </summary>
77 private bool isPredTerm = false;
78  
79 /// <summary>The alternating sequence of 0's and 1's used for byte padding </summary>
80 internal const int PAD_SEQ = 0x2A;
81  
82 /// <summary>Flag that indicates if an FF has been delayed </summary>
83 internal bool delFF = false;
84  
85 /// <summary>The byte based output </summary>
86 internal ByteOutputBuffer out_Renamed;
87  
88 /// <summary>The bit buffer </summary>
89 internal int bbuf;
90  
91 /// <summary>The position of the next bit to put in the bit buffer. When it is 7
92 /// the bit buffer 'bbuf' is empty. The value should always be between 7
93 /// and 0 (i.e. if it gets to -1, the bit buffer should be immediately
94 /// written to the byte output).
95 /// </summary>
96 internal int bpos = 7;
97  
98 /// <summary>The number of written bytes (excluding the bit buffer) </summary>
99 internal int nb = 0;
100  
101 /// <summary> Instantiates a new 'BitToByteOutput' object that uses 'out' as the
102 /// underlying byte based output.
103 ///
104 /// </summary>
105 /// <param name="out">The underlying byte based output
106 ///
107 /// </param>
108 internal BitToByteOutput(ByteOutputBuffer out_Renamed)
109 {
110 this.out_Renamed = out_Renamed;
111 }
112  
113 /// <summary> Writes to the bit stream the symbols contained in the 'symbuf'
114 /// buffer. The least significant bit of each element in 'symbuf'is
115 /// written.
116 ///
117 /// </summary>
118 /// <param name="symbuf">The symbols to write
119 ///
120 /// </param>
121 /// <param name="nsym">The number of symbols in symbuf
122 ///
123 /// </param>
124 internal void writeBits(int[] symbuf, int nsym)
125 {
126 int i;
127 int bbuf, bpos;
128 bbuf = this.bbuf;
129 bpos = this.bpos;
130 // Write symbol by symbol to bit buffer
131 for (i = 0; i < nsym; i++)
132 {
133 bbuf |= (symbuf[i] & 0x01) << (bpos--);
134 if (bpos < 0)
135 {
136 // Bit buffer is full, write it
137 if (bbuf != 0xFF)
138 {
139 // No bit-stuffing needed
140 if (delFF)
141 {
142 // Output delayed 0xFF if any
143 out_Renamed.write(0xFF);
144 nb++;
145 delFF = false;
146 }
147 out_Renamed.write(bbuf);
148 nb++;
149 bpos = 7;
150 }
151 else
152 {
153 // We need to do bit stuffing on next byte
154 delFF = true;
155 bpos = 6; // One less bit in next byte
156 }
157 bbuf = 0;
158 }
159 }
160 this.bbuf = bbuf;
161 this.bpos = bpos;
162 }
163  
164 /// <summary> Write a bit to the output. The least significant bit of 'bit' is
165 /// written to the output.
166 ///
167 /// </summary>
168 /// <param name="bit">
169 /// </param>
170 internal void writeBit(int bit)
171 {
172 bbuf |= (bit & 0x01) << (bpos--);
173 if (bpos < 0)
174 {
175 if (bbuf != 0xFF)
176 {
177 // No bit-stuffing needed
178 if (delFF)
179 {
180 // Output delayed 0xFF if any
181 out_Renamed.write(0xFF);
182 nb++;
183 delFF = false;
184 }
185 // Output the bit buffer
186 out_Renamed.write(bbuf);
187 nb++;
188 bpos = 7;
189 }
190 else
191 {
192 // We need to do bit stuffing on next byte
193 delFF = true;
194 bpos = 6; // One less bit in next byte
195 }
196 bbuf = 0;
197 }
198 }
199  
200 /// <summary> Writes the contents of the bit buffer and byte aligns the output by
201 /// filling bits with an alternating sequence of 0's and 1's.
202 ///
203 /// </summary>
204 internal virtual void flush()
205 {
206 if (delFF)
207 {
208 // There was a bit stuffing
209 if (bpos != 6)
210 {
211 // Bit buffer is not empty
212 // Output delayed 0xFF
213 out_Renamed.write(0xFF);
214 nb++;
215 delFF = false;
216 // Pad to byte boundary with an alternating sequence of 0's
217 // and 1's.
218 bbuf |= (SupportClass.URShift(PAD_SEQ, (6 - bpos)));
219 // Output the bit buffer
220 out_Renamed.write(bbuf);
221 nb++;
222 bpos = 7;
223 bbuf = 0;
224 }
225 else if (isPredTerm)
226 {
227 out_Renamed.write(0xFF);
228 nb++;
229 out_Renamed.write(0x2A);
230 nb++;
231 bpos = 7;
232 bbuf = 0;
233 delFF = false;
234 }
235 }
236 else
237 {
238 // There was no bit stuffing
239 if (bpos != 7)
240 {
241 // Bit buffer is not empty
242 // Pad to byte boundary with an alternating sequence of 0's and
243 // 1's.
244 bbuf |= (SupportClass.URShift(PAD_SEQ, (6 - bpos)));
245 // Output the bit buffer (bbuf can not be 0xFF)
246 out_Renamed.write(bbuf);
247 nb++;
248 bpos = 7;
249 bbuf = 0;
250 }
251 }
252 }
253  
254 /// <summary> Terminates the bit stream by calling 'flush()' and then
255 /// 'reset()'. Finally, it returns the number of bytes effectively written.
256 ///
257 /// </summary>
258 /// <returns> The number of bytes effectively written.
259 ///
260 /// </returns>
261 public virtual int terminate()
262 {
263 flush();
264 int savedNb = nb;
265 reset();
266 return savedNb;
267 }
268  
269 /// <summary> Resets the bit buffer to empty, without writing anything to the
270 /// underlying byte output, and resets the byte count. The underlying byte
271 /// output is NOT reset.
272 ///
273 /// </summary>
274 internal virtual void reset()
275 {
276 delFF = false;
277 bpos = 7;
278 bbuf = 0;
279 nb = 0;
280 }
281  
282 /// <summary> Returns the length, in bytes, of the output bit stream as written by
283 /// this object. If the output bit stream does not have an integer number
284 /// of bytes in length then it is rounded to the next integer.
285 ///
286 /// </summary>
287 /// <returns> The length, in bytes, of the output bit stream.
288 ///
289 /// </returns>
290 internal virtual int length()
291 {
292 if (delFF)
293 {
294 // If bit buffer is empty we just need 'nb' bytes. If not we need
295 // the delayed FF and the padded bit buffer.
296 return nb + 2;
297 }
298 else
299 {
300 // If the bit buffer is empty, we just need 'nb' bytes. If not, we
301 // add length of the padded bit buffer
302 return nb + ((bpos == 7)?0:1);
303 }
304 }
305 }
306 }