Version 5.4.3.2, tag libreoffice-5.4.3.2
[LibreOffice.git] / vcl / headless / svpbmp.cxx
blob5ff0b0a978ee57fd450b5938ff7aae774cf33c22
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 .
20 #include <sal/config.h>
22 #include <cstring>
24 #include "headless/svpbmp.hxx"
25 #include "headless/svpgdi.hxx"
26 #include "headless/svpinst.hxx"
28 #include <basegfx/vector/b2ivector.hxx>
29 #include <basegfx/range/b2ibox.hxx>
30 #include <o3tl/safeint.hxx>
31 #include <vcl/salbtype.hxx>
32 #include <vcl/bitmap.hxx>
34 using namespace basegfx;
36 SvpSalBitmap::~SvpSalBitmap()
38 Destroy();
41 BitmapBuffer* ImplCreateDIB(
42 const Size& rSize,
43 sal_uInt16 nBitCount,
44 const BitmapPalette& rPal)
46 assert(
47 (nBitCount == 0
48 || nBitCount == 1
49 || nBitCount == 4
50 || nBitCount == 8
51 || nBitCount == 16
52 || nBitCount == 24
53 || nBitCount == 32)
54 && "Unsupported BitCount!");
56 if (!rSize.Width() || !rSize.Height())
57 return nullptr;
59 BitmapBuffer* pDIB = nullptr;
61 try
63 pDIB = new BitmapBuffer;
65 catch (const std::bad_alloc&)
67 pDIB = nullptr;
70 if(!pDIB)
71 return nullptr;
73 const sal_uInt16 nColors = ( nBitCount <= 8 ) ? ( 1 << nBitCount ) : 0;
75 switch (nBitCount)
77 case 1:
78 pDIB->mnFormat = ScanlineFormat::N1BitLsbPal;
79 break;
80 case 4:
81 pDIB->mnFormat = ScanlineFormat::N4BitMsnPal;
82 break;
83 case 8:
84 pDIB->mnFormat = ScanlineFormat::N8BitPal;
85 break;
86 case 16:
88 #ifdef OSL_BIGENDIAN
89 pDIB->mnFormat= ScanlineFormat::N16BitTcMsbMask;
90 #else
91 pDIB->mnFormat= ScanlineFormat::N16BitTcLsbMask;
92 #endif
93 ColorMaskElement aRedMask(0xf800);
94 aRedMask.CalcMaskShift();
95 ColorMaskElement aGreenMask(0x07e0);
96 aGreenMask.CalcMaskShift();
97 ColorMaskElement aBlueMask(0x001f);
98 aBlueMask.CalcMaskShift();
99 pDIB->maColorMask = ColorMask(aRedMask, aGreenMask, aBlueMask);
100 break;
102 default:
103 nBitCount = 32;
104 SAL_FALLTHROUGH;
105 case 32:
107 pDIB->mnFormat = SVP_CAIRO_FORMAT;
108 break;
112 pDIB->mnFormat |= ScanlineFormat::TopDown;
113 pDIB->mnWidth = rSize.Width();
114 pDIB->mnHeight = rSize.Height();
115 long nScanlineBase;
116 bool bFail = o3tl::checked_multiply<long>(pDIB->mnWidth, nBitCount, nScanlineBase);
117 if (bFail)
119 SAL_WARN("vcl.gdi", "checked multiply failed");
120 delete pDIB;
121 return nullptr;
123 pDIB->mnScanlineSize = AlignedWidth4Bytes(nScanlineBase);
124 if (pDIB->mnScanlineSize < nScanlineBase/8)
126 SAL_WARN("vcl.gdi", "scanline calculation wraparound");
127 delete pDIB;
128 return nullptr;
130 pDIB->mnBitCount = nBitCount;
132 if( nColors )
134 pDIB->maPalette = rPal;
135 pDIB->maPalette.SetEntryCount( nColors );
138 size_t size;
139 bFail = o3tl::checked_multiply<size_t>(pDIB->mnHeight, pDIB->mnScanlineSize, size);
140 SAL_WARN_IF(bFail, "vcl.gdi", "checked multiply failed");
141 if (bFail || size > SAL_MAX_INT32/2)
143 delete pDIB;
144 return nullptr;
149 pDIB->mpBits = new sal_uInt8[size];
150 #ifdef __SANITIZE_ADDRESS__
151 if (!pDIB->mpBits)
152 { // can only happen with ASAN allocator_may_return_null=1
153 delete pDIB;
154 pDIB = nullptr;
156 else
157 #endif
159 std::memset(pDIB->mpBits, 0, size);
162 catch (const std::bad_alloc&)
164 delete pDIB;
165 pDIB = nullptr;
168 return pDIB;
171 bool SvpSalBitmap::Create(BitmapBuffer *pBuf)
173 Destroy();
174 mpDIB = pBuf;
175 return mpDIB != nullptr;
178 bool SvpSalBitmap::Create(const Size& rSize, sal_uInt16 nBitCount, const BitmapPalette& rPal)
180 Destroy();
181 mpDIB = ImplCreateDIB( rSize, nBitCount, rPal );
182 return mpDIB != nullptr;
185 bool SvpSalBitmap::Create(const SalBitmap& rBmp)
187 Destroy();
189 const SvpSalBitmap& rSalBmp = static_cast<const SvpSalBitmap&>(rBmp);
191 if (rSalBmp.mpDIB)
193 // TODO: reference counting...
194 mpDIB = new BitmapBuffer( *rSalBmp.mpDIB );
196 const size_t size = mpDIB->mnScanlineSize * mpDIB->mnHeight;
197 if (size > SAL_MAX_INT32/2)
199 delete mpDIB;
200 mpDIB = nullptr;
201 return false;
204 // TODO: get rid of this when BitmapBuffer gets copy constructor
207 mpDIB->mpBits = new sal_uInt8[size];
208 std::memcpy(mpDIB->mpBits, rSalBmp.mpDIB->mpBits, size);
210 catch (const std::bad_alloc&)
212 delete mpDIB;
213 mpDIB = nullptr;
217 return !rSalBmp.mpDIB || (mpDIB != nullptr);
220 bool SvpSalBitmap::Create( const SalBitmap& /*rSalBmp*/,
221 SalGraphics* /*pGraphics*/ )
223 return false;
226 bool SvpSalBitmap::Create( const SalBitmap& /*rSalBmp*/,
227 sal_uInt16 /*nNewBitCount*/ )
229 return false;
232 bool SvpSalBitmap::Create( const css::uno::Reference< css::rendering::XBitmapCanvas >& /*xBitmapCanvas*/, Size& /*rSize*/, bool /*bMask*/ )
234 return false;
237 void SvpSalBitmap::Destroy()
239 if (mpDIB)
241 delete[] mpDIB->mpBits;
242 delete mpDIB;
243 mpDIB = nullptr;
247 Size SvpSalBitmap::GetSize() const
249 Size aSize;
251 if (mpDIB)
253 aSize.Width() = mpDIB->mnWidth;
254 aSize.Height() = mpDIB->mnHeight;
257 return aSize;
260 sal_uInt16 SvpSalBitmap::GetBitCount() const
262 sal_uInt16 nBitCount;
264 if (mpDIB)
265 nBitCount = mpDIB->mnBitCount;
266 else
267 nBitCount = 0;
269 return nBitCount;
272 BitmapBuffer* SvpSalBitmap::AcquireBuffer(BitmapAccessMode)
274 return mpDIB;
277 void SvpSalBitmap::ReleaseBuffer(BitmapBuffer*, BitmapAccessMode)
281 bool SvpSalBitmap::GetSystemData( BitmapSystemData& )
283 return false;
286 bool SvpSalBitmap::ScalingSupported() const
288 return false;
291 bool SvpSalBitmap::Scale( const double& /*rScaleX*/, const double& /*rScaleY*/, BmpScaleFlag /*nScaleFlag*/ )
293 return false;
296 bool SvpSalBitmap::Replace( const ::Color& /*rSearchColor*/, const ::Color& /*rReplaceColor*/, sal_uLong /*nTol*/ )
298 return false;
301 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */