1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: lzwdecom.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_goodies.hxx"
34 #include "lzwdecom.hxx"
36 LZWDecompressor::LZWDecompressor()
40 pTable
=new LZWTableEntry
[4096];
41 pOutBuf
=new BYTE
[4096];
42 for (i
=0; i
<4096; i
++)
44 pTable
[i
].nPrevCode
=0;
45 pTable
[i
].nDataCount
=1;
46 pTable
[i
].nData
=(BYTE
)i
;
54 LZWDecompressor::~LZWDecompressor()
61 void LZWDecompressor::StartDecompression(SvStream
& rIStream
)
71 *pIStream
>> nInputBitsBuf
;
77 bInvert
= nInputBitsBuf
== 1;
82 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 );
86 ULONG
LZWDecompressor::Decompress(BYTE
* pTarget
, ULONG nMaxCount
)
90 if (pIStream
==NULL
) return 0;
95 if (pIStream
->GetError()) break;
97 if (((ULONG
)nOutBufDataLen
)>=nMaxCount
) {
98 nOutBufDataLen
= nOutBufDataLen
- (USHORT
)nMaxCount
;
100 while (nMaxCount
>0) {
101 *(pTarget
++)=*(pOutBufData
++);
107 nMaxCount
-=(ULONG
)nOutBufDataLen
;
108 nCount
+=nOutBufDataLen
;
109 while (nOutBufDataLen
>0) {
110 *(pTarget
++)=*(pOutBufData
++);
114 if (bEOIFound
==TRUE
) break;
124 USHORT
LZWDecompressor::GetNextCode()
128 if (nTableSize
<511) nBits
=9;
129 else if (nTableSize
<1023) nBits
=10;
130 else if (nTableSize
<2047) nBits
=11;
135 if (nInputBitsBufSize
<=nBits
)
137 nCode
=(nCode
<<nInputBitsBufSize
) | nInputBitsBuf
;
138 nBits
= nBits
- nInputBitsBufSize
;
139 *pIStream
>> nInputBitsBuf
;
141 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 );
146 nCode
=(nCode
<<nBits
) | (nInputBitsBuf
>>(nInputBitsBufSize
-nBits
));
147 nInputBitsBufSize
= nInputBitsBufSize
- nBits
;
148 nInputBitsBuf
&=0x00ff>>(8-nInputBitsBufSize
);
157 void LZWDecompressor::AddToTable(USHORT nPrevCode
, USHORT nCodeFirstData
)
159 while (pTable
[nCodeFirstData
].nDataCount
>1)
160 nCodeFirstData
=pTable
[nCodeFirstData
].nPrevCode
;
162 pTable
[nTableSize
].nPrevCode
=nPrevCode
;
163 pTable
[nTableSize
].nDataCount
=pTable
[nPrevCode
].nDataCount
+1;
164 pTable
[nTableSize
].nData
=pTable
[nCodeFirstData
].nData
;
170 void LZWDecompressor::DecompressSome()
178 if (nCode
==257) { bEOIFound
=TRUE
; return; }
180 else if (nCode
<nTableSize
) AddToTable(nOldCode
,nCode
);
181 else if (nCode
==nTableSize
) AddToTable(nOldCode
,nOldCode
);
182 else { bEOIFound
=TRUE
; return; }
186 nOutBufDataLen
=pTable
[nCode
].nDataCount
;
187 pOutBufData
=pOutBuf
+nOutBufDataLen
;
188 for (i
=0; i
<nOutBufDataLen
; i
++) {
189 *(--pOutBufData
)=pTable
[nCode
].nData
;
190 nCode
=pTable
[nCode
].nPrevCode
;