1e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li/*
2e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li * Copyright (c) 2005 Oren J. Maurice <oymaurice@hazorea.org.il>
3e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li *
4e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li * Redistribution and use in source and binary forms, with or without modifica-
5e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li * tion, are permitted provided that the following conditions are met:
6e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li *
7e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li *   1.  Redistributions of source code must retain the above copyright notice,
8e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li *       this list of conditions and the following disclaimer.
9e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li *
10e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li *   2.  Redistributions in binary form must reproduce the above copyright
11e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li *       notice, this list of conditions and the following disclaimer in the
12e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li *       documentation and/or other materials provided with the distribution.
13e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li *
14e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li *   3.  The name of the author may not be used to endorse or promote products
15e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li *       derived from this software without specific prior written permission.
16e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li *
17e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
18e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER-
19e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li * CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO
20e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE-
21e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li * CIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
23e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH-
25e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li * ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
26e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li * OF THE POSSIBILITY OF SUCH DAMAGE.
27e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li *
28e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li * Alternatively, the contents of this file may be used under the terms of
29e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li * the GNU General Public License version 2 (the "GPL"), in which case the
30e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li * provisions of the GPL are applicable instead of the above. If you wish to
31e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li * allow the use of your version of this file only under the terms of the
32e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li * GPL and not to allow others to use your version of this file under the
33e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li * BSD license, indicate your decision by deleting the provisions above and
34e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li * replace them with the notice and other provisions required by the GPL. If
35e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li * you do not delete the provisions above, a recipient may use your version
36e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li * of this file under either the BSD or the GPL.
37e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li */
38e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li
39e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Liusing System;
40e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li
41e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Linamespace LZF.NET
42e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li{
43e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li
44e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li	/// <summary>
45e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li	/// Summary description for CLZF.
46e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li	/// </summary>
47e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li	public class CLZF
48e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li	{
49e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li		// CRC32 data & function
50e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li		UInt32 []crc_32_tab = new UInt32[256]
51e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li		{
52e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li			0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419,
53e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li			0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4,
54e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li			0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07,
55e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li			0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
56e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li			0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856,
57e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li			0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
58e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li			0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4,
59e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li			0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
60e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li			0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3,
61e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li			0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a,
62e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li			0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599,
63e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li			0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
64e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li			0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190,
65e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li			0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f,
66e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li			0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e,
67e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li			0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
68e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li			0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed,
69e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li			0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
70e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li			0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3,
71e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li			0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
72e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li			0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a,
73e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li			0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5,
74e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li			0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010,
75e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li			0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
76e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li			0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17,
77e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li			0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6,
78e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li			0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615,
79e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li			0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
80e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li			0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344,
81e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li			0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
82e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li			0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a,
83e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li			0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
84e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li			0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1,
85e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li			0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c,
86e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li			0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef,
87e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li			0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
88e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li			0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe,
89e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li			0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31,
90e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li			0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c,
91e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li			0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
92e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li			0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b,
93e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li			0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
94e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li			0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1,
95e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li			0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
96e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li			0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278,
97e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li			0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7,
98e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li			0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66,
99e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li			0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
100e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li			0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605,
101e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li			0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8,
102e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li			0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b,
103e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li			0x2d02ef8d
104e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li		};
105e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li
106e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li		public UInt32 crc32(UInt32 OldCRC,byte NewData)
107e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li		{
108e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li			return crc_32_tab[(OldCRC & 0xff) ^ NewData] ^ (OldCRC >> 8);
109e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li		}
110e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li
111e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li
112e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li		/// <summary>
113e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li		/// LZF Compressor
114e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li		/// </summary>
115e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li
116e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li		UInt32 HLOG=14;
117e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li		UInt32 HSIZE=(1<<14);
118e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li
119e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li		/*
120e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li		* don't play with this unless you benchmark!
121e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li		* decompression is not dependent on the hash function
122e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li		* the hashing function might seem strange, just believe me
123e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li		* it works ;)
124e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li		*/
125e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li		UInt32 MAX_LIT=(1 <<  5);
126e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li		UInt32 MAX_OFF=(1 << 13);
127e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li		UInt32 MAX_REF=((1 <<  8) + (1 << 3));
128e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li
129e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li		UInt32 FRST(byte[] Array,UInt32 ptr)
130e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li		{
131e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li			return (UInt32)(((Array[ptr]) << 8) | Array[ptr+1]);
132e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li		}
133e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li
134e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li		UInt32 NEXT(UInt32 v,byte[] Array,UInt32 ptr)
135e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li		{
136e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li			return ((v) << 8) | Array[ptr+2];
137e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li		}
138e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li
139e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li		UInt32 IDX(UInt32 h)
140e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li		{
141e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li                	return ((((h ^ (h << 5)) >> (int) (3*8 - HLOG)) - h*5) & (HSIZE - 1));
142e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li		}
143e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li
144e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li		/*
145e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li		* compressed format
146e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li		*
147e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li		* 000LLLLL <L+1>    ; literal
148e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li		* LLLOOOOO oooooooo ; backref L
149e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li		* 111OOOOO LLLLLLLL oooooooo ; backref L+7
150e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li		*
151e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li		*/
152e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li
153e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li		public int lzf_compress (byte[] in_data, int in_len,byte[] out_data, int out_len)
154e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li		{
155e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li			int c;
156e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li			long []htab=new long[1<<14];
157e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li			for (c=0;c<1<<14;c++)
158e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li			{
159e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li				htab[c]=0;
160e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li			}
161e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li
162e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li			long hslot;
163e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li			UInt32 iidx = 0;
164e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li			UInt32 oidx = 0;
165e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li			//byte *in_end  = ip + in_len;
166e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li			//byte *out_end = op + out_len;
167e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li			long reference;
168e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li
169e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li			UInt32 hval = FRST (in_data,iidx);
170e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li			long off;
171e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li			int lit = 0;
172e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li
173e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li			for (;;)
174e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li				{
175e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li				if (iidx < in_len - 2)
176e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li					{
177e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li					hval = NEXT (hval, in_data,iidx);
178e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li					hslot = IDX (hval);
179e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li					reference = htab[hslot];
180e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li					htab[hslot] = (long)iidx;
181e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li
182e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li					if ((off = iidx - reference - 1) < MAX_OFF
183e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li						&& iidx + 4 < in_len
184e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li						&& reference > 0
185e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li						&& in_data[reference+0] == in_data[iidx+0]
186e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li						&& in_data[reference+1] == in_data[iidx+1]
187e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li						&& in_data[reference+2] == in_data[iidx+2]
188e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li						)
189e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li						{
190e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li						/* match found at *reference++ */
191e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li						UInt32 len = 2;
192e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li						UInt32 maxlen = (UInt32)in_len - iidx - len;
193e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li						maxlen = maxlen > MAX_REF ? MAX_REF : maxlen;
194e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li
195e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li						if (oidx + lit + 1 + 3 >= out_len)
196e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li							return 0;
197e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li
198e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li						do
199e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li							len++;
200e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li						while (len < maxlen && in_data[reference+len] == in_data[iidx+len]);
201e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li
202e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li						if (lit!=0)
203e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li							{
204e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li							out_data[oidx++] = (byte)(lit - 1);
205e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li							lit = -lit;
206e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li							do
207e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li								out_data[oidx++] = in_data[iidx+lit];
208e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li							while ((++lit)!=0);
209e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li							}
210e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li
211e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li						len -= 2;
212e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li						iidx++;
213e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li
214e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li						if (len < 7)
215e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li							{
216e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li							out_data[oidx++] = (byte)((off >> 8) + (len << 5));
217e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li							}
218e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li						else
219e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li							{
220e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li							out_data[oidx++] = (byte)((off >> 8) + (  7 << 5));
221e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li							out_data[oidx++] = (byte)(len - 7);
222e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li							}
223e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li
224e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li						out_data[oidx++] = (byte)off;
225e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li
226e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li						iidx += len-1;
227e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li						hval = FRST (in_data,iidx);
228e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li
229e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li						hval = NEXT (hval,in_data, iidx);
230e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li						htab[IDX (hval)] = iidx;
231e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li						iidx++;
232e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li
233e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li						hval = NEXT (hval, in_data,iidx);
234e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li						htab[IDX (hval)] = iidx;
235e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li						iidx++;
236e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li						continue;
237e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li						}
238e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li					}
239e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li				else if (iidx == in_len)
240e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li					break;
241e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li
242e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li				/* one more literal byte we must copy */
243e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li				lit++;
244e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li				iidx++;
245e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li
246e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li				if (lit == MAX_LIT)
247e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li					{
248e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li					if (oidx + 1 + MAX_LIT >= out_len)
249e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li						return 0;
250e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li
251e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li					out_data[oidx++] = (byte)(MAX_LIT - 1);
252e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li					lit = -lit;
253e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li					do
254e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li						out_data[oidx++] = in_data[iidx+lit];
255e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li					while ((++lit)!=0);
256e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li					}
257e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li				}
258e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li
259e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li			if (lit!=0)
260e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li				{
261e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li				if (oidx + lit + 1 >= out_len)
262e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li					return 0;
263e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li
264e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li				out_data[oidx++] = (byte)(lit - 1);
265e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li				lit = -lit;
266e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li				do
267e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li					out_data[oidx++] = in_data[iidx+lit];
268e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li				while ((++lit)!=0);
269e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li				}
270e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li
271e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li			return (int)oidx;
272e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li		}
273e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li
274e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li		/// <summary>
275e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li		/// LZF Decompressor
276e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li		/// </summary>
277e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li		public int lzf_decompress ( byte[] in_data, int in_len, byte[] out_data, int out_len)
278e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li		{
279e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li			UInt32 iidx=0;
280e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li			UInt32 oidx=0;
281e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li
282e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li			do
283e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li				{
284e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li				UInt32 ctrl = in_data[iidx++];
285e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li
286e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li				if (ctrl < (1 << 5)) /* literal run */
287e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li					{
288e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li					ctrl++;
289e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li
290e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li					if (oidx + ctrl > out_len)
291e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li						{
292e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li						//SET_ERRNO (E2BIG);
293e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li						return 0;
294e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li						}
295e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li
296e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li					do
297e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li						out_data[oidx++] = in_data[iidx++];
298e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li					while ((--ctrl)!=0);
299e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li					}
300e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li				else /* back reference */
301e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li					{
302e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li					UInt32 len = ctrl >> 5;
303e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li
304e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li					int reference = (int)(oidx - ((ctrl & 0x1f) << 8) - 1);
305e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li
306e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li					if (len == 7)
307e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li						len += in_data[iidx++];
308e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li
309e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li					reference -= in_data[iidx++];
310e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li
311e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li					if (oidx + len + 2 > out_len)
312e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li						{
313e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li						//SET_ERRNO (E2BIG);
314e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li						return 0;
315e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li						}
316e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li
317e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li					if (reference < 0)
318e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li						{
319e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li						//SET_ERRNO (EINVAL);
320e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li						return 0;
321e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li						}
322e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li
323e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li					out_data[oidx++]=out_data[reference++];
324e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li					out_data[oidx++]=out_data[reference++];
325e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li
326e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li					do
327e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li						out_data[oidx++]=out_data[reference++];
328e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li					while ((--len)!=0);
329e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li					}
330e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li				}
331e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li			while (iidx < in_len);
332e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li
333e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li			return (int)oidx;
334e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li		}
335e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li
336e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li		public CLZF()
337e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li		{
338e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li			//
339e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li			// TODO: Add ructor logic here
340e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li			//
341e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li		}
342e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li	}
343e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li}
344e54acca48ba1ab84ac7c693de45ed31ac3f311c2David Li
345