Krita Source Code Documentation
Loading...
Searching...
No Matches
kis_lzf_compression.cpp File Reference
#include "kis_lzf_compression.h"
#include "kis_debug.h"

Go to the source code of this file.

Macros

#define HASH_LOG   12
 
#define HASH_MASK   (HASH_SIZE-1)
 
#define HASH_SIZE   (1<< HASH_LOG)
 
#define MAX_COPY   32
 
#define MAX_DISTANCE   8192
 
#define MAX_LEN   264 /* 256 + 8 */
 
#define UPDATE_HASH(v, p)   { v = *((quint16*)p); v ^= *((quint16*)(p+1))^(v>>(16-HASH_LOG)); }
 

Functions

int lzff_compress (const void *input, int length, void *output, int)
 
int lzff_decompress (const void *input, int length, void *output, int maxout)
 

Macro Definition Documentation

◆ HASH_LOG

#define HASH_LOG   12

Definition at line 12 of file kis_lzf_compression.cpp.

◆ HASH_MASK

#define HASH_MASK   (HASH_SIZE-1)

Definition at line 14 of file kis_lzf_compression.cpp.

◆ HASH_SIZE

#define HASH_SIZE   (1<< HASH_LOG)

Definition at line 13 of file kis_lzf_compression.cpp.

◆ MAX_COPY

#define MAX_COPY   32

Definition at line 21 of file kis_lzf_compression.cpp.

◆ MAX_DISTANCE

#define MAX_DISTANCE   8192

Definition at line 23 of file kis_lzf_compression.cpp.

◆ MAX_LEN

#define MAX_LEN   264 /* 256 + 8 */

Definition at line 22 of file kis_lzf_compression.cpp.

◆ UPDATE_HASH

#define UPDATE_HASH ( v,
p )   { v = *((quint16*)p); v ^= *((quint16*)(p+1))^(v>>(16-HASH_LOG)); }

Definition at line 19 of file kis_lzf_compression.cpp.

Function Documentation

◆ lzff_compress()

int lzff_compress ( const void * input,
int length,
void * output,
int  )

Definition at line 28 of file kis_lzf_compression.cpp.

