Version 6.1.4.1, tag libreoffice-6.1.4.1
[LibreOffice.git] / vcl / headless / svpbmp.cxx
blobed74e702fbee37c66263128c309cf6214637c7a4
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 std::unique_ptr<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 std::unique_ptr<BitmapBuffer> pDIB;
61 try
63 pDIB.reset(new BitmapBuffer);
65 catch (const std::bad_alloc&)
67 return nullptr;
70 const sal_uInt16 nColors = ( nBitCount <= 8 ) ? ( 1 << nBitCount ) : 0;
72 switch (nBitCount)
74 case 1:
75 pDIB->mnFormat = ScanlineFormat::N1BitLsbPal;
76 break;
77 case 4:
78 pDIB->mnFormat = ScanlineFormat::N4BitMsnPal;
79 break;
80 case 8:
81 pDIB->mnFormat = ScanlineFormat::N8BitPal;
82 break;
83 case 16:
85 #ifdef OSL_BIGENDIAN
86 pDIB->mnFormat= ScanlineFormat::N16BitTcMsbMask;
87 #else
88 pDIB->mnFormat= ScanlineFormat::N16BitTcLsbMask;
89 #endif
90 ColorMaskElement aRedMask(0xf800);
91 aRedMask.CalcMaskShift();
92 ColorMaskElement aGreenMask(0x07e0);
93 aGreenMask.CalcMaskShift();
94 ColorMaskElement aBlueMask(0x001f);
95 aBlueMask.CalcMaskShift();
96 pDIB->maColorMask = ColorMask(aRedMask, aGreenMask, aBlueMask);
97 break;
99 case 24:
100 pDIB->mnFormat = SVP_24BIT_FORMAT;
101 break;
102 default:
103 nBitCount = 32;
104 SAL_FALLTHROUGH;
105 case 32:
106 pDIB->mnFormat = SVP_CAIRO_FORMAT;
107 break;
110 pDIB->mnFormat |= ScanlineFormat::TopDown;
111 pDIB->mnWidth = rSize.Width();
112 pDIB->mnHeight = rSize.Height();
113 long nScanlineBase;
114 bool bFail = o3tl::checked_multiply<long>(pDIB->mnWidth, nBitCount, nScanlineBase);
115 if (bFail)
117 SAL_WARN("vcl.gdi", "checked multiply failed");
118 return nullptr;
120 pDIB->mnScanlineSize = AlignedWidth4Bytes(nScanlineBase);
121 if (pDIB->mnScanlineSize < nScanlineBase/8)
123 SAL_WARN("vcl.gdi", "scanline calculation wraparound");
124 return nullptr;
126 pDIB->mnBitCount = nBitCount;
128 if( nColors )
130 pDIB->maPalette = rPal;
131 pDIB->maPalette.SetEntryCount( nColors );
134 size_t size;
135 bFail = o3tl::checked_multiply<size_t>(pDIB->mnHeight, pDIB->mnScanlineSize, size);
136 SAL_WARN_IF(bFail, "vcl.gdi", "checked multiply failed");
137 if (bFail || size > SAL_MAX_INT32/2)
139 return nullptr;
144 pDIB->mpBits = new sal_uInt8[size];
145 #ifdef __SANITIZE_ADDRESS__
146 if (!pDIB->mpBits)
147 { // can only happen with ASAN allocator_may_return_null=1
148 pDIB.reset();
150 else
151 #endif
153 std::memset(pDIB->mpBits, 0, size);
156 catch (const std::bad_alloc&)
158 pDIB.reset();
161 return pDIB;
164 void SvpSalBitmap::Create(std::unique_ptr<BitmapBuffer> pBuf)
166 Destroy();
167 mpDIB = std::move(pBuf);
170 bool SvpSalBitmap::Create(const Size& rSize, sal_uInt16 nBitCount, const BitmapPalette& rPal)
172 Destroy();
173 mpDIB = ImplCreateDIB( rSize, nBitCount, rPal );
174 return mpDIB != nullptr;
177 bool SvpSalBitmap::Create(const SalBitmap& rBmp)
179 Destroy();
181 const SvpSalBitmap& rSalBmp = static_cast<const SvpSalBitmap&>(rBmp);
183 if (rSalBmp.mpDIB)
185 // TODO: reference counting...
186 mpDIB.reset(new BitmapBuffer( *rSalBmp.mpDIB ));
188 const size_t size = mpDIB->mnScanlineSize * mpDIB->mnHeight;
189 if (size > SAL_MAX_INT32/2)
191 mpDIB.reset();
192 return false;
195 // TODO: get rid of this when BitmapBuffer gets copy constructor
198 mpDIB->mpBits = new sal_uInt8[size];
199 std::memcpy(mpDIB->mpBits, rSalBmp.mpDIB->mpBits, size);
201 catch (const std::bad_alloc&)
203 mpDIB.reset();
207 return !rSalBmp.mpDIB || (mpDIB != nullptr);
210 bool SvpSalBitmap::Create( const SalBitmap& /*rSalBmp*/,
211 SalGraphics* /*pGraphics*/ )
213 return false;
216 bool SvpSalBitmap::Create( const SalBitmap& /*rSalBmp*/,
217 sal_uInt16 /*nNewBitCount*/ )
219 return false;
222 bool SvpSalBitmap::Create( const css::uno::Reference< css::rendering::XBitmapCanvas >& /*xBitmapCanvas*/, Size& /*rSize*/, bool /*bMask*/ )
224 return false;
227 void SvpSalBitmap::Destroy()
229 if (mpDIB)
231 delete[] mpDIB->mpBits;
232 mpDIB.reset();
236 Size SvpSalBitmap::GetSize() const
238 Size aSize;
240 if (mpDIB)
242 aSize.setWidth( mpDIB->mnWidth );
243 aSize.setHeight( mpDIB->mnHeight );
246 return aSize;
249 sal_uInt16 SvpSalBitmap::GetBitCount() const
251 sal_uInt16 nBitCount;
253 if (mpDIB)
254 nBitCount = mpDIB->mnBitCount;
255 else
256 nBitCount = 0;
258 return nBitCount;
261 BitmapBuffer* SvpSalBitmap::AcquireBuffer(BitmapAccessMode)
263 return mpDIB.get();
266 void SvpSalBitmap::ReleaseBuffer(BitmapBuffer*, BitmapAccessMode nMode)
268 if( nMode == BitmapAccessMode::Write )
269 InvalidateChecksum();
272 bool SvpSalBitmap::GetSystemData( BitmapSystemData& )
274 return false;
277 bool SvpSalBitmap::ScalingSupported() const
279 return false;
282 bool SvpSalBitmap::Scale( const double& /*rScaleX*/, const double& /*rScaleY*/, BmpScaleFlag /*nScaleFlag*/ )
284 return false;
287 bool SvpSalBitmap::Replace( const ::Color& /*rSearchColor*/, const ::Color& /*rReplaceColor*/, sal_uInt8 /*nTol*/ )
289 return false;
292 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */