LibreOffice Module vcl (master)  1
bmpacc.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
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/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
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 .
18  */
19 
20 #include <vcl/bitmap.hxx>
21 #include <vcl/bitmapaccess.hxx>
22 
23 #include <bitmapwriteaccess.hxx>
24 #include <salbmp.hxx>
25 #include <svdata.hxx>
26 #include <salinst.hxx>
27 #include <bmpfast.hxx>
28 
29 #include <string.h>
30 #include <sal/log.hxx>
31 #include <tools/debug.hxx>
32 
34  mpBuffer ( nullptr ),
35  mnAccessMode ( nMode )
36 {
37  std::shared_ptr<SalBitmap> xImpBmp = rBitmap.ImplGetSalBitmap();
38 
39  if( !xImpBmp )
40  return;
41 
43  {
44  xImpBmp->DropScaledCache();
45 
46  if (xImpBmp.use_count() > 2)
47  {
48  xImpBmp.reset();
49  rBitmap.ImplMakeUnique();
50  xImpBmp = rBitmap.ImplGetSalBitmap();
51  }
52  }
53 
54  mpBuffer = xImpBmp->AcquireBuffer( mnAccessMode );
55 
56  if( !mpBuffer )
57  {
58  std::shared_ptr<SalBitmap> xNewImpBmp(ImplGetSVData()->mpDefInst->CreateSalBitmap());
59  if (xNewImpBmp->Create(*xImpBmp, rBitmap.GetBitCount()))
60  {
61  xImpBmp = xNewImpBmp;
62  rBitmap.ImplSetSalBitmap( xImpBmp );
63  mpBuffer = xImpBmp->AcquireBuffer( mnAccessMode );
64  }
65  }
66 
67  maBitmap = rBitmap;
68 }
69 
71 {
72  std::shared_ptr<SalBitmap> xImpBmp = maBitmap.ImplGetSalBitmap();
73 
74  if (mpBuffer && xImpBmp)
75  {
76  xImpBmp->ReleaseBuffer( mpBuffer, mnAccessMode );
77  }
78 }
79 
80 sal_uInt16 BitmapInfoAccess::GetBestPaletteIndex( const BitmapColor& rBitmapColor ) const
81 {
82  return( HasPalette() ? mpBuffer->maPalette.GetBestIndex( rBitmapColor ) : 0 );
83 }
84 
86  BitmapInfoAccess( rBitmap, nMode ),
87  mFncGetPixel ( nullptr ),
88  mFncSetPixel ( nullptr )
89 {
90  if (!mpBuffer)
91  return;
92 
93  const std::shared_ptr<SalBitmap>& xImpBmp = rBitmap.ImplGetSalBitmap();
94  if (!xImpBmp)
95  return;
96 
98 
101 
102  if (!mFncGetPixel || !mFncSetPixel)
103  {
104  xImpBmp->ReleaseBuffer( mpBuffer, mnAccessMode );
105  mpBuffer = nullptr;
106  }
107 }
108 
110 {
111 }
112 
113 namespace
114 {
115  bool Bitmap32IsPreMultipled()
116  {
117  auto pBackendCapabilities = ImplGetSVData()->mpDefInst->GetBackendCapabilities();
118  return pBackendCapabilities->mbSupportsBitmap32;
119  }
120 }
121 
123 {
124  switch( RemoveScanline( nFormat ))
125  {
127  return GetPixelForN1BitMsbPal;
129  return GetPixelForN1BitLsbPal;
131  return GetPixelForN4BitMsnPal;
133  return GetPixelForN4BitLsnPal;
135  return GetPixelForN8BitPal;
137  return GetPixelForN24BitTcBgr;
139  return GetPixelForN24BitTcRgb;
141  if (Bitmap32IsPreMultipled())
143  else
146  if (Bitmap32IsPreMultipled())
148  else
151  if (Bitmap32IsPreMultipled())
153  else
156  if (Bitmap32IsPreMultipled())
158  else
162 
163  default:
164  return nullptr;
165  }
166 }
167 
169 {
170  switch( RemoveScanline( nFormat ))
171  {
173  return SetPixelForN1BitMsbPal;
175  return SetPixelForN1BitLsbPal;
177  return SetPixelForN4BitMsnPal;
179  return SetPixelForN4BitLsnPal;
181  return SetPixelForN8BitPal;
183  return SetPixelForN24BitTcBgr;
185  return SetPixelForN24BitTcRgb;
187  if (Bitmap32IsPreMultipled())
189  else
192  if (Bitmap32IsPreMultipled())
194  else
197  if (Bitmap32IsPreMultipled())
199  else
202  if (Bitmap32IsPreMultipled())
204  else
208  break;
209 
210  default:
211  return nullptr;
212  }
213 }
214 
215 BitmapColor BitmapReadAccess::GetInterpolatedColorWithFallback( double fY, double fX, const BitmapColor& rFallback ) const
216 {
217  // ask directly doubles >= 0.0 here to avoid rounded values of 0 at small negative
218  // double values, e.g. static_cast< sal_Int32 >(-0.25) is 0, not -1, but *has* to be outside (!)
219  if(mpBuffer && fX >= 0.0 && fY >= 0.0)
220  {
221  const sal_Int64 nX(static_cast<sal_Int64>(fX));
222  const sal_Int64 nY(static_cast<sal_Int64>(fY));
223 
224  if(nX < mpBuffer->mnWidth && nY < mpBuffer->mnHeight)
225  {
226  // get base-return value from inside pixel
227  BitmapColor aRetval(GetColor(nY, nX));
228 
229  // calculate deltas and indices for neighbour accesses
230  sal_Int16 nDeltaX((fX - (nX + 0.5)) * 255.0); // [-255 .. 255]
231  sal_Int16 nDeltaY((fY - (nY + 0.5)) * 255.0); // [-255 .. 255]
232  sal_Int16 nIndX(0);
233  sal_Int16 nIndY(0);
234 
235  if(nDeltaX > 0)
236  {
237  nIndX = nX + 1;
238  }
239  else
240  {
241  nIndX = nX - 1;
242  nDeltaX = -nDeltaX;
243  }
244 
245  if(nDeltaY > 0)
246  {
247  nIndY = nY + 1;
248  }
249  else
250  {
251  nIndY = nY - 1;
252  nDeltaY = -nDeltaY;
253  }
254 
255  // get right/left neighbour
256  BitmapColor aXCol(rFallback);
257 
258  if(nDeltaX && nIndX >= 0 && nIndX < mpBuffer->mnWidth)
259  {
260  aXCol = GetColor(nY, nIndX);
261  }
262 
263  // get top/bottom neighbour
264  BitmapColor aYCol(rFallback);
265 
266  if(nDeltaY && nIndY >= 0 && nIndY < mpBuffer->mnHeight)
267  {
268  aYCol = GetColor(nIndY, nX);
269  }
270 
271  // get one of four edge neighbours
272  BitmapColor aXYCol(rFallback);
273 
274  if(nDeltaX && nDeltaY && nIndX >=0 && nIndY >= 0 && nIndX < mpBuffer->mnWidth && nIndY < mpBuffer->mnHeight)
275  {
276  aXYCol = GetColor(nIndY, nIndX);
277  }
278 
279  // merge return value with right/left neighbour
280  if(aXCol != aRetval)
281  {
282  aRetval.Merge(aXCol, 255 - nDeltaX);
283  }
284 
285  // merge top/bottom neighbour with edge
286  if(aYCol != aXYCol)
287  {
288  aYCol.Merge(aXYCol, 255 - nDeltaX);
289  }
290 
291  // merge return value with already merged top/bottom neighbour
292  if(aRetval != aYCol)
293  {
294  aRetval.Merge(aYCol, 255 - nDeltaY);
295  }
296 
297  return aRetval;
298  }
299  }
300 
301  return rFallback;
302 }
303 
304 BitmapColor BitmapReadAccess::GetColorWithFallback( double fY, double fX, const BitmapColor& rFallback ) const
305 {
306  // ask directly doubles >= 0.0 here to avoid rounded values of 0 at small negative
307  // double values, e.g. static_cast< sal_Int32 >(-0.25) is 0, not -1, but *has* to be outside (!)
308  if(mpBuffer && fX >= 0.0 && fY >= 0.0)
309  {
310  const sal_Int32 nX(static_cast< sal_Int32 >(fX));
311  const sal_Int32 nY(static_cast< sal_Int32 >(fY));
312 
313  if(nX < mpBuffer->mnWidth && nY < mpBuffer->mnHeight)
314  {
315  return GetColor(nY, nX);
316  }
317  }
318 
319  return rFallback;
320 }
321 
324 {
325 }
326 
328 {
329 }
330 
332 {
333  assert(nY >= 0 && nY < mpBuffer->mnHeight && "y-coordinate in destination out of range!");
334  SAL_WARN_IF( nY >= rReadAcc.Height(), "vcl", "y-coordinate in source out of range!" );
335  SAL_WARN_IF( ( !HasPalette() || !rReadAcc.HasPalette() ) && ( HasPalette() || rReadAcc.HasPalette() ), "vcl", "No copying possible between palette bitmap and TC bitmap!" );
336 
337  if( ( GetScanlineFormat() == rReadAcc.GetScanlineFormat() ) &&
338  ( GetScanlineSize() >= rReadAcc.GetScanlineSize() ) )
339  {
340  memcpy(GetScanline(nY), rReadAcc.GetScanline(nY), rReadAcc.GetScanlineSize());
341  }
342  else
343  {
344  tools::Long nWidth = std::min( mpBuffer->mnWidth, rReadAcc.Width() );
346  {
347  Scanline pScanline = GetScanline( nY );
348  Scanline pScanlineRead = rReadAcc.GetScanline(nY);
349  for( tools::Long nX = 0; nX < nWidth; nX++ )
350  SetPixelOnData( pScanline, nX, rReadAcc.GetPixelFromData( pScanlineRead, nX ) );
351  }
352  }
353 }
354 
356  ScanlineFormat nSrcScanlineFormat, sal_uInt32 nSrcScanlineSize )
357 {
358  const ScanlineFormat nFormat = RemoveScanline( nSrcScanlineFormat );
359 
360  assert(nY >= 0 && nY < mpBuffer->mnHeight && "y-coordinate in destination out of range!");
361  DBG_ASSERT( ( HasPalette() && nFormat <= ScanlineFormat::N8BitPal ) ||
362  ( !HasPalette() && nFormat > ScanlineFormat::N8BitPal ),
363  "No copying possible between palette and non palette scanlines!" );
364 
365  const sal_uLong nCount = std::min( GetScanlineSize(), nSrcScanlineSize );
366 
367  if( !nCount )
368  return;
369 
370  if( GetScanlineFormat() == RemoveScanline( nSrcScanlineFormat ) )
371  memcpy(GetScanline(nY), aSrcScanline, nCount);
372  else
373  {
374  if(ImplFastCopyScanline( nY, *ImplGetBitmapBuffer(), aSrcScanline, nSrcScanlineFormat, nSrcScanlineSize ))
375  return;
376 
378  "No support for pixel formats with color masks yet!" );
379  FncGetPixel pFncGetPixel;
380  switch( nFormat )
381  {
382  case ScanlineFormat::N1BitMsbPal: pFncGetPixel = GetPixelForN1BitMsbPal; break;
383  case ScanlineFormat::N1BitLsbPal: pFncGetPixel = GetPixelForN1BitLsbPal; break;
384  case ScanlineFormat::N4BitMsnPal: pFncGetPixel = GetPixelForN4BitMsnPal; break;
385  case ScanlineFormat::N4BitLsnPal: pFncGetPixel = GetPixelForN4BitLsnPal; break;
386  case ScanlineFormat::N8BitPal: pFncGetPixel = GetPixelForN8BitPal; break;
387  case ScanlineFormat::N24BitTcBgr: pFncGetPixel = GetPixelForN24BitTcBgr; break;
388  case ScanlineFormat::N24BitTcRgb: pFncGetPixel = GetPixelForN24BitTcRgb; break;
390  if (Bitmap32IsPreMultipled())
391  pFncGetPixel = GetPixelForN32BitTcAbgr;
392  else
393  pFncGetPixel = GetPixelForN32BitTcXbgr;
394  break;
396  if (Bitmap32IsPreMultipled())
397  pFncGetPixel = GetPixelForN32BitTcArgb;
398  else
399  pFncGetPixel = GetPixelForN32BitTcXrgb;
400  break;
402  if (Bitmap32IsPreMultipled())
403  pFncGetPixel = GetPixelForN32BitTcBgra;
404  else
405  pFncGetPixel = GetPixelForN32BitTcBgrx;
406  break;
408  if (Bitmap32IsPreMultipled())
409  pFncGetPixel = GetPixelForN32BitTcRgba;
410  else
411  pFncGetPixel = GetPixelForN32BitTcRgbx;
412  break;
414  pFncGetPixel = GetPixelForN32BitTcMask;
415  break;
416 
417  default:
418  assert(false);
419  pFncGetPixel = nullptr;
420  break;
421  }
422 
423  if( pFncGetPixel )
424  {
425  const ColorMask aDummyMask;
426  Scanline pScanline = GetScanline(nY);
427  for (tools::Long nX = 0, nWidth = mpBuffer->mnWidth; nX < nWidth; ++nX)
428  SetPixelOnData(pScanline, nX, pFncGetPixel(aSrcScanline, nX, aDummyMask));
429  }
430  }
431 }
432 
433 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
double mnHeight
static BitmapColor GetPixelForN1BitMsbPal(ConstScanline pScanline, tools::Long nX, const ColorMask &rMask)
Definition: bmpacc2.cxx:23
static void SetPixelForN32BitTcBgra(Scanline pScanline, tools::Long nX, const BitmapColor &rBitmapColor, const ColorMask &rMask)
Definition: bmpacc2.cxx:269
static BitmapColor GetPixelForN4BitLsnPal(ConstScanline pScanline, tools::Long nX, const ColorMask &rMask)
Definition: bmpacc2.cxx:74
tools::Long Height() const
ColorMask maColorMask
static BitmapColor GetPixelForN32BitTcRgbx(ConstScanline pScanline, tools::Long nX, const ColorMask &rMask)
Definition: bmpacc2.cxx:305
static BitmapColor GetPixelForN32BitTcXbgr(ConstScanline pScanline, tools::Long nX, const ColorMask &rMask)
Definition: bmpacc2.cxx:161
static void SetPixelForN32BitTcArgb(Scanline pScanline, tools::Long nX, const BitmapColor &rBitmapColor, const ColorMask &rMask)
Definition: bmpacc2.cxx:221
static FncSetPixel SetPixelFunction(ScanlineFormat nFormat)
Definition: bmpacc.cxx:168
BitmapAccessMode mnAccessMode
void Merge(const Color &rMergeColor, sal_uInt8 cTransparency)
BitmapColor GetColorWithFallback(double fY, double fX, const BitmapColor &rFallback) const
Get the color at coordinates fY, fX; if outside, return rFallback.
Definition: bmpacc.cxx:304
virtual ~BitmapReadAccess() override
Definition: bmpacc.cxx:109
static void SetPixelForN32BitTcXbgr(Scanline pScanline, tools::Long nX, const BitmapColor &rBitmapColor, const ColorMask &rMask)
Definition: bmpacc2.cxx:184
virtual ~BitmapInfoAccess()
Definition: bmpacc.cxx:70
const std::shared_ptr< SalBitmap > & ImplGetSalBitmap() const
Definition: bitmap.hxx:521
sal_uIntPtr sal_uLong
long Long
static BitmapColor GetPixelForN32BitTcXrgb(ConstScanline pScanline, tools::Long nX, const ColorMask &rMask)
Definition: bmpacc2.cxx:209
sal_uInt16 GetBestPaletteIndex(const BitmapColor &rBitmapColor) const
Definition: bmpacc.cxx:80
void SetPixelOnData(sal_uInt8 *pData, tools::Long nX, const BitmapColor &rBitmapColor)
ScanlineFormat
Definition: Scanline.hxx:28
const BorderLinePrimitive2D *pCandidateB assert(pCandidateA)
Scanline GetScanline(tools::Long nY) const
static void SetPixelForN1BitMsbPal(Scanline pScanline, tools::Long nX, const BitmapColor &rBitmapColor, const ColorMask &rMask)
Definition: bmpacc2.cxx:28
int nCount
BitmapReadAccess(Bitmap &rBitmap, BitmapAccessMode nMode=BitmapAccessMode::Read)
Definition: bmpacc.cxx:85
BitmapColor GetInterpolatedColorWithFallback(double fY, double fX, const BitmapColor &rFallback) const
Get the interpolated color at coordinates fY, fX; if outside, return rFallback.
Definition: bmpacc.cxx:215
BitmapBuffer * mpBuffer
static void SetPixelForN32BitTcBgrx(Scanline pScanline, tools::Long nX, const BitmapColor &rBitmapColor, const ColorMask &rMask)
Definition: bmpacc2.cxx:280
static void SetPixelForN32BitTcMask(Scanline pScanline, tools::Long nX, const BitmapColor &rBitmapColor, const ColorMask &rMask)
Definition: bmpacc2.cxx:344
SAL_DLLPRIVATE BitmapBuffer * ImplGetBitmapBuffer() const
ScanlineFormat mnFormat
FncGetPixel mFncGetPixel
static void SetPixelForN4BitMsnPal(Scanline pScanline, tools::Long nX, const BitmapColor &rBitmapColor, const ColorMask &rMask)
Definition: bmpacc2.cxx:58
ImplSVData * ImplGetSVData()
Definition: svdata.cxx:76
sal_uInt8 * Scanline
Definition: Scanline.hxx:25
sal_uInt32 GetScanlineSize() const
#define DBG_ASSERT(sCon, aError)
static BitmapColor GetPixelForN4BitMsnPal(ConstScanline pScanline, tools::Long nX, const ColorMask &rMask)
Definition: bmpacc2.cxx:53
bool HasPalette() const
ScanlineFormat GetScanlineFormat() const
static BitmapColor GetPixelForN24BitTcBgr(ConstScanline pScanline, tools::Long nX, const ColorMask &rMask)
Definition: bmpacc2.cxx:105
static void SetPixelForN1BitLsbPal(Scanline pScanline, tools::Long nX, const BitmapColor &rBitmapColor, const ColorMask &rMask)
Definition: bmpacc2.cxx:43
static BitmapColor GetPixelForN32BitTcBgrx(ConstScanline pScanline, tools::Long nX, const ColorMask &rMask)
Definition: bmpacc2.cxx:257
BitmapColor GetColor(tools::Long nY, tools::Long nX) const
virtual std::shared_ptr< vcl::BackendCapabilities > GetBackendCapabilities()
Definition: salinst.hxx:132
static BitmapColor GetPixelForN32BitTcMask(ConstScanline pScanline, tools::Long nX, const ColorMask &rMask)
Definition: bmpacc2.cxx:337
static BitmapColor GetPixelForN32BitTcRgba(ConstScanline pScanline, tools::Long nX, const ColorMask &rMask)
Definition: bmpacc2.cxx:289
BitmapAccessMode
tools::Long Width() const
static void SetPixelForN32BitTcRgbx(Scanline pScanline, tools::Long nX, const BitmapColor &rBitmapColor, const ColorMask &rMask)
Definition: bmpacc2.cxx:328
BitmapWriteAccess()=delete
static BitmapColor GetPixelForN1BitLsbPal(ConstScanline pScanline, tools::Long nX, const ColorMask &rMask)
Definition: bmpacc2.cxx:38
static BitmapColor GetPixelForN32BitTcAbgr(ConstScanline pScanline, tools::Long nX, const ColorMask &rMask)
Definition: bmpacc2.cxx:145
sal_uInt16 GetBestIndex(const BitmapColor &rCol) const
FncSetPixel mFncSetPixel
const sal_uInt8 * ConstScanline
Definition: Scanline.hxx:26
static BitmapColor GetPixelForN8BitPal(ConstScanline pScanline, tools::Long nX, const ColorMask &rMask)
Definition: bmpacc2.cxx:95
BitmapInfoAccess(Bitmap &rBitmap, BitmapAccessMode nMode=BitmapAccessMode::Info)
Definition: bmpacc.cxx:33
static FncGetPixel GetPixelFunction(ScanlineFormat nFormat)
Definition: bmpacc.cxx:122
static BitmapColor GetPixelForN32BitTcBgra(ConstScanline pScanline, tools::Long nX, const ColorMask &rMask)
Definition: bmpacc2.cxx:241
void(* FncSetPixel)(Scanline pScanline, tools::Long nX, const BitmapColor &rBitmapColor, const ColorMask &rMask)
bool ImplFastCopyScanline(tools::Long nY, BitmapBuffer &rDst, ConstScanline aSrcScanline, ScanlineFormat nSrcScanlineFormat, sal_uInt32 nSrcScanlineSize)
Definition: bmpfast.cxx:512
#define SAL_WARN_IF(condition, area, stream)
void CopyScanline(tools::Long nY, const BitmapReadAccess &rReadAcc)
Definition: bmpacc.cxx:331
static void SetPixelForN32BitTcXrgb(Scanline pScanline, tools::Long nX, const BitmapColor &rBitmapColor, const ColorMask &rMask)
Definition: bmpacc2.cxx:232
static BitmapColor GetPixelForN24BitTcRgb(ConstScanline pScanline, tools::Long nX, const ColorMask &rMask)
Definition: bmpacc2.cxx:125
double mnWidth
BitmapColor GetPixelFromData(const sal_uInt8 *pData, tools::Long nX) const
ColorMask maColorMask
ScanlineFormat RemoveScanline(ScanlineFormat nFormat)
Definition: Scanline.hxx:56
SAL_DLLPRIVATE void ImplMakeUnique()
BitmapPalette maPalette
virtual ~BitmapWriteAccess() override
Definition: bmpacc.cxx:327
BitmapColor(* FncGetPixel)(ConstScanline pScanline, tools::Long nX, const ColorMask &rMask)
sal_uInt16 GetBitCount() const
static void SetPixelForN8BitPal(Scanline pScanline, tools::Long nX, const BitmapColor &rBitmapColor, const ColorMask &rMask)
Definition: bmpacc2.cxx:100
static void SetPixelForN4BitLsnPal(Scanline pScanline, tools::Long nX, const BitmapColor &rBitmapColor, const ColorMask &rMask)
Definition: bmpacc2.cxx:79
static void SetPixelForN24BitTcRgb(Scanline pScanline, tools::Long nX, const BitmapColor &rBitmapColor, const ColorMask &rMask)
Definition: bmpacc2.cxx:137
tools::Long mnWidth
static void SetPixelForN24BitTcBgr(Scanline pScanline, tools::Long nX, const BitmapColor &rBitmapColor, const ColorMask &rMask)
Definition: bmpacc2.cxx:117
static BitmapColor GetPixelForN32BitTcArgb(ConstScanline pScanline, tools::Long nX, const ColorMask &rMask)
Definition: bmpacc2.cxx:193
SalInstance * mpDefInst
Definition: svdata.hxx:381
static void SetPixelForN32BitTcAbgr(Scanline pScanline, tools::Long nX, const BitmapColor &rBitmapColor, const ColorMask &rMask)
Definition: bmpacc2.cxx:173
static void SetPixelForN32BitTcRgba(Scanline pScanline, tools::Long nX, const BitmapColor &rBitmapColor, const ColorMask &rMask)
Definition: bmpacc2.cxx:317
SAL_DLLPRIVATE void ImplSetSalBitmap(const std::shared_ptr< SalBitmap > &xImpBmp)