2 * Copyright (C) 2004-2008 Geometer Plus <contact@geometerplus.com>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
22 #include <ZLInputStream.h>
24 #include "DocDecompressor.h"
26 static unsigned char TOKEN_CODE
[256] = {
27 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0,
28 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
29 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
30 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
31 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
32 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
33 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
34 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
35 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
36 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
37 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
38 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
39 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
40 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
41 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
42 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
45 size_t DocDecompressor::decompress(ZLInputStream
&stream
, char *targetBuffer
, size_t compressedSize
, size_t maxUncompressedSize
) {
46 const unsigned char *sourceBuffer
= new unsigned char[compressedSize
];
47 const unsigned char *sourceBufferEnd
= sourceBuffer
+ compressedSize
;
48 const unsigned char *sourcePtr
= sourceBuffer
;
50 unsigned char *targetBufferEnd
= (unsigned char*)targetBuffer
+ maxUncompressedSize
;
51 unsigned char *targetPtr
= (unsigned char*)targetBuffer
;
53 if (stream
.read((char*)sourceBuffer
, compressedSize
) == compressedSize
) {
55 unsigned short copyLength
, N
, shift
;
56 unsigned char *shifted
;
58 while ((sourcePtr
< sourceBufferEnd
) && (targetPtr
< targetBufferEnd
)) {
59 token
= *(sourcePtr
++);
60 switch (TOKEN_CODE
[token
]) {
62 *(targetPtr
++) = token
;
65 if ((sourcePtr
+ token
> sourceBufferEnd
) || (targetPtr
+ token
> targetBufferEnd
)) {
68 memcpy(targetPtr
, sourcePtr
, token
);
73 if (targetPtr
+ 2 > targetBufferEnd
) {
77 *(targetPtr
++) = token
^ 0x80;
80 if (sourcePtr
+ 1 > sourceBufferEnd
) {
83 N
= 256 * token
+ *(sourcePtr
++);
84 copyLength
= (N
& 7) + 3;
85 if (targetPtr
+ copyLength
> targetBufferEnd
) {
88 shift
= (N
& 0x3fff) / 8;
89 shifted
= targetPtr
- shift
;
90 if ((char*)shifted
>= targetBuffer
) {
91 for (short i
= 0; i
< copyLength
; i
++) {
92 *(targetPtr
++) = *(shifted
++);
101 delete[] sourceBuffer
;
102 return targetPtr
- (unsigned char*)targetBuffer
;