LibreOffice Module vcl (master) 1
decode.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#include "decode.hxx"
21
22#include <cstdlib>
23#include <cstring>
24
26{
30};
31
33 : pTable(new GIFLZWTableEntry[4098])
34 , pOutBufData(pOutBuf.data() + 4096)
35 , pBlockBuf(nullptr)
36 , nInputBitsBuf(0)
37 , bEOIFound(false)
38 , nDataSize(cDataSize)
39 , nBlockBufSize(0)
40 , nBlockBufPos(0)
41 , nClearCode(1 << nDataSize)
42 , nEOICode(nClearCode + 1)
43 , nTableSize(nEOICode + 1)
44 , nCodeSize(nDataSize + 1)
45 , nOldCode(0xffff)
46 , nOutBufDataLen(0)
47 , nInputBitsBufSize(0)
48{
49 for (sal_uInt16 i = 0; i < nTableSize; ++i)
50 {
51 pTable[i].pPrev = nullptr;
52 pTable[i].pFirst = &pTable[i];
53 pTable[i].nData = static_cast<sal_uInt8>(i);
54 }
55
56 memset(pTable.get() + nTableSize, 0, sizeof(GIFLZWTableEntry) * (4098 - nTableSize));
57}
58
60{
61}
62
64 sal_uLong& rCount, bool& rEOI )
65{
66 sal_uLong nTargetSize = 4096;
67 sal_uLong nCount = 0;
68 sal_uInt8* pTarget = static_cast<sal_uInt8*>(std::malloc( nTargetSize ));
69 sal_uInt8* pTmpTarget = pTarget;
70
71 nBlockBufSize = cBufSize;
72 nBlockBufPos = 0;
73 pBlockBuf = pSrc;
74
75 while (pTarget && ProcessOneCode())
76 {
78
79 if( nCount > nTargetSize )
80 {
81 sal_uLong nNewSize = nTargetSize << 1;
82 sal_uLong nOffset = pTmpTarget - pTarget;
83 if (auto p = static_cast<sal_uInt8*>(std::realloc(pTarget, nNewSize)))
84 pTarget = p;
85 else
86 {
87 free(pTarget);
88 pTarget = nullptr;
89 break;
90 }
91
92 nTargetSize = nNewSize;
93 pTmpTarget = pTarget + nOffset;
94 }
95
96 memcpy( pTmpTarget, pOutBufData, nOutBufDataLen );
97 pTmpTarget += nOutBufDataLen;
100
101 if ( bEOIFound )
102 break;
103 }
104
105 rCount = nCount;
106 rEOI = bEOIFound;
107
108 return pTarget;
109}
110
111bool GIFLZWDecompressor::AddToTable( sal_uInt16 nPrevCode, sal_uInt16 nCodeFirstData )
112{
113 if( nTableSize < 4096 )
114 {
116 pE->pPrev = pTable.get() + nPrevCode;
117 pE->pFirst = pE->pPrev->pFirst;
118 GIFLZWTableEntry *pEntry = pTable[nCodeFirstData].pFirst;
119 if (!pEntry)
120 return false;
121 pE->nData = pEntry->nData;
122 nTableSize++;
123
124 if ( ( nTableSize == static_cast<sal_uInt16>(1 << nCodeSize) ) && ( nTableSize < 4096 ) )
125 nCodeSize++;
126 }
127 return true;
128}
129
131{
132 bool bRet = false;
133 bool bEndOfBlock = false;
134
136 {
138 {
139 bEndOfBlock = true;
140 break;
141 }
142
145 }
146
147 if ( !bEndOfBlock )
148 {
149 // fetch code from input buffer
150 sal_uInt16 nCode = sal::static_int_cast< sal_uInt16 >(
151 static_cast<sal_uInt16>(nInputBitsBuf) & ( ~( 0xffff << nCodeSize ) ));
154
155 if ( nCode < nClearCode )
156 {
157 bool bOk = true;
158 if ( nOldCode != 0xffff )
159 bOk = AddToTable(nOldCode, nCode);
160 if (!bOk)
161 return false;
162 }
163 else if ( ( nCode > nEOICode ) && ( nCode <= nTableSize ) )
164 {
165 if ( nOldCode != 0xffff )
166 {
167 bool bOk;
168 if ( nCode == nTableSize )
169 bOk = AddToTable( nOldCode, nOldCode );
170 else
171 bOk = AddToTable( nOldCode, nCode );
172 if (!bOk)
173 return false;
174 }
175 }
176 else
177 {
178 if ( nCode == nClearCode )
179 {
180 nTableSize = nEOICode + 1;
181 nCodeSize = nDataSize + 1;
182 nOldCode = 0xffff;
183 nOutBufDataLen = 0;
184 }
185 else
186 bEOIFound = true;
187
188 return true;
189 }
190
191 nOldCode = nCode;
192
193 if (nCode >= 4096)
194 return false;
195
196 // write character(/-sequence) of code nCode in the output buffer:
197 GIFLZWTableEntry* pE = pTable.get() + nCode;
198 do
199 {
200 if (pOutBufData == pOutBuf.data()) //can't go back past start
201 return false;
203 *(--pOutBufData) = pE->nData;
204 pE = pE->pPrev;
205 }
206 while( pE );
207
208 bRet = true;
209 }
210
211 return bRet;
212}
213
214/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
sal_uInt8 * Scanline
Definition: Scanline.hxx:26
sal_uLong nInputBitsBuf
Definition: decode.hxx:38
sal_uInt16 nOutBufDataLen
Definition: decode.hxx:48
bool ProcessOneCode()
Definition: decode.cxx:130
sal_uInt16 nInputBitsBufSize
Definition: decode.hxx:49
std::unique_ptr< GIFLZWTableEntry[]> pTable
Definition: decode.hxx:33
sal_uInt8 * pOutBufData
Definition: decode.hxx:36
sal_uInt8 nBlockBufSize
Definition: decode.hxx:41
sal_uInt16 nOldCode
Definition: decode.hxx:47
sal_uInt16 nCodeSize
Definition: decode.hxx:46
GIFLZWDecompressor(const GIFLZWDecompressor &)=delete
sal_uInt8 nDataSize
Definition: decode.hxx:40
sal_uInt8 * pBlockBuf
Definition: decode.hxx:37
sal_uInt16 nEOICode
Definition: decode.hxx:44
sal_uInt8 nBlockBufPos
Definition: decode.hxx:42
sal_uInt16 nClearCode
Definition: decode.hxx:43
Scanline DecompressBlock(sal_uInt8 *pSrc, sal_uInt8 cBufSize, sal_uLong &rCount, bool &rEOI)
Definition: decode.cxx:63
std::array< sal_uInt8, 4096 > pOutBuf
Definition: decode.hxx:35
sal_uInt16 nTableSize
Definition: decode.hxx:45
bool AddToTable(sal_uInt16 nPrevCode, sal_uInt16 nCodeFirstData)
Definition: decode.cxx:111
int nCount
FormulaCommand pE
void * p
sal_uInt16 nCode
int i
sal_uIntPtr sal_uLong
GIFLZWTableEntry * pFirst
Definition: decode.cxx:28
GIFLZWTableEntry * pPrev
Definition: decode.cxx:27
sal_uInt8 nData
Definition: decode.cxx:29
unsigned char sal_uInt8