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