KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > h2 > compress > CompressLZF


1 /*
2  * Copyright 2004-2006 H2 Group. Licensed under the H2 License, Version 1.0 (http://h2database.com/html/license.html).
3  * Copyright (c) 2000-2005 Marc Alexander Lehmann <schmorp@schmorp.de>
4  * Copyright (c) 2005 Oren J. Maurice <oymaurice@hazorea.org.il>
5  *
6  * Redistribution and use in source and binary forms, with or without modifica-
7  * tion, are permitted provided that the following conditions are met:
8  *
9  * 1. Redistributions of source code must retain the above copyright notice,
10  * this list of conditions and the following disclaimer.
11  *
12  * 2. Redistributions in binary form must reproduce the above copyright
13  * notice, this list of conditions and the following disclaimer in the
14  * documentation and/or other materials provided with the distribution.
15  *
16  * 3. The name of the author may not be used to endorse or promote products
17  * derived from this software without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
20  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER-
21  * CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
22  * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE-
23  * CIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
25  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
26  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH-
27  * ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
28  * OF THE POSSIBILITY OF SUCH DAMAGE.
29  *
30  * Alternatively, the contents of this file may be used under the terms of
31  * the GNU General Public License version 2 (the "GPL"), in which case the
32  * provisions of the GPL are applicable instead of the above. If you wish to
33  * allow the use of your version of this file only under the terms of the
34  * GPL and not to allow others to use your version of this file under the
35  * BSD license, indicate your decision by deleting the provisions above and
36  * replace them with the notice and other provisions required by the GPL. If
37  * you do not delete the provisions above, a recipient may use your version
38  * of this file under either the BSD or the GPL.
39  */

40
41 package org.h2.compress;
42
43 public class CompressLZF implements Compresser {
44
45     public void setOptions(String JavaDoc options) {
46     }
47     
48     public int getAlgorithm() {
49         return Compresser.LZF;
50     }
51     
52     static final int HLOG = 14;
53     static final int HASH_SIZE = (1 << 14);
54     static final int MAX_LITERAL = (1 << 5);
55     static final int MAX_OFF = (1 << 13);
56     static final int MAX_REF = ((1 << 8) + (1 << 3));
57
58     int first(byte[] in, int inPos) {
59         return (in[inPos] << 8) + (in[inPos + 1] & 255);
60     }
61
62     int next(int v, byte[] in, int inPos) {
63         return (v << 8) + (in[inPos + 2] & 255);
64     }
65
66     int hash(int h) {
67         // or 57321
68
return ((h * 184117) >> 9) & (HASH_SIZE - 1);
69     }
70
71     private int[] hashTab;
72     private static int[] empty = new int[HASH_SIZE];
73
74     public int compress(byte[] in, int inLen, byte[] out, int outPos) {
75         int inPos = 0;
76         if(hashTab == null) {
77             hashTab = new int[HASH_SIZE];
78         } else {
79             System.arraycopy(empty, 0, hashTab, 0, HASH_SIZE);
80         }
81         int literals = 0;
82         int hval = first(in, inPos);
83         while (true) {
84             if (inPos < inLen - 4) {
85                 hval = next(hval, in, inPos);
86                 int off = hash(hval);
87                 int ref = hashTab[off];
88                 hashTab[off] = inPos;
89                 off = inPos - ref - 1;
90                 if (off < MAX_OFF && ref > 0 && in[ref + 2] == in[inPos + 2] && in[ref + 1] == in[inPos + 1] && in[ref] == in[inPos]) {
91                     int maxlen = inLen - inPos - 2;
92                     maxlen = maxlen > MAX_REF ? MAX_REF : maxlen;
93                     int len = 3;
94                     while (len < maxlen && in[ref + len] == in[inPos + len]) {
95                         len++;
96                     }
97                     len -= 2;
98                     if (literals != 0) {
99                         out[outPos++] = (byte) (literals - 1);
100                         literals = -literals;
101                         do {
102                             out[outPos++] = in[inPos + literals++];
103                         } while (literals != 0);
104                     }
105                     if (len < 7) {
106                         out[outPos++] = (byte) ((off >> 8) + (len << 5));
107                     } else {
108                         out[outPos++] = (byte) ((off >> 8) + (7 << 5));
109                         out[outPos++] = (byte) (len - 7);
110                     }
111                     out[outPos++] = (byte) off;
112                     inPos += len;
113                     hval = first(in, inPos);
114                     hval = next(hval, in, inPos);
115                     hashTab[hash(hval)] = inPos++;
116                     hval = next(hval, in, inPos);
117                     hashTab[hash(hval)] = inPos++;
118                     continue;
119                 }
120             } else if (inPos == inLen) {
121                 break;
122             }
123             inPos++;
124             literals++;
125             if (literals == MAX_LITERAL) {
126                 out[outPos++] = (byte) (literals - 1);
127                 literals = -literals;
128                 do {
129                     out[outPos++] = in[inPos + literals++];
130                 } while (literals != 0);
131             }
132         }
133         if (literals != 0) {
134             out[outPos++] = (byte) (literals - 1);
135             literals = -literals;
136             do {
137                 out[outPos++] = in[inPos + literals++];
138             } while (literals != 0);
139         }
140         return outPos;
141     }
142
143     public void expand(byte[] in, int inPos, int inLen, byte[] out, int outPos, int outLen) {
144         do {
145             int ctrl = in[inPos++] & 255;
146             if (ctrl < (1 << 5)) {
147                 // literal run
148
ctrl += inPos;
149                 do {
150                     out[outPos++] = in[inPos];
151                 } while (inPos++ < ctrl);
152             } else {
153                 // back reference
154
int len = ctrl >> 5;
155                 int ref = -((ctrl & 0x1f) << 8) - 1;
156                 if (len == 7) {
157                     len += in[inPos++] & 255;
158                 }
159                 ref -= in[inPos++] & 255;
160                 len += outPos + 2;
161                 out[outPos] = out[outPos++ + ref];
162                 out[outPos] = out[outPos++ + ref];
163                 while (outPos < len - 8) {
164                     out[outPos] = out[outPos++ + ref];
165                     out[outPos] = out[outPos++ + ref];
166                     out[outPos] = out[outPos++ + ref];
167                     out[outPos] = out[outPos++ + ref];
168                     out[outPos] = out[outPos++ + ref];
169                     out[outPos] = out[outPos++ + ref];
170                     out[outPos] = out[outPos++ + ref];
171                     out[outPos] = out[outPos++ + ref];
172                 }
173                 while (outPos < len) {
174                     out[outPos] = out[outPos++ + ref];
175                 }
176             }
177         } while (outPos < outLen);
178     }
179 }
180
181
182
Popular Tags