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
39extern "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)
211static void __attribute__((__unused__))
212#else
213static void
214#endif
215DVAL_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/*
307vi:ts=4:et
308*/
309
310