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  {
77  nCount += nOutBufDataLen;
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;
99  nOutBufDataLen = 0;
100 
101  if ( bEOIFound )
102  break;
103  }
104 
105  rCount = nCount;
106  rEOI = bEOIFound;
107 
108  return pTarget;
109 }
110 
111 bool 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 
135  while( nInputBitsBufSize < nCodeSize )
136  {
137  if( nBlockBufPos >= nBlockBufSize )
138  {
139  bEndOfBlock = true;
140  break;
141  }
142 
144  nInputBitsBufSize += 8;
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;
202  nOutBufDataLen++;
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_uInt16 nClearCode
Definition: decode.hxx:43
bool AddToTable(sal_uInt16 nPrevCode, sal_uInt16 nCodeFirstData)
Definition: decode.cxx:111
FormulaCommand pE
sal_uIntPtr sal_uLong
bool ProcessOneCode()
Definition: decode.cxx:130
GIFLZWTableEntry * pPrev
Definition: decode.cxx:27
std::array< sal_uInt8, 4096 > pOutBuf
Definition: decode.hxx:35
sal_uInt8 * pOutBufData
Definition: decode.hxx:36
sal_uInt16 nEOICode
Definition: decode.hxx:44
sal_uInt16 nTableSize
Definition: decode.hxx:45
int nCount
sal_uLong nInputBitsBuf
Definition: decode.hxx:38
GIFLZWTableEntry * pFirst
Definition: decode.cxx:28
sal_uInt16 nCode
sal_uInt8 nBlockBufPos
Definition: decode.hxx:42
Scanline DecompressBlock(sal_uInt8 *pSrc, sal_uInt8 cBufSize, sal_uLong &rCount, bool &rEOI)
Definition: decode.cxx:63
sal_uInt8 nData
Definition: decode.cxx:29
sal_uInt8 * Scanline
Definition: Scanline.hxx:26
int i
std::unique_ptr< GIFLZWTableEntry[]> pTable
Definition: decode.hxx:33
exports com.sun.star.chart2. data
unsigned char sal_uInt8
sal_uInt8 * pBlockBuf
Definition: decode.hxx:37
sal_uInt16 nOutBufDataLen
Definition: decode.hxx:48
void * p
sal_uInt16 nOldCode
Definition: decode.hxx:47
GIFLZWDecompressor(const GIFLZWDecompressor &)=delete
sal_uInt8 nDataSize
Definition: decode.hxx:40
sal_uInt8 nBlockBufSize
Definition: decode.hxx:41
sal_uInt16 nCodeSize
Definition: decode.hxx:46
sal_uInt16 nInputBitsBufSize
Definition: decode.hxx:49