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 
28 #include <string.h>
29 #include <sal/log.hxx>
30 #include <tools/debug.hxx>
31 
33  mpBuffer ( nullptr ),
34  mnAccessMode ( nMode )
35 {
36  std::shared_ptr<SalBitmap> xImpBmp = rBitmap.ImplGetSalBitmap();
37 
38  if( !xImpBmp )
39  return;
40 
42  {
43  xImpBmp->DropScaledCache();
44 
45  if (xImpBmp.use_count() > 2)
46  {
47  xImpBmp.reset();
48  rBitmap.ImplMakeUnique();
49  xImpBmp = rBitmap.ImplGetSalBitmap();
50  }
51  }
52 
53  mpBuffer = xImpBmp->AcquireBuffer( mnAccessMode );
54 
55  if( !mpBuffer )
56  {
57  std::shared_ptr<SalBitmap> xNewImpBmp(ImplGetSVData()->mpDefInst->CreateSalBitmap());
58  if (xNewImpBmp->Create(*xImpBmp, rBitmap.GetBitCount()))
59  {
60  xImpBmp = xNewImpBmp;
61  rBitmap.ImplSetSalBitmap( xImpBmp );
62  mpBuffer = xImpBmp->AcquireBuffer( mnAccessMode );
63  }
64  }
65 
66  maBitmap = rBitmap;
67 }
68 
70 {
71  std::shared_ptr<SalBitmap> xImpBmp = maBitmap.ImplGetSalBitmap();
72 
73  if (mpBuffer && xImpBmp)
74  {
75  xImpBmp->ReleaseBuffer( mpBuffer, mnAccessMode );
76  }
77 }
78 
79 sal_uInt16 BitmapInfoAccess::GetBestPaletteIndex( const BitmapColor& rBitmapColor ) const
80 {
81  return( HasPalette() ? mpBuffer->maPalette.GetBestIndex( rBitmapColor ) : 0 );
82 }
83 
85  BitmapInfoAccess( rBitmap, nMode ),
86  mFncGetPixel ( nullptr ),
87  mFncSetPixel ( nullptr )
88 {
89  if (!mpBuffer)
90  return;
91 
92  const std::shared_ptr<SalBitmap>& xImpBmp = rBitmap.ImplGetSalBitmap();
93  if (!xImpBmp)
94  return;
95 
97 
100 
101  if (!mFncGetPixel || !mFncSetPixel)
102  {
103  xImpBmp->ReleaseBuffer( mpBuffer, mnAccessMode );
104  mpBuffer = nullptr;
105  }
106 }
107 
109 {
110 }
111 
112 namespace
113 {
114  bool Bitmap32IsPreMultipled()
115  {
116  auto pBackendCapabilities = ImplGetSVData()->mpDefInst->GetBackendCapabilities();
117  return pBackendCapabilities->mbSupportsBitmap32;
118  }
119 }
120 
122 {
123  switch( RemoveScanline( nFormat ))
124  {
126  return GetPixelForN1BitMsbPal;
128  return GetPixelForN1BitLsbPal;
130  return GetPixelForN4BitMsnPal;
132  return GetPixelForN4BitLsnPal;
134  return GetPixelForN8BitPal;
136  return GetPixelForN8BitTcMask;
138  return GetPixelForN24BitTcBgr;
140  return GetPixelForN24BitTcRgb;
142  if (Bitmap32IsPreMultipled())
144  else
147  if (Bitmap32IsPreMultipled())
149  else
152  if (Bitmap32IsPreMultipled())
154  else
157  if (Bitmap32IsPreMultipled())
159  else
163 
164  default:
165  return nullptr;
166  }
167 }
168 
170 {
171  switch( RemoveScanline( nFormat ))
172  {
174  return SetPixelForN1BitMsbPal;
176  return SetPixelForN1BitLsbPal;
178  return SetPixelForN4BitMsnPal;
180  return SetPixelForN4BitLsnPal;
182  return SetPixelForN8BitPal;
184  return SetPixelForN8BitTcMask;
186  return SetPixelForN24BitTcBgr;
188  return SetPixelForN24BitTcRgb;
190  if (Bitmap32IsPreMultipled())
192  else
195  if (Bitmap32IsPreMultipled())
197  else
200  if (Bitmap32IsPreMultipled())
202  else
205  if (Bitmap32IsPreMultipled())
207  else
211  break;
212 
213  default:
214  return nullptr;
215  }
216 }
217 
218 BitmapColor BitmapReadAccess::GetInterpolatedColorWithFallback( double fY, double fX, const BitmapColor& rFallback ) const
219 {
220  // ask directly doubles >= 0.0 here to avoid rounded values of 0 at small negative
221  // double values, e.g. static_cast< sal_Int32 >(-0.25) is 0, not -1, but *has* to be outside (!)
222  if(mpBuffer && fX >= 0.0 && fY >= 0.0)
223  {
224  const sal_Int64 nX(static_cast<sal_Int64>(fX));
225  const sal_Int64 nY(static_cast<sal_Int64>(fY));
226 
227  if(nX < mpBuffer->mnWidth && nY < mpBuffer->mnHeight)
228  {
229  // get base-return value from inside pixel
230  BitmapColor aRetval(GetColor(nY, nX));
231 
232  // calculate deltas and indices for neighbour accesses
233  sal_Int16 nDeltaX((fX - (nX + 0.5)) * 255.0); // [-255 .. 255]
234  sal_Int16 nDeltaY((fY - (nY + 0.5)) * 255.0); // [-255 .. 255]
235  sal_Int16 nIndX(0);
236  sal_Int16 nIndY(0);
237 
238  if(nDeltaX > 0)
239  {
240  nIndX = nX + 1;
241  }
242  else
243  {
244  nIndX = nX - 1;
245  nDeltaX = -nDeltaX;
246  }
247 
248  if(nDeltaY > 0)
249  {
250  nIndY = nY + 1;
251  }
252  else
253  {
254  nIndY = nY - 1;
255  nDeltaY = -nDeltaY;
256  }
257 
258  // get right/left neighbour
259  BitmapColor aXCol(rFallback);
260 
261  if(nDeltaX && nIndX >= 0 && nIndX < mpBuffer->mnWidth)
262  {
263  aXCol = GetColor(nY, nIndX);
264  }
265 
266  // get top/bottom neighbour
267  BitmapColor aYCol(rFallback);
268 
269  if(nDeltaY && nIndY >= 0 && nIndY < mpBuffer->mnHeight)
270  {
271  aYCol = GetColor(nIndY, nX);
272  }
273 
274  // get one of four edge neighbours
275  BitmapColor aXYCol(rFallback);
276 
277  if(nDeltaX && nDeltaY && nIndX >=0 && nIndY >= 0 && nIndX < mpBuffer->mnWidth && nIndY < mpBuffer->mnHeight)
278  {
279  aXYCol = GetColor(nIndY, nIndX);
280  }
281 
282  // merge return value with right/left neighbour
283  if(aXCol != aRetval)
284  {
285  aRetval.Merge(aXCol, 255 - nDeltaX);
286  }
287 
288  // merge top/bottom neighbour with edge
289  if(aYCol != aXYCol)
290  {
291  aYCol.Merge(aXYCol, 255 - nDeltaX);
292  }
293 
294  // merge return value with already merged top/bottom neighbour
295  if(aRetval != aYCol)
296  {
297  aRetval.Merge(aYCol, 255 - nDeltaY);
298  }
299 
300  return aRetval;
301  }
302  }
303 
304  return rFallback;
305 }
306 
307 BitmapColor BitmapReadAccess::GetColorWithFallback( double fY, double fX, const BitmapColor& rFallback ) const
308 {
309  // ask directly doubles >= 0.0 here to avoid rounded values of 0 at small negative
310  // double values, e.g. static_cast< sal_Int32 >(-0.25) is 0, not -1, but *has* to be outside (!)
311  if(mpBuffer && fX >= 0.0 && fY >= 0.0)
312  {
313  const sal_Int32 nX(static_cast< sal_Int32 >(fX));
314  const sal_Int32 nY(static_cast< sal_Int32 >(fY));
315 
316  if(nX < mpBuffer->mnWidth && nY < mpBuffer->mnHeight)
317  {
318  return GetColor(nY, nX);
319  }
320  }
321 
322  return rFallback;
323 }
324 
327 {
328 }
329 
331 {
332 }
333 
334 void BitmapWriteAccess::CopyScanline( long nY, const BitmapReadAccess& rReadAcc )
335 {
336  assert(nY >= 0 && nY < mpBuffer->mnHeight && "y-coordinate in destination out of range!");
337  SAL_WARN_IF( nY >= rReadAcc.Height(), "vcl", "y-coordinate in source out of range!" );
338  SAL_WARN_IF( ( !HasPalette() || !rReadAcc.HasPalette() ) && ( HasPalette() || rReadAcc.HasPalette() ), "vcl", "No copying possible between palette bitmap and TC bitmap!" );
339 
340  if( ( GetScanlineFormat() == rReadAcc.GetScanlineFormat() ) &&
341  ( GetScanlineSize() >= rReadAcc.GetScanlineSize() ) )
342  {
343  memcpy(GetScanline(nY), rReadAcc.GetScanline(nY), rReadAcc.GetScanlineSize());
344  }
345  else
346  {
347  // TODO: use fastbmp infrastructure
348  Scanline pScanline = GetScanline( nY );
349  Scanline pScanlineRead = rReadAcc.GetScanline(nY);
350  for( long nX = 0, nWidth = std::min( mpBuffer->mnWidth, rReadAcc.Width() ); nX < nWidth; nX++ )
351  SetPixelOnData( pScanline, nX, rReadAcc.GetPixelFromData( pScanlineRead, nX ) );
352  }
353 }
354 
355 void BitmapWriteAccess::CopyScanline( long nY, ConstScanline aSrcScanline,
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  {
375  nFormat != ScanlineFormat::N32BitTcMask,
376  "No support for pixel formats with color masks yet!" );
377 
378  // TODO: use fastbmp infrastructure
379  FncGetPixel pFncGetPixel;
380 
381  switch( nFormat )
382  {
383  case ScanlineFormat::N1BitMsbPal: pFncGetPixel = GetPixelForN1BitMsbPal; break;
384  case ScanlineFormat::N1BitLsbPal: pFncGetPixel = GetPixelForN1BitLsbPal; break;
385  case ScanlineFormat::N4BitMsnPal: pFncGetPixel = GetPixelForN4BitMsnPal; break;
386  case ScanlineFormat::N4BitLsnPal: pFncGetPixel = GetPixelForN4BitLsnPal; break;
387  case ScanlineFormat::N8BitPal: pFncGetPixel = GetPixelForN8BitPal; break;
388  case ScanlineFormat::N8BitTcMask: pFncGetPixel = GetPixelForN8BitTcMask; break;
389  case ScanlineFormat::N24BitTcBgr: pFncGetPixel = GetPixelForN24BitTcBgr; break;
390  case ScanlineFormat::N24BitTcRgb: pFncGetPixel = GetPixelForN24BitTcRgb; break;
392  if (Bitmap32IsPreMultipled())
393  pFncGetPixel = GetPixelForN32BitTcAbgr;
394  else
395  pFncGetPixel = GetPixelForN32BitTcXbgr;
396  break;
398  if (Bitmap32IsPreMultipled())
399  pFncGetPixel = GetPixelForN32BitTcArgb;
400  else
401  pFncGetPixel = GetPixelForN32BitTcXrgb;
402  break;
404  if (Bitmap32IsPreMultipled())
405  pFncGetPixel = GetPixelForN32BitTcBgra;
406  else
407  pFncGetPixel = GetPixelForN32BitTcBgrx;
408  break;
410  if (Bitmap32IsPreMultipled())
411  pFncGetPixel = GetPixelForN32BitTcRgba;
412  else
413  pFncGetPixel = GetPixelForN32BitTcRgbx;
414  break;
416  pFncGetPixel = GetPixelForN32BitTcMask;
417  break;
418 
419  default:
420  assert(false);
421  pFncGetPixel = nullptr;
422  break;
423  }
424 
425  if( pFncGetPixel )
426  {
427  const ColorMask aDummyMask;
428  Scanline pScanline = GetScanline(nY);
429  for (long nX = 0, nWidth = mpBuffer->mnWidth; nX < nWidth; ++nX)
430  SetPixelOnData(pScanline, nX, pFncGetPixel(aSrcScanline, nX, aDummyMask));
431  }
432  }
433 }
434 
435 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
double mnHeight
static BitmapColor GetPixelForN4BitLsnPal(ConstScanline pScanline, long nX, const ColorMask &rMask)
Definition: bmpacc2.cxx:74
static BitmapColor GetPixelForN8BitTcMask(ConstScanline pScanline, long nX, const ColorMask &rMask)
Definition: bmpacc2.cxx:105
void(* FncSetPixel)(Scanline pScanline, long nX, const BitmapColor &rBitmapColor, const ColorMask &rMask)
ColorMask maColorMask
static void SetPixelForN32BitTcRgba(Scanline pScanline, long nX, const BitmapColor &rBitmapColor, const ColorMask &rMask)
Definition: bmpacc2.cxx:330
static FncSetPixel SetPixelFunction(ScanlineFormat nFormat)
Definition: bmpacc.cxx:169
Scanline GetScanline(long nY) const
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:307
virtual ~BitmapReadAccess() override
Definition: bmpacc.cxx:108
virtual ~BitmapInfoAccess()
Definition: bmpacc.cxx:69
const std::shared_ptr< SalBitmap > & ImplGetSalBitmap() const
Definition: bitmap.hxx:520
sal_uIntPtr sal_uLong
static BitmapColor GetPixelForN32BitTcArgb(ConstScanline pScanline, long nX, const ColorMask &rMask)
Definition: bmpacc2.cxx:206
static void SetPixelForN32BitTcBgrx(Scanline pScanline, long nX, const BitmapColor &rBitmapColor, const ColorMask &rMask)
Definition: bmpacc2.cxx:293
static BitmapColor GetPixelForN32BitTcBgrx(ConstScanline pScanline, long nX, const ColorMask &rMask)
Definition: bmpacc2.cxx:270
sal_uInt16 GetBestPaletteIndex(const BitmapColor &rBitmapColor) const
Definition: bmpacc.cxx:79
long Width() const
static void SetPixelForN32BitTcXrgb(Scanline pScanline, long nX, const BitmapColor &rBitmapColor, const ColorMask &rMask)
Definition: bmpacc2.cxx:245
static void SetPixelForN24BitTcBgr(Scanline pScanline, long nX, const BitmapColor &rBitmapColor, const ColorMask &rMask)
Definition: bmpacc2.cxx:130
static BitmapColor GetPixelForN32BitTcRgba(ConstScanline pScanline, long nX, const ColorMask &rMask)
Definition: bmpacc2.cxx:302
static void SetPixelForN32BitTcMask(Scanline pScanline, long nX, const BitmapColor &rBitmapColor, const ColorMask &rMask)
Definition: bmpacc2.cxx:357
static void SetPixelForN4BitMsnPal(Scanline pScanline, long nX, const BitmapColor &rBitmapColor, const ColorMask &rMask)
Definition: bmpacc2.cxx:58
ScanlineFormat
Definition: Scanline.hxx:28
static BitmapColor GetPixelForN4BitMsnPal(ConstScanline pScanline, long nX, const ColorMask &rMask)
Definition: bmpacc2.cxx:53
static BitmapColor GetPixelForN32BitTcMask(ConstScanline pScanline, long nX, const ColorMask &rMask)
Definition: bmpacc2.cxx:350
const BorderLinePrimitive2D *pCandidateB assert(pCandidateA)
int nCount
BitmapReadAccess(Bitmap &rBitmap, BitmapAccessMode nMode=BitmapAccessMode::Read)
Definition: bmpacc.cxx:84
static BitmapColor GetPixelForN8BitPal(ConstScanline pScanline, long nX, const ColorMask &rMask)
Definition: bmpacc2.cxx:95
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:218
void SetPixelOnData(sal_uInt8 *pData, long nX, const BitmapColor &rBitmapColor)
static BitmapColor GetPixelForN32BitTcBgra(ConstScanline pScanline, long nX, const ColorMask &rMask)
Definition: bmpacc2.cxx:254
BitmapBuffer * mpBuffer
static BitmapColor GetPixelForN1BitMsbPal(ConstScanline pScanline, long nX, const ColorMask &rMask)
Definition: bmpacc2.cxx:23
static BitmapColor GetPixelForN32BitTcXbgr(ConstScanline pScanline, long nX, const ColorMask &rMask)
Definition: bmpacc2.cxx:174
ScanlineFormat mnFormat
FncGetPixel mFncGetPixel
ImplSVData * ImplGetSVData()
Definition: svdata.cxx:76
sal_uInt8 * Scanline
Definition: Scanline.hxx:25
static void SetPixelForN32BitTcXbgr(Scanline pScanline, long nX, const BitmapColor &rBitmapColor, const ColorMask &rMask)
Definition: bmpacc2.cxx:197
sal_uInt32 GetScanlineSize() const
#define DBG_ASSERT(sCon, aError)
bool HasPalette() const
ScanlineFormat GetScanlineFormat() const
static BitmapColor GetPixelForN24BitTcBgr(ConstScanline pScanline, long nX, const ColorMask &rMask)
Definition: bmpacc2.cxx:118
virtual std::shared_ptr< vcl::BackendCapabilities > GetBackendCapabilities()
Definition: salinst.hxx:132
BitmapAccessMode
BitmapWriteAccess()=delete
static BitmapColor GetPixelForN32BitTcXrgb(ConstScanline pScanline, long nX, const ColorMask &rMask)
Definition: bmpacc2.cxx:222
static BitmapColor GetPixelForN32BitTcAbgr(ConstScanline pScanline, long nX, const ColorMask &rMask)
Definition: bmpacc2.cxx:158
sal_uInt16 GetBestIndex(const BitmapColor &rCol) const
FncSetPixel mFncSetPixel
const sal_uInt8 * ConstScanline
Definition: Scanline.hxx:26
BitmapInfoAccess(Bitmap &rBitmap, BitmapAccessMode nMode=BitmapAccessMode::Info)
Definition: bmpacc.cxx:32
static FncGetPixel GetPixelFunction(ScanlineFormat nFormat)
Definition: bmpacc.cxx:121
static BitmapColor GetPixelForN32BitTcRgbx(ConstScanline pScanline, long nX, const ColorMask &rMask)
Definition: bmpacc2.cxx:318
long Height() const
#define SAL_WARN_IF(condition, area, stream)
static void SetPixelForN8BitPal(Scanline pScanline, long nX, const BitmapColor &rBitmapColor, const ColorMask &rMask)
Definition: bmpacc2.cxx:100
BitmapColor GetColor(long nY, long nX) const
double mnWidth
static void SetPixelForN1BitLsbPal(Scanline pScanline, long nX, const BitmapColor &rBitmapColor, const ColorMask &rMask)
Definition: bmpacc2.cxx:43
static void SetPixelForN32BitTcBgra(Scanline pScanline, long nX, const BitmapColor &rBitmapColor, const ColorMask &rMask)
Definition: bmpacc2.cxx:282
ColorMask maColorMask
BitmapColor GetPixelFromData(const sal_uInt8 *pData, long nX) const
ScanlineFormat RemoveScanline(ScanlineFormat nFormat)
Definition: Scanline.hxx:57
SAL_DLLPRIVATE void ImplMakeUnique()
BitmapPalette maPalette
static void SetPixelForN4BitLsnPal(Scanline pScanline, long nX, const BitmapColor &rBitmapColor, const ColorMask &rMask)
Definition: bmpacc2.cxx:79
static void SetPixelForN32BitTcRgbx(Scanline pScanline, long nX, const BitmapColor &rBitmapColor, const ColorMask &rMask)
Definition: bmpacc2.cxx:341
virtual ~BitmapWriteAccess() override
Definition: bmpacc.cxx:330
void CopyScanline(long nY, const BitmapReadAccess &rReadAcc)
Definition: bmpacc.cxx:334
static BitmapColor GetPixelForN1BitLsbPal(ConstScanline pScanline, long nX, const ColorMask &rMask)
Definition: bmpacc2.cxx:38
sal_uInt16 GetBitCount() const
static BitmapColor GetPixelForN24BitTcRgb(ConstScanline pScanline, long nX, const ColorMask &rMask)
Definition: bmpacc2.cxx:138
BitmapColor(* FncGetPixel)(ConstScanline pScanline, long nX, const ColorMask &rMask)
static void SetPixelForN8BitTcMask(Scanline pScanline, long nX, const BitmapColor &rBitmapColor, const ColorMask &rMask)
Definition: bmpacc2.cxx:112
static void SetPixelForN1BitMsbPal(Scanline pScanline, long nX, const BitmapColor &rBitmapColor, const ColorMask &rMask)
Definition: bmpacc2.cxx:28
static void SetPixelForN32BitTcArgb(Scanline pScanline, long nX, const BitmapColor &rBitmapColor, const ColorMask &rMask)
Definition: bmpacc2.cxx:234
static void SetPixelForN32BitTcAbgr(Scanline pScanline, long nX, const BitmapColor &rBitmapColor, const ColorMask &rMask)
Definition: bmpacc2.cxx:186
SalInstance * mpDefInst
Definition: svdata.hxx:381
static void SetPixelForN24BitTcRgb(Scanline pScanline, long nX, const BitmapColor &rBitmapColor, const ColorMask &rMask)
Definition: bmpacc2.cxx:150
SAL_DLLPRIVATE void ImplSetSalBitmap(const std::shared_ptr< SalBitmap > &xImpBmp)