bump product version to 6.4.0.3
[LibreOffice.git] / vcl / headless / svpbmp.cxx
blob6dd5aeb64bfbf00e52c88ef435fd8206073375c5
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 <tools/helpers.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 == 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 24:
84 pDIB->mnFormat = SVP_24BIT_FORMAT;
85 break;
86 default:
87 nBitCount = 32;
88 [[fallthrough]];
89 case 32:
90 pDIB->mnFormat = SVP_CAIRO_FORMAT;
91 break;
94 pDIB->mnFormat |= ScanlineFormat::TopDown;
95 pDIB->mnWidth = rSize.Width();
96 pDIB->mnHeight = rSize.Height();
97 long nScanlineBase;
98 bool bFail = o3tl::checked_multiply<long>(pDIB->mnWidth, nBitCount, nScanlineBase);
99 if (bFail)
101 SAL_WARN("vcl.gdi", "checked multiply failed");
102 return nullptr;
104 pDIB->mnScanlineSize = AlignedWidth4Bytes(nScanlineBase);
105 if (pDIB->mnScanlineSize < nScanlineBase/8)
107 SAL_WARN("vcl.gdi", "scanline calculation wraparound");
108 return nullptr;
110 pDIB->mnBitCount = nBitCount;
112 if( nColors )
114 pDIB->maPalette = rPal;
115 pDIB->maPalette.SetEntryCount( nColors );
118 size_t size;
119 bFail = o3tl::checked_multiply<size_t>(pDIB->mnHeight, pDIB->mnScanlineSize, size);
120 SAL_WARN_IF(bFail, "vcl.gdi", "checked multiply failed");
121 if (bFail || size > SAL_MAX_INT32/2)
123 return nullptr;
128 pDIB->mpBits = new sal_uInt8[size];
129 #ifdef __SANITIZE_ADDRESS__
130 if (!pDIB->mpBits)
131 { // can only happen with ASAN allocator_may_return_null=1
132 pDIB.reset();
134 else
135 #endif
137 std::memset(pDIB->mpBits, 0, size);
140 catch (const std::bad_alloc&)
142 pDIB.reset();
145 return pDIB;
148 void SvpSalBitmap::Create(std::unique_ptr<BitmapBuffer> pBuf)
150 Destroy();
151 mpDIB = std::move(pBuf);
154 bool SvpSalBitmap::Create(const Size& rSize, sal_uInt16 nBitCount, const BitmapPalette& rPal)
156 Destroy();
157 mpDIB = ImplCreateDIB( rSize, nBitCount, rPal );
158 return mpDIB != nullptr;
161 bool SvpSalBitmap::Create(const SalBitmap& rBmp)
163 Destroy();
165 const SvpSalBitmap& rSalBmp = static_cast<const SvpSalBitmap&>(rBmp);
167 if (rSalBmp.mpDIB)
169 // TODO: reference counting...
170 mpDIB.reset(new BitmapBuffer( *rSalBmp.mpDIB ));
172 const size_t size = mpDIB->mnScanlineSize * mpDIB->mnHeight;
173 if (size > SAL_MAX_INT32/2)
175 mpDIB.reset();
176 return false;
179 // TODO: get rid of this when BitmapBuffer gets copy constructor
182 mpDIB->mpBits = new sal_uInt8[size];
183 std::memcpy(mpDIB->mpBits, rSalBmp.mpDIB->mpBits, size);
185 catch (const std::bad_alloc&)
187 mpDIB.reset();
191 return !rSalBmp.mpDIB || (mpDIB != nullptr);
194 bool SvpSalBitmap::Create( const SalBitmap& /*rSalBmp*/,
195 SalGraphics* /*pGraphics*/ )
197 return false;
200 bool SvpSalBitmap::Create( const SalBitmap& /*rSalBmp*/,
201 sal_uInt16 /*nNewBitCount*/ )
203 return false;
206 bool SvpSalBitmap::Create( const css::uno::Reference< css::rendering::XBitmapCanvas >& /*xBitmapCanvas*/, Size& /*rSize*/, bool /*bMask*/ )
208 return false;
211 void SvpSalBitmap::Destroy()
213 if (mpDIB)
215 delete[] mpDIB->mpBits;
216 mpDIB.reset();
220 Size SvpSalBitmap::GetSize() const
222 Size aSize;
224 if (mpDIB)
226 aSize.setWidth( mpDIB->mnWidth );
227 aSize.setHeight( mpDIB->mnHeight );
230 return aSize;
233 sal_uInt16 SvpSalBitmap::GetBitCount() const
235 sal_uInt16 nBitCount;
237 if (mpDIB)
238 nBitCount = mpDIB->mnBitCount;
239 else
240 nBitCount = 0;
242 return nBitCount;
245 BitmapBuffer* SvpSalBitmap::AcquireBuffer(BitmapAccessMode)
247 return mpDIB.get();
250 void SvpSalBitmap::ReleaseBuffer(BitmapBuffer*, BitmapAccessMode nMode)
252 if( nMode == BitmapAccessMode::Write )
253 InvalidateChecksum();
256 bool SvpSalBitmap::GetSystemData( BitmapSystemData& )
258 return false;
261 bool SvpSalBitmap::ScalingSupported() const
263 return false;
266 bool SvpSalBitmap::Scale( const double& /*rScaleX*/, const double& /*rScaleY*/, BmpScaleFlag /*nScaleFlag*/ )
268 return false;
271 bool SvpSalBitmap::Replace( const ::Color& /*rSearchColor*/, const ::Color& /*rReplaceColor*/, sal_uInt8 /*nTol*/ )
273 return false;
276 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */