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: decode.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_svtools.hxx"
36 // ------------------------------------------------------------------------
38 struct GIFLZWTableEntry
40 GIFLZWTableEntry
* pPrev
;
41 GIFLZWTableEntry
* pFirst
;
45 // ------------------------------------------------------------------------
47 GIFLZWDecompressor::GIFLZWDecompressor( BYTE cDataSize
) :
50 nInputBitsBufSize ( 0 ),
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;
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()
80 // ------------------------------------------------------------------------
82 HPBYTE
GIFLZWDecompressor::DecompressBlock( HPBYTE pSrc
, BYTE cBufSize
,
83 ULONG
& rCount
, BOOL
& rEOI
)
85 ULONG nTargetSize
= 4096;
87 HPBYTE pTarget
= (HPBYTE
) rtl_allocateMemory( nTargetSize
);
88 HPBYTE pTmpTarget
= pTarget
;
90 nBlockBufSize
= cBufSize
;
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
;
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
;
140 if ( ( nTableSize
== (USHORT
) (1 << nCodeSize
) ) && ( nTableSize
< 4096 ) )
145 // ------------------------------------------------------------------------
147 BOOL
GIFLZWDecompressor::ProcessOneCode()
149 GIFLZWTableEntry
* pE
;
152 BOOL bEndOfBlock
= FALSE
;
154 while( nInputBitsBufSize
< nCodeSize
)
156 if( nBlockBufPos
>= nBlockBufSize
)
162 nInputBitsBuf
|= ( (ULONG
) pBlockBuf
[ nBlockBufPos
++ ] ) << nInputBitsBufSize
;
163 nInputBitsBufSize
+= 8;
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
);
184 AddToTable( nOldCode
, nCode
);
188 if ( nCode
== nClearCode
)
190 nTableSize
= nEOICode
+ 1;
191 nCodeSize
= nDataSize
+ 1;
203 // Zeichen(/-folge) des Codes nCode in den Ausgabe-Buffer schreiben:
208 *(--pOutBufData
) = pE
->nData
;