tdf#131098 docx export: write fill property of graphic
[LibreOffice.git] / lotuswordpro / source / filter / lwpobjstrm.cxx
blob728e3a71f8f3d997d333c045cc62cf88736f58f6
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * The Contents of this file are made available subject to the terms of
5 * either of the following licenses
7 * - GNU Lesser General Public License Version 2.1
8 * - Sun Industry Standards Source License Version 1.1
10 * Sun Microsystems Inc., October, 2000
12 * GNU Lesser General Public License Version 2.1
13 * =============================================
14 * Copyright 2000 by Sun Microsystems, Inc.
15 * 901 San Antonio Road, Palo Alto, CA 94303, USA
17 * This library is free software; you can redistribute it and/or
18 * modify it under the terms of the GNU Lesser General Public
19 * License version 2.1, as published by the Free Software Foundation.
21 * This library is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
24 * Lesser General Public License for more details.
26 * You should have received a copy of the GNU Lesser General Public
27 * License along with this library; if not, write to the Free Software
28 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
29 * MA 02111-1307 USA
32 * Sun Industry Standards Source License Version 1.1
33 * =================================================
34 * The contents of this file are subject to the Sun Industry Standards
35 * Source License Version 1.1 (the "License"); You may not use this file
36 * except in compliance with the License. You may obtain a copy of the
37 * License at http://www.openoffice.org/license.html.
39 * Software provided under this License is provided on an "AS IS" basis,
40 * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
41 * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
42 * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
43 * See the License for the specific provisions governing your rights and
44 * obligations concerning the Software.
46 * The Initial Developer of the Original Code is: IBM Corporation
48 * Copyright: 2008 by IBM Corporation
50 * All Rights Reserved.
52 * Contributor(s): _______________________________________
55 ************************************************************************/
57 #include <lwpobjstrm.hxx>
58 #include <lwptools.hxx>
60 #include <sal/types.h>
61 #include <tools/solar.h>
62 #include <memory>
64 /**
65 * @descr ctor() from LwpSvStream
67 LwpObjectStream::LwpObjectStream(LwpSvStream* pStrm, bool isCompressed, sal_uInt16 size)
68 : m_pContentBuf(nullptr)
69 , m_nBufSize(size)
70 , m_nReadPos(0)
71 , m_pStrm(pStrm)
72 , m_bCompressed(isCompressed)
74 if (m_nBufSize >= IO_BUFFERSIZE)
75 throw std::range_error("bad Object size");
76 // read object data from stream
77 if (m_nBufSize > 0)
78 Read2Buffer();
81 /**
82 * @descr read object data from stream to buffer
84 void LwpObjectStream::Read2Buffer()
86 ReleaseBuffer();
88 m_nReadPos = 0;
90 if (m_bCompressed)
92 std::unique_ptr<sal_uInt8[]> xCompressBuf(new sal_uInt8[m_nBufSize]);
94 sal_uInt8* pCompressBuffer = xCompressBuf.get();
95 memset(pCompressBuffer, 0, m_nBufSize);
96 m_nBufSize = m_pStrm->Read(pCompressBuffer, m_nBufSize);
98 sal_uInt8 pTempDst[IO_BUFFERSIZE];
99 m_nBufSize = DecompressBuffer(pTempDst, pCompressBuffer, m_nBufSize);
100 assert(m_nBufSize < IO_BUFFERSIZE);
102 m_pContentBuf = AllocBuffer(m_nBufSize);
103 memcpy(m_pContentBuf, pTempDst, m_nBufSize);
105 else
107 m_pContentBuf = AllocBuffer(m_nBufSize);
108 m_nBufSize = m_pStrm->Read(m_pContentBuf, m_nBufSize);
112 * @descr alloc size of buffer
114 sal_uInt8* LwpObjectStream::AllocBuffer(sal_uInt16 size)
116 if (size <= 100)
118 return m_SmallBuffer;
120 m_BigBuffer.resize(size);
121 return m_BigBuffer.data();
124 * @descr signal complete to release object buffer
126 void LwpObjectStream::ReadComplete() { ReleaseBuffer(); }
128 LwpObjectStream::~LwpObjectStream() { ReleaseBuffer(); }
130 * @descr release object buffer
132 void LwpObjectStream::ReleaseBuffer()
134 m_BigBuffer.clear();
135 m_pContentBuf = nullptr;
138 sal_uInt16 LwpObjectStream::remainingSize() const { return m_nBufSize - m_nReadPos; }
141 * @descr read len bytes from object stream to buffer
143 sal_uInt16 LwpObjectStream::QuickRead(void* buf, sal_uInt16 len)
145 memset(buf, 0, len);
146 if (len > m_nBufSize - m_nReadPos)
148 len = m_nBufSize - m_nReadPos;
150 if (m_pContentBuf && len)
152 memcpy(buf, m_pContentBuf + m_nReadPos, len);
153 m_nReadPos += len;
155 return len;
158 * @descr SeekRel pos in object stream/buffer
160 void LwpObjectStream::SeekRel(sal_uInt16 pos)
162 if (pos > m_nBufSize - m_nReadPos)
163 pos = m_nBufSize - m_nReadPos;
164 m_nReadPos += pos;
167 * @descr Seek to pos in object buffer/buffer
169 void LwpObjectStream::Seek(sal_uInt16 pos)
171 if (pos < m_nBufSize)
173 m_nReadPos = pos;
178 * @descr Quick read sal_Bool
180 bool LwpObjectStream::QuickReadBool()
182 SVBT16 aValue = { 0 };
183 QuickRead(aValue, sizeof(aValue));
184 return static_cast<bool>(SVBT16ToUInt16(aValue));
187 * @descr Quick read sal_uInt32
189 sal_uInt32 LwpObjectStream::QuickReaduInt32(bool* pFailure)
191 SVBT32 aValue = { 0 };
192 sal_uInt16 nRead = QuickRead(aValue, sizeof(aValue));
193 if (pFailure)
194 *pFailure = (nRead != sizeof(aValue));
195 return SVBT32ToUInt32(aValue);
198 * @descr Quick read sal_uInt32
200 sal_uInt16 LwpObjectStream::QuickReaduInt16(bool* pFailure)
202 SVBT16 aValue = { 0 };
203 sal_uInt16 nRead = QuickRead(aValue, sizeof(aValue));
204 if (pFailure)
205 *pFailure = (nRead != sizeof(aValue));
206 return SVBT16ToUInt16(aValue);
209 * @descr Quick read sal_Int32
211 sal_Int32 LwpObjectStream::QuickReadInt32()
213 SVBT32 aValue = { 0 };
214 QuickRead(aValue, sizeof(aValue));
215 return static_cast<sal_Int32>(SVBT32ToUInt32(aValue));
218 * @descr Quick read sal_Int16
220 sal_Int16 LwpObjectStream::QuickReadInt16()
222 SVBT16 aValue = { 0 };
223 QuickRead(aValue, sizeof(aValue));
225 return static_cast<sal_Int16>(SVBT16ToUInt16(aValue));
228 * @descr Quick read sal_uInt8
230 sal_uInt8 LwpObjectStream::QuickReaduInt8(bool* pFailure)
232 sal_uInt8 aValue = 0;
233 sal_uInt16 nRead = QuickRead(&aValue, sizeof(aValue));
234 if (pFailure)
235 *pFailure = (nRead != sizeof(aValue));
236 return aValue;
239 * @descr Quick read double
241 double LwpObjectStream::QuickReadDouble()
243 union {
244 double d;
245 sal_uInt8 c[8];
246 } s;
247 memset(s.c, 0, sizeof(s.c));
248 QuickRead(s.c, sizeof(s.c));
249 #if defined(OSL_BIGENDIAN)
250 for (size_t i = 0; i < 4; ++i)
251 std::swap(s.c[i], s.c[7 - i]);
252 #endif
253 return s.d;
256 * @descr skip extra bytes
258 void LwpObjectStream::SkipExtra()
260 sal_uInt16 extra = QuickReaduInt16();
261 while (extra != 0)
262 extra = QuickReaduInt16();
265 * @descr check if extra bytes
267 sal_uInt16 LwpObjectStream::CheckExtra() { return QuickReaduInt16(); }
269 * @descr decompress data buffer from pSrc to pDst
270 * Refer to the CAmiPro40File::DecompressObject(~) in LWP
272 sal_uInt16 LwpObjectStream::DecompressBuffer(sal_uInt8* pDst, sal_uInt8* pSrc, sal_uInt16 Size)
274 sal_uInt16 Cnt;
275 sal_uInt32 DstSize = 0;
277 while (Size)
279 switch (*pSrc & 0xC0)
281 case 0x00:
282 // 1 - 64 bytes of 0
283 // Code 00zzzzzz
284 // where zzzzzz is the count - 1 of compressed 0 bytes
286 Cnt = (*pSrc++ & 0x3F) + 1;
287 if (DstSize + Cnt >= IO_BUFFERSIZE)
288 throw BadDecompress();
289 memset(pDst, 0, Cnt);
290 pDst += Cnt;
291 DstSize += Cnt;
292 Size--;
293 break;
295 case 0x40:
296 // 1 - 8 zeros followed by 1 - 8 non-zero
297 // Code 01zzznnn binary
298 // where zzz is the count - 1 of compressed zero bytes
299 // and nnn is the count - 1 of following non-zero bytes
301 Cnt = ((*pSrc & 0x38) >> 3) + 1;
302 if (DstSize + Cnt >= IO_BUFFERSIZE)
303 throw BadDecompress();
304 memset(pDst, 0, Cnt);
305 pDst += Cnt;
306 DstSize += Cnt;
307 Cnt = (*pSrc++ & 0x07) + 1;
308 if (Size < Cnt + 1)
309 throw BadDecompress();
310 Size -= Cnt + 1;
311 if (DstSize + Cnt >= IO_BUFFERSIZE)
312 throw BadDecompress();
313 memcpy(pDst, pSrc, Cnt);
314 pDst += Cnt;
315 DstSize += Cnt;
316 pSrc += Cnt;
317 break;
319 case 0x80:
320 // 1 0 followed by 1 - 64 bytes of non-zero
321 // Code 0x80 (or 0x40 if 8 or less non-zero)
322 // Code 10nnnnnn binary
323 // where nnnnnn is the count - 1 of following non-zero bytes
325 *pDst++ = 0;
326 DstSize++;
327 [[fallthrough]];
329 case 0xC0:
330 // 1 - 64 bytes of non-zero
331 // Code = 11nnnnnn binary
332 // nnnnnn is the count less 1 of following non-zero bytes
334 Cnt = (*pSrc++ & 0x3F) + 1;
335 if (Size < Cnt + 1)
336 throw BadDecompress();
337 Size -= Cnt + 1;
338 if (DstSize + Cnt >= IO_BUFFERSIZE)
339 throw BadDecompress();
340 memcpy(pDst, pSrc, Cnt);
341 pDst += Cnt;
342 DstSize += Cnt;
343 pSrc += Cnt;
344 break;
346 assert(DstSize < IO_BUFFERSIZE);
347 if (DstSize >= IO_BUFFERSIZE)
348 throw BadDecompress();
350 return static_cast<sal_uInt16>(DstSize);
353 * @descr quick read string with 1252
355 OUString LwpObjectStream::QuickReadStringPtr()
357 sal_uInt16 diskSize;
359 diskSize = QuickReaduInt16();
360 QuickReaduInt16(); //len
362 OUString str;
363 if (diskSize < sizeof diskSize)
364 throw std::range_error("Too small size");
365 LwpTools::QuickReadUnicode(this, str, diskSize - sizeof(diskSize), RTL_TEXTENCODING_MS_1252);
366 return str;
369 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */