Statistics
| Branch: | Revision:

root / trunk / hammock / src / net35 / ICSharpCode.SharpZipLib.Silverlight / BZip2 / BZip2InputStream.cs @ 0eea575a

History | View | Annotate | Download (32.5 kB)

1 0eea575a Panagiotis Kanavos
// BZip2InputStream.cs
2 0eea575a Panagiotis Kanavos
//
3 0eea575a Panagiotis Kanavos
// Copyright (C) 2001 Mike Krueger
4 0eea575a Panagiotis Kanavos
//
5 0eea575a Panagiotis Kanavos
// This program is free software; you can redistribute it and/or
6 0eea575a Panagiotis Kanavos
// modify it under the terms of the GNU General Public License
7 0eea575a Panagiotis Kanavos
// as published by the Free Software Foundation; either version 2
8 0eea575a Panagiotis Kanavos
// of the License, or (at your option) any later version.
9 0eea575a Panagiotis Kanavos
//
10 0eea575a Panagiotis Kanavos
// This program is distributed in the hope that it will be useful,
11 0eea575a Panagiotis Kanavos
// but WITHOUT ANY WARRANTY; without even the implied warranty of
12 0eea575a Panagiotis Kanavos
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 0eea575a Panagiotis Kanavos
// GNU General Public License for more details.
14 0eea575a Panagiotis Kanavos
//
15 0eea575a Panagiotis Kanavos
// You should have received a copy of the GNU General Public License
16 0eea575a Panagiotis Kanavos
// along with this program; if not, write to the Free Software
17 0eea575a Panagiotis Kanavos
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
18 0eea575a Panagiotis Kanavos
//
19 0eea575a Panagiotis Kanavos
// Linking this library statically or dynamically with other modules is
20 0eea575a Panagiotis Kanavos
// making a combined work based on this library.  Thus, the terms and
21 0eea575a Panagiotis Kanavos
// conditions of the GNU General Public License cover the whole
22 0eea575a Panagiotis Kanavos
// combination.
23 0eea575a Panagiotis Kanavos
// 
24 0eea575a Panagiotis Kanavos
// As a special exception, the copyright holders of this library give you
25 0eea575a Panagiotis Kanavos
// permission to link this library with independent modules to produce an
26 0eea575a Panagiotis Kanavos
// executable, regardless of the license terms of these independent
27 0eea575a Panagiotis Kanavos
// modules, and to copy and distribute the resulting executable under
28 0eea575a Panagiotis Kanavos
// terms of your choice, provided that you also meet, for each linked
29 0eea575a Panagiotis Kanavos
// independent module, the terms and conditions of the license of that
30 0eea575a Panagiotis Kanavos
// module.  An independent module is a module which is not derived from
31 0eea575a Panagiotis Kanavos
// or based on this library.  If you modify this library, you may extend
32 0eea575a Panagiotis Kanavos
// this exception to your version of the library, but you are not
33 0eea575a Panagiotis Kanavos
// obligated to do so.  If you do not wish to do so, delete this
34 0eea575a Panagiotis Kanavos
// exception statement from your version.
35 0eea575a Panagiotis Kanavos
36 0eea575a Panagiotis Kanavos
using System;
37 0eea575a Panagiotis Kanavos
using System.IO;
38 0eea575a Panagiotis Kanavos
using ICSharpCode.SharpZipLib.Silverlight.Checksums;
39 0eea575a Panagiotis Kanavos
40 0eea575a Panagiotis Kanavos
namespace ICSharpCode.SharpZipLib.Silverlight.BZip2
41 0eea575a Panagiotis Kanavos
{
42 0eea575a Panagiotis Kanavos
    /// <summary>
43 0eea575a Panagiotis Kanavos
    /// An input stream that decompresses files in the BZip2 format 
44 0eea575a Panagiotis Kanavos
    /// </summary>
45 0eea575a Panagiotis Kanavos
    public class BZip2InputStream : Stream
46 0eea575a Panagiotis Kanavos
    {
47 0eea575a Panagiotis Kanavos
        #region Constants
48 0eea575a Panagiotis Kanavos
49 0eea575a Panagiotis Kanavos
        private const int NO_RAND_PART_A_STATE = 5;
50 0eea575a Panagiotis Kanavos
        private const int NO_RAND_PART_B_STATE = 6;
51 0eea575a Panagiotis Kanavos
        private const int NO_RAND_PART_C_STATE = 7;
52 0eea575a Panagiotis Kanavos
        private const int RAND_PART_A_STATE = 2;
53 0eea575a Panagiotis Kanavos
        private const int RAND_PART_B_STATE = 3;
54 0eea575a Panagiotis Kanavos
        private const int RAND_PART_C_STATE = 4;
55 0eea575a Panagiotis Kanavos
        private const int START_BLOCK_STATE = 1;
56 0eea575a Panagiotis Kanavos
57 0eea575a Panagiotis Kanavos
        #endregion
58 0eea575a Panagiotis Kanavos
59 0eea575a Panagiotis Kanavos
        #region Constructors
60 0eea575a Panagiotis Kanavos
61 0eea575a Panagiotis Kanavos
        /// <summary>
62 0eea575a Panagiotis Kanavos
        /// Construct instance for reading from stream
63 0eea575a Panagiotis Kanavos
        /// </summary>
64 0eea575a Panagiotis Kanavos
        /// <param name="stream">Data source</param>
65 0eea575a Panagiotis Kanavos
        public BZip2InputStream(Stream stream)
66 0eea575a Panagiotis Kanavos
        {
67 0eea575a Panagiotis Kanavos
            // init arrays
68 0eea575a Panagiotis Kanavos
            for (var i = 0; i < BZip2Constants.N_GROUPS; ++i)
69 0eea575a Panagiotis Kanavos
            {
70 0eea575a Panagiotis Kanavos
                limit[i] = new int[BZip2Constants.MAX_ALPHA_SIZE];
71 0eea575a Panagiotis Kanavos
                baseArray[i] = new int[BZip2Constants.MAX_ALPHA_SIZE];
72 0eea575a Panagiotis Kanavos
                perm[i] = new int[BZip2Constants.MAX_ALPHA_SIZE];
73 0eea575a Panagiotis Kanavos
            }
74 0eea575a Panagiotis Kanavos
75 0eea575a Panagiotis Kanavos
            BsSetStream(stream);
76 0eea575a Panagiotis Kanavos
            Initialize();
77 0eea575a Panagiotis Kanavos
            InitBlock();
78 0eea575a Panagiotis Kanavos
            SetupBlock();
79 0eea575a Panagiotis Kanavos
        }
80 0eea575a Panagiotis Kanavos
81 0eea575a Panagiotis Kanavos
        #endregion
82 0eea575a Panagiotis Kanavos
83 0eea575a Panagiotis Kanavos
        /// <summary>
84 0eea575a Panagiotis Kanavos
        /// Get/set flag indicating ownership of underlying stream.
85 0eea575a Panagiotis Kanavos
        /// When the flag is true <see cref="Close"></see> will close the underlying stream also.
86 0eea575a Panagiotis Kanavos
        /// </summary>
87 0eea575a Panagiotis Kanavos
        public bool IsStreamOwner
88 0eea575a Panagiotis Kanavos
        {
89 0eea575a Panagiotis Kanavos
            get { return isStreamOwner; }
90 0eea575a Panagiotis Kanavos
            set { isStreamOwner = value; }
91 0eea575a Panagiotis Kanavos
        }
92 0eea575a Panagiotis Kanavos
93 0eea575a Panagiotis Kanavos
        #region Stream Overrides
94 0eea575a Panagiotis Kanavos
95 0eea575a Panagiotis Kanavos
        /// <summary>
96 0eea575a Panagiotis Kanavos
        /// Gets a value indicating if the stream supports reading
97 0eea575a Panagiotis Kanavos
        /// </summary>
98 0eea575a Panagiotis Kanavos
        public override bool CanRead
99 0eea575a Panagiotis Kanavos
        {
100 0eea575a Panagiotis Kanavos
            get { return baseStream.CanRead; }
101 0eea575a Panagiotis Kanavos
        }
102 0eea575a Panagiotis Kanavos
103 0eea575a Panagiotis Kanavos
        /// <summary>
104 0eea575a Panagiotis Kanavos
        /// Gets a value indicating whether the current stream supports seeking.
105 0eea575a Panagiotis Kanavos
        /// </summary>
106 0eea575a Panagiotis Kanavos
        public override bool CanSeek
107 0eea575a Panagiotis Kanavos
        {
108 0eea575a Panagiotis Kanavos
            get { return baseStream.CanSeek; }
109 0eea575a Panagiotis Kanavos
        }
110 0eea575a Panagiotis Kanavos
111 0eea575a Panagiotis Kanavos
        /// <summary>
112 0eea575a Panagiotis Kanavos
        /// Gets a value indicating whether the current stream supports writing.
113 0eea575a Panagiotis Kanavos
        /// This property always returns false
114 0eea575a Panagiotis Kanavos
        /// </summary>
115 0eea575a Panagiotis Kanavos
        public override bool CanWrite
116 0eea575a Panagiotis Kanavos
        {
117 0eea575a Panagiotis Kanavos
            get { return false; }
118 0eea575a Panagiotis Kanavos
        }
119 0eea575a Panagiotis Kanavos
120 0eea575a Panagiotis Kanavos
        /// <summary>
121 0eea575a Panagiotis Kanavos
        /// Gets the length in bytes of the stream.
122 0eea575a Panagiotis Kanavos
        /// </summary>
123 0eea575a Panagiotis Kanavos
        public override long Length
124 0eea575a Panagiotis Kanavos
        {
125 0eea575a Panagiotis Kanavos
            get { return baseStream.Length; }
126 0eea575a Panagiotis Kanavos
        }
127 0eea575a Panagiotis Kanavos
128 0eea575a Panagiotis Kanavos
        /// <summary>
129 0eea575a Panagiotis Kanavos
        /// Gets or sets the streams position.
130 0eea575a Panagiotis Kanavos
        /// Setting the position is not supported and will throw a NotSupportException
131 0eea575a Panagiotis Kanavos
        /// </summary>
132 0eea575a Panagiotis Kanavos
        /// <exception cref="NotSupportedException">Any attempt to set the position</exception>
133 0eea575a Panagiotis Kanavos
        public override long Position
134 0eea575a Panagiotis Kanavos
        {
135 0eea575a Panagiotis Kanavos
            get { return baseStream.Position; }
136 0eea575a Panagiotis Kanavos
            set { throw new NotSupportedException("BZip2InputStream position cannot be set"); }
137 0eea575a Panagiotis Kanavos
        }
138 0eea575a Panagiotis Kanavos
139 0eea575a Panagiotis Kanavos
        /// <summary>
140 0eea575a Panagiotis Kanavos
        /// Flushes the stream.
141 0eea575a Panagiotis Kanavos
        /// </summary>
142 0eea575a Panagiotis Kanavos
        public override void Flush()
143 0eea575a Panagiotis Kanavos
        {
144 0eea575a Panagiotis Kanavos
            if (baseStream != null)
145 0eea575a Panagiotis Kanavos
            {
146 0eea575a Panagiotis Kanavos
                baseStream.Flush();
147 0eea575a Panagiotis Kanavos
            }
148 0eea575a Panagiotis Kanavos
        }
149 0eea575a Panagiotis Kanavos
150 0eea575a Panagiotis Kanavos
        /// <summary>
151 0eea575a Panagiotis Kanavos
        /// Set the streams position.  This operation is not supported and will throw a NotSupportedException
152 0eea575a Panagiotis Kanavos
        /// </summary>
153 0eea575a Panagiotis Kanavos
        /// <param name="offset">A byte offset relative to the <paramref name="origin"/> parameter.</param>
154 0eea575a Panagiotis Kanavos
        /// <param name="origin">A value of type <see cref="SeekOrigin"/> indicating the reference point used to obtain the new position.</param>
155 0eea575a Panagiotis Kanavos
        /// <returns>The new position of the stream.</returns>
156 0eea575a Panagiotis Kanavos
        /// <exception cref="NotSupportedException">Any access</exception>
157 0eea575a Panagiotis Kanavos
        public override long Seek(long offset, SeekOrigin origin)
158 0eea575a Panagiotis Kanavos
        {
159 0eea575a Panagiotis Kanavos
            throw new NotSupportedException("BZip2InputStream Seek not supported");
160 0eea575a Panagiotis Kanavos
        }
161 0eea575a Panagiotis Kanavos
162 0eea575a Panagiotis Kanavos
        /// <summary>
163 0eea575a Panagiotis Kanavos
        /// Sets the length of this stream to the given value.
164 0eea575a Panagiotis Kanavos
        /// This operation is not supported and will throw a NotSupportedExceptionortedException
165 0eea575a Panagiotis Kanavos
        /// </summary>
166 0eea575a Panagiotis Kanavos
        /// <param name="value">The new length for the stream.</param>
167 0eea575a Panagiotis Kanavos
        /// <exception cref="NotSupportedException">Any access</exception>
168 0eea575a Panagiotis Kanavos
        public override void SetLength(long value)
169 0eea575a Panagiotis Kanavos
        {
170 0eea575a Panagiotis Kanavos
            throw new NotSupportedException("BZip2InputStream SetLength not supported");
171 0eea575a Panagiotis Kanavos
        }
172 0eea575a Panagiotis Kanavos
173 0eea575a Panagiotis Kanavos
        /// <summary>
174 0eea575a Panagiotis Kanavos
        /// Writes a block of bytes to this stream using data from a buffer.
175 0eea575a Panagiotis Kanavos
        /// This operation is not supported and will throw a NotSupportedException
176 0eea575a Panagiotis Kanavos
        /// </summary>
177 0eea575a Panagiotis Kanavos
        /// <param name="buffer">The buffer to source data from.</param>
178 0eea575a Panagiotis Kanavos
        /// <param name="offset">The offset to start obtaining data from.</param>
179 0eea575a Panagiotis Kanavos
        /// <param name="count">The number of bytes of data to write.</param>
180 0eea575a Panagiotis Kanavos
        /// <exception cref="NotSupportedException">Any access</exception>
181 0eea575a Panagiotis Kanavos
        public override void Write(byte[] buffer, int offset, int count)
182 0eea575a Panagiotis Kanavos
        {
183 0eea575a Panagiotis Kanavos
            throw new NotSupportedException("BZip2InputStream Write not supported");
184 0eea575a Panagiotis Kanavos
        }
185 0eea575a Panagiotis Kanavos
186 0eea575a Panagiotis Kanavos
        /// <summary>
187 0eea575a Panagiotis Kanavos
        /// Writes a byte to the current position in the file stream.
188 0eea575a Panagiotis Kanavos
        /// This operation is not supported and will throw a NotSupportedException
189 0eea575a Panagiotis Kanavos
        /// </summary>
190 0eea575a Panagiotis Kanavos
        /// <param name="value">The value to write.</param>
191 0eea575a Panagiotis Kanavos
        /// <exception cref="NotSupportedException">Any access</exception>
192 0eea575a Panagiotis Kanavos
        public override void WriteByte(byte value)
193 0eea575a Panagiotis Kanavos
        {
194 0eea575a Panagiotis Kanavos
            throw new NotSupportedException("BZip2InputStream WriteByte not supported");
195 0eea575a Panagiotis Kanavos
        }
196 0eea575a Panagiotis Kanavos
197 0eea575a Panagiotis Kanavos
        /// <summary>
198 0eea575a Panagiotis Kanavos
        /// Read a sequence of bytes and advances the read position by one byte.
199 0eea575a Panagiotis Kanavos
        /// </summary>
200 0eea575a Panagiotis Kanavos
        /// <param name="buffer">Array of bytes to store values in</param>
201 0eea575a Panagiotis Kanavos
        /// <param name="offset">Offset in array to begin storing data</param>
202 0eea575a Panagiotis Kanavos
        /// <param name="count">The maximum number of bytes to read</param>
203 0eea575a Panagiotis Kanavos
        /// <returns>The total number of bytes read into the buffer. This might be less
204 0eea575a Panagiotis Kanavos
        /// than the number of bytes requested if that number of bytes are not 
205 0eea575a Panagiotis Kanavos
        /// currently available or zero if the end of the stream is reached.
206 0eea575a Panagiotis Kanavos
        /// </returns>
207 0eea575a Panagiotis Kanavos
        public override int Read(byte[] buffer, int offset, int count)
208 0eea575a Panagiotis Kanavos
        {
209 0eea575a Panagiotis Kanavos
            if (buffer == null)
210 0eea575a Panagiotis Kanavos
            {
211 0eea575a Panagiotis Kanavos
                throw new ArgumentNullException("buffer");
212 0eea575a Panagiotis Kanavos
            }
213 0eea575a Panagiotis Kanavos
214 0eea575a Panagiotis Kanavos
            for (var i = 0; i < count; ++i)
215 0eea575a Panagiotis Kanavos
            {
216 0eea575a Panagiotis Kanavos
                var rb = ReadByte();
217 0eea575a Panagiotis Kanavos
                if (rb == -1)
218 0eea575a Panagiotis Kanavos
                {
219 0eea575a Panagiotis Kanavos
                    return i;
220 0eea575a Panagiotis Kanavos
                }
221 0eea575a Panagiotis Kanavos
                buffer[offset + i] = (byte) rb;
222 0eea575a Panagiotis Kanavos
            }
223 0eea575a Panagiotis Kanavos
            return count;
224 0eea575a Panagiotis Kanavos
        }
225 0eea575a Panagiotis Kanavos
226 0eea575a Panagiotis Kanavos
        /// <summary>
227 0eea575a Panagiotis Kanavos
        /// Closes the stream, releasing any associated resources.
228 0eea575a Panagiotis Kanavos
        /// </summary>
229 0eea575a Panagiotis Kanavos
        public override void Close()
230 0eea575a Panagiotis Kanavos
        {
231 0eea575a Panagiotis Kanavos
            if (IsStreamOwner && (baseStream != null))
232 0eea575a Panagiotis Kanavos
            {
233 0eea575a Panagiotis Kanavos
                baseStream.Close();
234 0eea575a Panagiotis Kanavos
            }
235 0eea575a Panagiotis Kanavos
        }
236 0eea575a Panagiotis Kanavos
237 0eea575a Panagiotis Kanavos
        /// <summary>
238 0eea575a Panagiotis Kanavos
        /// Read a byte from stream advancing position
239 0eea575a Panagiotis Kanavos
        /// </summary>
240 0eea575a Panagiotis Kanavos
        /// <returns>byte read or -1 on end of stream</returns>
241 0eea575a Panagiotis Kanavos
        public override int ReadByte()
242 0eea575a Panagiotis Kanavos
        {
243 0eea575a Panagiotis Kanavos
            if (streamEnd)
244 0eea575a Panagiotis Kanavos
            {
245 0eea575a Panagiotis Kanavos
                return -1; // ok
246 0eea575a Panagiotis Kanavos
            }
247 0eea575a Panagiotis Kanavos
248 0eea575a Panagiotis Kanavos
            var retChar = currentChar;
249 0eea575a Panagiotis Kanavos
            switch (currentState)
250 0eea575a Panagiotis Kanavos
            {
251 0eea575a Panagiotis Kanavos
                case RAND_PART_B_STATE:
252 0eea575a Panagiotis Kanavos
                    SetupRandPartB();
253 0eea575a Panagiotis Kanavos
                    break;
254 0eea575a Panagiotis Kanavos
                case RAND_PART_C_STATE:
255 0eea575a Panagiotis Kanavos
                    SetupRandPartC();
256 0eea575a Panagiotis Kanavos
                    break;
257 0eea575a Panagiotis Kanavos
                case NO_RAND_PART_B_STATE:
258 0eea575a Panagiotis Kanavos
                    SetupNoRandPartB();
259 0eea575a Panagiotis Kanavos
                    break;
260 0eea575a Panagiotis Kanavos
                case NO_RAND_PART_C_STATE:
261 0eea575a Panagiotis Kanavos
                    SetupNoRandPartC();
262 0eea575a Panagiotis Kanavos
                    break;
263 0eea575a Panagiotis Kanavos
                case START_BLOCK_STATE:
264 0eea575a Panagiotis Kanavos
                case NO_RAND_PART_A_STATE:
265 0eea575a Panagiotis Kanavos
                case RAND_PART_A_STATE:
266 0eea575a Panagiotis Kanavos
                    break;
267 0eea575a Panagiotis Kanavos
                default:
268 0eea575a Panagiotis Kanavos
                    break;
269 0eea575a Panagiotis Kanavos
            }
270 0eea575a Panagiotis Kanavos
            return retChar;
271 0eea575a Panagiotis Kanavos
        }
272 0eea575a Panagiotis Kanavos
273 0eea575a Panagiotis Kanavos
        #endregion
274 0eea575a Panagiotis Kanavos
275 0eea575a Panagiotis Kanavos
        private void MakeMaps()
276 0eea575a Panagiotis Kanavos
        {
277 0eea575a Panagiotis Kanavos
            nInUse = 0;
278 0eea575a Panagiotis Kanavos
            for (var i = 0; i < 256; ++i)
279 0eea575a Panagiotis Kanavos
            {
280 0eea575a Panagiotis Kanavos
                if (inUse[i])
281 0eea575a Panagiotis Kanavos
                {
282 0eea575a Panagiotis Kanavos
                    seqToUnseq[nInUse] = (byte) i;
283 0eea575a Panagiotis Kanavos
                    unseqToSeq[i] = (byte) nInUse;
284 0eea575a Panagiotis Kanavos
                    nInUse++;
285 0eea575a Panagiotis Kanavos
                }
286 0eea575a Panagiotis Kanavos
            }
287 0eea575a Panagiotis Kanavos
        }
288 0eea575a Panagiotis Kanavos
289 0eea575a Panagiotis Kanavos
        private void Initialize()
290 0eea575a Panagiotis Kanavos
        {
291 0eea575a Panagiotis Kanavos
            var magic1 = BsGetUChar();
292 0eea575a Panagiotis Kanavos
            var magic2 = BsGetUChar();
293 0eea575a Panagiotis Kanavos
294 0eea575a Panagiotis Kanavos
            var magic3 = BsGetUChar();
295 0eea575a Panagiotis Kanavos
            var magic4 = BsGetUChar();
296 0eea575a Panagiotis Kanavos
297 0eea575a Panagiotis Kanavos
            if (magic1 != 'B' || magic2 != 'Z' || magic3 != 'h' || magic4 < '1' || magic4 > '9')
298 0eea575a Panagiotis Kanavos
            {
299 0eea575a Panagiotis Kanavos
                streamEnd = true;
300 0eea575a Panagiotis Kanavos
                return;
301 0eea575a Panagiotis Kanavos
            }
302 0eea575a Panagiotis Kanavos
303 0eea575a Panagiotis Kanavos
            SetDecompressStructureSizes(magic4 - '0');
304 0eea575a Panagiotis Kanavos
            computedCombinedCRC = 0;
305 0eea575a Panagiotis Kanavos
        }
306 0eea575a Panagiotis Kanavos
307 0eea575a Panagiotis Kanavos
        private void InitBlock()
308 0eea575a Panagiotis Kanavos
        {
309 0eea575a Panagiotis Kanavos
            var magic1 = BsGetUChar();
310 0eea575a Panagiotis Kanavos
            var magic2 = BsGetUChar();
311 0eea575a Panagiotis Kanavos
            var magic3 = BsGetUChar();
312 0eea575a Panagiotis Kanavos
            var magic4 = BsGetUChar();
313 0eea575a Panagiotis Kanavos
            var magic5 = BsGetUChar();
314 0eea575a Panagiotis Kanavos
            var magic6 = BsGetUChar();
315 0eea575a Panagiotis Kanavos
316 0eea575a Panagiotis Kanavos
            if (magic1 == 0x17 && magic2 == 0x72 && magic3 == 0x45 && magic4 == 0x38 && magic5 == 0x50 && magic6 == 0x90)
317 0eea575a Panagiotis Kanavos
            {
318 0eea575a Panagiotis Kanavos
                Complete();
319 0eea575a Panagiotis Kanavos
                return;
320 0eea575a Panagiotis Kanavos
            }
321 0eea575a Panagiotis Kanavos
322 0eea575a Panagiotis Kanavos
            if (magic1 != 0x31 || magic2 != 0x41 || magic3 != 0x59 || magic4 != 0x26 || magic5 != 0x53 || magic6 != 0x59)
323 0eea575a Panagiotis Kanavos
            {
324 0eea575a Panagiotis Kanavos
                BadBlockHeader();
325 0eea575a Panagiotis Kanavos
                streamEnd = true;
326 0eea575a Panagiotis Kanavos
                return;
327 0eea575a Panagiotis Kanavos
            }
328 0eea575a Panagiotis Kanavos
329 0eea575a Panagiotis Kanavos
            storedBlockCRC = BsGetInt32();
330 0eea575a Panagiotis Kanavos
331 0eea575a Panagiotis Kanavos
            blockRandomised = (BsR(1) == 1);
332 0eea575a Panagiotis Kanavos
333 0eea575a Panagiotis Kanavos
            GetAndMoveToFrontDecode();
334 0eea575a Panagiotis Kanavos
335 0eea575a Panagiotis Kanavos
            mCrc.Reset();
336 0eea575a Panagiotis Kanavos
            currentState = START_BLOCK_STATE;
337 0eea575a Panagiotis Kanavos
        }
338 0eea575a Panagiotis Kanavos
339 0eea575a Panagiotis Kanavos
        private void EndBlock()
340 0eea575a Panagiotis Kanavos
        {
341 0eea575a Panagiotis Kanavos
            computedBlockCRC = (int) mCrc.Value;
342 0eea575a Panagiotis Kanavos
343 0eea575a Panagiotis Kanavos
            // -- A bad CRC is considered a fatal error. --
344 0eea575a Panagiotis Kanavos
            if (storedBlockCRC != computedBlockCRC)
345 0eea575a Panagiotis Kanavos
            {
346 0eea575a Panagiotis Kanavos
                CrcError();
347 0eea575a Panagiotis Kanavos
            }
348 0eea575a Panagiotis Kanavos
349 0eea575a Panagiotis Kanavos
            // 1528150659
350 0eea575a Panagiotis Kanavos
            computedCombinedCRC = ((computedCombinedCRC << 1) & 0xFFFFFFFF) | (computedCombinedCRC >> 31);
351 0eea575a Panagiotis Kanavos
            computedCombinedCRC = computedCombinedCRC ^ (uint) computedBlockCRC;
352 0eea575a Panagiotis Kanavos
        }
353 0eea575a Panagiotis Kanavos
354 0eea575a Panagiotis Kanavos
        private void Complete()
355 0eea575a Panagiotis Kanavos
        {
356 0eea575a Panagiotis Kanavos
            storedCombinedCRC = BsGetInt32();
357 0eea575a Panagiotis Kanavos
            if (storedCombinedCRC != (int) computedCombinedCRC)
358 0eea575a Panagiotis Kanavos
            {
359 0eea575a Panagiotis Kanavos
                CrcError();
360 0eea575a Panagiotis Kanavos
            }
361 0eea575a Panagiotis Kanavos
362 0eea575a Panagiotis Kanavos
            streamEnd = true;
363 0eea575a Panagiotis Kanavos
        }
364 0eea575a Panagiotis Kanavos
365 0eea575a Panagiotis Kanavos
        private void BsSetStream(Stream stream)
366 0eea575a Panagiotis Kanavos
        {
367 0eea575a Panagiotis Kanavos
            baseStream = stream;
368 0eea575a Panagiotis Kanavos
            bsLive = 0;
369 0eea575a Panagiotis Kanavos
            bsBuff = 0;
370 0eea575a Panagiotis Kanavos
        }
371 0eea575a Panagiotis Kanavos
372 0eea575a Panagiotis Kanavos
        private void FillBuffer()
373 0eea575a Panagiotis Kanavos
        {
374 0eea575a Panagiotis Kanavos
            var thech = 0;
375 0eea575a Panagiotis Kanavos
376 0eea575a Panagiotis Kanavos
            try
377 0eea575a Panagiotis Kanavos
            {
378 0eea575a Panagiotis Kanavos
                thech = baseStream.ReadByte();
379 0eea575a Panagiotis Kanavos
            }
380 0eea575a Panagiotis Kanavos
            catch (Exception)
381 0eea575a Panagiotis Kanavos
            {
382 0eea575a Panagiotis Kanavos
                CompressedStreamEOF();
383 0eea575a Panagiotis Kanavos
            }
384 0eea575a Panagiotis Kanavos
385 0eea575a Panagiotis Kanavos
            if (thech == -1)
386 0eea575a Panagiotis Kanavos
            {
387 0eea575a Panagiotis Kanavos
                CompressedStreamEOF();
388 0eea575a Panagiotis Kanavos
            }
389 0eea575a Panagiotis Kanavos
390 0eea575a Panagiotis Kanavos
            bsBuff = (bsBuff << 8) | (thech & 0xFF);
391 0eea575a Panagiotis Kanavos
            bsLive += 8;
392 0eea575a Panagiotis Kanavos
        }
393 0eea575a Panagiotis Kanavos
394 0eea575a Panagiotis Kanavos
        private int BsR(int n)
395 0eea575a Panagiotis Kanavos
        {
396 0eea575a Panagiotis Kanavos
            while (bsLive < n)
397 0eea575a Panagiotis Kanavos
            {
398 0eea575a Panagiotis Kanavos
                FillBuffer();
399 0eea575a Panagiotis Kanavos
            }
400 0eea575a Panagiotis Kanavos
401 0eea575a Panagiotis Kanavos
            var v = (bsBuff >> (bsLive - n)) & ((1 << n) - 1);
402 0eea575a Panagiotis Kanavos
            bsLive -= n;
403 0eea575a Panagiotis Kanavos
            return v;
404 0eea575a Panagiotis Kanavos
        }
405 0eea575a Panagiotis Kanavos
406 0eea575a Panagiotis Kanavos
        private char BsGetUChar()
407 0eea575a Panagiotis Kanavos
        {
408 0eea575a Panagiotis Kanavos
            return (char) BsR(8);
409 0eea575a Panagiotis Kanavos
        }
410 0eea575a Panagiotis Kanavos
411 0eea575a Panagiotis Kanavos
        private int BsGetint()
412 0eea575a Panagiotis Kanavos
        {
413 0eea575a Panagiotis Kanavos
            var u = BsR(8);
414 0eea575a Panagiotis Kanavos
            u = (u << 8) | BsR(8);
415 0eea575a Panagiotis Kanavos
            u = (u << 8) | BsR(8);
416 0eea575a Panagiotis Kanavos
            u = (u << 8) | BsR(8);
417 0eea575a Panagiotis Kanavos
            return u;
418 0eea575a Panagiotis Kanavos
        }
419 0eea575a Panagiotis Kanavos
420 0eea575a Panagiotis Kanavos
        private int BsGetIntVS(int numBits)
421 0eea575a Panagiotis Kanavos
        {
422 0eea575a Panagiotis Kanavos
            return BsR(numBits);
423 0eea575a Panagiotis Kanavos
        }
424 0eea575a Panagiotis Kanavos
425 0eea575a Panagiotis Kanavos
        private int BsGetInt32()
426 0eea575a Panagiotis Kanavos
        {
427 0eea575a Panagiotis Kanavos
            return BsGetint();
428 0eea575a Panagiotis Kanavos
        }
429 0eea575a Panagiotis Kanavos
430 0eea575a Panagiotis Kanavos
        private void RecvDecodingTables()
431 0eea575a Panagiotis Kanavos
        {
432 0eea575a Panagiotis Kanavos
            var len = new char[BZip2Constants.N_GROUPS][];
433 0eea575a Panagiotis Kanavos
            for (var i = 0; i < BZip2Constants.N_GROUPS; ++i)
434 0eea575a Panagiotis Kanavos
            {
435 0eea575a Panagiotis Kanavos
                len[i] = new char[BZip2Constants.MAX_ALPHA_SIZE];
436 0eea575a Panagiotis Kanavos
            }
437 0eea575a Panagiotis Kanavos
438 0eea575a Panagiotis Kanavos
            var inUse16 = new bool[16];
439 0eea575a Panagiotis Kanavos
440 0eea575a Panagiotis Kanavos
            //--- Receive the mapping table ---
441 0eea575a Panagiotis Kanavos
            for (var i = 0; i < 16; i++)
442 0eea575a Panagiotis Kanavos
            {
443 0eea575a Panagiotis Kanavos
                inUse16[i] = (BsR(1) == 1);
444 0eea575a Panagiotis Kanavos
            }
445 0eea575a Panagiotis Kanavos
446 0eea575a Panagiotis Kanavos
            for (var i = 0; i < 16; i++)
447 0eea575a Panagiotis Kanavos
            {
448 0eea575a Panagiotis Kanavos
                if (inUse16[i])
449 0eea575a Panagiotis Kanavos
                {
450 0eea575a Panagiotis Kanavos
                    for (var j = 0; j < 16; j++)
451 0eea575a Panagiotis Kanavos
                    {
452 0eea575a Panagiotis Kanavos
                        inUse[i*16 + j] = (BsR(1) == 1);
453 0eea575a Panagiotis Kanavos
                    }
454 0eea575a Panagiotis Kanavos
                }
455 0eea575a Panagiotis Kanavos
                else
456 0eea575a Panagiotis Kanavos
                {
457 0eea575a Panagiotis Kanavos
                    for (var j = 0; j < 16; j++)
458 0eea575a Panagiotis Kanavos
                    {
459 0eea575a Panagiotis Kanavos
                        inUse[i*16 + j] = false;
460 0eea575a Panagiotis Kanavos
                    }
461 0eea575a Panagiotis Kanavos
                }
462 0eea575a Panagiotis Kanavos
            }
463 0eea575a Panagiotis Kanavos
464 0eea575a Panagiotis Kanavos
            MakeMaps();
465 0eea575a Panagiotis Kanavos
            var alphaSize = nInUse + 2;
466 0eea575a Panagiotis Kanavos
467 0eea575a Panagiotis Kanavos
            //--- Now the selectors ---
468 0eea575a Panagiotis Kanavos
            var nGroups = BsR(3);
469 0eea575a Panagiotis Kanavos
            var nSelectors = BsR(15);
470 0eea575a Panagiotis Kanavos
471 0eea575a Panagiotis Kanavos
            for (var i = 0; i < nSelectors; i++)
472 0eea575a Panagiotis Kanavos
            {
473 0eea575a Panagiotis Kanavos
                var j = 0;
474 0eea575a Panagiotis Kanavos
                while (BsR(1) == 1)
475 0eea575a Panagiotis Kanavos
                {
476 0eea575a Panagiotis Kanavos
                    j++;
477 0eea575a Panagiotis Kanavos
                }
478 0eea575a Panagiotis Kanavos
                selectorMtf[i] = (byte) j;
479 0eea575a Panagiotis Kanavos
            }
480 0eea575a Panagiotis Kanavos
481 0eea575a Panagiotis Kanavos
            //--- Undo the MTF values for the selectors. ---
482 0eea575a Panagiotis Kanavos
            var pos = new byte[BZip2Constants.N_GROUPS];
483 0eea575a Panagiotis Kanavos
            for (var v = 0; v < nGroups; v++)
484 0eea575a Panagiotis Kanavos
            {
485 0eea575a Panagiotis Kanavos
                pos[v] = (byte) v;
486 0eea575a Panagiotis Kanavos
            }
487 0eea575a Panagiotis Kanavos
488 0eea575a Panagiotis Kanavos
            for (var i = 0; i < nSelectors; i++)
489 0eea575a Panagiotis Kanavos
            {
490 0eea575a Panagiotis Kanavos
                int v = selectorMtf[i];
491 0eea575a Panagiotis Kanavos
                var tmp = pos[v];
492 0eea575a Panagiotis Kanavos
                while (v > 0)
493 0eea575a Panagiotis Kanavos
                {
494 0eea575a Panagiotis Kanavos
                    pos[v] = pos[v - 1];
495 0eea575a Panagiotis Kanavos
                    v--;
496 0eea575a Panagiotis Kanavos
                }
497 0eea575a Panagiotis Kanavos
                pos[0] = tmp;
498 0eea575a Panagiotis Kanavos
                selector[i] = tmp;
499 0eea575a Panagiotis Kanavos
            }
500 0eea575a Panagiotis Kanavos
501 0eea575a Panagiotis Kanavos
            //--- Now the coding tables ---
502 0eea575a Panagiotis Kanavos
            for (var t = 0; t < nGroups; t++)
503 0eea575a Panagiotis Kanavos
            {
504 0eea575a Panagiotis Kanavos
                var curr = BsR(5);
505 0eea575a Panagiotis Kanavos
                for (var i = 0; i < alphaSize; i++)
506 0eea575a Panagiotis Kanavos
                {
507 0eea575a Panagiotis Kanavos
                    while (BsR(1) == 1)
508 0eea575a Panagiotis Kanavos
                    {
509 0eea575a Panagiotis Kanavos
                        if (BsR(1) == 0)
510 0eea575a Panagiotis Kanavos
                        {
511 0eea575a Panagiotis Kanavos
                            curr++;
512 0eea575a Panagiotis Kanavos
                        }
513 0eea575a Panagiotis Kanavos
                        else
514 0eea575a Panagiotis Kanavos
                        {
515 0eea575a Panagiotis Kanavos
                            curr--;
516 0eea575a Panagiotis Kanavos
                        }
517 0eea575a Panagiotis Kanavos
                    }
518 0eea575a Panagiotis Kanavos
                    len[t][i] = (char) curr;
519 0eea575a Panagiotis Kanavos
                }
520 0eea575a Panagiotis Kanavos
            }
521 0eea575a Panagiotis Kanavos
522 0eea575a Panagiotis Kanavos
            //--- Create the Huffman decoding tables ---
523 0eea575a Panagiotis Kanavos
            for (var t = 0; t < nGroups; t++)
524 0eea575a Panagiotis Kanavos
            {
525 0eea575a Panagiotis Kanavos
                var minLen = 32;
526 0eea575a Panagiotis Kanavos
                var maxLen = 0;
527 0eea575a Panagiotis Kanavos
                for (var i = 0; i < alphaSize; i++)
528 0eea575a Panagiotis Kanavos
                {
529 0eea575a Panagiotis Kanavos
                    maxLen = Math.Max(maxLen, len[t][i]);
530 0eea575a Panagiotis Kanavos
                    minLen = Math.Min(minLen, len[t][i]);
531 0eea575a Panagiotis Kanavos
                }
532 0eea575a Panagiotis Kanavos
                HbCreateDecodeTables(limit[t], baseArray[t], perm[t], len[t], minLen, maxLen, alphaSize);
533 0eea575a Panagiotis Kanavos
                minLens[t] = minLen;
534 0eea575a Panagiotis Kanavos
            }
535 0eea575a Panagiotis Kanavos
        }
536 0eea575a Panagiotis Kanavos
537 0eea575a Panagiotis Kanavos
        private void GetAndMoveToFrontDecode()
538 0eea575a Panagiotis Kanavos
        {
539 0eea575a Panagiotis Kanavos
            var yy = new byte[256];
540 0eea575a Panagiotis Kanavos
541 0eea575a Panagiotis Kanavos
            var limitLast = BZip2Constants.baseBlockSize*blockSize100k;
542 0eea575a Panagiotis Kanavos
            origPtr = BsGetIntVS(24);
543 0eea575a Panagiotis Kanavos
544 0eea575a Panagiotis Kanavos
            RecvDecodingTables();
545 0eea575a Panagiotis Kanavos
            var EOB = nInUse + 1;
546 0eea575a Panagiotis Kanavos
            var groupNo = -1;
547 0eea575a Panagiotis Kanavos
            var groupPos = 0;
548 0eea575a Panagiotis Kanavos
549 0eea575a Panagiotis Kanavos
            /*--
550 0eea575a Panagiotis Kanavos
			Setting up the unzftab entries here is not strictly
551 0eea575a Panagiotis Kanavos
			necessary, but it does save having to do it later
552 0eea575a Panagiotis Kanavos
			in a separate pass, and so saves a block's worth of
553 0eea575a Panagiotis Kanavos
			cache misses.
554 0eea575a Panagiotis Kanavos
			--*/
555 0eea575a Panagiotis Kanavos
            for (var i = 0; i <= 255; i++)
556 0eea575a Panagiotis Kanavos
            {
557 0eea575a Panagiotis Kanavos
                unzftab[i] = 0;
558 0eea575a Panagiotis Kanavos
            }
559 0eea575a Panagiotis Kanavos
560 0eea575a Panagiotis Kanavos
            for (var i = 0; i <= 255; i++)
561 0eea575a Panagiotis Kanavos
            {
562 0eea575a Panagiotis Kanavos
                yy[i] = (byte) i;
563 0eea575a Panagiotis Kanavos
            }
564 0eea575a Panagiotis Kanavos
565 0eea575a Panagiotis Kanavos
            last = -1;
566 0eea575a Panagiotis Kanavos
567 0eea575a Panagiotis Kanavos
            if (groupPos == 0)
568 0eea575a Panagiotis Kanavos
            {
569 0eea575a Panagiotis Kanavos
                groupNo++;
570 0eea575a Panagiotis Kanavos
                groupPos = BZip2Constants.G_SIZE;
571 0eea575a Panagiotis Kanavos
            }
572 0eea575a Panagiotis Kanavos
573 0eea575a Panagiotis Kanavos
            groupPos--;
574 0eea575a Panagiotis Kanavos
            int zt = selector[groupNo];
575 0eea575a Panagiotis Kanavos
            var zn = minLens[zt];
576 0eea575a Panagiotis Kanavos
            var zvec = BsR(zn);
577 0eea575a Panagiotis Kanavos
            int zj;
578 0eea575a Panagiotis Kanavos
579 0eea575a Panagiotis Kanavos
            while (zvec > limit[zt][zn])
580 0eea575a Panagiotis Kanavos
            {
581 0eea575a Panagiotis Kanavos
                if (zn > 20)
582 0eea575a Panagiotis Kanavos
                {
583 0eea575a Panagiotis Kanavos
                    // the longest code
584 0eea575a Panagiotis Kanavos
                    throw new BZip2Exception("Bzip data error");
585 0eea575a Panagiotis Kanavos
                }
586 0eea575a Panagiotis Kanavos
                zn++;
587 0eea575a Panagiotis Kanavos
                while (bsLive < 1)
588 0eea575a Panagiotis Kanavos
                {
589 0eea575a Panagiotis Kanavos
                    FillBuffer();
590 0eea575a Panagiotis Kanavos
                }
591 0eea575a Panagiotis Kanavos
                zj = (bsBuff >> (bsLive - 1)) & 1;
592 0eea575a Panagiotis Kanavos
                bsLive--;
593 0eea575a Panagiotis Kanavos
                zvec = (zvec << 1) | zj;
594 0eea575a Panagiotis Kanavos
            }
595 0eea575a Panagiotis Kanavos
            if (zvec - baseArray[zt][zn] < 0 || zvec - baseArray[zt][zn] >= BZip2Constants.MAX_ALPHA_SIZE)
596 0eea575a Panagiotis Kanavos
            {
597 0eea575a Panagiotis Kanavos
                throw new BZip2Exception("Bzip data error");
598 0eea575a Panagiotis Kanavos
            }
599 0eea575a Panagiotis Kanavos
            int nextSym = perm[zt][zvec - baseArray[zt][zn]];
600 0eea575a Panagiotis Kanavos
601 0eea575a Panagiotis Kanavos
            while (true)
602 0eea575a Panagiotis Kanavos
            {
603 0eea575a Panagiotis Kanavos
                if (nextSym == EOB)
604 0eea575a Panagiotis Kanavos
                {
605 0eea575a Panagiotis Kanavos
                    break;
606 0eea575a Panagiotis Kanavos
                }
607 0eea575a Panagiotis Kanavos
608 0eea575a Panagiotis Kanavos
                if (nextSym == BZip2Constants.RUNA || nextSym == BZip2Constants.RUNB)
609 0eea575a Panagiotis Kanavos
                {
610 0eea575a Panagiotis Kanavos
                    var s = -1;
611 0eea575a Panagiotis Kanavos
                    var n = 1;
612 0eea575a Panagiotis Kanavos
                    do
613 0eea575a Panagiotis Kanavos
                    {
614 0eea575a Panagiotis Kanavos
                        if (nextSym == BZip2Constants.RUNA)
615 0eea575a Panagiotis Kanavos
                        {
616 0eea575a Panagiotis Kanavos
                            s += (0 + 1)*n;
617 0eea575a Panagiotis Kanavos
                        }
618 0eea575a Panagiotis Kanavos
                        else if (nextSym == BZip2Constants.RUNB)
619 0eea575a Panagiotis Kanavos
                        {
620 0eea575a Panagiotis Kanavos
                            s += (1 + 1)*n;
621 0eea575a Panagiotis Kanavos
                        }
622 0eea575a Panagiotis Kanavos
623 0eea575a Panagiotis Kanavos
                        n <<= 1;
624 0eea575a Panagiotis Kanavos
625 0eea575a Panagiotis Kanavos
                        if (groupPos == 0)
626 0eea575a Panagiotis Kanavos
                        {
627 0eea575a Panagiotis Kanavos
                            groupNo++;
628 0eea575a Panagiotis Kanavos
                            groupPos = BZip2Constants.G_SIZE;
629 0eea575a Panagiotis Kanavos
                        }
630 0eea575a Panagiotis Kanavos
631 0eea575a Panagiotis Kanavos
                        groupPos--;
632 0eea575a Panagiotis Kanavos
633 0eea575a Panagiotis Kanavos
                        zt = selector[groupNo];
634 0eea575a Panagiotis Kanavos
                        zn = minLens[zt];
635 0eea575a Panagiotis Kanavos
                        zvec = BsR(zn);
636 0eea575a Panagiotis Kanavos
637 0eea575a Panagiotis Kanavos
                        while (zvec > limit[zt][zn])
638 0eea575a Panagiotis Kanavos
                        {
639 0eea575a Panagiotis Kanavos
                            zn++;
640 0eea575a Panagiotis Kanavos
                            while (bsLive < 1)
641 0eea575a Panagiotis Kanavos
                            {
642 0eea575a Panagiotis Kanavos
                                FillBuffer();
643 0eea575a Panagiotis Kanavos
                            }
644 0eea575a Panagiotis Kanavos
                            zj = (bsBuff >> (bsLive - 1)) & 1;
645 0eea575a Panagiotis Kanavos
                            bsLive--;
646 0eea575a Panagiotis Kanavos
                            zvec = (zvec << 1) | zj;
647 0eea575a Panagiotis Kanavos
                        }
648 0eea575a Panagiotis Kanavos
                        nextSym = perm[zt][zvec - baseArray[zt][zn]];
649 0eea575a Panagiotis Kanavos
                    } while (nextSym == BZip2Constants.RUNA || nextSym == BZip2Constants.RUNB);
650 0eea575a Panagiotis Kanavos
651 0eea575a Panagiotis Kanavos
                    s++;
652 0eea575a Panagiotis Kanavos
                    var ch = seqToUnseq[yy[0]];
653 0eea575a Panagiotis Kanavos
                    unzftab[ch] += s;
654 0eea575a Panagiotis Kanavos
655 0eea575a Panagiotis Kanavos
                    while (s > 0)
656 0eea575a Panagiotis Kanavos
                    {
657 0eea575a Panagiotis Kanavos
                        last++;
658 0eea575a Panagiotis Kanavos
                        ll8[last] = ch;
659 0eea575a Panagiotis Kanavos
                        s--;
660 0eea575a Panagiotis Kanavos
                    }
661 0eea575a Panagiotis Kanavos
662 0eea575a Panagiotis Kanavos
                    if (last >= limitLast)
663 0eea575a Panagiotis Kanavos
                    {
664 0eea575a Panagiotis Kanavos
                        BlockOverrun();
665 0eea575a Panagiotis Kanavos
                    }
666 0eea575a Panagiotis Kanavos
                    continue;
667 0eea575a Panagiotis Kanavos
                }
668 0eea575a Panagiotis Kanavos
                last++;
669 0eea575a Panagiotis Kanavos
                if (last >= limitLast)
670 0eea575a Panagiotis Kanavos
                {
671 0eea575a Panagiotis Kanavos
                    BlockOverrun();
672 0eea575a Panagiotis Kanavos
                }
673 0eea575a Panagiotis Kanavos
674 0eea575a Panagiotis Kanavos
                var tmp = yy[nextSym - 1];
675 0eea575a Panagiotis Kanavos
                unzftab[seqToUnseq[tmp]]++;
676 0eea575a Panagiotis Kanavos
                ll8[last] = seqToUnseq[tmp];
677 0eea575a Panagiotis Kanavos
678 0eea575a Panagiotis Kanavos
                for (var j = nextSym - 1; j > 0; --j)
679 0eea575a Panagiotis Kanavos
                {
680 0eea575a Panagiotis Kanavos
                    yy[j] = yy[j - 1];
681 0eea575a Panagiotis Kanavos
                }
682 0eea575a Panagiotis Kanavos
                yy[0] = tmp;
683 0eea575a Panagiotis Kanavos
684 0eea575a Panagiotis Kanavos
                if (groupPos == 0)
685 0eea575a Panagiotis Kanavos
                {
686 0eea575a Panagiotis Kanavos
                    groupNo++;
687 0eea575a Panagiotis Kanavos
                    groupPos = BZip2Constants.G_SIZE;
688 0eea575a Panagiotis Kanavos
                }
689 0eea575a Panagiotis Kanavos
690 0eea575a Panagiotis Kanavos
                groupPos--;
691 0eea575a Panagiotis Kanavos
                zt = selector[groupNo];
692 0eea575a Panagiotis Kanavos
                zn = minLens[zt];
693 0eea575a Panagiotis Kanavos
                zvec = BsR(zn);
694 0eea575a Panagiotis Kanavos
                while (zvec > limit[zt][zn])
695 0eea575a Panagiotis Kanavos
                {
696 0eea575a Panagiotis Kanavos
                    zn++;
697 0eea575a Panagiotis Kanavos
                    while (bsLive < 1)
698 0eea575a Panagiotis Kanavos
                    {
699 0eea575a Panagiotis Kanavos
                        FillBuffer();
700 0eea575a Panagiotis Kanavos
                    }
701 0eea575a Panagiotis Kanavos
                    zj = (bsBuff >> (bsLive - 1)) & 1;
702 0eea575a Panagiotis Kanavos
                    bsLive--;
703 0eea575a Panagiotis Kanavos
                    zvec = (zvec << 1) | zj;
704 0eea575a Panagiotis Kanavos
                }
705 0eea575a Panagiotis Kanavos
                nextSym = perm[zt][zvec - baseArray[zt][zn]];
706 0eea575a Panagiotis Kanavos
                continue;
707 0eea575a Panagiotis Kanavos
            }
708 0eea575a Panagiotis Kanavos
        }
709 0eea575a Panagiotis Kanavos
710 0eea575a Panagiotis Kanavos
        private void SetupBlock()
711 0eea575a Panagiotis Kanavos
        {
712 0eea575a Panagiotis Kanavos
            var cftab = new int[257];
713 0eea575a Panagiotis Kanavos
714 0eea575a Panagiotis Kanavos
            cftab[0] = 0;
715 0eea575a Panagiotis Kanavos
            Array.Copy(unzftab, 0, cftab, 1, 256);
716 0eea575a Panagiotis Kanavos
717 0eea575a Panagiotis Kanavos
            for (var i = 1; i <= 256; i++)
718 0eea575a Panagiotis Kanavos
            {
719 0eea575a Panagiotis Kanavos
                cftab[i] += cftab[i - 1];
720 0eea575a Panagiotis Kanavos
            }
721 0eea575a Panagiotis Kanavos
722 0eea575a Panagiotis Kanavos
            for (var i = 0; i <= last; i++)
723 0eea575a Panagiotis Kanavos
            {
724 0eea575a Panagiotis Kanavos
                var ch = ll8[i];
725 0eea575a Panagiotis Kanavos
                tt[cftab[ch]] = i;
726 0eea575a Panagiotis Kanavos
                cftab[ch]++;
727 0eea575a Panagiotis Kanavos
            }
728 0eea575a Panagiotis Kanavos
729 0eea575a Panagiotis Kanavos
            tPos = tt[origPtr];
730 0eea575a Panagiotis Kanavos
731 0eea575a Panagiotis Kanavos
            count = 0;
732 0eea575a Panagiotis Kanavos
            i2 = 0;
733 0eea575a Panagiotis Kanavos
            ch2 = 256; /*-- not a char and not EOF --*/
734 0eea575a Panagiotis Kanavos
735 0eea575a Panagiotis Kanavos
            if (blockRandomised)
736 0eea575a Panagiotis Kanavos
            {
737 0eea575a Panagiotis Kanavos
                rNToGo = 0;
738 0eea575a Panagiotis Kanavos
                rTPos = 0;
739 0eea575a Panagiotis Kanavos
                SetupRandPartA();
740 0eea575a Panagiotis Kanavos
            }
741 0eea575a Panagiotis Kanavos
            else
742 0eea575a Panagiotis Kanavos
            {
743 0eea575a Panagiotis Kanavos
                SetupNoRandPartA();
744 0eea575a Panagiotis Kanavos
            }
745 0eea575a Panagiotis Kanavos
        }
746 0eea575a Panagiotis Kanavos
747 0eea575a Panagiotis Kanavos
        private void SetupRandPartA()
748 0eea575a Panagiotis Kanavos
        {
749 0eea575a Panagiotis Kanavos
            if (i2 <= last)
750 0eea575a Panagiotis Kanavos
            {
751 0eea575a Panagiotis Kanavos
                chPrev = ch2;
752 0eea575a Panagiotis Kanavos
                ch2 = ll8[tPos];
753 0eea575a Panagiotis Kanavos
                tPos = tt[tPos];
754 0eea575a Panagiotis Kanavos
                if (rNToGo == 0)
755 0eea575a Panagiotis Kanavos
                {
756 0eea575a Panagiotis Kanavos
                    rNToGo = BZip2Constants.rNums[rTPos];
757 0eea575a Panagiotis Kanavos
                    rTPos++;
758 0eea575a Panagiotis Kanavos
                    if (rTPos == 512)
759 0eea575a Panagiotis Kanavos
                    {
760 0eea575a Panagiotis Kanavos
                        rTPos = 0;
761 0eea575a Panagiotis Kanavos
                    }
762 0eea575a Panagiotis Kanavos
                }
763 0eea575a Panagiotis Kanavos
                rNToGo--;
764 0eea575a Panagiotis Kanavos
                ch2 ^= ((rNToGo == 1) ? 1 : 0);
765 0eea575a Panagiotis Kanavos
                i2++;
766 0eea575a Panagiotis Kanavos
767 0eea575a Panagiotis Kanavos
                currentChar = ch2;
768 0eea575a Panagiotis Kanavos
                currentState = RAND_PART_B_STATE;
769 0eea575a Panagiotis Kanavos
                mCrc.Update(ch2);
770 0eea575a Panagiotis Kanavos
            }
771 0eea575a Panagiotis Kanavos
            else
772 0eea575a Panagiotis Kanavos
            {
773 0eea575a Panagiotis Kanavos
                EndBlock();
774 0eea575a Panagiotis Kanavos
                InitBlock();
775 0eea575a Panagiotis Kanavos
                SetupBlock();
776 0eea575a Panagiotis Kanavos
            }
777 0eea575a Panagiotis Kanavos
        }
778 0eea575a Panagiotis Kanavos
779 0eea575a Panagiotis Kanavos
        private void SetupNoRandPartA()
780 0eea575a Panagiotis Kanavos
        {
781 0eea575a Panagiotis Kanavos
            if (i2 <= last)
782 0eea575a Panagiotis Kanavos
            {
783 0eea575a Panagiotis Kanavos
                chPrev = ch2;
784 0eea575a Panagiotis Kanavos
                ch2 = ll8[tPos];
785 0eea575a Panagiotis Kanavos
                tPos = tt[tPos];
786 0eea575a Panagiotis Kanavos
                i2++;
787 0eea575a Panagiotis Kanavos
788 0eea575a Panagiotis Kanavos
                currentChar = ch2;
789 0eea575a Panagiotis Kanavos
                currentState = NO_RAND_PART_B_STATE;
790 0eea575a Panagiotis Kanavos
                mCrc.Update(ch2);
791 0eea575a Panagiotis Kanavos
            }
792 0eea575a Panagiotis Kanavos
            else
793 0eea575a Panagiotis Kanavos
            {
794 0eea575a Panagiotis Kanavos
                EndBlock();
795 0eea575a Panagiotis Kanavos
                InitBlock();
796 0eea575a Panagiotis Kanavos
                SetupBlock();
797 0eea575a Panagiotis Kanavos
            }
798 0eea575a Panagiotis Kanavos
        }
799 0eea575a Panagiotis Kanavos
800 0eea575a Panagiotis Kanavos
        private void SetupRandPartB()
801 0eea575a Panagiotis Kanavos
        {
802 0eea575a Panagiotis Kanavos
            if (ch2 != chPrev)
803 0eea575a Panagiotis Kanavos
            {
804 0eea575a Panagiotis Kanavos
                currentState = RAND_PART_A_STATE;
805 0eea575a Panagiotis Kanavos
                count = 1;
806 0eea575a Panagiotis Kanavos
                SetupRandPartA();
807 0eea575a Panagiotis Kanavos
            }
808 0eea575a Panagiotis Kanavos
            else
809 0eea575a Panagiotis Kanavos
            {
810 0eea575a Panagiotis Kanavos
                count++;
811 0eea575a Panagiotis Kanavos
                if (count >= 4)
812 0eea575a Panagiotis Kanavos
                {
813 0eea575a Panagiotis Kanavos
                    z = ll8[tPos];
814 0eea575a Panagiotis Kanavos
                    tPos = tt[tPos];
815 0eea575a Panagiotis Kanavos
                    if (rNToGo == 0)
816 0eea575a Panagiotis Kanavos
                    {
817 0eea575a Panagiotis Kanavos
                        rNToGo = BZip2Constants.rNums[rTPos];
818 0eea575a Panagiotis Kanavos
                        rTPos++;
819 0eea575a Panagiotis Kanavos
                        if (rTPos == 512)
820 0eea575a Panagiotis Kanavos
                        {
821 0eea575a Panagiotis Kanavos
                            rTPos = 0;
822 0eea575a Panagiotis Kanavos
                        }
823 0eea575a Panagiotis Kanavos
                    }
824 0eea575a Panagiotis Kanavos
                    rNToGo--;
825 0eea575a Panagiotis Kanavos
                    z ^= (byte) ((rNToGo == 1) ? 1 : 0);
826 0eea575a Panagiotis Kanavos
                    j2 = 0;
827 0eea575a Panagiotis Kanavos
                    currentState = RAND_PART_C_STATE;
828 0eea575a Panagiotis Kanavos
                    SetupRandPartC();
829 0eea575a Panagiotis Kanavos
                }
830 0eea575a Panagiotis Kanavos
                else
831 0eea575a Panagiotis Kanavos
                {
832 0eea575a Panagiotis Kanavos
                    currentState = RAND_PART_A_STATE;
833 0eea575a Panagiotis Kanavos
                    SetupRandPartA();
834 0eea575a Panagiotis Kanavos
                }
835 0eea575a Panagiotis Kanavos
            }
836 0eea575a Panagiotis Kanavos
        }
837 0eea575a Panagiotis Kanavos
838 0eea575a Panagiotis Kanavos
        private void SetupRandPartC()
839 0eea575a Panagiotis Kanavos
        {
840 0eea575a Panagiotis Kanavos
            if (j2 < z)
841 0eea575a Panagiotis Kanavos
            {
842 0eea575a Panagiotis Kanavos
                currentChar = ch2;
843 0eea575a Panagiotis Kanavos
                mCrc.Update(ch2);
844 0eea575a Panagiotis Kanavos
                j2++;
845 0eea575a Panagiotis Kanavos
            }
846 0eea575a Panagiotis Kanavos
            else
847 0eea575a Panagiotis Kanavos
            {
848 0eea575a Panagiotis Kanavos
                currentState = RAND_PART_A_STATE;
849 0eea575a Panagiotis Kanavos
                i2++;
850 0eea575a Panagiotis Kanavos
                count = 0;
851 0eea575a Panagiotis Kanavos
                SetupRandPartA();
852 0eea575a Panagiotis Kanavos
            }
853 0eea575a Panagiotis Kanavos
        }
854 0eea575a Panagiotis Kanavos
855 0eea575a Panagiotis Kanavos
        private void SetupNoRandPartB()
856 0eea575a Panagiotis Kanavos
        {
857 0eea575a Panagiotis Kanavos
            if (ch2 != chPrev)
858 0eea575a Panagiotis Kanavos
            {
859 0eea575a Panagiotis Kanavos
                currentState = NO_RAND_PART_A_STATE;
860 0eea575a Panagiotis Kanavos
                count = 1;
861 0eea575a Panagiotis Kanavos
                SetupNoRandPartA();
862 0eea575a Panagiotis Kanavos
            }
863 0eea575a Panagiotis Kanavos
            else
864 0eea575a Panagiotis Kanavos
            {
865 0eea575a Panagiotis Kanavos
                count++;
866 0eea575a Panagiotis Kanavos
                if (count >= 4)
867 0eea575a Panagiotis Kanavos
                {
868 0eea575a Panagiotis Kanavos
                    z = ll8[tPos];
869 0eea575a Panagiotis Kanavos
                    tPos = tt[tPos];
870 0eea575a Panagiotis Kanavos
                    currentState = NO_RAND_PART_C_STATE;
871 0eea575a Panagiotis Kanavos
                    j2 = 0;
872 0eea575a Panagiotis Kanavos
                    SetupNoRandPartC();
873 0eea575a Panagiotis Kanavos
                }
874 0eea575a Panagiotis Kanavos
                else
875 0eea575a Panagiotis Kanavos
                {
876 0eea575a Panagiotis Kanavos
                    currentState = NO_RAND_PART_A_STATE;
877 0eea575a Panagiotis Kanavos
                    SetupNoRandPartA();
878 0eea575a Panagiotis Kanavos
                }
879 0eea575a Panagiotis Kanavos
            }
880 0eea575a Panagiotis Kanavos
        }
881 0eea575a Panagiotis Kanavos
882 0eea575a Panagiotis Kanavos
        private void SetupNoRandPartC()
883 0eea575a Panagiotis Kanavos
        {
884 0eea575a Panagiotis Kanavos
            if (j2 < z)
885 0eea575a Panagiotis Kanavos
            {
886 0eea575a Panagiotis Kanavos
                currentChar = ch2;
887 0eea575a Panagiotis Kanavos
                mCrc.Update(ch2);
888 0eea575a Panagiotis Kanavos
                j2++;
889 0eea575a Panagiotis Kanavos
            }
890 0eea575a Panagiotis Kanavos
            else
891 0eea575a Panagiotis Kanavos
            {
892 0eea575a Panagiotis Kanavos
                currentState = NO_RAND_PART_A_STATE;
893 0eea575a Panagiotis Kanavos
                i2++;
894 0eea575a Panagiotis Kanavos
                count = 0;
895 0eea575a Panagiotis Kanavos
                SetupNoRandPartA();
896 0eea575a Panagiotis Kanavos
            }
897 0eea575a Panagiotis Kanavos
        }
898 0eea575a Panagiotis Kanavos
899 0eea575a Panagiotis Kanavos
        private void SetDecompressStructureSizes(int newSize100k)
900 0eea575a Panagiotis Kanavos
        {
901 0eea575a Panagiotis Kanavos
            if (!(0 <= newSize100k && newSize100k <= 9 && 0 <= blockSize100k && blockSize100k <= 9))
902 0eea575a Panagiotis Kanavos
            {
903 0eea575a Panagiotis Kanavos
                throw new BZip2Exception("Invalid block size");
904 0eea575a Panagiotis Kanavos
            }
905 0eea575a Panagiotis Kanavos
906 0eea575a Panagiotis Kanavos
            blockSize100k = newSize100k;
907 0eea575a Panagiotis Kanavos
908 0eea575a Panagiotis Kanavos
            if (newSize100k == 0)
909 0eea575a Panagiotis Kanavos
            {
910 0eea575a Panagiotis Kanavos
                return;
911 0eea575a Panagiotis Kanavos
            }
912 0eea575a Panagiotis Kanavos
913 0eea575a Panagiotis Kanavos
            var n = BZip2Constants.baseBlockSize*newSize100k;
914 0eea575a Panagiotis Kanavos
            ll8 = new byte[n];
915 0eea575a Panagiotis Kanavos
            tt = new int[n];
916 0eea575a Panagiotis Kanavos
        }
917 0eea575a Panagiotis Kanavos
918 0eea575a Panagiotis Kanavos
        private static void CompressedStreamEOF()
919 0eea575a Panagiotis Kanavos
        {
920 0eea575a Panagiotis Kanavos
            throw new EndOfStreamException("BZip2 input stream end of compressed stream");
921 0eea575a Panagiotis Kanavos
        }
922 0eea575a Panagiotis Kanavos
923 0eea575a Panagiotis Kanavos
        private static void BlockOverrun()
924 0eea575a Panagiotis Kanavos
        {
925 0eea575a Panagiotis Kanavos
            throw new BZip2Exception("BZip2 input stream block overrun");
926 0eea575a Panagiotis Kanavos
        }
927 0eea575a Panagiotis Kanavos
928 0eea575a Panagiotis Kanavos
        private static void BadBlockHeader()
929 0eea575a Panagiotis Kanavos
        {
930 0eea575a Panagiotis Kanavos
            throw new BZip2Exception("BZip2 input stream bad block header");
931 0eea575a Panagiotis Kanavos
        }
932 0eea575a Panagiotis Kanavos
933 0eea575a Panagiotis Kanavos
        private static void CrcError()
934 0eea575a Panagiotis Kanavos
        {
935 0eea575a Panagiotis Kanavos
            throw new BZip2Exception("BZip2 input stream crc error");
936 0eea575a Panagiotis Kanavos
        }
937 0eea575a Panagiotis Kanavos
938 0eea575a Panagiotis Kanavos
        private static void HbCreateDecodeTables(int[] limit, int[] baseArray, int[] perm, char[] length, int minLen,
939 0eea575a Panagiotis Kanavos
                                                 int maxLen, int alphaSize)
940 0eea575a Panagiotis Kanavos
        {
941 0eea575a Panagiotis Kanavos
            var pp = 0;
942 0eea575a Panagiotis Kanavos
943 0eea575a Panagiotis Kanavos
            for (var i = minLen; i <= maxLen; ++i)
944 0eea575a Panagiotis Kanavos
            {
945 0eea575a Panagiotis Kanavos
                for (var j = 0; j < alphaSize; ++j)
946 0eea575a Panagiotis Kanavos
                {
947 0eea575a Panagiotis Kanavos
                    if (length[j] == i)
948 0eea575a Panagiotis Kanavos
                    {
949 0eea575a Panagiotis Kanavos
                        perm[pp] = j;
950 0eea575a Panagiotis Kanavos
                        ++pp;
951 0eea575a Panagiotis Kanavos
                    }
952 0eea575a Panagiotis Kanavos
                }
953 0eea575a Panagiotis Kanavos
            }
954 0eea575a Panagiotis Kanavos
955 0eea575a Panagiotis Kanavos
            for (var i = 0; i < BZip2Constants.MAX_CODE_LEN; i++)
956 0eea575a Panagiotis Kanavos
            {
957 0eea575a Panagiotis Kanavos
                baseArray[i] = 0;
958 0eea575a Panagiotis Kanavos
            }
959 0eea575a Panagiotis Kanavos
960 0eea575a Panagiotis Kanavos
            for (var i = 0; i < alphaSize; i++)
961 0eea575a Panagiotis Kanavos
            {
962 0eea575a Panagiotis Kanavos
                ++baseArray[length[i] + 1];
963 0eea575a Panagiotis Kanavos
            }
964 0eea575a Panagiotis Kanavos
965 0eea575a Panagiotis Kanavos
            for (var i = 1; i < BZip2Constants.MAX_CODE_LEN; i++)
966 0eea575a Panagiotis Kanavos
            {
967 0eea575a Panagiotis Kanavos
                baseArray[i] += baseArray[i - 1];
968 0eea575a Panagiotis Kanavos
            }
969 0eea575a Panagiotis Kanavos
970 0eea575a Panagiotis Kanavos
            for (var i = 0; i < BZip2Constants.MAX_CODE_LEN; i++)
971 0eea575a Panagiotis Kanavos
            {
972 0eea575a Panagiotis Kanavos
                limit[i] = 0;
973 0eea575a Panagiotis Kanavos
            }
974 0eea575a Panagiotis Kanavos
975 0eea575a Panagiotis Kanavos
            var vec = 0;
976 0eea575a Panagiotis Kanavos
977 0eea575a Panagiotis Kanavos
            for (var i = minLen; i <= maxLen; i++)
978 0eea575a Panagiotis Kanavos
            {
979 0eea575a Panagiotis Kanavos
                vec += (baseArray[i + 1] - baseArray[i]);
980 0eea575a Panagiotis Kanavos
                limit[i] = vec - 1;
981 0eea575a Panagiotis Kanavos
                vec <<= 1;
982 0eea575a Panagiotis Kanavos
            }
983 0eea575a Panagiotis Kanavos
984 0eea575a Panagiotis Kanavos
            for (var i = minLen + 1; i <= maxLen; i++)
985 0eea575a Panagiotis Kanavos
            {
986 0eea575a Panagiotis Kanavos
                baseArray[i] = ((limit[i - 1] + 1) << 1) - baseArray[i];
987 0eea575a Panagiotis Kanavos
            }
988 0eea575a Panagiotis Kanavos
        }
989 0eea575a Panagiotis Kanavos
990 0eea575a Panagiotis Kanavos
        #region Instance Fields
991 0eea575a Panagiotis Kanavos
992 0eea575a Panagiotis Kanavos
        /*--
993 0eea575a Panagiotis Kanavos
		index of the last char in the block, so
994 0eea575a Panagiotis Kanavos
		the block size == last + 1.
995 0eea575a Panagiotis Kanavos
		--*/
996 0eea575a Panagiotis Kanavos
997 0eea575a Panagiotis Kanavos
        private readonly int[][] baseArray = new int[BZip2Constants.N_GROUPS][];
998 0eea575a Panagiotis Kanavos
        private readonly bool[] inUse = new bool[256];
999 0eea575a Panagiotis Kanavos
        private readonly int[][] limit = new int[BZip2Constants.N_GROUPS][];
1000 0eea575a Panagiotis Kanavos
        private readonly IChecksum mCrc = new StrangeCRC();
1001 0eea575a Panagiotis Kanavos
        private readonly int[] minLens = new int[BZip2Constants.N_GROUPS];
1002 0eea575a Panagiotis Kanavos
        private readonly int[][] perm = new int[BZip2Constants.N_GROUPS][];
1003 0eea575a Panagiotis Kanavos
1004 0eea575a Panagiotis Kanavos
        private readonly byte[] selector = new byte[BZip2Constants.MAX_SELECTORS];
1005 0eea575a Panagiotis Kanavos
        private readonly byte[] selectorMtf = new byte[BZip2Constants.MAX_SELECTORS];
1006 0eea575a Panagiotis Kanavos
        private readonly byte[] seqToUnseq = new byte[256];
1007 0eea575a Panagiotis Kanavos
        private readonly byte[] unseqToSeq = new byte[256];
1008 0eea575a Panagiotis Kanavos
1009 0eea575a Panagiotis Kanavos
        /*--
1010 0eea575a Panagiotis Kanavos
		freq table collected to save a pass over the data
1011 0eea575a Panagiotis Kanavos
		during decompression.
1012 0eea575a Panagiotis Kanavos
		--*/
1013 0eea575a Panagiotis Kanavos
        private readonly int[] unzftab = new int[256];
1014 0eea575a Panagiotis Kanavos
1015 0eea575a Panagiotis Kanavos
        private Stream baseStream;
1016 0eea575a Panagiotis Kanavos
        private bool blockRandomised;
1017 0eea575a Panagiotis Kanavos
        private int blockSize100k;
1018 0eea575a Panagiotis Kanavos
        private int bsBuff;
1019 0eea575a Panagiotis Kanavos
        private int bsLive;
1020 0eea575a Panagiotis Kanavos
        private int ch2;
1021 0eea575a Panagiotis Kanavos
        private int chPrev;
1022 0eea575a Panagiotis Kanavos
        private int computedBlockCRC;
1023 0eea575a Panagiotis Kanavos
        private uint computedCombinedCRC;
1024 0eea575a Panagiotis Kanavos
1025 0eea575a Panagiotis Kanavos
        private int count;
1026 0eea575a Panagiotis Kanavos
        private int currentChar = -1;
1027 0eea575a Panagiotis Kanavos
1028 0eea575a Panagiotis Kanavos
        private int currentState = START_BLOCK_STATE;
1029 0eea575a Panagiotis Kanavos
        private int i2;
1030 0eea575a Panagiotis Kanavos
        private bool isStreamOwner = true;
1031 0eea575a Panagiotis Kanavos
        private int j2;
1032 0eea575a Panagiotis Kanavos
        private int last;
1033 0eea575a Panagiotis Kanavos
        private byte[] ll8;
1034 0eea575a Panagiotis Kanavos
        private int nInUse;
1035 0eea575a Panagiotis Kanavos
        private int origPtr;
1036 0eea575a Panagiotis Kanavos
        private int rNToGo;
1037 0eea575a Panagiotis Kanavos
        private int rTPos;
1038 0eea575a Panagiotis Kanavos
        private int storedBlockCRC, storedCombinedCRC;
1039 0eea575a Panagiotis Kanavos
        private bool streamEnd;
1040 0eea575a Panagiotis Kanavos
        private int tPos;
1041 0eea575a Panagiotis Kanavos
        private int[] tt;
1042 0eea575a Panagiotis Kanavos
        private byte z;
1043 0eea575a Panagiotis Kanavos
1044 0eea575a Panagiotis Kanavos
        #endregion
1045 0eea575a Panagiotis Kanavos
    }
1046 0eea575a Panagiotis Kanavos
}
1047 0eea575a Panagiotis Kanavos
1048 0eea575a Panagiotis Kanavos
/* This file was derived from a file containing this license:
1049 0eea575a Panagiotis Kanavos
 * 
1050 0eea575a Panagiotis Kanavos
 * This file is a part of bzip2 and/or libbzip2, a program and
1051 0eea575a Panagiotis Kanavos
 * library for lossless, block-sorting data compression.
1052 0eea575a Panagiotis Kanavos
 * 
1053 0eea575a Panagiotis Kanavos
 * Copyright (C) 1996-1998 Julian R Seward.  All rights reserved.
1054 0eea575a Panagiotis Kanavos
 * 
1055 0eea575a Panagiotis Kanavos
 * Redistribution and use in source and binary forms, with or without
1056 0eea575a Panagiotis Kanavos
 * modification, are permitted provided that the following conditions
1057 0eea575a Panagiotis Kanavos
 * are met:
1058 0eea575a Panagiotis Kanavos
 * 
1059 0eea575a Panagiotis Kanavos
 * 1. Redistributions of source code must retain the above copyright
1060 0eea575a Panagiotis Kanavos
 * notice, this list of conditions and the following disclaimer.
1061 0eea575a Panagiotis Kanavos
 * 
1062 0eea575a Panagiotis Kanavos
 * 2. The origin of this software must not be misrepresented; you must 
1063 0eea575a Panagiotis Kanavos
 * not claim that you wrote the original software.  If you use this 
1064 0eea575a Panagiotis Kanavos
 * software in a product, an acknowledgment in the product 
1065 0eea575a Panagiotis Kanavos
 * documentation would be appreciated but is not required.
1066 0eea575a Panagiotis Kanavos
 * 
1067 0eea575a Panagiotis Kanavos
 * 3. Altered source versions must be plainly marked as such, and must
1068 0eea575a Panagiotis Kanavos
 * not be misrepresented as being the original software.
1069 0eea575a Panagiotis Kanavos
 * 
1070 0eea575a Panagiotis Kanavos
 * 4. The name of the author may not be used to endorse or promote 
1071 0eea575a Panagiotis Kanavos
 * products derived from this software without specific prior written 
1072 0eea575a Panagiotis Kanavos
 * permission.
1073 0eea575a Panagiotis Kanavos
 * 
1074 0eea575a Panagiotis Kanavos
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
1075 0eea575a Panagiotis Kanavos
 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
1076 0eea575a Panagiotis Kanavos
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1077 0eea575a Panagiotis Kanavos
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
1078 0eea575a Panagiotis Kanavos
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1079 0eea575a Panagiotis Kanavos
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
1080 0eea575a Panagiotis Kanavos
 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
1081 0eea575a Panagiotis Kanavos
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
1082 0eea575a Panagiotis Kanavos
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
1083 0eea575a Panagiotis Kanavos
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
1084 0eea575a Panagiotis Kanavos
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1085 0eea575a Panagiotis Kanavos
 * 
1086 0eea575a Panagiotis Kanavos
 * Java version ported by Keiron Liddle, Aftex Software <keiron@aftexsw.com> 1999-2001
1087 0eea575a Panagiotis Kanavos
 */