LibreOffice Module vcl (master) 1
giflzwc.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
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 .
18 */
19
20
21#include <tools/stream.hxx>
22#include "giflzwc.hxx"
23#include <array>
24
25
27{
28private:
29
30 void FlushBlockBuf();
31 inline void FlushBitsBufsFullBytes();
32
34 std::array<sal_uInt8, 255>
37 sal_uInt32 nBitsBuf;
38 sal_uInt16 nBitsBufSize;
39
40public:
41
42 GIFImageDataOutputStream( SvStream & rGIF, sal_uInt8 nLZWDataSize );
44
45 inline void WriteBits( sal_uInt16 nCode, sal_uInt16 nCodeLen );
46};
47
48
50{
51 while (nBitsBufSize>=8)
52 {
53 if( nBlockBufSize==255 )
55
56 pBlockBuf[nBlockBufSize++] = static_cast<sal_uInt8>(nBitsBuf);
57 nBitsBuf >>= 8;
58 nBitsBufSize -= 8;
59 }
60}
61
62
63inline void GIFImageDataOutputStream::WriteBits( sal_uInt16 nCode, sal_uInt16 nCodeLen )
64{
65 if( nBitsBufSize+nCodeLen>32 )
67
68 nBitsBuf |= static_cast<sal_uInt32>(nCode) << nBitsBufSize;
69 nBitsBufSize = nBitsBufSize + nCodeLen;
70}
71
72
74 rStream(rGIF), nBlockBufSize(0), nBitsBuf(0), nBitsBufSize(0)
75{
76 rStream.WriteUChar( nLZWDataSize );
77}
78
79
81{
82 WriteBits(0,7);
86}
87
88
90{
91 if( nBlockBufSize )
92 {
95 nBlockBufSize = 0;
96 }
97}
98
99
101{
102
103 GIFLZWCTreeNode* pBrother; // next node which has the same father
105 sal_uInt16 nCode; // the code for the string of pixel values which comes about
106 sal_uInt16 nValue; // the pixel value
107};
108
109
111 : pPrefix(nullptr), nDataSize(0), nClearCode(0),
112 nEOICode(0), nTableSize(0), nCodeSize(0)
113{
114}
115
116
118{
119 if (pIDOS!=nullptr) EndCompression();
120}
121
122
123void GIFLZWCompressor::StartCompression( SvStream& rGIF, sal_uInt16 nPixelSize )
124{
125 if( pIDOS )
126 return;
127
128 sal_uInt16 i;
129
130 nDataSize = nPixelSize;
131
132 if( nDataSize < 2 )
133 nDataSize=2;
134
139
140 pIDOS.reset(new GIFImageDataOutputStream(rGIF,static_cast<sal_uInt8>(nDataSize)));
141 pTable.reset(new GIFLZWCTreeNode[4096]);
142
143 for (i=0; i<4096; i++)
144 {
145 pTable[i].pBrother = pTable[i].pFirstChild = nullptr;
146 pTable[i].nCode = i;
147 pTable[i].nValue = static_cast<sal_uInt8>( i );
148 }
149
150 pPrefix = nullptr;
151 pIDOS->WriteBits( nClearCode,nCodeSize );
152}
153
154void GIFLZWCompressor::Compress(sal_uInt8* pSrc, sal_uInt32 nSize)
155{
156 if( !pIDOS )
157 return;
158
160 sal_uInt16 i;
161 sal_uInt8 nV;
162
163 if( !pPrefix && nSize )
164 {
165 pPrefix=&pTable[*pSrc++];
166 nSize--;
167 }
168
169 while( nSize )
170 {
171 nSize--;
172 nV=*pSrc++;
173 for( p=pPrefix->pFirstChild; p!=nullptr; p=p->pBrother )
174 {
175 if (p->nValue==nV)
176 break;
177 }
178
179 if( p)
180 pPrefix=p;
181 else
182 {
183 pIDOS->WriteBits(pPrefix->nCode,nCodeSize);
184
185 if (nTableSize==4096)
186 {
187 pIDOS->WriteBits(nClearCode,nCodeSize);
188
189 for (i=0; i<nClearCode; i++)
190 pTable[i].pFirstChild=nullptr;
191
194 }
195 else
196 {
197 if(nTableSize==static_cast<sal_uInt16>(1<<nCodeSize))
198 nCodeSize++;
199
200 p=&pTable[nTableSize++];
201 p->pBrother=pPrefix->pFirstChild;
203 p->nValue=nV;
204 p->pFirstChild=nullptr;
205 }
206
207 pPrefix=&pTable[nV];
208 }
209 }
210}
211
213{
214 if( pIDOS )
215 {
216 if( pPrefix )
217 pIDOS->WriteBits(pPrefix->nCode,nCodeSize);
218
219 pIDOS->WriteBits( nEOICode,nCodeSize );
220 pTable.reset();
221 pIDOS.reset();
222 }
223}
224
225/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
std::array< sal_uInt8, 255 > pBlockBuf
Definition: giflzwc.cxx:35
sal_uInt16 nBitsBufSize
Definition: giflzwc.cxx:38
GIFImageDataOutputStream(SvStream &rGIF, sal_uInt8 nLZWDataSize)
Definition: giflzwc.cxx:73
void WriteBits(sal_uInt16 nCode, sal_uInt16 nCodeLen)
Definition: giflzwc.cxx:63
void Compress(sal_uInt8 *pSrc, sal_uInt32 nSize)
Definition: giflzwc.cxx:154
sal_uInt16 nCodeSize
Definition: giflzwc.hxx:41
sal_uInt16 nTableSize
Definition: giflzwc.hxx:40
GIFLZWCTreeNode * pPrefix
Definition: giflzwc.hxx:36
std::unique_ptr< GIFLZWCTreeNode[]> pTable
Definition: giflzwc.hxx:35
sal_uInt16 nClearCode
Definition: giflzwc.hxx:38
sal_uInt16 nDataSize
Definition: giflzwc.hxx:37
void StartCompression(SvStream &rGIF, sal_uInt16 nPixelSize)
Definition: giflzwc.cxx:123
std::unique_ptr< GIFImageDataOutputStream > pIDOS
Definition: giflzwc.hxx:34
sal_uInt16 nEOICode
Definition: giflzwc.hxx:39
void EndCompression()
Definition: giflzwc.cxx:212
std::size_t WriteBytes(const void *pData, std::size_t nSize)
SvStream & WriteUChar(unsigned char nChar)
void * p
sal_uInt16 nCode
int i
GIFLZWCTreeNode * pBrother
Definition: giflzwc.cxx:103
GIFLZWCTreeNode * pFirstChild
Definition: giflzwc.cxx:104
sal_uInt16 nCode
Definition: giflzwc.cxx:105
sal_uInt16 nValue
Definition: giflzwc.cxx:106
unsigned char sal_uInt8