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  assert( xImpBmp && "Forbidden Access to empty bitmap!" );
39 
40  if( !xImpBmp )
41  return;
42 
44  {
45  xImpBmp->DropScaledCache();
46 
47  if (xImpBmp.use_count() > 2)
48  {
49  xImpBmp.reset();
50  rBitmap.ImplMakeUnique();
51  xImpBmp = rBitmap.ImplGetSalBitmap();
52  }
53  }
54 
55  mpBuffer = xImpBmp->AcquireBuffer( mnAccessMode );
56 
57  if( !mpBuffer )
58  {
59  std::shared_ptr<SalBitmap> xNewImpBmp(ImplGetSVData()->mpDefInst->CreateSalBitmap());
60  if (xNewImpBmp->Create(*xImpBmp, rBitmap.GetBitCount()))
61  {
62  xImpBmp = xNewImpBmp;
63  rBitmap.ImplSetSalBitmap( xImpBmp );
64  mpBuffer = xImpBmp->AcquireBuffer( mnAccessMode );
65  }
66  }
67 
68  maBitmap = rBitmap;
69 }
70 
72 {
73  std::shared_ptr<SalBitmap> xImpBmp = maBitmap.ImplGetSalBitmap();
74 
75  if (mpBuffer && xImpBmp)
76  {
77  xImpBmp->ReleaseBuffer( mpBuffer, mnAccessMode );
78  }
79 }
80 
81 sal_uInt16 BitmapInfoAccess::GetBestPaletteIndex( const BitmapColor& rBitmapColor ) const
82 {
83  return( HasPalette() ? mpBuffer->maPalette.GetBestIndex( rBitmapColor ) : 0 );
84 }
85 
87  BitmapInfoAccess( rBitmap, nMode ),
88  mFncGetPixel ( nullptr ),
89  mFncSetPixel ( nullptr )
90 {
91  if (!mpBuffer)
92  return;
93 
94  const std::shared_ptr<SalBitmap>& xImpBmp = rBitmap.ImplGetSalBitmap();
95  if (!xImpBmp)
96  return;
97 
99 
101 
102  if (!bOk)
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  bool bRet = true;
125 
126  switch( nFormat )
127  {
129  {
132  }
133  break;
135  {
138  }
139  break;
141  {
144  }
145  break;
147  {
150  }
151  break;
153  {
156  }
157  break;
159  {
162  }
163  break;
165  {
168  }
169  break;
171  {
174  }
175  break;
177  {
178  if (Bitmap32IsPreMultipled())
179  {
182  }
183  else
184  {
187  }
188  }
189  break;
191  {
192  if (Bitmap32IsPreMultipled())
193  {
196  }
197  else
198  {
201  }
202  }
203  break;
205  {
206  if (Bitmap32IsPreMultipled())
207  {
210  }
211  else
212  {
215  }
216  }
217  break;
219  {
220  if (Bitmap32IsPreMultipled())
221  {
224  }
225  else
226  {
229  }
230  }
231  break;
233  {
236  }
237  break;
238 
239  default:
240  bRet = false;
241  break;
242  }
243 
244  return bRet;
245 }
246 
247 BitmapColor BitmapReadAccess::GetInterpolatedColorWithFallback( double fY, double fX, const BitmapColor& rFallback ) const
248 {
249  // ask directly doubles >= 0.0 here to avoid rounded values of 0 at small negative
250  // double values, e.g. static_cast< sal_Int32 >(-0.25) is 0, not -1, but *has* to be outside (!)
251  if(mpBuffer && fX >= 0.0 && fY >= 0.0)
252  {
253  const sal_Int64 nX(static_cast<sal_Int64>(fX));
254  const sal_Int64 nY(static_cast<sal_Int64>(fY));
255 
256  if(nX < mpBuffer->mnWidth && nY < mpBuffer->mnHeight)
257  {
258  // get base-return value from inside pixel
259  BitmapColor aRetval(GetColor(nY, nX));
260 
261  // calculate deltas and indices for neighbour accesses
262  sal_Int16 nDeltaX((fX - (nX + 0.5)) * 255.0); // [-255 .. 255]
263  sal_Int16 nDeltaY((fY - (nY + 0.5)) * 255.0); // [-255 .. 255]
264  sal_Int16 nIndX(0);
265  sal_Int16 nIndY(0);
266 
267  if(nDeltaX > 0)
268  {
269  nIndX = nX + 1;
270  }
271  else
272  {
273  nIndX = nX - 1;
274  nDeltaX = -nDeltaX;
275  }
276 
277  if(nDeltaY > 0)
278  {
279  nIndY = nY + 1;
280  }
281  else
282  {
283  nIndY = nY - 1;
284  nDeltaY = -nDeltaY;
285  }
286 
287  // get right/left neighbour
288  BitmapColor aXCol(rFallback);
289 
290  if(nDeltaX && nIndX >= 0 && nIndX < mpBuffer->mnWidth)
291  {
292  aXCol = GetColor(nY, nIndX);
293  }
294 
295  // get top/bottom neighbour
296  BitmapColor aYCol(rFallback);
297 
298  if(nDeltaY && nIndY >= 0 && nIndY < mpBuffer->mnHeight)
299  {
300  aYCol = GetColor(nIndY, nX);
301  }
302 
303  // get one of four edge neighbours
304  BitmapColor aXYCol(rFallback);
305 
306  if(nDeltaX && nDeltaY && nIndX >=0 && nIndY >= 0 && nIndX < mpBuffer->mnWidth && nIndY < mpBuffer->mnHeight)
307  {
308  aXYCol = GetColor(nIndY, nIndX);
309  }
310 
311  // merge return value with right/left neighbour
312  if(aXCol != aRetval)
313  {
314  aRetval.Merge(aXCol, 255 - nDeltaX);
315  }
316 
317  // merge top/bottom neighbour with edge
318  if(aYCol != aXYCol)
319  {
320  aYCol.Merge(aXYCol, 255 - nDeltaX);
321  }
322 
323  // merge return value with already merged top/bottom neighbour
324  if(aRetval != aYCol)
325  {
326  aRetval.Merge(aYCol, 255 - nDeltaY);
327  }
328 
329  return aRetval;
330  }
331  }
332 
333  return rFallback;
334 }
335 
336 BitmapColor BitmapReadAccess::GetColorWithFallback( double fY, double fX, const BitmapColor& rFallback ) const
337 {
338  // ask directly doubles >= 0.0 here to avoid rounded values of 0 at small negative
339  // double values, e.g. static_cast< sal_Int32 >(-0.25) is 0, not -1, but *has* to be outside (!)
340  if(mpBuffer && fX >= 0.0 && fY >= 0.0)
341  {
342  const sal_Int32 nX(static_cast< sal_Int32 >(fX));
343  const sal_Int32 nY(static_cast< sal_Int32 >(fY));
344 
345  if(nX < mpBuffer->mnWidth && nY < mpBuffer->mnHeight)
346  {
347  return GetColor(nY, nX);
348  }
349  }
350 
351  return rFallback;
352 }
353 
356 {
357 }
358 
360 {
361 }
362 
363 void BitmapWriteAccess::CopyScanline( long nY, const BitmapReadAccess& rReadAcc )
364 {
365  assert(nY >= 0 && nY < mpBuffer->mnHeight && "y-coordinate in destination out of range!");
366  SAL_WARN_IF( nY >= rReadAcc.Height(), "vcl", "y-coordinate in source out of range!" );
367  SAL_WARN_IF( ( !HasPalette() || !rReadAcc.HasPalette() ) && ( HasPalette() || rReadAcc.HasPalette() ), "vcl", "No copying possible between palette bitmap and TC bitmap!" );
368 
369  if( ( GetScanlineFormat() == rReadAcc.GetScanlineFormat() ) &&
370  ( GetScanlineSize() >= rReadAcc.GetScanlineSize() ) )
371  {
372  memcpy(GetScanline(nY), rReadAcc.GetScanline(nY), rReadAcc.GetScanlineSize());
373  }
374  else
375  {
376  // TODO: use fastbmp infrastructure
377  Scanline pScanline = GetScanline( nY );
378  Scanline pScanlineRead = rReadAcc.GetScanline(nY);
379  for( long nX = 0, nWidth = std::min( mpBuffer->mnWidth, rReadAcc.Width() ); nX < nWidth; nX++ )
380  SetPixelOnData( pScanline, nX, rReadAcc.GetPixelFromData( pScanlineRead, nX ) );
381  }
382 }
383 
384 void BitmapWriteAccess::CopyScanline( long nY, ConstScanline aSrcScanline,
385  ScanlineFormat nSrcScanlineFormat, sal_uInt32 nSrcScanlineSize )
386 {
387  const ScanlineFormat nFormat = RemoveScanline( nSrcScanlineFormat );
388 
389  assert(nY >= 0 && nY < mpBuffer->mnHeight && "y-coordinate in destination out of range!");
390  DBG_ASSERT( ( HasPalette() && nFormat <= ScanlineFormat::N8BitPal ) ||
391  ( !HasPalette() && nFormat > ScanlineFormat::N8BitPal ),
392  "No copying possible between palette and non palette scanlines!" );
393 
394  const sal_uLong nCount = std::min( GetScanlineSize(), nSrcScanlineSize );
395 
396  if( nCount )
397  {
398  if( GetScanlineFormat() == RemoveScanline( nSrcScanlineFormat ) )
399  memcpy(GetScanline(nY), aSrcScanline, nCount);
400  else
401  {
403  nFormat != ScanlineFormat::N32BitTcMask,
404  "No support for pixel formats with color masks yet!" );
405 
406  // TODO: use fastbmp infrastructure
407  FncGetPixel pFncGetPixel;
408 
409  switch( nFormat )
410  {
411  case ScanlineFormat::N1BitMsbPal: pFncGetPixel = GetPixelForN1BitMsbPal; break;
412  case ScanlineFormat::N1BitLsbPal: pFncGetPixel = GetPixelForN1BitLsbPal; break;
413  case ScanlineFormat::N4BitMsnPal: pFncGetPixel = GetPixelForN4BitMsnPal; break;
414  case ScanlineFormat::N4BitLsnPal: pFncGetPixel = GetPixelForN4BitLsnPal; break;
415  case ScanlineFormat::N8BitPal: pFncGetPixel = GetPixelForN8BitPal; break;
416  case ScanlineFormat::N8BitTcMask: pFncGetPixel = GetPixelForN8BitTcMask; break;
417  case ScanlineFormat::N24BitTcBgr: pFncGetPixel = GetPixelForN24BitTcBgr; break;
418  case ScanlineFormat::N24BitTcRgb: pFncGetPixel = GetPixelForN24BitTcRgb; break;
420  if (Bitmap32IsPreMultipled())
421  pFncGetPixel = GetPixelForN32BitTcAbgr;
422  else
423  pFncGetPixel = GetPixelForN32BitTcXbgr;
424  break;
426  if (Bitmap32IsPreMultipled())
427  pFncGetPixel = GetPixelForN32BitTcArgb;
428  else
429  pFncGetPixel = GetPixelForN32BitTcXrgb;
430  break;
432  if (Bitmap32IsPreMultipled())
433  pFncGetPixel = GetPixelForN32BitTcBgra;
434  else
435  pFncGetPixel = GetPixelForN32BitTcBgrx;
436  break;
438  if (Bitmap32IsPreMultipled())
439  pFncGetPixel = GetPixelForN32BitTcRgba;
440  else
441  pFncGetPixel = GetPixelForN32BitTcRgbx;
442  break;
444  pFncGetPixel = GetPixelForN32BitTcMask;
445  break;
446 
447  default:
448  assert(false);
449  pFncGetPixel = nullptr;
450  break;
451  }
452 
453  if( pFncGetPixel )
454  {
455  const ColorMask aDummyMask;
456  Scanline pScanline = GetScanline(nY);
457  for (long nX = 0, nWidth = mpBuffer->mnWidth; nX < nWidth; ++nX)
458  SetPixelOnData(pScanline, nX, pFncGetPixel(aSrcScanline, nX, aDummyMask));
459  }
460  }
461  }
462 }
463 
465 {
466  SAL_WARN_IF( ( !HasPalette() || !rReadAcc.HasPalette() ) && ( HasPalette() || rReadAcc.HasPalette() ), "vcl", "No copying possible between palette bitmap and TC bitmap!" );
467 
468  if( ( GetScanlineFormat() == rReadAcc.GetScanlineFormat() ) &&
469  ( GetScanlineSize() == rReadAcc.GetScanlineSize() ) )
470  {
471  const long nHeight = std::min( mpBuffer->mnHeight, rReadAcc.Height() );
472  const sal_uLong nCount = nHeight * mpBuffer->mnScanlineSize;
473 
474  memcpy( mpBuffer->mpBits, rReadAcc.GetBuffer(), nCount );
475  }
476  else
477  for( long nY = 0, nHeight = std::min( mpBuffer->mnHeight, rReadAcc.Height() ); nY < nHeight; nY++ )
478  CopyScanline( nY, rReadAcc );
479 }
480 
481 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
double mnHeight
static BitmapColor GetPixelForN4BitLsnPal(ConstScanline pScanline, long nX, const ColorMask &rMask)
Definition: bmpacc2.cxx:74
Scanline GetBuffer() const
static BitmapColor GetPixelForN8BitTcMask(ConstScanline pScanline, long nX, const ColorMask &rMask)
Definition: bmpacc2.cxx:105
ColorMask maColorMask
static void SetPixelForN32BitTcRgba(Scanline pScanline, long nX, const BitmapColor &rBitmapColor, const ColorMask &rMask)
Definition: bmpacc2.cxx:330
Scanline GetScanline(long nY) const
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:336
virtual ~BitmapReadAccess() override
Definition: bmpacc.cxx:109
virtual ~BitmapInfoAccess()
Definition: bmpacc.cxx:71
const std::shared_ptr< SalBitmap > & ImplGetSalBitmap() const
Definition: bitmap.hxx:518
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
SAL_DLLPRIVATE bool ImplSetAccessPointers(ScanlineFormat nFormat)
Definition: bmpacc.cxx:122
static BitmapColor GetPixelForN32BitTcBgrx(ConstScanline pScanline, long nX, const ColorMask &rMask)
Definition: bmpacc2.cxx:270
sal_uInt16 GetBestPaletteIndex(const BitmapColor &rBitmapColor) const
Definition: bmpacc.cxx:81
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
BitmapReadAccess(Bitmap &rBitmap, BitmapAccessMode nMode=BitmapAccessMode::Read)
Definition: bmpacc.cxx:86
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:247
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:67
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:135
BitmapAccessMode
BitmapWriteAccess()=delete
sal_uInt8 * mpBits
static BitmapColor GetPixelForN32BitTcXrgb(ConstScanline pScanline, long nX, const ColorMask &rMask)
Definition: bmpacc2.cxx:222
void CopyBuffer(const BitmapReadAccess &rReadAcc)
Definition: bmpacc.cxx:464
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 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:359
void CopyScanline(long nY, const BitmapReadAccess &rReadAcc)
Definition: bmpacc.cxx:363
BitmapAccessMode const mnAccessMode
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:336
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)