merge the formfield patch from ooo-build
[ooovba.git] / svtools / source / filter.vcl / igif / decode.cxx
blobec63b4f4e793c6891c5d0b634c95d4d3e996e5a5
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: decode.cxx,v $
10 * $Revision: 1.8 $
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_svtools.hxx"
34 #include "decode.hxx"
36 // ------------------------------------------------------------------------
38 struct GIFLZWTableEntry
40 GIFLZWTableEntry* pPrev;
41 GIFLZWTableEntry* pFirst;
42 BYTE nData;
45 // ------------------------------------------------------------------------
47 GIFLZWDecompressor::GIFLZWDecompressor( BYTE cDataSize ) :
48 nInputBitsBuf ( 0 ),
49 nOutBufDataLen ( 0 ),
50 nInputBitsBufSize ( 0 ),
51 bEOIFound ( FALSE ),
52 nDataSize ( cDataSize )
54 pTable = new GIFLZWTableEntry[ 4096 ];
55 pOutBuf = new BYTE[ 4096 ];
57 nClearCode = 1 << nDataSize;
58 nEOICode = nClearCode + 1;
59 nTableSize = nEOICode + 1;
60 nCodeSize = nDataSize + 1;
61 nOldCode = 0xffff;
62 pOutBufData = pOutBuf + 4096;
64 for( USHORT i = 0; i < nTableSize; i++ )
66 pTable[i].pPrev = NULL;
67 pTable[i].pFirst = pTable + i;
68 pTable[i].nData = (BYTE) i;
72 // ------------------------------------------------------------------------
74 GIFLZWDecompressor::~GIFLZWDecompressor()
76 delete[] pOutBuf;
77 delete[] pTable;
80 // ------------------------------------------------------------------------
82 HPBYTE GIFLZWDecompressor::DecompressBlock( HPBYTE pSrc, BYTE cBufSize,
83 ULONG& rCount, BOOL& rEOI )
85 ULONG nTargetSize = 4096;
86 ULONG nCount = 0;
87 HPBYTE pTarget = (HPBYTE) rtl_allocateMemory( nTargetSize );
88 HPBYTE pTmpTarget = pTarget;
90 nBlockBufSize = cBufSize;
91 nBlockBufPos = 0;
92 pBlockBuf = pSrc;
94 while( ProcessOneCode() )
96 nCount += nOutBufDataLen;
98 if( nCount > nTargetSize )
100 ULONG nNewSize = nTargetSize << 1;
101 ULONG nOffset = pTmpTarget - pTarget;
102 HPBYTE pTmp = (HPBYTE) rtl_allocateMemory( nNewSize );
104 memcpy( pTmp, pTarget, nTargetSize );
105 rtl_freeMemory( pTarget );
107 nTargetSize = nNewSize;
108 pTmpTarget = ( pTarget = pTmp ) + nOffset;
111 memcpy( pTmpTarget, pOutBufData, nOutBufDataLen );
112 pTmpTarget += nOutBufDataLen;
113 pOutBufData += nOutBufDataLen;
114 nOutBufDataLen = 0;
116 if ( bEOIFound )
117 break;
120 rCount = nCount;
121 rEOI = bEOIFound;
123 return pTarget;
126 // ------------------------------------------------------------------------
128 void GIFLZWDecompressor::AddToTable( USHORT nPrevCode, USHORT nCodeFirstData )
130 GIFLZWTableEntry* pE;
132 if( nTableSize < 4096 )
134 pE = pTable + nTableSize;
135 pE->pPrev = pTable + nPrevCode;
136 pE->pFirst = pE->pPrev->pFirst;
137 pE->nData = pTable[ nCodeFirstData ].pFirst->nData;
138 nTableSize++;
140 if ( ( nTableSize == (USHORT) (1 << nCodeSize) ) && ( nTableSize < 4096 ) )
141 nCodeSize++;
145 // ------------------------------------------------------------------------
147 BOOL GIFLZWDecompressor::ProcessOneCode()
149 GIFLZWTableEntry* pE;
150 USHORT nCode;
151 BOOL bRet = FALSE;
152 BOOL bEndOfBlock = FALSE;
154 while( nInputBitsBufSize < nCodeSize )
156 if( nBlockBufPos >= nBlockBufSize )
158 bEndOfBlock = TRUE;
159 break;
162 nInputBitsBuf |= ( (ULONG) pBlockBuf[ nBlockBufPos++ ] ) << nInputBitsBufSize;
163 nInputBitsBufSize += 8;
166 if ( !bEndOfBlock )
168 // Einen Code aus dem Eingabe-Buffer holen:
169 nCode = sal::static_int_cast< USHORT >(
170 ( (USHORT) nInputBitsBuf ) & ( ~( 0xffff << nCodeSize ) ));
171 nInputBitsBuf >>= nCodeSize;
172 nInputBitsBufSize = nInputBitsBufSize - nCodeSize;
174 if ( nCode < nClearCode )
176 if ( nOldCode != 0xffff )
177 AddToTable( nOldCode, nCode );
179 else if ( ( nCode > nEOICode ) && ( nCode <= nTableSize ) )
181 if ( nCode == nTableSize )
182 AddToTable( nOldCode, nOldCode );
183 else
184 AddToTable( nOldCode, nCode );
186 else
188 if ( nCode == nClearCode )
190 nTableSize = nEOICode + 1;
191 nCodeSize = nDataSize + 1;
192 nOldCode = 0xffff;
193 nOutBufDataLen = 0;
195 else
196 bEOIFound = TRUE;
198 return TRUE;
201 nOldCode = nCode;
203 // Zeichen(/-folge) des Codes nCode in den Ausgabe-Buffer schreiben:
204 pE = pTable + nCode;
207 nOutBufDataLen++;
208 *(--pOutBufData) = pE->nData;
209 pE = pE->pPrev;
211 while( pE );
213 bRet = TRUE;
216 return bRet;