Update ooo320-m1
[ooovba.git] / goodies / source / filter.vcl / egif / giflzwc.cxx
blob9c1417c685d5488dc612317568e8d1f440b6e7a8
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: giflzwc.cxx,v $
10 * $Revision: 1.5 $
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 <tools/stream.hxx>
35 #include "giflzwc.hxx"
37 // ----------------------------
38 // - GIFImageDataOutputStream -
39 // ----------------------------
41 class GIFImageDataOutputStream
43 private:
45 void FlushBlockBuf();
46 inline void FlushBitsBufsFullBytes();
48 SvStream& rStream;
49 BYTE* pBlockBuf;
50 BYTE nBlockBufSize;
51 ULONG nBitsBuf;
52 USHORT nBitsBufSize;
54 public:
56 GIFImageDataOutputStream( SvStream & rGIF, BYTE nLZWDataSize );
57 ~GIFImageDataOutputStream();
59 inline void WriteBits( USHORT nCode, USHORT nCodeLen );
62 // ------------------------------------------------------------------------
64 inline void GIFImageDataOutputStream::FlushBitsBufsFullBytes()
66 while (nBitsBufSize>=8)
68 if( nBlockBufSize==255 )
69 FlushBlockBuf();
71 pBlockBuf[nBlockBufSize++] = (BYTE) nBitsBuf;
72 nBitsBuf >>= 8;
73 nBitsBufSize -= 8;
77 // ------------------------------------------------------------------------
79 inline void GIFImageDataOutputStream::WriteBits( USHORT nCode, USHORT nCodeLen )
81 if( nBitsBufSize+nCodeLen>32 )
82 FlushBitsBufsFullBytes();
84 nBitsBuf |= (ULONG) nCode << nBitsBufSize;
85 nBitsBufSize = nBitsBufSize + nCodeLen;
88 // ------------------------------------------------------------------------
90 GIFImageDataOutputStream::GIFImageDataOutputStream( SvStream & rGIF, BYTE nLZWDataSize ) :
91 rStream(rGIF)
93 pBlockBuf = new BYTE[ 255 ];
94 nBlockBufSize = 0;
95 nBitsBufSize = 0;
96 nBitsBuf = 0;
97 rStream << nLZWDataSize;
100 // ------------------------------------------------------------------------
103 GIFImageDataOutputStream::~GIFImageDataOutputStream()
105 WriteBits(0,7);
106 FlushBitsBufsFullBytes();
107 FlushBlockBuf();
108 rStream << (BYTE)0;
109 delete[] pBlockBuf;
112 // ------------------------------------------------------------------------
114 void GIFImageDataOutputStream::FlushBlockBuf()
116 if( nBlockBufSize )
118 rStream << (BYTE) nBlockBufSize;
119 rStream.Write( pBlockBuf,nBlockBufSize );
120 nBlockBufSize = 0;
124 // -------------------
125 // - GIFLZWCTreeNode -
126 // -------------------
128 struct GIFLZWCTreeNode
131 GIFLZWCTreeNode* pBrother; // naechster Knoten, der den selben Vater hat
132 GIFLZWCTreeNode* pFirstChild; // erster Sohn
133 USHORT nCode; // Der Code fuer den String von Pixelwerten, der sich ergibt, wenn
134 USHORT nValue; // Der Pixelwert
137 // --------------------
138 // - GIFLZWCompressor -
139 // --------------------
141 GIFLZWCompressor::GIFLZWCompressor()
143 pIDOS=NULL;
146 // ------------------------------------------------------------------------
148 GIFLZWCompressor::~GIFLZWCompressor()
150 if (pIDOS!=NULL) EndCompression();
153 // ------------------------------------------------------------------------
155 void GIFLZWCompressor::StartCompression( SvStream& rGIF, USHORT nPixelSize )
157 if( !pIDOS )
159 USHORT i;
161 nDataSize = nPixelSize;
163 if( nDataSize < 2 )
164 nDataSize=2;
166 nClearCode=1<<nDataSize;
167 nEOICode=nClearCode+1;
168 nTableSize=nEOICode+1;
169 nCodeSize=nDataSize+1;
171 pIDOS=new GIFImageDataOutputStream(rGIF,(BYTE)nDataSize);
172 pTable=new GIFLZWCTreeNode[4096];
174 for (i=0; i<4096; i++)
176 pTable[i].pBrother = pTable[i].pFirstChild = NULL;
177 pTable[i].nValue = (BYTE) ( pTable[i].nCode = i );
180 pPrefix = NULL;
181 pIDOS->WriteBits( nClearCode,nCodeSize );
185 // ------------------------------------------------------------------------
187 void GIFLZWCompressor::Compress( HPBYTE pSrc, ULONG nSize )
189 if( pIDOS )
191 GIFLZWCTreeNode* p;
192 USHORT i;
193 BYTE nV;
195 if( !pPrefix && nSize )
197 pPrefix=pTable+(*pSrc++);
198 nSize--;
201 while( nSize )
203 nSize--;
204 nV=*pSrc++;
205 for( p=pPrefix->pFirstChild; p!=NULL; p=p->pBrother )
207 if (p->nValue==nV)
208 break;
211 if( p)
212 pPrefix=p;
213 else
215 pIDOS->WriteBits(pPrefix->nCode,nCodeSize);
217 if (nTableSize==4096)
219 pIDOS->WriteBits(nClearCode,nCodeSize);
221 for (i=0; i<nClearCode; i++)
222 pTable[i].pFirstChild=NULL;
224 nCodeSize=nDataSize+1;
225 nTableSize=nEOICode+1;
227 else
229 if(nTableSize==(USHORT)(1<<nCodeSize))
230 nCodeSize++;
232 p=pTable+(nTableSize++);
233 p->pBrother=pPrefix->pFirstChild;
234 pPrefix->pFirstChild=p;
235 p->nValue=nV;
236 p->pFirstChild=NULL;
239 pPrefix=pTable+nV;
245 // ------------------------------------------------------------------------
247 void GIFLZWCompressor::EndCompression()
249 if( pIDOS )
251 if( pPrefix )
252 pIDOS->WriteBits(pPrefix->nCode,nCodeSize);
254 pIDOS->WriteBits( nEOICode,nCodeSize );
255 delete[] pTable;
256 delete pIDOS;
257 pIDOS=NULL;