nss: upgrade to release 3.73
[LibreOffice.git] / vcl / headless / svpbmp.cxx
blob7dfa5a89eb4124e0eba94e2998383153a493fd21
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()
38 : SalBitmap(),
39 basegfx::SystemDependentDataHolder(), // MM02
40 mpDIB()
44 SvpSalBitmap::~SvpSalBitmap()
46 Destroy();
49 static std::unique_ptr<BitmapBuffer> ImplCreateDIB(
50 const Size& rSize,
51 sal_uInt16 nBitCount,
52 const BitmapPalette& rPal)
54 assert(
55 (nBitCount == 0
56 || nBitCount == 1
57 || nBitCount == 4
58 || nBitCount == 8
59 || nBitCount == 24
60 || nBitCount == 32)
61 && "Unsupported BitCount!");
63 if (!rSize.Width() || !rSize.Height())
64 return nullptr;
66 std::unique_ptr<BitmapBuffer> pDIB;
68 try
70 pDIB.reset(new BitmapBuffer);
72 catch (const std::bad_alloc&)
74 return nullptr;
77 const sal_uInt16 nColors = ( nBitCount <= 8 ) ? ( 1 << nBitCount ) : 0;
79 switch (nBitCount)
81 case 1:
82 pDIB->mnFormat = ScanlineFormat::N1BitLsbPal;
83 break;
84 case 4:
85 pDIB->mnFormat = ScanlineFormat::N4BitMsnPal;
86 break;
87 case 8:
88 pDIB->mnFormat = ScanlineFormat::N8BitPal;
89 break;
90 case 24:
91 pDIB->mnFormat = SVP_24BIT_FORMAT;
92 break;
93 default:
94 nBitCount = 32;
95 [[fallthrough]];
96 case 32:
97 pDIB->mnFormat = SVP_CAIRO_FORMAT;
98 break;
101 pDIB->mnFormat |= ScanlineFormat::TopDown;
102 pDIB->mnWidth = rSize.Width();
103 pDIB->mnHeight = rSize.Height();
104 tools::Long nScanlineBase;
105 bool bFail = o3tl::checked_multiply<tools::Long>(pDIB->mnWidth, nBitCount, nScanlineBase);
106 if (bFail)
108 SAL_WARN("vcl.gdi", "checked multiply failed");
109 return nullptr;
111 pDIB->mnScanlineSize = AlignedWidth4Bytes(nScanlineBase);
112 if (pDIB->mnScanlineSize < nScanlineBase/8)
114 SAL_WARN("vcl.gdi", "scanline calculation wraparound");
115 return nullptr;
117 pDIB->mnBitCount = nBitCount;
119 if( nColors )
121 pDIB->maPalette = rPal;
122 pDIB->maPalette.SetEntryCount( nColors );
125 size_t size;
126 bFail = o3tl::checked_multiply<size_t>(pDIB->mnHeight, pDIB->mnScanlineSize, size);
127 SAL_WARN_IF(bFail, "vcl.gdi", "checked multiply failed");
128 if (bFail || size > SAL_MAX_INT32/2)
130 return nullptr;
135 pDIB->mpBits = new sal_uInt8[size];
136 #ifdef __SANITIZE_ADDRESS__
137 if (!pDIB->mpBits)
138 { // can only happen with ASAN allocator_may_return_null=1
139 pDIB.reset();
141 else
142 #endif
144 std::memset(pDIB->mpBits, 0, size);
147 catch (const std::bad_alloc&)
149 pDIB.reset();
152 return pDIB;
155 void SvpSalBitmap::Create(std::unique_ptr<BitmapBuffer> pBuf)
157 Destroy();
158 mpDIB = std::move(pBuf);
161 bool SvpSalBitmap::Create(const Size& rSize, sal_uInt16 nBitCount, const BitmapPalette& rPal)
163 Destroy();
164 mpDIB = ImplCreateDIB( rSize, nBitCount, rPal );
165 return mpDIB != nullptr;
168 bool SvpSalBitmap::Create(const SalBitmap& rBmp)
170 Destroy();
172 const SvpSalBitmap& rSalBmp = static_cast<const SvpSalBitmap&>(rBmp);
174 if (rSalBmp.mpDIB)
176 // TODO: reference counting...
177 mpDIB.reset(new BitmapBuffer( *rSalBmp.mpDIB ));
179 const size_t size = mpDIB->mnScanlineSize * mpDIB->mnHeight;
180 if (size > SAL_MAX_INT32/2)
182 mpDIB.reset();
183 return false;
186 // TODO: get rid of this when BitmapBuffer gets copy constructor
189 mpDIB->mpBits = new sal_uInt8[size];
190 std::memcpy(mpDIB->mpBits, rSalBmp.mpDIB->mpBits, size);
192 catch (const std::bad_alloc&)
194 mpDIB.reset();
198 return !rSalBmp.mpDIB || (mpDIB != nullptr);
201 bool SvpSalBitmap::Create( const SalBitmap& /*rSalBmp*/,
202 SalGraphics* /*pGraphics*/ )
204 return false;
207 bool SvpSalBitmap::Create( const SalBitmap& /*rSalBmp*/,
208 sal_uInt16 /*nNewBitCount*/ )
210 return false;
213 bool SvpSalBitmap::Create( const css::uno::Reference< css::rendering::XBitmapCanvas >& /*xBitmapCanvas*/, Size& /*rSize*/, bool /*bMask*/ )
215 return false;
218 void SvpSalBitmap::Destroy()
220 if (mpDIB)
222 delete[] mpDIB->mpBits;
223 mpDIB.reset();
227 Size SvpSalBitmap::GetSize() const
229 Size aSize;
231 if (mpDIB)
233 aSize.setWidth( mpDIB->mnWidth );
234 aSize.setHeight( mpDIB->mnHeight );
237 return aSize;
240 sal_uInt16 SvpSalBitmap::GetBitCount() const
242 sal_uInt16 nBitCount;
244 if (mpDIB)
245 nBitCount = mpDIB->mnBitCount;
246 else
247 nBitCount = 0;
249 return nBitCount;
252 BitmapBuffer* SvpSalBitmap::AcquireBuffer(BitmapAccessMode)
254 return mpDIB.get();
257 void SvpSalBitmap::ReleaseBuffer(BitmapBuffer*, BitmapAccessMode nMode)
259 if( nMode == BitmapAccessMode::Write )
260 InvalidateChecksum();
263 bool SvpSalBitmap::GetSystemData( BitmapSystemData& )
265 return false;
268 bool SvpSalBitmap::ScalingSupported() const
270 return false;
273 bool SvpSalBitmap::Scale( const double& /*rScaleX*/, const double& /*rScaleY*/, BmpScaleFlag /*nScaleFlag*/ )
275 return false;
278 bool SvpSalBitmap::Replace( const ::Color& /*rSearchColor*/, const ::Color& /*rReplaceColor*/, sal_uInt8 /*nTol*/ )
280 return false;
283 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */