Mercurial > projects > dwt2
annotate org.eclipse.swt.gtk.linux.x86/src/org/eclipse/swt/internal/image/PngDeflater.d @ 125:c43718956f21 default tip
Updated the snippets status.
author | Jacob Carlborg <doob@me.com> |
---|---|
date | Thu, 11 Aug 2011 19:55:14 +0200 |
parents | 536e43f63c81 |
children |
rev | line source |
---|---|
25 | 1 /******************************************************************************* |
2 * Copyright (c) 2000, 2008 IBM Corporation and others. | |
3 * All rights reserved. This program and the accompanying materials | |
4 * are made available under the terms of the Eclipse Public License v1.0 | |
5 * which accompanies this distribution, and is available at | |
6 * http://www.eclipse.org/legal/epl-v10.html | |
7 * | |
8 * Contributors: | |
9 * IBM Corporation - initial API and implementation | |
10 * Port to the D programming language: | |
11 * Frank Benoit <benoit@tionex.de> | |
12 *******************************************************************************/ | |
13 module org.eclipse.swt.internal.image.PngDeflater; | |
14 | |
120
536e43f63c81
Comprehensive update for Win32/Linux32 dmd-2.053/dmd-1.068+Tango-r5661
Denis Shelomovskij <verylonglogin.reg@gmail.com>
parents:
51
diff
changeset
|
15 import java.io.ByteArrayOutputStream; |
25 | 16 import java.lang.all; |
17 | |
18 public class PngDeflater { | |
19 | |
20 static const int BASE = 65521; | |
21 static const int WINDOW = 32768; | |
22 static const int MIN_LENGTH = 3; | |
23 static const int MAX_MATCHES = 32; | |
24 static const int HASH = 8209; | |
25 | |
120
536e43f63c81
Comprehensive update for Win32/Linux32 dmd-2.053/dmd-1.068+Tango-r5661
Denis Shelomovskij <verylonglogin.reg@gmail.com>
parents:
51
diff
changeset
|
26 TryConst!(byte)[] istr; |
25 | 27 int inLength; |
28 | |
29 ByteArrayOutputStream bytes; | |
30 | |
31 int adler32 = 1; | |
32 | |
33 int buffer, bitCount; | |
34 | |
35 Link[HASH] hashtable;// = new Link[HASH]; | |
36 Link[WINDOW] window;// = new Link[WINDOW]; | |
37 int nextWindow; | |
38 | |
39 public this(){ | |
40 bytes = new ByteArrayOutputStream(1024); | |
41 } | |
42 | |
43 class Link { | |
44 | |
45 int hash, value; | |
46 Link previous, next; | |
47 | |
48 this() { | |
49 | |
50 this.hash = 0; | |
51 this.value = 0; | |
52 this.previous = null; | |
53 this.next = null; | |
54 | |
55 } | |
56 | |
57 } | |
58 | |
59 static class Match { | |
60 | |
61 int length, distance; | |
62 | |
63 this(int length, int distance) { | |
64 | |
65 this.length = length; | |
66 this.distance = distance; | |
67 | |
68 } | |
69 | |
70 } | |
71 | |
72 static const short mirrorBytes[] = [ cast(short) | |
73 | |
74 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, | |
75 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0, | |
76 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8, | |
77 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8, | |
78 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4, | |
79 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4, | |
80 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec, | |
81 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc, | |
82 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2, | |
83 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2, | |
84 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea, | |
85 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa, | |
86 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6, | |
87 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6, | |
88 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee, | |
89 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe, | |
90 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1, | |
91 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1, | |
92 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9, | |
93 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9, | |
94 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5, | |
95 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5, | |
96 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed, | |
97 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd, | |
98 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3, | |
99 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3, | |
100 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb, | |
101 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb, | |
102 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7, | |
103 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7, | |
104 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef, | |
105 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff, | |
106 | |
107 ]; | |
108 | |
109 static class Code { | |
110 | |
111 int code, extraBits, min, max; | |
112 | |
113 this(int code, int extraBits, int min, int max) { | |
114 | |
115 this.code = code; | |
116 this.extraBits = extraBits; | |
117 this.min = min; | |
118 this.max = max; | |
119 | |
120 } | |
121 | |
122 } | |
123 | |
120
536e43f63c81
Comprehensive update for Win32/Linux32 dmd-2.053/dmd-1.068+Tango-r5661
Denis Shelomovskij <verylonglogin.reg@gmail.com>
parents:
51
diff
changeset
|
124 static TryConst!(Code[]) lengthCodes; |
536e43f63c81
Comprehensive update for Win32/Linux32 dmd-2.053/dmd-1.068+Tango-r5661
Denis Shelomovskij <verylonglogin.reg@gmail.com>
parents:
51
diff
changeset
|
125 static TryConst!(Code[]) distanceCodes; |
25 | 126 |
127 static this() { | |
128 lengthCodes = [ | |
129 new Code(257, 0, 3, 3), | |
130 new Code(258, 0, 4, 4), | |
131 new Code(259, 0, 5, 5), | |
132 new Code(260, 0, 6, 6), | |
133 new Code(261, 0, 7, 7), | |
134 new Code(262, 0, 8, 8), | |
135 new Code(263, 0, 9, 9), | |
136 new Code(264, 0, 10, 10), | |
137 new Code(265, 1, 11, 12), | |
138 new Code(266, 1, 13, 14), | |
139 new Code(267, 1, 15, 16), | |
140 new Code(268, 1, 17, 18), | |
141 new Code(269, 2, 19, 22), | |
142 new Code(270, 2, 23, 26), | |
143 new Code(271, 2, 27, 30), | |
144 new Code(272, 2, 31, 34), | |
145 new Code(273, 3, 35, 42), | |
146 new Code(274, 3, 43, 50), | |
147 new Code(275, 3, 51, 58), | |
148 new Code(276, 3, 59, 66), | |
149 new Code(277, 4, 67, 82), | |
150 new Code(278, 4, 83, 98), | |
151 new Code(279, 4, 99, 114), | |
152 new Code(280, 4, 115, 130), | |
153 new Code(281, 5, 131, 162), | |
154 new Code(282, 5, 163, 194), | |
155 new Code(283, 5, 195, 226), | |
156 new Code(284, 5, 227, 257), | |
157 new Code(285, 0, 258, 258)]; | |
158 | |
159 distanceCodes = [ | |
160 new Code(0, 0, 1, 1), | |
161 new Code(1, 0, 2, 2), | |
162 new Code(2, 0, 3, 3), | |
163 new Code(3, 0, 4, 4), | |
164 new Code(4, 1, 5, 6), | |
165 new Code(5, 1, 7, 8), | |
166 new Code(6, 2, 9, 12), | |
167 new Code(7, 2, 13, 16), | |
168 new Code(8, 3, 17, 24), | |
169 new Code(9, 3, 25, 32), | |
170 new Code(10, 4, 33, 48), | |
171 new Code(11, 4, 49, 64), | |
172 new Code(12, 5, 65, 96), | |
173 new Code(13, 5, 97, 128), | |
174 new Code(14, 6, 129, 192), | |
175 new Code(15, 6, 193, 256), | |
176 new Code(16, 7, 257, 384), | |
177 new Code(17, 7, 385, 512), | |
178 new Code(18, 8, 513, 768), | |
179 new Code(19, 8, 769, 1024), | |
180 new Code(20, 9, 1025, 1536), | |
181 new Code(21, 9, 1537, 2048), | |
182 new Code(22, 10, 2049, 3072), | |
183 new Code(23, 10, 3073, 4096), | |
184 new Code(24, 11, 4097, 6144), | |
185 new Code(25, 11, 6145, 8192), | |
186 new Code(26, 12, 8193, 12288), | |
187 new Code(27, 12, 12289, 16384), | |
188 new Code(28, 13, 16385, 24576), | |
189 new Code(29, 13, 24577, 32768)]; | |
190 } | |
191 | |
192 void writeShortLSB(ByteArrayOutputStream baos, int theShort) { | |
193 | |
194 byte byte1 = cast(byte) (theShort & 0xff); | |
195 byte byte2 = cast(byte) ((theShort >> 8) & 0xff); | |
196 byte[] temp = [byte1, byte2]; | |
197 baos.write(temp, 0, 2); | |
198 | |
199 } | |
200 | |
201 void writeInt(ByteArrayOutputStream baos, int theInt) { | |
202 | |
203 byte byte1 = cast(byte) ((theInt >> 24) & 0xff); | |
204 byte byte2 = cast(byte) ((theInt >> 16) & 0xff); | |
205 byte byte3 = cast(byte) ((theInt >> 8) & 0xff); | |
206 byte byte4 = cast(byte) (theInt & 0xff); | |
207 byte[] temp = [byte1, byte2, byte3, byte4]; | |
208 baos.write(temp, 0, 4); | |
209 | |
210 } | |
211 | |
212 void updateAdler(byte value) { | |
213 | |
214 int low = adler32 & 0xffff; | |
215 int high = (adler32 >> 16) & 0xffff; | |
216 int valueInt = value & 0xff; | |
217 low = (low + valueInt) % BASE; | |
218 high = (low + high) % BASE; | |
219 adler32 = (high << 16) | low; | |
220 | |
221 } | |
222 | |
120
536e43f63c81
Comprehensive update for Win32/Linux32 dmd-2.053/dmd-1.068+Tango-r5661
Denis Shelomovskij <verylonglogin.reg@gmail.com>
parents:
51
diff
changeset
|
223 int hash(in byte[] bytes) { |
25 | 224 |
225 int hash = ((bytes[0] & 0xff) << 24 | (bytes[1] & 0xff) << 16 | (bytes[2] & 0xff) << 8) % HASH; | |
226 if (hash < 0) { | |
227 hash = hash + HASH; | |
228 } | |
229 return hash; | |
230 | |
231 } | |
232 | |
233 void writeBits(int value, int count) { | |
234 | |
235 buffer |= value << bitCount; | |
236 bitCount += count; | |
237 if (bitCount >= 16) { | |
238 bytes.write(cast(byte) buffer); | |
239 bytes.write(cast(byte) (buffer >>> 8)); | |
240 buffer >>>= 16; | |
241 bitCount -= 16; | |
242 } | |
243 | |
244 } | |
245 | |
246 void alignToByte() { | |
247 | |
248 if (bitCount > 0) { | |
249 bytes.write(cast(byte) buffer); | |
250 if (bitCount > 8) bytes.write(cast(byte) (buffer >>> 8)); | |
251 } | |
252 buffer = 0; | |
253 bitCount = 0; | |
254 | |
255 } | |
256 | |
257 void outputLiteral(byte literal) { | |
258 | |
259 int i = literal & 0xff; | |
260 | |
261 if (i <= 143) { | |
262 // 0 through 143 are 8 bits long starting at 00110000 | |
263 writeBits(mirrorBytes[0x30 + i], 8); | |
264 } | |
265 else { | |
266 // 144 through 255 are 9 bits long starting at 110010000 | |
267 writeBits(1 + 2 * mirrorBytes[0x90 - 144 + i], 9); | |
268 } | |
269 | |
270 } | |
271 | |
120
536e43f63c81
Comprehensive update for Win32/Linux32 dmd-2.053/dmd-1.068+Tango-r5661
Denis Shelomovskij <verylonglogin.reg@gmail.com>
parents:
51
diff
changeset
|
272 TryConst!(Code) findCode(int value, in Code[] codes) { |
25 | 273 |
274 int i, j, k; | |
275 | |
276 i = -1; | |
277 j = codes.length; | |
278 while (true) { | |
279 k = (j + i) / 2; | |
280 if (value < codes[k].min) { | |
281 j = k; | |
282 } | |
283 else if (value > codes[k].max) { | |
284 i = k; | |
285 } | |
286 else { | |
287 return codes[k]; | |
288 } | |
289 } | |
290 | |
291 } | |
292 | |
293 void outputMatch(int length, int distance) { | |
294 | |
295 int thisLength; | |
296 | |
297 while (length > 0) { | |
298 | |
299 // we can transmit matches of lengths 3 through 258 inclusive | |
300 // so if length exceeds 258, we must transmit in several steps, | |
301 // with 258 or less in each step | |
302 | |
303 if (length > 260) { | |
304 thisLength = 258; | |
305 } | |
306 else if (length <= 258) { | |
307 thisLength = length; | |
308 } | |
309 else { | |
310 thisLength = length - 3; | |
311 } | |
312 | |
313 length = length - thisLength; | |
314 | |
315 // find length code | |
120
536e43f63c81
Comprehensive update for Win32/Linux32 dmd-2.053/dmd-1.068+Tango-r5661
Denis Shelomovskij <verylonglogin.reg@gmail.com>
parents:
51
diff
changeset
|
316 auto l = findCode(thisLength, lengthCodes); |
25 | 317 |
318 // transmit the length code | |
319 // 256 through 279 are 7 bits long starting at 0000000 | |
320 // 280 through 287 are 8 bits long starting at 11000000 | |
321 if (l.code <= 279) { | |
322 writeBits(mirrorBytes[(l.code - 256) * 2], 7); | |
323 } | |
324 else { | |
325 writeBits(mirrorBytes[0xc0 - 280 + l.code], 8); | |
326 } | |
327 | |
328 // transmit the extra bits | |
329 if (l.extraBits !is 0) { | |
330 writeBits(thisLength - l.min, l.extraBits); | |
331 } | |
332 | |
333 // find distance code | |
120
536e43f63c81
Comprehensive update for Win32/Linux32 dmd-2.053/dmd-1.068+Tango-r5661
Denis Shelomovskij <verylonglogin.reg@gmail.com>
parents:
51
diff
changeset
|
334 auto d = findCode(distance, distanceCodes); |
25 | 335 |
336 // transmit the distance code | |
337 // 5 bits long starting at 00000 | |
338 writeBits(mirrorBytes[d.code * 8], 5); | |
339 | |
340 // transmit the extra bits | |
341 if (d.extraBits !is 0) { | |
342 writeBits(distance - d.min, d.extraBits); | |
343 } | |
344 | |
345 } | |
346 | |
347 } | |
348 | |
349 Match findLongestMatch(int position, Link firstPosition) { | |
350 | |
351 Link link = firstPosition; | |
352 int numberOfMatches = 0; | |
353 Match bestMatch = new Match(-1, -1); | |
354 | |
355 while (true) { | |
356 | |
357 int matchPosition = link.value; | |
358 | |
359 if (position - matchPosition < WINDOW && matchPosition !is 0) { | |
360 | |
361 int i; | |
362 | |
363 for (i = 1; position + i < inLength; i++) { | |
364 if (istr[position + i] !is istr[matchPosition + i]) { | |
365 break; | |
366 } | |
367 } | |
368 | |
369 if (i >= MIN_LENGTH) { | |
370 | |
371 if (i > bestMatch.length) { | |
372 bestMatch.length = i; | |
373 bestMatch.distance = position - matchPosition; | |
374 } | |
375 | |
376 numberOfMatches = numberOfMatches + 1; | |
377 | |
378 if (numberOfMatches is MAX_MATCHES) { | |
379 break; | |
380 } | |
381 | |
382 } | |
383 | |
384 } | |
385 | |
386 link = link.next; | |
387 if (link is null) { | |
388 break; | |
389 } | |
390 | |
391 } | |
392 | |
393 if (bestMatch.length < MIN_LENGTH || bestMatch.distance < 1 || bestMatch.distance > WINDOW) { | |
394 return null; | |
395 } | |
396 | |
397 return bestMatch; | |
398 | |
399 } | |
400 | |
401 void updateHashtable(int to, int from) { | |
402 | |
403 byte[] data = new byte[3]; | |
404 int hashval; | |
405 Link temp; | |
406 | |
407 for (int i = to; i < from; i++) { | |
408 | |
409 if (i + MIN_LENGTH > inLength) { | |
410 break; | |
411 } | |
412 | |
413 data[0] = istr[i]; | |
414 data[1] = istr[i + 1]; | |
415 data[2] = istr[i + 2]; | |
416 | |
417 hashval = hash(data); | |
418 | |
419 if (window[nextWindow].previous !is null) { | |
420 window[nextWindow].previous.next = null; | |
421 } | |
422 else if (window[nextWindow].hash !is 0) { | |
423 hashtable[window[nextWindow].hash].next = null; | |
424 } | |
425 | |
426 window[nextWindow].hash = hashval; | |
427 window[nextWindow].value = i; | |
428 window[nextWindow].previous = null; | |
429 temp = window[nextWindow].next = hashtable[hashval].next; | |
430 hashtable[hashval].next = window[nextWindow]; | |
431 if (temp !is null) { | |
432 temp.previous = window[nextWindow]; | |
433 } | |
434 | |
435 nextWindow = nextWindow + 1; | |
436 if (nextWindow is WINDOW) { | |
437 nextWindow = 0; | |
438 } | |
439 | |
440 } | |
441 | |
442 } | |
443 | |
444 void compress() { | |
445 | |
446 int position, newPosition; | |
447 byte[] data = new byte[3]; | |
448 int hashval; | |
449 for (int i = 0; i < HASH; i++) { | |
450 hashtable[i] = new Link(); | |
451 } | |
452 for (int i = 0; i < WINDOW; i++) { | |
453 window[i] = new Link(); | |
454 } | |
455 nextWindow = 0; | |
456 Link firstPosition; | |
457 Match match; | |
458 int deferredPosition = -1; | |
459 Match deferredMatch = null; | |
460 | |
461 writeBits(0x01, 1); // BFINAL = 0x01 (final block) | |
462 writeBits(0x01, 2); // BTYPE = 0x01 (compression with fixed Huffman codes) | |
463 | |
464 // just output first byte so we never match at zero | |
465 outputLiteral(istr[0]); | |
466 position = 1; | |
467 | |
468 while (position < inLength) { | |
469 | |
470 if (inLength - position < MIN_LENGTH) { | |
471 outputLiteral(istr[position]); | |
472 position = position + 1; | |
473 continue; | |
474 } | |
475 | |
476 data[0] = istr[position]; | |
477 data[1] = istr[position + 1]; | |
478 data[2] = istr[position + 2]; | |
479 | |
480 hashval = hash(data); | |
481 firstPosition = hashtable[hashval]; | |
482 | |
483 match = findLongestMatch(position, firstPosition); | |
484 | |
485 updateHashtable(position, position + 1); | |
486 | |
487 if (match !is null) { | |
488 | |
489 if (deferredMatch !is null) { | |
490 if (match.length > deferredMatch.length + 1) { | |
491 // output literal at deferredPosition | |
492 outputLiteral(istr[deferredPosition]); | |
493 // defer this match | |
494 deferredPosition = position; | |
495 deferredMatch = match; | |
496 position = position + 1; | |
497 } | |
498 else { | |
499 // output deferredMatch | |
500 outputMatch(deferredMatch.length, deferredMatch.distance); | |
501 newPosition = deferredPosition + deferredMatch.length; | |
502 deferredPosition = -1; | |
503 deferredMatch = null; | |
504 updateHashtable(position + 1, newPosition); | |
505 position = newPosition; | |
506 } | |
507 } | |
508 else { | |
509 // defer this match | |
510 deferredPosition = position; | |
511 deferredMatch = match; | |
512 position = position + 1; | |
513 } | |
514 | |
515 } | |
516 | |
517 else { | |
518 | |
519 // no match found | |
520 if (deferredMatch !is null) { | |
521 outputMatch(deferredMatch.length, deferredMatch.distance); | |
522 newPosition = deferredPosition + deferredMatch.length; | |
523 deferredPosition = -1; | |
524 deferredMatch = null; | |
525 updateHashtable(position + 1, newPosition); | |
526 position = newPosition; | |
527 } | |
528 else { | |
529 outputLiteral(istr[position]); | |
530 position = position + 1; | |
531 } | |
532 | |
533 } | |
534 | |
535 } | |
536 | |
537 writeBits(0, 7); // end of block code | |
538 alignToByte(); | |
539 | |
540 } | |
541 | |
542 void compressHuffmanOnly() { | |
543 | |
544 int position; | |
545 | |
546 writeBits(0x01, 1); // BFINAL = 0x01 (final block) | |
547 writeBits(0x01, 2); // BTYPE = 0x01 (compression with fixed Huffman codes) | |
548 | |
549 for (position = 0; position < inLength;) { | |
550 | |
551 outputLiteral(istr[position]); | |
552 position = position + 1; | |
553 | |
554 } | |
555 | |
556 writeBits(0, 7); // end of block code | |
557 alignToByte(); | |
558 | |
559 } | |
560 | |
561 void store() { | |
562 | |
563 // stored blocks are limited to 0xffff bytes | |
564 | |
565 int start = 0; | |
566 int length = inLength; | |
567 int blockLength; | |
568 int BFINAL = 0x00; // BFINAL = 0x00 or 0x01 (if final block), BTYPE = 0x00 (no compression) | |
569 | |
570 while (length > 0) { | |
571 | |
572 if (length < 65535) { | |
573 blockLength = length; | |
574 BFINAL = 0x01; | |
575 } | |
576 else { | |
577 blockLength = 65535; | |
578 BFINAL = 0x00; | |
579 } | |
580 | |
581 // write data header | |
582 bytes.write(cast(byte) BFINAL); | |
583 writeShortLSB(bytes, blockLength); // LEN | |
584 writeShortLSB(bytes, blockLength ^ 0xffff); // NLEN (one's complement of LEN) | |
585 | |
586 // write actual data | |
587 bytes.write(istr, start, blockLength); | |
588 | |
589 length = length - blockLength; | |
590 start = start + blockLength; | |
591 | |
592 } | |
593 | |
594 } | |
595 | |
120
536e43f63c81
Comprehensive update for Win32/Linux32 dmd-2.053/dmd-1.068+Tango-r5661
Denis Shelomovskij <verylonglogin.reg@gmail.com>
parents:
51
diff
changeset
|
596 public byte[] deflate(in byte[] input) { |
25 | 597 |
598 istr = input; | |
599 inLength = input.length; | |
600 | |
601 // write zlib header | |
602 bytes.write(cast(byte) 0x78); // window size = 0x70 (32768), compression method = 0x08 | |
603 bytes.write(cast(byte) 0x9C); // compression level = 0x80 (default), check bits = 0x1C | |
604 | |
605 // compute checksum | |
606 for (int i = 0; i < inLength; i++) { | |
607 updateAdler(istr[i]); | |
608 } | |
609 | |
610 //store(); | |
611 | |
612 //compressHuffmanOnly(); | |
613 | |
614 compress(); | |
615 | |
616 // write checksum | |
617 writeInt(bytes, adler32); | |
618 | |
619 return bytes.toByteArray(); | |
620 | |
621 } | |
622 | |
623 } |