1 /* lzo_dict.h -- dictionary definitions for the the LZO library
2 
3    This file is part of the LZO real-time data compression library.
4 
5    Copyright (C) 1996-2014 Markus Franz Xaver Johannes Oberhumer
6    All Rights Reserved.
7 
8    The LZO library is free software; you can redistribute it and/or
9    modify it under the terms of the GNU General Public License as
10    published by the Free Software Foundation; either version 2 of
11    the License, or (at your option) any later version.
12 
13    The LZO library is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17 
18    You should have received a copy of the GNU General Public License
19    along with the LZO library; see the file COPYING.
20    If not, write to the Free Software Foundation, Inc.,
21    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
22 
23    Markus F.X.J. Oberhumer
24    <markus@oberhumer.com>
25    http://www.oberhumer.com/opensource/lzo/
26  */
27 
28 
29 /* WARNING: this file should *not* be used by applications. It is
30    part of the implementation of the library and is subject
31    to change.
32  */
33 
34 
35 #ifndef __LZO_DICT_H
36 #define __LZO_DICT_H 1
37 
38 #ifdef __cplusplus
39 extern "C" {
40 #endif
41 
42 
43 
44 /***********************************************************************
45 // dictionary size
46 ************************************************************************/
47 
48 /* dictionary needed for compression */
49 #if !defined(D_BITS) && defined(DBITS)
50 #  define D_BITS        DBITS
51 #endif
52 #if !defined(D_BITS)
53 #  error "D_BITS is not defined"
54 #endif
55 #if (D_BITS < 16)
56 #  define D_SIZE        LZO_SIZE(D_BITS)
57 #  define D_MASK        LZO_MASK(D_BITS)
58 #else
59 #  define D_SIZE        LZO_USIZE(D_BITS)
60 #  define D_MASK        LZO_UMASK(D_BITS)
61 #endif
62 #define D_HIGH          ((D_MASK >> 1) + 1)
63 
64 
65 /* dictionary depth */
66 #if !defined(DD_BITS)
67 #  define DD_BITS       0
68 #endif
69 #define DD_SIZE         LZO_SIZE(DD_BITS)
70 #define DD_MASK         LZO_MASK(DD_BITS)
71 
72 /* dictionary length */
73 #if !defined(DL_BITS)
74 #  define DL_BITS       (D_BITS - DD_BITS)
75 #endif
76 #if (DL_BITS < 16)
77 #  define DL_SIZE       LZO_SIZE(DL_BITS)
78 #  define DL_MASK       LZO_MASK(DL_BITS)
79 #else
80 #  define DL_SIZE       LZO_USIZE(DL_BITS)
81 #  define DL_MASK       LZO_UMASK(DL_BITS)
82 #endif
83 
84 
85 #if (D_BITS != DL_BITS + DD_BITS)
86 #  error "D_BITS does not match"
87 #endif
88 #if (D_BITS < 6 || D_BITS > 18)
89 #  error "invalid D_BITS"
90 #endif
91 #if (DL_BITS < 6 || DL_BITS > 20)
92 #  error "invalid DL_BITS"
93 #endif
94 #if (DD_BITS < 0 || DD_BITS > 6)
95 #  error "invalid DD_BITS"
96 #endif
97 
98 
99 #if !defined(DL_MIN_LEN)
100 #  define DL_MIN_LEN    3
101 #endif
102 #if !defined(DL_SHIFT)
103 #  define DL_SHIFT      ((DL_BITS + (DL_MIN_LEN - 1)) / DL_MIN_LEN)
104 #endif
105 
106 
107 
108 /***********************************************************************
109 // dictionary access
110 ************************************************************************/
111 
112 #define LZO_HASH_GZIP                   1
113 #define LZO_HASH_GZIP_INCREMENTAL       2
114 #define LZO_HASH_LZO_INCREMENTAL_A      3
115 #define LZO_HASH_LZO_INCREMENTAL_B      4
116 
117 #if !defined(LZO_HASH)
118 #  error "choose a hashing strategy"
119 #endif
120 
121 #undef DM
122 #undef DX
123 
124 #if (DL_MIN_LEN == 3)
125 #  define _DV2_A(p,shift1,shift2) \
126         (((( (lzo_xint)((p)[0]) << shift1) ^ (p)[1]) << shift2) ^ (p)[2])
127 #  define _DV2_B(p,shift1,shift2) \
128         (((( (lzo_xint)((p)[2]) << shift1) ^ (p)[1]) << shift2) ^ (p)[0])
129 #  define _DV3_B(p,shift1,shift2,shift3) \
130         ((_DV2_B((p)+1,shift1,shift2) << (shift3)) ^ (p)[0])
131 #elif (DL_MIN_LEN == 2)
132 #  define _DV2_A(p,shift1,shift2) \
133         (( (lzo_xint)(p[0]) << shift1) ^ p[1])
134 #  define _DV2_B(p,shift1,shift2) \
135         (( (lzo_xint)(p[1]) << shift1) ^ p[2])
136 #else
137 #  error "invalid DL_MIN_LEN"
138 #endif
139 #define _DV_A(p,shift)      _DV2_A(p,shift,shift)
140 #define _DV_B(p,shift)      _DV2_B(p,shift,shift)
141 #define DA2(p,s1,s2) \
142         (((((lzo_xint)((p)[2]) << (s2)) + (p)[1]) << (s1)) + (p)[0])
143 #define DS2(p,s1,s2) \
144         (((((lzo_xint)((p)[2]) << (s2)) - (p)[1]) << (s1)) - (p)[0])
145 #define DX2(p,s1,s2) \
146         (((((lzo_xint)((p)[2]) << (s2)) ^ (p)[1]) << (s1)) ^ (p)[0])
147 #define DA3(p,s1,s2,s3) ((DA2((p)+1,s2,s3) << (s1)) + (p)[0])
148 #define DS3(p,s1,s2,s3) ((DS2((p)+1,s2,s3) << (s1)) - (p)[0])
149 #define DX3(p,s1,s2,s3) ((DX2((p)+1,s2,s3) << (s1)) ^ (p)[0])
150 #define DMS(v,s)        ((lzo_uint) (((v) & (D_MASK >> (s))) << (s)))
151 #define DM(v)           DMS(v,0)
152 
153 
154 #if (LZO_HASH == LZO_HASH_GZIP)
155    /* hash function like in gzip/zlib (deflate) */
156 #  define _DINDEX(dv,p)     (_DV_A((p),DL_SHIFT))
157 
158 #elif (LZO_HASH == LZO_HASH_GZIP_INCREMENTAL)
159    /* incremental hash like in gzip/zlib (deflate) */
160 #  define __LZO_HASH_INCREMENTAL 1
161 #  define DVAL_FIRST(dv,p)  dv = _DV_A((p),DL_SHIFT)
162 #  define DVAL_NEXT(dv,p)   dv = (((dv) << DL_SHIFT) ^ p[2])
163 #  define _DINDEX(dv,p)     (dv)
164 #  define DVAL_LOOKAHEAD    DL_MIN_LEN
165 
166 #elif (LZO_HASH == LZO_HASH_LZO_INCREMENTAL_A)
167    /* incremental LZO hash version A */
168 #  define __LZO_HASH_INCREMENTAL 1
169 #  define DVAL_FIRST(dv,p)  dv = _DV_A((p),5)
170 #  define DVAL_NEXT(dv,p) \
171                 dv ^= (lzo_xint)(p[-1]) << (2*5); dv = (((dv) << 5) ^ p[2])
172 #  define _DINDEX(dv,p)     ((DMUL(0x9f5f,dv)) >> 5)
173 #  define DVAL_LOOKAHEAD    DL_MIN_LEN
174 
175 #elif (LZO_HASH == LZO_HASH_LZO_INCREMENTAL_B)
176    /* incremental LZO hash version B */
177 #  define __LZO_HASH_INCREMENTAL 1
178 #  define DVAL_FIRST(dv,p)  dv = _DV_B((p),5)
179 #  define DVAL_NEXT(dv,p) \
180                 dv ^= p[-1]; dv = (((dv) >> 5) ^ ((lzo_xint)(p[2]) << (2*5)))
181 #  define _DINDEX(dv,p)     ((DMUL(0x9f5f,dv)) >> 5)
182 #  define DVAL_LOOKAHEAD    DL_MIN_LEN
183 
184 #else
185 #  error "choose a hashing strategy"
186 #endif
187 
188 
189 #ifndef DINDEX
190 #define DINDEX(dv,p)        ((lzo_uint)((_DINDEX(dv,p)) & DL_MASK) << DD_BITS)
191 #endif
192 #if !defined(DINDEX1) && defined(D_INDEX1)
193 #define DINDEX1             D_INDEX1
194 #endif
195 #if !defined(DINDEX2) && defined(D_INDEX2)
196 #define DINDEX2             D_INDEX2
197 #endif
198 
199 
200 
201 #if !defined(__LZO_HASH_INCREMENTAL)
202 #  define DVAL_FIRST(dv,p)  ((void) 0)
203 #  define DVAL_NEXT(dv,p)   ((void) 0)
204 #  define DVAL_LOOKAHEAD    0
205 #endif
206 
207 
208 #if !defined(DVAL_ASSERT)
209 #if defined(__LZO_HASH_INCREMENTAL) && !defined(NDEBUG)
210 #if (LZO_CC_CLANG || (LZO_CC_GNUC >= 0x020700ul) || LZO_CC_LLVM)
211 static void __attribute__((__unused__))
212 #else
213 static void
214 #endif
DVAL_ASSERT(lzo_xint dv,const lzo_bytep p)215 DVAL_ASSERT(lzo_xint dv, const lzo_bytep p)
216 {
217     lzo_xint df;
218     DVAL_FIRST(df,(p));
219     assert(DINDEX(dv,p) == DINDEX(df,p));
220 }
221 #else
222 #  define DVAL_ASSERT(dv,p) ((void) 0)
223 #endif
224 #endif
225 
226 
227 
228 /***********************************************************************
229 // dictionary updating
230 ************************************************************************/
231 
232 #if (LZO_DICT_USE_PTR)
233 #  define DENTRY(p,in)                          (p)
234 #  define GINDEX(m_pos,m_off,dict,dindex,in)    m_pos = dict[dindex]
235 #else
236 #  define DENTRY(p,in)                          ((lzo_dict_t) pd(p, in))
237 #  define GINDEX(m_pos,m_off,dict,dindex,in)    m_off = dict[dindex]
238 #endif
239 
240 
241 #if (DD_BITS == 0)
242 
243 #  define UPDATE_D(dict,drun,dv,p,in)       dict[ DINDEX(dv,p) ] = DENTRY(p,in)
244 #  define UPDATE_I(dict,drun,index,p,in)    dict[index] = DENTRY(p,in)
245 #  define UPDATE_P(ptr,drun,p,in)           (ptr)[0] = DENTRY(p,in)
246 
247 #else
248 
249 #  define UPDATE_D(dict,drun,dv,p,in)   \
250         dict[ DINDEX(dv,p) + drun++ ] = DENTRY(p,in); drun &= DD_MASK
251 #  define UPDATE_I(dict,drun,index,p,in)    \
252         dict[ (index) + drun++ ] = DENTRY(p,in); drun &= DD_MASK
253 #  define UPDATE_P(ptr,drun,p,in)   \
254         (ptr) [ drun++ ] = DENTRY(p,in); drun &= DD_MASK
255 
256 #endif
257 
258 
259 /***********************************************************************
260 // test for a match
261 ************************************************************************/
262 
263 #if (LZO_DICT_USE_PTR)
264 
265 /* m_pos is either NULL or a valid pointer */
266 #define LZO_CHECK_MPOS_DET(m_pos,m_off,in,ip,max_offset) \
267         (m_pos == NULL || (m_off = pd(ip, m_pos)) > max_offset)
268 
269 /* m_pos may point anywhere... */
270 #define LZO_CHECK_MPOS_NON_DET(m_pos,m_off,in,ip,max_offset) \
271     (BOUNDS_CHECKING_OFF_IN_EXPR(( \
272         m_pos = ip - (lzo_uint) PTR_DIFF(ip,m_pos), \
273         PTR_LT(m_pos,in) || \
274         (m_off = (lzo_uint) PTR_DIFF(ip,m_pos)) == 0 || \
275          m_off > max_offset )))
276 
277 #else
278 
279 #define LZO_CHECK_MPOS_DET(m_pos,m_off,in,ip,max_offset) \
280         (m_off == 0 || \
281          ((m_off = pd(ip, in) - m_off) > max_offset) || \
282          (m_pos = (ip) - (m_off), 0) )
283 
284 #define LZO_CHECK_MPOS_NON_DET(m_pos,m_off,in,ip,max_offset) \
285         (pd(ip, in) <= m_off || \
286          ((m_off = pd(ip, in) - m_off) > max_offset) || \
287          (m_pos = (ip) - (m_off), 0) )
288 
289 #endif
290 
291 
292 #if (LZO_DETERMINISTIC)
293 #  define LZO_CHECK_MPOS    LZO_CHECK_MPOS_DET
294 #else
295 #  define LZO_CHECK_MPOS    LZO_CHECK_MPOS_NON_DET
296 #endif
297 
298 
299 
300 #ifdef __cplusplus
301 } /* extern "C" */
302 #endif
303 
304 #endif /* already included */
305 
306 /*
307 vi:ts=4:et
308 */
309 
310