xref: /AOO41X/main/filter/source/graphicfilter/itiff/lzwdecom.cxx (revision 9e0fc027f109ec4ffcb6033aeec742a099701108)
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