hunspell: no need for autoreconf when not patching configure
[LibreOffice.git] / vcl / headless / svpbmp.cxx
blob824fb847a7325d602ad275c42f38f197b614a6bd
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>
21 #include <sal/log.hxx>
23 #include <cstring>
25 #include <headless/svpbmp.hxx>
26 #include <headless/svpgdi.hxx>
27 #include <headless/svpinst.hxx>
29 #include <basegfx/vector/b2ivector.hxx>
30 #include <basegfx/range/b2ibox.hxx>
31 #include <o3tl/safeint.hxx>
32 #include <vcl/salbtype.hxx>
33 #include <vcl/bitmap.hxx>
35 using namespace basegfx;
37 SvpSalBitmap::~SvpSalBitmap()
39 Destroy();
42 static std::unique_ptr<BitmapBuffer> ImplCreateDIB(
43 const Size& rSize,
44 sal_uInt16 nBitCount,
45 const BitmapPalette& rPal)
47 assert(
48 (nBitCount == 0
49 || nBitCount == 1
50 || nBitCount == 4
51 || nBitCount == 8
52 || nBitCount == 16
53 || nBitCount == 24
54 || nBitCount == 32)
55 && "Unsupported BitCount!");
57 if (!rSize.Width() || !rSize.Height())
58 return nullptr;
60 std::unique_ptr<BitmapBuffer> pDIB;
62 try
64 pDIB.reset(new BitmapBuffer);
66 catch (const std::bad_alloc&)
68 return nullptr;
71 const sal_uInt16 nColors = ( nBitCount <= 8 ) ? ( 1 << nBitCount ) : 0;
73 switch (nBitCount)
75 case 1:
76 pDIB->mnFormat = ScanlineFormat::N1BitLsbPal;
77 break;
78 case 4:
79 pDIB->mnFormat = ScanlineFormat::N4BitMsnPal;
80 break;
81 case 8:
82 pDIB->mnFormat = ScanlineFormat::N8BitPal;
83 break;
84 case 16:
86 #ifdef OSL_BIGENDIAN
87 pDIB->mnFormat= ScanlineFormat::N16BitTcMsbMask;
88 #else
89 pDIB->mnFormat= ScanlineFormat::N16BitTcLsbMask;
90 #endif
91 ColorMaskElement aRedMask(0xf800);
92 aRedMask.CalcMaskShift();
93 ColorMaskElement aGreenMask(0x07e0);
94 aGreenMask.CalcMaskShift();
95 ColorMaskElement aBlueMask(0x001f);
96 aBlueMask.CalcMaskShift();
97 pDIB->maColorMask = ColorMask(aRedMask, aGreenMask, aBlueMask);
98 break;
100 case 24:
101 pDIB->mnFormat = SVP_24BIT_FORMAT;
102 break;
103 default:
104 nBitCount = 32;
105 SAL_FALLTHROUGH;
106 case 32:
107 pDIB->mnFormat = SVP_CAIRO_FORMAT;
108 break;
111 pDIB->mnFormat |= ScanlineFormat::TopDown;
112 pDIB->mnWidth = rSize.Width();
113 pDIB->mnHeight = rSize.Height();
114 long nScanlineBase;
115 bool bFail = o3tl::checked_multiply<long>(pDIB->mnWidth, nBitCount, nScanlineBase);
116 if (bFail)
118 SAL_WARN("vcl.gdi", "checked multiply failed");
119 return nullptr;
121 pDIB->mnScanlineSize = AlignedWidth4Bytes(nScanlineBase);
122 if (pDIB->mnScanlineSize < nScanlineBase/8)
124 SAL_WARN("vcl.gdi", "scanline calculation wraparound");
125 return nullptr;
127 pDIB->mnBitCount = nBitCount;
129 if( nColors )
131 pDIB->maPalette = rPal;
132 pDIB->maPalette.SetEntryCount( nColors );
135 size_t size;
136 bFail = o3tl::checked_multiply<size_t>(pDIB->mnHeight, pDIB->mnScanlineSize, size);
137 SAL_WARN_IF(bFail, "vcl.gdi", "checked multiply failed");
138 if (bFail || size > SAL_MAX_INT32/2)
140 return nullptr;
145 pDIB->mpBits = new sal_uInt8[size];
146 #ifdef __SANITIZE_ADDRESS__
147 if (!pDIB->mpBits)
148 { // can only happen with ASAN allocator_may_return_null=1
149 pDIB.reset();
151 else
152 #endif
154 std::memset(pDIB->mpBits, 0, size);
157 catch (const std::bad_alloc&)
159 pDIB.reset();
162 return pDIB;
165 void SvpSalBitmap::Create(std::unique_ptr<BitmapBuffer> pBuf)
167 Destroy();
168 mpDIB = std::move(pBuf);
171 bool SvpSalBitmap::Create(const Size& rSize, sal_uInt16 nBitCount, const BitmapPalette& rPal)
173 Destroy();
174 mpDIB = ImplCreateDIB( rSize, nBitCount, rPal );
175 return mpDIB != nullptr;
178 bool SvpSalBitmap::Create(const SalBitmap& rBmp)
180 Destroy();
182 const SvpSalBitmap& rSalBmp = static_cast<const SvpSalBitmap&>(rBmp);
184 if (rSalBmp.mpDIB)
186 // TODO: reference counting...
187 mpDIB.reset(new BitmapBuffer( *rSalBmp.mpDIB ));
189 const size_t size = mpDIB->mnScanlineSize * mpDIB->mnHeight;
190 if (size > SAL_MAX_INT32/2)
192 mpDIB.reset();
193 return false;
196 // TODO: get rid of this when BitmapBuffer gets copy constructor
199 mpDIB->mpBits = new sal_uInt8[size];
200 std::memcpy(mpDIB->mpBits, rSalBmp.mpDIB->mpBits, size);
202 catch (const std::bad_alloc&)
204 mpDIB.reset();
208 return !rSalBmp.mpDIB || (mpDIB != nullptr);
211 bool SvpSalBitmap::Create( const SalBitmap& /*rSalBmp*/,
212 SalGraphics* /*pGraphics*/ )
214 return false;
217 bool SvpSalBitmap::Create( const SalBitmap& /*rSalBmp*/,
218 sal_uInt16 /*nNewBitCount*/ )
220 return false;
223 bool SvpSalBitmap::Create( const css::uno::Reference< css::rendering::XBitmapCanvas >& /*xBitmapCanvas*/, Size& /*rSize*/, bool /*bMask*/ )
225 return false;
228 void SvpSalBitmap::Destroy()
230 if (mpDIB)
232 delete[] mpDIB->mpBits;
233 mpDIB.reset();
237 Size SvpSalBitmap::GetSize() const
239 Size aSize;
241 if (mpDIB)
243 aSize.setWidth( mpDIB->mnWidth );
244 aSize.setHeight( mpDIB->mnHeight );
247 return aSize;
250 sal_uInt16 SvpSalBitmap::GetBitCount() const
252 sal_uInt16 nBitCount;
254 if (mpDIB)
255 nBitCount = mpDIB->mnBitCount;
256 else
257 nBitCount = 0;
259 return nBitCount;
262 BitmapBuffer* SvpSalBitmap::AcquireBuffer(BitmapAccessMode)
264 return mpDIB.get();
267 void SvpSalBitmap::ReleaseBuffer(BitmapBuffer*, BitmapAccessMode nMode)
269 if( nMode == BitmapAccessMode::Write )
270 InvalidateChecksum();
273 bool SvpSalBitmap::GetSystemData( BitmapSystemData& )
275 return false;
278 bool SvpSalBitmap::ScalingSupported() const
280 return false;
283 bool SvpSalBitmap::Scale( const double& /*rScaleX*/, const double& /*rScaleY*/, BmpScaleFlag /*nScaleFlag*/ )
285 return false;
288 bool SvpSalBitmap::Replace( const ::Color& /*rSearchColor*/, const ::Color& /*rReplaceColor*/, sal_uInt8 /*nTol*/ )
290 return false;
293 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */