bump product version to 4.1.6.2
[LibreOffice.git] / filter / source / graphicfilter / egif / giflzwc.cxx
blobdcc1533640d545f8074f0f5c4dc972d4ba57b3a8
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include <tools/stream.hxx>
22 #include "giflzwc.hxx"
24 // ----------------------------
25 // - GIFImageDataOutputStream -
26 // ----------------------------
28 class GIFImageDataOutputStream
30 private:
32 void FlushBlockBuf();
33 inline void FlushBitsBufsFullBytes();
35 SvStream& rStream;
36 sal_uInt8* pBlockBuf;
37 sal_uInt8 nBlockBufSize;
38 sal_uLong nBitsBuf;
39 sal_uInt16 nBitsBufSize;
41 public:
43 GIFImageDataOutputStream( SvStream & rGIF, sal_uInt8 nLZWDataSize );
44 ~GIFImageDataOutputStream();
46 inline void WriteBits( sal_uInt16 nCode, sal_uInt16 nCodeLen );
49 // ------------------------------------------------------------------------
51 inline void GIFImageDataOutputStream::FlushBitsBufsFullBytes()
53 while (nBitsBufSize>=8)
55 if( nBlockBufSize==255 )
56 FlushBlockBuf();
58 pBlockBuf[nBlockBufSize++] = (sal_uInt8) nBitsBuf;
59 nBitsBuf >>= 8;
60 nBitsBufSize -= 8;
64 // ------------------------------------------------------------------------
66 inline void GIFImageDataOutputStream::WriteBits( sal_uInt16 nCode, sal_uInt16 nCodeLen )
68 if( nBitsBufSize+nCodeLen>32 )
69 FlushBitsBufsFullBytes();
71 nBitsBuf |= (sal_uLong) nCode << nBitsBufSize;
72 nBitsBufSize = nBitsBufSize + nCodeLen;
75 // ------------------------------------------------------------------------
77 GIFImageDataOutputStream::GIFImageDataOutputStream( SvStream & rGIF, sal_uInt8 nLZWDataSize ) :
78 rStream(rGIF)
80 pBlockBuf = new sal_uInt8[ 255 ];
81 nBlockBufSize = 0;
82 nBitsBufSize = 0;
83 nBitsBuf = 0;
84 rStream << nLZWDataSize;
87 // ------------------------------------------------------------------------
90 GIFImageDataOutputStream::~GIFImageDataOutputStream()
92 WriteBits(0,7);
93 FlushBitsBufsFullBytes();
94 FlushBlockBuf();
95 rStream << (sal_uInt8)0;
96 delete[] pBlockBuf;
99 // ------------------------------------------------------------------------
101 void GIFImageDataOutputStream::FlushBlockBuf()
103 if( nBlockBufSize )
105 rStream << (sal_uInt8) nBlockBufSize;
106 rStream.Write( pBlockBuf,nBlockBufSize );
107 nBlockBufSize = 0;
111 // -------------------
112 // - GIFLZWCTreeNode -
113 // -------------------
115 struct GIFLZWCTreeNode
118 GIFLZWCTreeNode* pBrother; // next node which has the same father
119 GIFLZWCTreeNode* pFirstChild; // first
120 sal_uInt16 nCode; // the code for the string of pixel values which comes about
121 sal_uInt16 nValue; // the pixel value
124 // --------------------
125 // - GIFLZWCompressor -
126 // --------------------
128 GIFLZWCompressor::GIFLZWCompressor()
130 pIDOS=NULL;
133 // ------------------------------------------------------------------------
135 GIFLZWCompressor::~GIFLZWCompressor()
137 if (pIDOS!=NULL) EndCompression();
140 // ------------------------------------------------------------------------
142 void GIFLZWCompressor::StartCompression( SvStream& rGIF, sal_uInt16 nPixelSize )
144 if( !pIDOS )
146 sal_uInt16 i;
148 nDataSize = nPixelSize;
150 if( nDataSize < 2 )
151 nDataSize=2;
153 nClearCode=1<<nDataSize;
154 nEOICode=nClearCode+1;
155 nTableSize=nEOICode+1;
156 nCodeSize=nDataSize+1;
158 pIDOS=new GIFImageDataOutputStream(rGIF,(sal_uInt8)nDataSize);
159 pTable=new GIFLZWCTreeNode[4096];
161 for (i=0; i<4096; i++)
163 pTable[i].pBrother = pTable[i].pFirstChild = NULL;
164 pTable[i].nValue = (sal_uInt8) ( pTable[i].nCode = i );
167 pPrefix = NULL;
168 pIDOS->WriteBits( nClearCode,nCodeSize );
172 // ------------------------------------------------------------------------
174 void GIFLZWCompressor::Compress( HPBYTE pSrc, sal_uLong nSize )
176 if( pIDOS )
178 GIFLZWCTreeNode* p;
179 sal_uInt16 i;
180 sal_uInt8 nV;
182 if( !pPrefix && nSize )
184 pPrefix=pTable+(*pSrc++);
185 nSize--;
188 while( nSize )
190 nSize--;
191 nV=*pSrc++;
192 for( p=pPrefix->pFirstChild; p!=NULL; p=p->pBrother )
194 if (p->nValue==nV)
195 break;
198 if( p)
199 pPrefix=p;
200 else
202 pIDOS->WriteBits(pPrefix->nCode,nCodeSize);
204 if (nTableSize==4096)
206 pIDOS->WriteBits(nClearCode,nCodeSize);
208 for (i=0; i<nClearCode; i++)
209 pTable[i].pFirstChild=NULL;
211 nCodeSize=nDataSize+1;
212 nTableSize=nEOICode+1;
214 else
216 if(nTableSize==(sal_uInt16)(1<<nCodeSize))
217 nCodeSize++;
219 p=pTable+(nTableSize++);
220 p->pBrother=pPrefix->pFirstChild;
221 pPrefix->pFirstChild=p;
222 p->nValue=nV;
223 p->pFirstChild=NULL;
226 pPrefix=pTable+nV;
232 // ------------------------------------------------------------------------
234 void GIFLZWCompressor::EndCompression()
236 if( pIDOS )
238 if( pPrefix )
239 pIDOS->WriteBits(pPrefix->nCode,nCodeSize);
241 pIDOS->WriteBits( nEOICode,nCodeSize );
242 delete[] pTable;
243 delete pIDOS;
244 pIDOS=NULL;
248 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */