1 /******************************************************************************
2 *
3 * Copyright (C) 2009, The Gentee Group. All rights reserved.
4 * This file is part of the Gentee open source project - http://www.gentee.com.
5 *
6 * THIS FILE IS PROVIDED UNDER THE TERMS OF THE GENTEE LICENSE ("AGREEMENT").
7 * ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS FILE CONSTITUTES RECIPIENTS
8 * ACCEPTANCE OF THE AGREEMENT.
9 *
10 * Author: Alexey Krivonogov ( gentee )
11 *
12 ******************************************************************************/
13
14 #include "lzge.h"
15 //#include "..\GEA\gea.h"
16 //#include "K:\Gentee\Gentee Language\VM Lib\memory.h"
17
18 //--------------------------------------------------------------------------
19
20 dword STACKAPI lzge_slot( pslzge lzge, dword len, dword offset, pdword footer,
21 pdword lenfooter )
22 {
23 dword i = 0, k = 0;
24
25 while ( rngmax[ i ] < offset ) i++;
26 if ( offset == lzge->mft[0] ) i = 0;
27 else
28 if ( offset == lzge->mft[1] )
29 {
30 lzge->mft[1] = lzge->mft[ 0 ];
31 lzge->mft[0] = offset;
32 i = 1;
33 }
34 else
35 {
36 if ( offset == lzge->mft[2] )
37 i = 2;
38 lzge->mft[2] = lzge->mft[1];
39 lzge->mft[1] = lzge->mft[0];
40 lzge->mft[0] = offset;
41 }
42
43 *footer = i;
44 k = 0;
45 while ( lenmax[ k ] < len ) k++;
46
47 *lenfooter = k;
48 return LZGE_ALPHABET + i * SLOT_LEN + k;
49 }
50
51 //--------------------------------------------------------------------------
52
53 dword STDCALL lzge_encode( pbyte in, dword size, pbyte out, pslzge lzge )
54 {
55 smatch match;
56 shuf huf;
57 dword numblock = 0;
58 dword len, offset;
59 pbyte end = in + size;
60 pdword proceed;
61 dword curp = 0, ip;
62 dword footer, lenfooter;
63
64 // dword ok = 0;
65
66 if ( !lzge->level ) lzge->level = 5;
67 if ( !lzge->hufblock ) lzge->hufblock = HUF_BLOCK;
68 proceed = mem_alloc(( lzge->hufblock + 1 ) * 3 * sizeof( dword ));
69
70 lzge_ranges( lzge, match_new( &match, in, end, min( 10, lzge->level )));
71 lzge->mft[0] = 3;
72 lzge->mft[1] = 4;
73 lzge->mft[2] = 5;
74 // lzge->mft[3] = 7;
75 if ( lzge->solidoff ) in++;
76 for ( ip = 1; ip < lzge->solidoff; ip++ )
77 {
78 match_update( &match, in++ );
79 }
80
81 huf_new( &huf, LZGE_ALPHABET + SLOT_LEN * lzge->numoff + 1 );
82 // huf_new( &huf, LZGE_ALPHABET + SLOT_LEN * + 1 );
83 // printf("HUF=%i numoff = %i\n", huf.numcode, lzge->numoff );
84 // huf.fixed = 1;
85 huf.ptr = out;
86
87 while ( in < end )
88 {
89 len = match_find( &match, in, &offset );
90 // ok++;
91 if ( len < MATCH_LEN )
92 {
93 huf_incfreq( &huf, *in );
94 proceed[ curp++ ] = *in;
95 // printf("%c", *in++ );
96 }
97 else
98 {
99 if ( len > lenmax[ SLOT_LEN - 1 ])
100 {
101 proceed[ curp ] = LZGE_ALPHABET + lzge->numoff * SLOT_LEN;
102 lenfooter = SLOT_LEN;
103 }
104 else
105 {
106 proceed[ curp ] = lzge_slot( lzge, len, offset, &footer,
107 &lenfooter );
108 }
109 huf_incfreq( &huf, proceed[ curp++ ] );
110 // if ( lenbits[ lenfooter ])
111 // {
112 proceed[ curp ] = len - lenmin[ lenfooter ];
113 proceed[ curp++ ] |= lenbits[ lenfooter ] << 24;
114 // }
115 if ( len > lenmax[ SLOT_LEN - 1 ])
116 {
117 proceed[ curp ] = offset;
118 proceed[ curp++ ] |= lzge->maxbit << 24;
119 }
120 else
121 {
122 //footer = lzge->mft[ 0 ];
123 proceed[ curp ] = offset - rngmin[ footer ];
124 proceed[ curp++ ] |= rngbits[ footer ] << 24;
125 }
126 // if ( size - (end - in) < 700 )
127 // printf("%i cur=%i len=%i\n", numblock, size - (end - in), len );
128 // if ( curp < 160 )
129 // printf("Cur=%i Offset = %i len= %i\n", size - (end - in), offset, len );
130 /* printf("<%i: %i :", offset, len );
131 while ( len-- )
132 {
133 printf("%c", *in++ );
134 }
135 printf(">");*/
136 }
137 numblock++;
138 in += len;
139
140 // if ( !( size - ( end - in ) & 0xFFF ))
141 // fgeauser( GUProcess, size - ( end - in ), 0 );
142
143 if ( numblock == lzge->hufblock || in == end )
144 {
145 // printf("Rebuild=%i %i-------------\n", numblock, lzge->hufblock);
146 huf_build( &huf );
147
148 ip = 0;
149 while ( ip < curp )
150 {
151 huf_outbits( &huf, proceed[ ip ] );
152 if ( proceed[ ip ] >= LZGE_ALPHABET )
153 {
154 // Упаковываем длину
155 if ( proceed[ ++ip ] >> 24 )
156 huf_packnum( &huf, proceed[ ip ] & 0xFFFFFF, proceed[ ip ] >> 24 );
157 // if ( ip < 120 )
158 // {
159 // printf("off = %i len=%i\n", proceed[ ip + 1 ] & 0xFFFFFF, proceed[ ip ] & 0xFFFFFF );
160 // }
161 // Упаковываем смещение
162 if ( proceed[ ++ip ] >> 24 )
163 huf_packnum( &huf, proceed[ ip ] & 0xFFFFFF, proceed[ ip ] >> 24 );
164 }
165 ip++;
166 }
167 fgeauser( size - ( end - in ) - lzge->solidoff,
168 lzge->userfunc, lzge->pgeaparam );
169 curp = 0;
170 numblock = 0;
171 }
172 }
173 // printf("OK=%i %i\n", ok, bits >> 3 );
174 // Записываем последний символ
175 if ( huf.bit )
176 *huf.ptr++ <<= 8 - huf.bit;
177
178 size = huf.ptr - out;
179 match_destroy( &match );
180 huf_destroy( &huf );
181 // fgeauser( GUProcess, size, 0 );
182
183 return size;
184 }
185
186 //--------------------------------------------------------------------------
187
188