29{
30 const quint8* ip = (const quint8*) input;
31 const quint8* ip_limit = ip + length - MAX_COPY - 4;
32 quint8* op = (quint8*) output;
33
34 const quint8* htab[HASH_SIZE];
35 const quint8** hslot;
36 quint32 hval;
37
38 quint8* ref;
39 qint32 copy;
40 qint32 len;
41 qint32 distance;
42 quint8* anchor;
43
44 /* initializes hash table */
45 for (hslot = htab; hslot < htab + HASH_SIZE; hslot++)
46 *hslot = ip;
47
48 /* we start with literal copy */
49 copy = 0;
50 *op++ = MAX_COPY - 1;
51
52 /* main loop */
53 while (ip < ip_limit) {
54 /* find potential match */
55 UPDATE_HASH(hval, ip);
56 hslot = htab + (hval & HASH_MASK);
57 ref = (quint8*) * hslot;
58
59 /* update hash table */
60 *hslot = ip;
61
62 /* find itself? then it's no match */
63 if (ip == ref)
64 goto literal;
65
66 /* is this a match? check the first 2 bytes */
67 if (*((quint16*)ref) != *((quint16*)ip))
68 goto literal;
69
70 /* now check the 3rd byte */
71 if (ref[2] != ip[2])
72 goto literal;
73
74 /* calculate distance to the match */
75 distance = ip - ref;
76
77 /* skip if too far away */
79 goto literal;
80
81 /* here we have 3-byte matches */
82 anchor = (quint8*)ip;
83 len = 3;
84 ref += 3;
85 ip += 3;
86
87 /* now we have to check how long the match is */
88 if (ip < ip_limit - MAX_LEN) {
89 while (len < MAX_LEN - 8) {
90 /* unroll 8 times */
91 if (*ref++ != *ip++) break;
92 if (*ref++ != *ip++) break;
93 if (*ref++ != *ip++) break;
94 if (*ref++ != *ip++) break;
95 if (*ref++ != *ip++) break;
96 if (*ref++ != *ip++) break;
97 if (*ref++ != *ip++) break;
98 if (*ref++ != *ip++) break;
99 len += 8;
100 }
101 ip--;
102 }
103 len = ip - anchor;
104
105 /* just before the last non-matching byte */
106 ip = anchor + len;
107
108 /* if we have copied something, adjust the copy count */
109 if (copy) {
110 /* copy is biased, '0' means 1 byte copy */
111 anchor = anchor - copy - 1;
112 *(op - copy - 1) = copy - 1;
113 copy = 0;
114 } else
115 /* back, to overwrite the copy count */
116 op--;
117
118 /* length is biased, '1' means a match of 3 bytes */
119 len -= 2;
120
121 /* distance is also biased */
122 distance--;
123
124 /* encode the match */
125 if (len < 7)
126 *op++ = (len << 5) + (distance >> 8);
127 else {
128 *op++ = (7 << 5) + (distance >> 8);
129 *op++ = len - 7;
130 }
131 *op++ = (distance & 255);
132
133 /* assuming next will be literal copy */
134 *op++ = MAX_COPY - 1;
135
136 /* update the hash at match boundary */
137 --ip;
138 UPDATE_HASH(hval, ip);
139 htab[hval & HASH_MASK] = ip;
140 ip++;
141
142 continue;
143
144 literal:
145 *op++ = *ip++;
146 copy++;
147 if (copy >= MAX_COPY) {
148 copy = 0;
149 *op++ = MAX_COPY - 1;
150 }
151 }
152
153 /* left-over as literal copy */
154 ip_limit = (const quint8*)input + length;
155 while (ip < ip_limit) {
156 *op++ = *ip++;
157 copy++;
158 if (copy == MAX_COPY) {
159 copy = 0;
160 *op++ = MAX_COPY - 1;
161 }
162 }
163
164 /* if we have copied something, adjust the copy length */
165 if (copy)
166 *(op - copy - 1) = copy - 1;
167 else
168 op--;
169
170 return op - (quint8*)output;
171}
qreal length(const QPointF &vec)
Definition Ellipse.cc:82
qreal distance(const QPointF &p1, const QPointF &p2)
#define MAX_DISTANCE
#define HASH_MASK
#define MAX_COPY
#define MAX_LEN
#define UPDATE_HASH(v, p)
#define HASH_SIZE

References distance(), HASH_MASK, HASH_SIZE, length(), MAX_COPY, MAX_DISTANCE, MAX_LEN, and UPDATE_HASH.

◆ lzff_decompress()

int lzff_decompress ( const void * input,
int length,
void * output,
int maxout )

Definition at line 173 of file kis_lzf_compression.cpp.

174{
175 const quint8* ip = (const quint8*) input;
176 const quint8* ip_limit = ip + length - 1;
177 quint8* op = (quint8*) output;
178 quint8* op_limit = op + maxout;
179 quint8* ref;
180
181 while (ip < ip_limit) {
182 quint32 ctrl = (*ip) + 1;
183 quint32 ofs = ((*ip) & 31) << 8;
184 quint32 len = (*ip++) >> 5;
185
186 if (ctrl < 33) {
187 /* literal copy */
188 if (op + ctrl > op_limit)
189 return 0;
190
191 /* crazy unrolling */
192 if (ctrl) {
193 *op++ = *ip++;
194 ctrl--;
195
196 if (ctrl) {
197 *op++ = *ip++;
198 ctrl--;
199
200 if (ctrl) {
201 *op++ = *ip++;
202 ctrl--;
203
204 for (; ctrl; ctrl--)
205 *op++ = *ip++;
206 }
207 }
208 }
209 } else {
210 /* back reference */
211 len--;
212 ref = op - ofs;
213 ref--;
214
215 if (len == 7 - 1)
216 len += *ip++;
217
218 ref -= *ip++;
219
220 if (op + len + 3 > op_limit)
221 return 0;
222
223 if (ref < (quint8 *)output)
224 return 0;
225
226 *op++ = *ref++;
227 *op++ = *ref++;
228 *op++ = *ref++;
229 if (len)
230 for (; len; --len)
231 *op++ = *ref++;
232 }
233 }
234
235 return op - (quint8*)output;
236}

References length().