1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_filter.hxx"
26 
27 #include "lzwdecom.hxx"
28 
LZWDecompressor()29 LZWDecompressor::LZWDecompressor()
30 {
31 	sal_uInt16 i;
32 
33 	pTable=new LZWTableEntry[4096];
34 	pOutBuf=new sal_uInt8[4096];
35 	for (i=0; i<4096; i++)
36 	{
37 		pTable[i].nPrevCode=0;
38 		pTable[i].nDataCount=1;
39 		pTable[i].nData=(sal_uInt8)i;
40 	}
41 	pIStream=NULL;
42 	bFirst = sal_True;
43 	nOldCode = 0;
44 }
45 
46 
~LZWDecompressor()47 LZWDecompressor::~LZWDecompressor()
48 {
49 	delete[] pOutBuf;
50 	delete[] pTable;
51 }
52 
53 
StartDecompression(SvStream & rIStream)54 void LZWDecompressor::StartDecompression(SvStream & rIStream)
55 {
56 	pIStream=&rIStream;
57 
58 	nTableSize=258;
59 
60 	bEOIFound=sal_False;
61 
62 	nOutBufDataLen=0;
63 
64 	*pIStream >> nInputBitsBuf;
65 
66 	nInputBitsBufSize=8;
67 
68 	if ( bFirst )
69 	{
70 		bInvert = nInputBitsBuf == 1;
71 		bFirst = sal_False;
72 	}
73 
74 	if ( bInvert )
75 		nInputBitsBuf = ( ( nInputBitsBuf & 1 ) << 7 ) | ( ( nInputBitsBuf & 2 ) << 5 ) | ( ( nInputBitsBuf & 4 ) << 3 ) | ( ( nInputBitsBuf & 8 ) << 1 ) | ( ( nInputBitsBuf & 16 ) >> 1 ) | ( ( nInputBitsBuf & 32 ) >> 3 ) | ( ( nInputBitsBuf & 64 ) >> 5 ) | ( (nInputBitsBuf & 128 ) >> 7 );
76 }
77 
78 
Decompress(sal_uInt8 * pTarget,sal_uLong nMaxCount)79 sal_uLong LZWDecompressor::Decompress(sal_uInt8 * pTarget, sal_uLong nMaxCount)
80 {
81 	sal_uLong nCount;
82 
83 	if (pIStream==NULL) return 0;
84 
85 	nCount=0;
86 	for (;;) {
87 
88 		if (pIStream->GetError()) break;
89 
90 		if (((sal_uLong)nOutBufDataLen)>=nMaxCount) {
91 			nOutBufDataLen = nOutBufDataLen - (sal_uInt16)nMaxCount;
92 			nCount+=nMaxCount;
93 			while (nMaxCount>0) {
94 				*(pTarget++)=*(pOutBufData++);
95 				nMaxCount--;
96 			}
97 			break;
98 		}
99 
100 		nMaxCount-=(sal_uLong)nOutBufDataLen;
101 		nCount+=nOutBufDataLen;
102 		while (nOutBufDataLen>0) {
103 			*(pTarget++)=*(pOutBufData++);
104 			nOutBufDataLen--;
105 		}
106 
107 		if (bEOIFound==sal_True) break;
108 
109 		DecompressSome();
110 
111 	}
112 
113 	return nCount;
114 }
115 
116 
GetNextCode()117 sal_uInt16 LZWDecompressor::GetNextCode()
118 {
119 	sal_uInt16 nBits,nCode;
120 
121 	if      (nTableSize<511)  nBits=9;
122 	else if (nTableSize<1023) nBits=10;
123 	else if (nTableSize<2047) nBits=11;
124 	else                      nBits=12;
125 
126 	nCode=0;
127 	do {
128 		if (nInputBitsBufSize<=nBits)
129 		{
130 			nCode=(nCode<<nInputBitsBufSize) | nInputBitsBuf;
131 			nBits = nBits - nInputBitsBufSize;
132 			*pIStream >> nInputBitsBuf;
133 			if ( bInvert )
134 				nInputBitsBuf = ( ( nInputBitsBuf & 1 ) << 7 ) | ( ( nInputBitsBuf & 2 ) << 5 ) | ( ( nInputBitsBuf & 4 ) << 3 ) | ( ( nInputBitsBuf & 8 ) << 1 ) | ( ( nInputBitsBuf & 16 ) >> 1 ) | ( ( nInputBitsBuf & 32 ) >> 3 ) | ( ( nInputBitsBuf & 64 ) >> 5 ) | ( (nInputBitsBuf & 128 ) >> 7 );
135 			nInputBitsBufSize=8;
136 		}
137 		else
138 		{
139 			nCode=(nCode<<nBits) | (nInputBitsBuf>>(nInputBitsBufSize-nBits));
140 			nInputBitsBufSize = nInputBitsBufSize - nBits;
141 			nInputBitsBuf&=0x00ff>>(8-nInputBitsBufSize);
142 			nBits=0;
143 		}
144 	} while (nBits>0);
145 
146 	return nCode;
147 }
148 
149 
AddToTable(sal_uInt16 nPrevCode,sal_uInt16 nCodeFirstData)150 void LZWDecompressor::AddToTable(sal_uInt16 nPrevCode, sal_uInt16 nCodeFirstData)
151 {
152 	while (pTable[nCodeFirstData].nDataCount>1)
153 		nCodeFirstData=pTable[nCodeFirstData].nPrevCode;
154 
155 	pTable[nTableSize].nPrevCode=nPrevCode;
156 	pTable[nTableSize].nDataCount=pTable[nPrevCode].nDataCount+1;
157 	pTable[nTableSize].nData=pTable[nCodeFirstData].nData;
158 
159 	nTableSize++;
160 }
161 
162 
DecompressSome()163 void LZWDecompressor::DecompressSome()
164 {
165 	sal_uInt16 i,nCode;
166 
167 	nCode=GetNextCode();
168 	if (nCode==256) {
169 		nTableSize=258;
170 		nCode=GetNextCode();
171 		if (nCode==257) { bEOIFound=sal_True; return; }
172 	}
173 	else if (nCode<nTableSize) AddToTable(nOldCode,nCode);
174 	else if (nCode==nTableSize) AddToTable(nOldCode,nOldCode);
175 	else { bEOIFound=sal_True; return; }
176 
177 	nOldCode=nCode;
178 
179 	nOutBufDataLen=pTable[nCode].nDataCount;
180 	pOutBufData=pOutBuf+nOutBufDataLen;
181 	for (i=0; i<nOutBufDataLen; i++) {
182 		*(--pOutBufData)=pTable[nCode].nData;
183 		nCode=pTable[nCode].nPrevCode;
184 	}
185 }
186 
187 
188 
189