LibreOffice Module vcl (master)  1
BitmapTools.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  */
10 
11 #include <vcl/BitmapTools.hxx>
12 
13 #include <sal/log.hxx>
15 #include <comphelper/seqstream.hxx>
16 #include <vcl/canvastools.hxx>
18 
19 #include <com/sun/star/graphic/SvgTools.hpp>
20 #include <com/sun/star/graphic/Primitive2DTools.hpp>
21 
23 
24 #include <com/sun/star/rendering/XIntegerReadOnlyBitmap.hpp>
25 
26 #include <vcl/dibtools.hxx>
27 #include <vcl/settings.hxx>
28 #include <vcl/svapp.hxx>
29 #include <vcl/virdev.hxx>
30 #if ENABLE_CAIRO_CANVAS
31 #include <cairo.h>
32 #endif
33 #include <tools/diagnose_ex.h>
34 #include <tools/fract.hxx>
35 #include <tools/stream.hxx>
37 
38 using namespace css;
39 
42 
43 namespace vcl::bitmap
44 {
45 
46 BitmapEx loadFromName(const OUString& rFileName, const ImageLoadFlags eFlags)
47 {
48  bool bSuccess = true;
49  OUString aIconTheme;
50  BitmapEx aBitmapEx;
51  try
52  {
54  ImageTree::get().loadImage(rFileName, aIconTheme, aBitmapEx, true, eFlags);
55  }
56  catch (...)
57  {
58  bSuccess = false;
59  }
60 
61  SAL_WARN_IF(!bSuccess, "vcl", "vcl::bitmap::loadFromName : could not load image " << rFileName << " via icon theme " << aIconTheme);
62 
63  return aBitmapEx;
64 }
65 
66 void loadFromSvg(SvStream& rStream, const OUString& sPath, BitmapEx& rBitmapEx, double fScalingFactor)
67 {
68  uno::Reference<uno::XComponentContext> xContext(comphelper::getProcessComponentContext());
69  const uno::Reference<graphic::XSvgParser> xSvgParser = graphic::SvgTools::create(xContext);
70 
71  std::size_t nSize = rStream.remainingSize();
72  std::vector<sal_Int8> aBuffer(nSize + 1);
73  rStream.ReadBytes(aBuffer.data(), nSize);
74  aBuffer[nSize] = 0;
75 
76  uno::Sequence<sal_Int8> aData(aBuffer.data(), nSize + 1);
77  uno::Reference<io::XInputStream> aInputStream(new comphelper::SequenceInputStream(aData));
78 
79  const Primitive2DSequence aPrimitiveSequence = xSvgParser->getDecomposition(aInputStream, sPath);
80 
81  if (!aPrimitiveSequence.hasElements())
82  return;
83 
84  uno::Sequence<beans::PropertyValue> aViewParameters;
85 
86  geometry::RealRectangle2D aRealRect;
87  basegfx::B2DRange aRange;
88  for (Primitive2DReference const & xReference : aPrimitiveSequence)
89  {
90  if (xReference.is())
91  {
92  aRealRect = xReference->getRange(aViewParameters);
93  aRange.expand(basegfx::B2DRange(aRealRect.X1, aRealRect.Y1, aRealRect.X2, aRealRect.Y2));
94  }
95  }
96 
97  aRealRect.X1 = aRange.getMinX();
98  aRealRect.Y1 = aRange.getMinY();
99  aRealRect.X2 = aRange.getMaxX();
100  aRealRect.Y2 = aRange.getMaxY();
101 
102  double nDPI = 96 * fScalingFactor;
103 
104  const css::uno::Reference<css::graphic::XPrimitive2DRenderer> xPrimitive2DRenderer = css::graphic::Primitive2DTools::create(xContext);
105  const css::uno::Reference<css::rendering::XBitmap> xBitmap(
106  xPrimitive2DRenderer->rasterize(aPrimitiveSequence, aViewParameters, nDPI, nDPI, aRealRect, 256*256));
107 
108  if (xBitmap.is())
109  {
110  const css::uno::Reference<css::rendering::XIntegerReadOnlyBitmap> xIntBmp(xBitmap, uno::UNO_QUERY_THROW);
111  rBitmapEx = vcl::unotools::bitmapExFromXBitmap(xIntBmp);
112  }
113 
114 }
115 
124 BitmapEx CreateFromData( sal_uInt8 const *pData, sal_Int32 nWidth, sal_Int32 nHeight, sal_Int32 nStride, sal_uInt16 nBitCount )
125 {
126  assert(nStride >= (nWidth * nBitCount / 8));
127  assert( nBitCount == 1 || nBitCount == 24 || nBitCount == 32);
128  Bitmap aBmp( Size( nWidth, nHeight ), nBitCount );
129 
130  BitmapScopedWriteAccess pWrite(aBmp);
131  assert(pWrite.get());
132  if( !pWrite )
133  return BitmapEx();
134  std::unique_ptr<AlphaMask> pAlphaMask;
135  AlphaScopedWriteAccess xMaskAcc;
136  if (nBitCount == 32)
137  {
138  pAlphaMask.reset( new AlphaMask( Size(nWidth, nHeight) ) );
139  xMaskAcc = AlphaScopedWriteAccess(*pAlphaMask);
140  }
141  if (nBitCount == 1)
142  {
143  for( tools::Long y = 0; y < nHeight; ++y )
144  {
145  Scanline pScanline = pWrite->GetScanline(y);
146  for (tools::Long x = 0; x < nWidth; ++x)
147  {
148  sal_uInt8 const *p = pData + y * nStride / 8;
149  int bitIndex = (y * nStride) % 8;
150  pWrite->SetPixelOnData(pScanline, x, BitmapColor((*p >> bitIndex) & 1));
151  }
152  }
153  }
154  else
155  {
156  for( tools::Long y = 0; y < nHeight; ++y )
157  {
158  sal_uInt8 const *p = pData + (y * nStride);
159  Scanline pScanline = pWrite->GetScanline(y);
160  for (tools::Long x = 0; x < nWidth; ++x)
161  {
162  BitmapColor col(p[0], p[1], p[2]);
163  pWrite->SetPixelOnData(pScanline, x, col);
164  p += nBitCount/8;
165  }
166  if (nBitCount == 32)
167  {
168  p = pData + (y * nStride) + 3;
169  Scanline pMaskScanLine = xMaskAcc->GetScanline(y);
170  for (tools::Long x = 0; x < nWidth; ++x)
171  {
172  xMaskAcc->SetPixelOnData(pMaskScanLine, x, BitmapColor(*p));
173  p += 4;
174  }
175  }
176  }
177  }
178  if (nBitCount == 32)
179  return BitmapEx(aBmp, *pAlphaMask);
180  else
181  return BitmapEx(aBmp);
182 }
183 
188 {
189  auto nBitCount = rawBitmap.GetBitCount();
190  assert( nBitCount == 24 || nBitCount == 32);
191  Bitmap aBmp( rawBitmap.maSize, nBitCount );
192 
193  BitmapScopedWriteAccess pWrite(aBmp);
194  assert(pWrite.get());
195  if( !pWrite )
196  return BitmapEx();
197  std::unique_ptr<AlphaMask> pAlphaMask;
198  AlphaScopedWriteAccess xMaskAcc;
199  if (nBitCount == 32)
200  {
201  pAlphaMask.reset( new AlphaMask( rawBitmap.maSize ) );
202  xMaskAcc = AlphaScopedWriteAccess(*pAlphaMask);
203  }
204 
205  auto nHeight = rawBitmap.maSize.getHeight();
206  auto nWidth = rawBitmap.maSize.getWidth();
207  auto nStride = nWidth * nBitCount / 8;
208  for( tools::Long y = 0; y < nHeight; ++y )
209  {
210  sal_uInt8 const *p = rawBitmap.mpData.get() + (y * nStride);
211  Scanline pScanline = pWrite->GetScanline(y);
212  for (tools::Long x = 0; x < nWidth; ++x)
213  {
214  BitmapColor col(p[0], p[1], p[2]);
215  pWrite->SetPixelOnData(pScanline, x, col);
216  p += nBitCount/8;
217  }
218  if (nBitCount == 32)
219  {
220  p = rawBitmap.mpData.get() + (y * nStride) + 3;
221  Scanline pMaskScanLine = xMaskAcc->GetScanline(y);
222  for (tools::Long x = 0; x < nWidth; ++x)
223  {
224  xMaskAcc->SetPixelOnData(pMaskScanLine, x, BitmapColor(*p));
225  p += 4;
226  }
227  }
228  }
229  if (nBitCount == 32)
230  return BitmapEx(aBmp, *pAlphaMask);
231  else
232  return BitmapEx(aBmp);
233 }
234 
235 #if ENABLE_CAIRO_CANVAS
236 BitmapEx* CreateFromCairoSurface(Size aSize, cairo_surface_t * pSurface)
237 {
238  // FIXME: if we could teach VCL/ about cairo handles, life could
239  // be significantly better here perhaps.
240 
241 #if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 12, 0)
242  cairo_surface_t *pPixels = cairo_surface_create_similar_image(pSurface,
243 #else
244  cairo_surface_t *pPixels = cairo_image_surface_create(
245 #endif
246  CAIRO_FORMAT_ARGB32, aSize.Width(), aSize.Height());
247  cairo_t *pCairo = cairo_create( pPixels );
248  if( !pPixels || !pCairo || cairo_status(pCairo) != CAIRO_STATUS_SUCCESS )
249  return nullptr;
250 
251  // suck ourselves from the X server to this buffer so then we can fiddle with
252  // Alpha to turn it into the ultra-lame vcl required format and then push it
253  // all back again later at vast expense [ urgh ]
254  cairo_set_source_surface( pCairo, pSurface, 0, 0 );
255  cairo_set_operator( pCairo, CAIRO_OPERATOR_SOURCE );
256  cairo_paint( pCairo );
257 
258  ::Bitmap aRGB( aSize, 24 );
259  ::AlphaMask aMask( aSize );
260 
261  BitmapScopedWriteAccess pRGBWrite(aRGB);
262  assert(pRGBWrite);
263  if (!pRGBWrite)
264  return nullptr;
265 
266  AlphaScopedWriteAccess pMaskWrite(aMask);
267  assert(pMaskWrite);
268  if (!pMaskWrite)
269  return nullptr;
270 
271  cairo_surface_flush(pPixels);
272  unsigned char *pSrc = cairo_image_surface_get_data( pPixels );
273  unsigned int nStride = cairo_image_surface_get_stride( pPixels );
275  for( tools::Long y = 0; y < aSize.Height(); y++ )
276  {
277  sal_uInt32 *pPix = reinterpret_cast<sal_uInt32 *>(pSrc + nStride * y);
278  for( tools::Long x = 0; x < aSize.Width(); x++ )
279  {
280 #if defined OSL_BIGENDIAN
281  sal_uInt8 nB = (*pPix >> 24);
282  sal_uInt8 nG = (*pPix >> 16) & 0xff;
283  sal_uInt8 nR = (*pPix >> 8) & 0xff;
284  sal_uInt8 nAlpha = *pPix & 0xff;
285 #else
286  sal_uInt8 nAlpha = (*pPix >> 24);
287  sal_uInt8 nR = (*pPix >> 16) & 0xff;
288  sal_uInt8 nG = (*pPix >> 8) & 0xff;
289  sal_uInt8 nB = *pPix & 0xff;
290 #endif
291  if( nAlpha != 0 && nAlpha != 255 )
292  {
293  // Cairo uses pre-multiplied alpha - we do not => re-multiply
294  nR = unpremultiply_table[nAlpha][nR];
295  nG = unpremultiply_table[nAlpha][nG];
296  nB = unpremultiply_table[nAlpha][nB];
297  }
298  pRGBWrite->SetPixel( y, x, BitmapColor( nR, nG, nB ) );
299  pMaskWrite->SetPixelIndex( y, x, 255 - nAlpha );
300  pPix++;
301  }
302  }
303 
304  // ignore potential errors above. will get caller a
305  // uniformly white bitmap, but not that there would
306  // be error handling in calling code ...
307  ::BitmapEx *pBitmapEx = new ::BitmapEx( aRGB, aMask );
308 
309  cairo_destroy( pCairo );
310  cairo_surface_destroy( pPixels );
311  return pBitmapEx;
312 }
313 #endif
314 
316  const ::basegfx::B2DHomMatrix& rTransform,
317  ::basegfx::B2DRectangle const & rDestRect,
318  ::basegfx::B2DHomMatrix const & rLocalTransform )
319 {
320  const Size aBmpSize( rBitmap.GetSizePixel() );
321  Bitmap aSrcBitmap( rBitmap.GetBitmap() );
322  Bitmap aSrcAlpha;
323 
324  // differentiate mask and alpha channel (on-off
325  // vs. multi-level transparency)
326  if( rBitmap.IsTransparent() )
327  {
328  if( rBitmap.IsAlpha() )
329  aSrcAlpha = rBitmap.GetAlpha().GetBitmap();
330  else
331  aSrcAlpha = rBitmap.GetMask();
332  }
333 
334  Bitmap::ScopedReadAccess pReadAccess( aSrcBitmap );
335  Bitmap::ScopedReadAccess pAlphaReadAccess( rBitmap.IsTransparent() ?
336  aSrcAlpha.AcquireReadAccess() :
337  nullptr,
338  aSrcAlpha );
339 
340  if( pReadAccess.get() == nullptr ||
341  (pAlphaReadAccess.get() == nullptr && rBitmap.IsTransparent()) )
342  {
343  // TODO(E2): Error handling!
344  ENSURE_OR_THROW( false,
345  "transformBitmap(): could not access source bitmap" );
346  }
347 
348  // mapping table, to translate pAlphaReadAccess' pixel
349  // values into destination alpha values (needed e.g. for
350  // paletted 1-bit masks).
351  sal_uInt8 aAlphaMap[256];
352 
353  if( rBitmap.IsTransparent() )
354  {
355  if( rBitmap.IsAlpha() )
356  {
357  // source already has alpha channel - 1:1 mapping,
358  // i.e. aAlphaMap[0]=0,...,aAlphaMap[255]=255.
359  sal_uInt8 val=0;
360  sal_uInt8* pCur=aAlphaMap;
361  sal_uInt8* const pEnd=&aAlphaMap[256];
362  while(pCur != pEnd)
363  *pCur++ = val++;
364  }
365  else
366  {
367  // mask transparency - determine used palette colors
368  const BitmapColor& rCol0( pAlphaReadAccess->GetPaletteColor( 0 ) );
369  const BitmapColor& rCol1( pAlphaReadAccess->GetPaletteColor( 1 ) );
370 
371  // shortcut for true luminance calculation
372  // (assumes that palette is grey-level)
373  aAlphaMap[0] = rCol0.GetRed();
374  aAlphaMap[1] = rCol1.GetRed();
375  }
376  }
377  // else: mapping table is not used
378 
379  const Size aDestBmpSize( ::basegfx::fround( rDestRect.getWidth() ),
380  ::basegfx::fround( rDestRect.getHeight() ) );
381 
382  if( aDestBmpSize.IsEmpty() )
383  return BitmapEx();
384 
385  Bitmap aDstBitmap( aDestBmpSize, aSrcBitmap.GetBitCount(), &pReadAccess->GetPalette() );
386  Bitmap aDstAlpha( AlphaMask( aDestBmpSize ).GetBitmap() );
387 
388  {
389  // just to be on the safe side: let the
390  // ScopedAccessors get destructed before
391  // copy-constructing the resulting bitmap. This will
392  // rule out the possibility that cached accessor data
393  // is not yet written back.
394  BitmapScopedWriteAccess pWriteAccess( aDstBitmap );
395  BitmapScopedWriteAccess pAlphaWriteAccess( aDstAlpha );
396 
397 
398  if( pWriteAccess.get() != nullptr &&
399  pAlphaWriteAccess.get() != nullptr &&
400  rTransform.isInvertible() )
401  {
402  // we're doing inverse mapping here, i.e. mapping
403  // points from the destination bitmap back to the
404  // source
405  ::basegfx::B2DHomMatrix aTransform( rLocalTransform );
406  aTransform.invert();
407 
408  // for the time being, always read as ARGB
409  for( tools::Long y=0; y<aDestBmpSize.Height(); ++y )
410  {
411  // differentiate mask and alpha channel (on-off
412  // vs. multi-level transparency)
413  if( rBitmap.IsTransparent() )
414  {
415  Scanline pScan = pWriteAccess->GetScanline( y );
416  Scanline pScanAlpha = pAlphaWriteAccess->GetScanline( y );
417  // Handling alpha and mask just the same...
418  for( tools::Long x=0; x<aDestBmpSize.Width(); ++x )
419  {
420  ::basegfx::B2DPoint aPoint(x,y);
421  aPoint *= aTransform;
422 
423  const int nSrcX( ::basegfx::fround( aPoint.getX() ) );
424  const int nSrcY( ::basegfx::fround( aPoint.getY() ) );
425  if( nSrcX < 0 || nSrcX >= aBmpSize.Width() ||
426  nSrcY < 0 || nSrcY >= aBmpSize.Height() )
427  {
428  pAlphaWriteAccess->SetPixelOnData( pScanAlpha, x, BitmapColor(255) );
429  }
430  else
431  {
432  const sal_uInt8 cAlphaIdx = pAlphaReadAccess->GetPixelIndex( nSrcY, nSrcX );
433  pAlphaWriteAccess->SetPixelOnData( pScanAlpha, x, BitmapColor(aAlphaMap[ cAlphaIdx ]) );
434  pWriteAccess->SetPixelOnData( pScan, x, pReadAccess->GetPixel( nSrcY, nSrcX ) );
435  }
436  }
437  }
438  else
439  {
440  Scanline pScan = pWriteAccess->GetScanline( y );
441  Scanline pScanAlpha = pAlphaWriteAccess->GetScanline( y );
442  for( tools::Long x=0; x<aDestBmpSize.Width(); ++x )
443  {
444  ::basegfx::B2DPoint aPoint(x,y);
445  aPoint *= aTransform;
446 
447  const int nSrcX( ::basegfx::fround( aPoint.getX() ) );
448  const int nSrcY( ::basegfx::fround( aPoint.getY() ) );
449  if( nSrcX < 0 || nSrcX >= aBmpSize.Width() ||
450  nSrcY < 0 || nSrcY >= aBmpSize.Height() )
451  {
452  pAlphaWriteAccess->SetPixelOnData( pScanAlpha, x, BitmapColor(255) );
453  }
454  else
455  {
456  pAlphaWriteAccess->SetPixelOnData( pScanAlpha, x, BitmapColor(0) );
457  pWriteAccess->SetPixelOnData( pScan, x, pReadAccess->GetPixel( nSrcY,
458  nSrcX ) );
459  }
460  }
461  }
462  }
463  }
464  else
465  {
466  // TODO(E2): Error handling!
467  ENSURE_OR_THROW( false,
468  "transformBitmap(): could not access bitmap" );
469  }
470  }
471 
472  return BitmapEx(aDstBitmap, AlphaMask(aDstAlpha));
473 }
474 
475 
476 void DrawAlphaBitmapAndAlphaGradient(BitmapEx & rBitmapEx, bool bFixedTransparence, float fTransparence, AlphaMask & rNewMask)
477 {
478  // mix existing and new alpha mask
479  AlphaMask aOldMask;
480 
481  if(rBitmapEx.IsAlpha())
482  {
483  aOldMask = rBitmapEx.GetAlpha();
484  }
485  else if(TransparentType::Bitmap == rBitmapEx.GetTransparentType())
486  {
487  aOldMask = rBitmapEx.GetMask();
488  }
489  else if(TransparentType::Color == rBitmapEx.GetTransparentType())
490  {
491  aOldMask = rBitmapEx.GetBitmap().CreateMask(rBitmapEx.GetTransparentColor());
492  }
493 
494  {
495  AlphaScopedWriteAccess pOld(aOldMask);
496 
497  assert(pOld && "Got no access to old alpha mask (!)");
498 
499  const double fFactor(1.0 / 255.0);
500 
501  if(bFixedTransparence)
502  {
503  const double fOpNew(1.0 - fTransparence);
504 
505  for(tools::Long y(0); y < pOld->Height(); y++)
506  {
507  Scanline pScanline = pOld->GetScanline( y );
508  for(tools::Long x(0); x < pOld->Width(); x++)
509  {
510  const double fOpOld(1.0 - (pOld->GetIndexFromData(pScanline, x) * fFactor));
511  const sal_uInt8 aCol(basegfx::fround((1.0 - (fOpOld * fOpNew)) * 255.0));
512 
513  pOld->SetPixelOnData(pScanline, x, BitmapColor(aCol));
514  }
515  }
516  }
517  else
518  {
519  AlphaMask::ScopedReadAccess pNew(rNewMask);
520 
521  assert(pNew && "Got no access to new alpha mask (!)");
522 
523  assert(pOld->Width() == pNew->Width() && pOld->Height() == pNew->Height() &&
524  "Alpha masks have different sizes (!)");
525 
526  for(tools::Long y(0); y < pOld->Height(); y++)
527  {
528  Scanline pScanline = pOld->GetScanline( y );
529  for(tools::Long x(0); x < pOld->Width(); x++)
530  {
531  const double fOpOld(1.0 - (pOld->GetIndexFromData(pScanline, x) * fFactor));
532  const double fOpNew(1.0 - (pNew->GetIndexFromData(pScanline, x) * fFactor));
533  const sal_uInt8 aCol(basegfx::fround((1.0 - (fOpOld * fOpNew)) * 255.0));
534 
535  pOld->SetPixelOnData(pScanline, x, BitmapColor(aCol));
536  }
537  }
538  }
539 
540  }
541 
542  // apply combined bitmap as mask
543  rBitmapEx = BitmapEx(rBitmapEx.GetBitmap(), aOldMask);
544 }
545 
546 
547 void DrawAndClipBitmap(const Point& rPos, const Size& rSize, const BitmapEx& rBitmap, BitmapEx & aBmpEx, basegfx::B2DPolyPolygon const & rClipPath)
548 {
550  MapMode aMapMode( MapUnit::Map100thMM );
551  aMapMode.SetOrigin( Point( -rPos.X(), -rPos.Y() ) );
552  const Size aOutputSizePixel( pVDev->LogicToPixel( rSize, aMapMode ) );
553  const Size aSizePixel( rBitmap.GetSizePixel() );
554  if ( aOutputSizePixel.Width() && aOutputSizePixel.Height() )
555  {
556  aMapMode.SetScaleX( Fraction( aSizePixel.Width(), aOutputSizePixel.Width() ) );
557  aMapMode.SetScaleY( Fraction( aSizePixel.Height(), aOutputSizePixel.Height() ) );
558  }
559  pVDev->SetMapMode( aMapMode );
560  pVDev->SetOutputSizePixel( aSizePixel );
561  pVDev->SetFillColor( COL_BLACK );
562  const tools::PolyPolygon aClip( rClipPath );
563  pVDev->DrawPolyPolygon( aClip );
564 
565  // #i50672# Extract whole VDev content (to match size of rBitmap)
566  pVDev->EnableMapMode( false );
567  const Bitmap aVDevMask(pVDev->GetBitmap(Point(), aSizePixel));
568 
569  if(aBmpEx.IsTransparent())
570  {
571  // bitmap already uses a Mask or Alpha, we need to blend that with
572  // the new masking in pVDev
573  if(aBmpEx.IsAlpha())
574  {
575  // need to blend in AlphaMask quality (8Bit)
576  AlphaMask fromVDev(aVDevMask);
577  AlphaMask fromBmpEx(aBmpEx.GetAlpha());
578  AlphaMask::ScopedReadAccess pR(fromVDev);
579  AlphaScopedWriteAccess pW(fromBmpEx);
580 
581  if(pR && pW)
582  {
583  const tools::Long nWidth(std::min(pR->Width(), pW->Width()));
584  const tools::Long nHeight(std::min(pR->Height(), pW->Height()));
585 
586  for(tools::Long nY(0); nY < nHeight; nY++)
587  {
588  Scanline pScanlineR = pR->GetScanline( nY );
589  Scanline pScanlineW = pW->GetScanline( nY );
590  for(tools::Long nX(0); nX < nWidth; nX++)
591  {
592  const sal_uInt8 nIndR(pR->GetIndexFromData(pScanlineR, nX));
593  const sal_uInt8 nIndW(pW->GetIndexFromData(pScanlineW, nX));
594 
595  // these values represent transparency (0 == no, 255 == fully transparent),
596  // so to blend these we have to multiply the inverse (opacity)
597  // and re-invert the result to transparence
598  const sal_uInt8 nCombined(0x00ff - (((0x00ff - nIndR) * (0x00ff - nIndW)) >> 8));
599 
600  pW->SetPixelOnData(pScanlineW, nX, BitmapColor(nCombined));
601  }
602  }
603  }
604 
605  pR.reset();
606  pW.reset();
607  aBmpEx = BitmapEx(aBmpEx.GetBitmap(), fromBmpEx);
608  }
609  else
610  {
611  // need to blend in Mask quality (1Bit)
612  Bitmap aMask(aVDevMask.CreateMask(COL_WHITE));
613 
614  if ( rBitmap.GetTransparentColor() == COL_WHITE )
615  {
616  aMask.CombineSimple( rBitmap.GetMask(), BmpCombine::Or );
617  }
618  else
619  {
620  aMask.CombineSimple( rBitmap.GetMask(), BmpCombine::And );
621  }
622 
623  aBmpEx = BitmapEx( rBitmap.GetBitmap(), aMask );
624  }
625  }
626  else
627  {
628  // no mask yet, create and add new mask. For better quality, use Alpha,
629  // this allows the drawn mask being processed with AntiAliasing (AAed)
630  aBmpEx = BitmapEx(rBitmap.GetBitmap(), aVDevMask);
631  }
632 }
633 
634 
635 css::uno::Sequence< sal_Int8 > GetMaskDIB(BitmapEx const & aBmpEx)
636 {
637  if ( aBmpEx.IsAlpha() )
638  {
639  SvMemoryStream aMem;
640  WriteDIB(aBmpEx.GetAlpha().GetBitmap(), aMem, false, true);
641  return css::uno::Sequence< sal_Int8 >( static_cast<sal_Int8 const *>(aMem.GetData()), aMem.Tell() );
642  }
643  else if ( aBmpEx.IsTransparent() )
644  {
645  SvMemoryStream aMem;
646  WriteDIB(aBmpEx.GetMask(), aMem, false, true);
647  return css::uno::Sequence< sal_Int8 >( static_cast<sal_Int8 const *>(aMem.GetData()), aMem.Tell() );
648  }
649 
650  return css::uno::Sequence< sal_Int8 >();
651 }
652 
653 static bool readAlpha( BitmapReadAccess const * pAlphaReadAcc, tools::Long nY, const tools::Long nWidth, unsigned char* data, tools::Long nOff )
654 {
655  bool bIsAlpha = false;
656  tools::Long nX;
657  int nAlpha;
658  Scanline pReadScan;
659 
660  nOff += 3;
661 
662  switch( pAlphaReadAcc->GetScanlineFormat() )
663  {
665  pReadScan = pAlphaReadAcc->GetScanline( nY );
666  for( nX = 0; nX < nWidth; nX++ )
667  {
668  BitmapColor const& rColor(
669  pAlphaReadAcc->GetPaletteColor(*pReadScan));
670  pReadScan++;
671  nAlpha = data[ nOff ] = 255 - rColor.GetIndex();
672  if( nAlpha != 255 )
673  bIsAlpha = true;
674  nOff += 4;
675  }
676  break;
677  default:
678  SAL_INFO( "canvas.cairo", "fallback to GetColor for alpha - slow, format: " << static_cast<int>(pAlphaReadAcc->GetScanlineFormat()) );
679  for( nX = 0; nX < nWidth; nX++ )
680  {
681  nAlpha = data[ nOff ] = 255 - pAlphaReadAcc->GetColor( nY, nX ).GetIndex();
682  if( nAlpha != 255 )
683  bIsAlpha = true;
684  nOff += 4;
685  }
686  }
687 
688  return bIsAlpha;
689 }
690 
691 
692 
697 void CanvasCairoExtractBitmapData( BitmapEx const & aBmpEx, Bitmap & aBitmap, unsigned char*& data, bool& bHasAlpha, tools::Long& rnWidth, tools::Long& rnHeight )
698 {
699  AlphaMask aAlpha = aBmpEx.GetAlpha();
700 
701  ::BitmapReadAccess* pBitmapReadAcc = aBitmap.AcquireReadAccess();
702  ::BitmapReadAccess* pAlphaReadAcc = nullptr;
703  const tools::Long nWidth = rnWidth = pBitmapReadAcc->Width();
704  const tools::Long nHeight = rnHeight = pBitmapReadAcc->Height();
705  tools::Long nX, nY;
706  bool bIsAlpha = false;
707 
708  if( aBmpEx.IsTransparent() || aBmpEx.IsAlpha() )
709  pAlphaReadAcc = aAlpha.AcquireReadAccess();
710 
711  data = static_cast<unsigned char*>(malloc( nWidth*nHeight*4 ));
712 
713  tools::Long nOff = 0;
714  ::Color aColor;
715  unsigned int nAlpha = 255;
716 
718  for( nY = 0; nY < nHeight; nY++ )
719  {
720  ::Scanline pReadScan;
721 
722  switch( pBitmapReadAcc->GetScanlineFormat() )
723  {
725  pReadScan = pBitmapReadAcc->GetScanline( nY );
726  if( pAlphaReadAcc )
727  if( readAlpha( pAlphaReadAcc, nY, nWidth, data, nOff ) )
728  bIsAlpha = true;
729 
730  for( nX = 0; nX < nWidth; nX++ )
731  {
732 #ifdef OSL_BIGENDIAN
733  if( pAlphaReadAcc )
734  nAlpha = data[ nOff++ ];
735  else
736  nAlpha = data[ nOff++ ] = 255;
737 #else
738  if( pAlphaReadAcc )
739  nAlpha = data[ nOff + 3 ];
740  else
741  nAlpha = data[ nOff + 3 ] = 255;
742 #endif
743  aColor = pBitmapReadAcc->GetPaletteColor(*pReadScan++);
744 
745 #ifdef OSL_BIGENDIAN
746  data[ nOff++ ] = premultiply_table[nAlpha][aColor.GetRed()];
747  data[ nOff++ ] = premultiply_table[nAlpha][aColor.GetGreen()];
748  data[ nOff++ ] = premultiply_table[nAlpha][aColor.GetBlue()];
749 #else
750  data[ nOff++ ] = premultiply_table[nAlpha][aColor.GetBlue()];
751  data[ nOff++ ] = premultiply_table[nAlpha][aColor.GetGreen()];
752  data[ nOff++ ] = premultiply_table[nAlpha][aColor.GetRed()];
753  nOff++;
754 #endif
755  }
756  break;
758  pReadScan = pBitmapReadAcc->GetScanline( nY );
759  if( pAlphaReadAcc )
760  if( readAlpha( pAlphaReadAcc, nY, nWidth, data, nOff ) )
761  bIsAlpha = true;
762 
763  for( nX = 0; nX < nWidth; nX++ )
764  {
765 #ifdef OSL_BIGENDIAN
766  if( pAlphaReadAcc )
767  nAlpha = data[ nOff ];
768  else
769  nAlpha = data[ nOff ] = 255;
770  data[ nOff + 3 ] = premultiply_table[nAlpha][*pReadScan++];
771  data[ nOff + 2 ] = premultiply_table[nAlpha][*pReadScan++];
772  data[ nOff + 1 ] = premultiply_table[nAlpha][*pReadScan++];
773  nOff += 4;
774 #else
775  if( pAlphaReadAcc )
776  nAlpha = data[ nOff + 3 ];
777  else
778  nAlpha = data[ nOff + 3 ] = 255;
779  data[ nOff++ ] = premultiply_table[nAlpha][*pReadScan++];
780  data[ nOff++ ] = premultiply_table[nAlpha][*pReadScan++];
781  data[ nOff++ ] = premultiply_table[nAlpha][*pReadScan++];
782  nOff++;
783 #endif
784  }
785  break;
787  pReadScan = pBitmapReadAcc->GetScanline( nY );
788  if( pAlphaReadAcc )
789  if( readAlpha( pAlphaReadAcc, nY, nWidth, data, nOff ) )
790  bIsAlpha = true;
791 
792  for( nX = 0; nX < nWidth; nX++ )
793  {
794 #ifdef OSL_BIGENDIAN
795  if( pAlphaReadAcc )
796  nAlpha = data[ nOff++ ];
797  else
798  nAlpha = data[ nOff++ ] = 255;
799  data[ nOff++ ] = premultiply_table[nAlpha][*pReadScan++];
800  data[ nOff++ ] = premultiply_table[nAlpha][*pReadScan++];
801  data[ nOff++ ] = premultiply_table[nAlpha][*pReadScan++];
802 #else
803  if( pAlphaReadAcc )
804  nAlpha = data[ nOff + 3 ];
805  else
806  nAlpha = data[ nOff + 3 ] = 255;
807  data[ nOff++ ] = premultiply_table[nAlpha][pReadScan[ 2 ]];
808  data[ nOff++ ] = premultiply_table[nAlpha][pReadScan[ 1 ]];
809  data[ nOff++ ] = premultiply_table[nAlpha][pReadScan[ 0 ]];
810  pReadScan += 3;
811  nOff++;
812 #endif
813  }
814  break;
816  pReadScan = pBitmapReadAcc->GetScanline( nY );
817  if( pAlphaReadAcc )
818  if( readAlpha( pAlphaReadAcc, nY, nWidth, data, nOff ) )
819  bIsAlpha = true;
820 
821  for( nX = 0; nX < nWidth; nX++ )
822  {
823 #ifdef OSL_BIGENDIAN
824  if( pAlphaReadAcc )
825  nAlpha = data[ nOff++ ];
826  else
827  nAlpha = data[ nOff++ ] = 255;
828  data[ nOff++ ] = premultiply_table[nAlpha][pReadScan[ 2 ]];
829  data[ nOff++ ] = premultiply_table[nAlpha][pReadScan[ 1 ]];
830  data[ nOff++ ] = premultiply_table[nAlpha][pReadScan[ 0 ]];
831  pReadScan += 4;
832 #else
833  if( pAlphaReadAcc )
834  nAlpha = data[ nOff + 3 ];
835  else
836  nAlpha = data[ nOff + 3 ] = 255;
837  data[ nOff++ ] = premultiply_table[nAlpha][*pReadScan++];
838  data[ nOff++ ] = premultiply_table[nAlpha][*pReadScan++];
839  data[ nOff++ ] = premultiply_table[nAlpha][*pReadScan++];
840  pReadScan++;
841  nOff++;
842 #endif
843  }
844  break;
846  pReadScan = pBitmapReadAcc->GetScanline( nY );
847  if( pAlphaReadAcc )
848  if( readAlpha( pAlphaReadAcc, nY, nWidth, data, nOff ) )
849  bIsAlpha = true;
850 
851  for( nX = 0; nX < nWidth; nX++ )
852  {
853 #ifdef OSL_BIGENDIAN
854  if( pAlphaReadAcc )
855  nAlpha = data[ nOff ++ ];
856  else
857  nAlpha = data[ nOff ++ ] = 255;
858  data[ nOff++ ] = premultiply_table[nAlpha][*pReadScan++];
859  data[ nOff++ ] = premultiply_table[nAlpha][*pReadScan++];
860  data[ nOff++ ] = premultiply_table[nAlpha][*pReadScan++];
861  pReadScan++;
862 #else
863  if( pAlphaReadAcc )
864  nAlpha = data[ nOff + 3 ];
865  else
866  nAlpha = data[ nOff + 3 ] = 255;
867  data[ nOff++ ] = premultiply_table[nAlpha][pReadScan[ 2 ]];
868  data[ nOff++ ] = premultiply_table[nAlpha][pReadScan[ 1 ]];
869  data[ nOff++ ] = premultiply_table[nAlpha][pReadScan[ 0 ]];
870  pReadScan += 4;
871  nOff++;
872 #endif
873  }
874  break;
875  default:
876  SAL_INFO( "canvas.cairo", "fallback to GetColor - slow, format: " << static_cast<int>(pBitmapReadAcc->GetScanlineFormat()) );
877 
878  if( pAlphaReadAcc )
879  if( readAlpha( pAlphaReadAcc, nY, nWidth, data, nOff ) )
880  bIsAlpha = true;
881 
882  for( nX = 0; nX < nWidth; nX++ )
883  {
884  aColor = pBitmapReadAcc->GetColor( nY, nX );
885 
886  // cairo need premultiplied color values
887  // TODO(rodo) handle endianness
888 #ifdef OSL_BIGENDIAN
889  if( pAlphaReadAcc )
890  nAlpha = data[ nOff++ ];
891  else
892  nAlpha = data[ nOff++ ] = 255;
893  data[ nOff++ ] = premultiply_table[nAlpha][aColor.GetRed()];
894  data[ nOff++ ] = premultiply_table[nAlpha][aColor.GetGreen()];
895  data[ nOff++ ] = premultiply_table[nAlpha][aColor.GetBlue()];
896 #else
897  if( pAlphaReadAcc )
898  nAlpha = data[ nOff + 3 ];
899  else
900  nAlpha = data[ nOff + 3 ] = 255;
901  data[ nOff++ ] = premultiply_table[nAlpha][aColor.GetBlue()];
902  data[ nOff++ ] = premultiply_table[nAlpha][aColor.GetGreen()];
903  data[ nOff++ ] = premultiply_table[nAlpha][aColor.GetRed()];
904  nOff ++;
905 #endif
906  }
907  }
908  }
909 
910  ::Bitmap::ReleaseAccess( pBitmapReadAcc );
911  if( pAlphaReadAcc )
912  aAlpha.ReleaseAccess( pAlphaReadAcc );
913 
914  bHasAlpha = bIsAlpha;
915 
916 }
917 
918  uno::Sequence< sal_Int8 > CanvasExtractBitmapData(BitmapEx const & rBitmapEx, const geometry::IntegerRectangle2D& rect)
919  {
920  Bitmap aBitmap( rBitmapEx.GetBitmap() );
921  Bitmap aAlpha( rBitmapEx.GetAlpha().GetBitmap() );
922 
923  Bitmap::ScopedReadAccess pReadAccess( aBitmap );
924  Bitmap::ScopedReadAccess pAlphaReadAccess( aAlpha.IsEmpty() ?
925  nullptr : aAlpha.AcquireReadAccess(),
926  aAlpha );
927 
928  assert( pReadAccess );
929 
930  // TODO(F1): Support more formats.
931  const Size aBmpSize( aBitmap.GetSizePixel() );
932 
933  // for the time being, always return as BGRA
934  uno::Sequence< sal_Int8 > aRes( 4*aBmpSize.Width()*aBmpSize.Height() );
935  sal_Int8* pRes = aRes.getArray();
936 
937  int nCurrPos(0);
938  for( tools::Long y=rect.Y1;
939  y<aBmpSize.Height() && y<rect.Y2;
940  ++y )
941  {
942  if( pAlphaReadAccess.get() != nullptr )
943  {
944  Scanline pScanlineReadAlpha = pAlphaReadAccess->GetScanline( y );
945  for( tools::Long x=rect.X1;
946  x<aBmpSize.Width() && x<rect.X2;
947  ++x )
948  {
949  pRes[ nCurrPos++ ] = pReadAccess->GetColor( y, x ).GetRed();
950  pRes[ nCurrPos++ ] = pReadAccess->GetColor( y, x ).GetGreen();
951  pRes[ nCurrPos++ ] = pReadAccess->GetColor( y, x ).GetBlue();
952  pRes[ nCurrPos++ ] = pAlphaReadAccess->GetIndexFromData( pScanlineReadAlpha, x );
953  }
954  }
955  else
956  {
957  for( tools::Long x=rect.X1;
958  x<aBmpSize.Width() && x<rect.X2;
959  ++x )
960  {
961  pRes[ nCurrPos++ ] = pReadAccess->GetColor( y, x ).GetRed();
962  pRes[ nCurrPos++ ] = pReadAccess->GetColor( y, x ).GetGreen();
963  pRes[ nCurrPos++ ] = pReadAccess->GetColor( y, x ).GetBlue();
964  pRes[ nCurrPos++ ] = sal_uInt8(255);
965  }
966  }
967  }
968  return aRes;
969  }
970 
971  BitmapEx createHistorical8x8FromArray(std::array<sal_uInt8,64> const & pArray, Color aColorPix, Color aColorBack)
972  {
973  BitmapPalette aPalette(2);
974 
975  aPalette[0] = BitmapColor(aColorBack);
976  aPalette[1] = BitmapColor(aColorPix);
977 
978  Bitmap aBitmap(Size(8, 8), 1, &aPalette);
980 
981  for(sal_uInt16 a(0); a < 8; a++)
982  {
983  for(sal_uInt16 b(0); b < 8; b++)
984  {
985  if(pArray[(a * 8) + b])
986  {
987  pContent->SetPixelIndex(a, b, 1);
988  }
989  else
990  {
991  pContent->SetPixelIndex(a, b, 0);
992  }
993  }
994  }
995 
996  return BitmapEx(aBitmap);
997  }
998 
999  bool isHistorical8x8(const BitmapEx& rBitmapEx, Color& o_rBack, Color& o_rFront)
1000  {
1001  bool bRet(false);
1002 
1003  if(!rBitmapEx.IsTransparent())
1004  {
1005  Bitmap aBitmap(rBitmapEx.GetBitmap());
1006 
1007  if(8 == aBitmap.GetSizePixel().Width() && 8 == aBitmap.GetSizePixel().Height())
1008  {
1009  if(2 == aBitmap.GetColorCount())
1010  {
1011  BitmapReadAccess* pRead = aBitmap.AcquireReadAccess();
1012 
1013  if(pRead)
1014  {
1015  if(pRead->HasPalette() && 2 == pRead->GetPaletteEntryCount())
1016  {
1017  const BitmapPalette& rPalette = pRead->GetPalette();
1018 
1019  // #i123564# background and foreground were exchanged; of course
1020  // rPalette[0] is the background color
1021  o_rFront = rPalette[1];
1022  o_rBack = rPalette[0];
1023 
1024  bRet = true;
1025  }
1026 
1027  Bitmap::ReleaseAccess(pRead);
1028  }
1029  }
1030  }
1031  }
1032 
1033  return bRet;
1034  }
1035 
1037  {
1038  return (a == 0) ? 0 : (c * 255 + a / 2) / a;
1039  }
1040 
1042  {
1043  return (c * a + 127) / 255;
1044  }
1045 
1047  {
1048  static bool inited;
1049  static sal_uInt8 unpremultiply_table[256][256];
1050 
1051  if (!inited)
1052  {
1053  for (int a = 0; a < 256; ++a)
1054  for (int c = 0; c < 256; ++c)
1055  unpremultiply_table[a][c] = unpremultiply(c, a);
1056  inited = true;
1057  }
1058 
1059  return unpremultiply_table;
1060  }
1061 
1063  {
1064  static bool inited;
1065  static sal_uInt8 premultiply_table[256][256];
1066 
1067  if (!inited)
1068  {
1069  for (int a = 0; a < 256; ++a)
1070  for (int c = 0; c < 256; ++c)
1071  premultiply_table[a][c] = premultiply(c, a);
1072  inited = true;
1073  }
1074 
1075  return premultiply_table;
1076  }
1077 
1078 bool convertBitmap32To24Plus8(BitmapEx const & rInput, BitmapEx & rResult)
1079 {
1080  Bitmap aBitmap(rInput.GetBitmap());
1081  if (aBitmap.GetBitCount() != 32)
1082  return false;
1083 
1084  Size aSize = aBitmap.GetSizePixel();
1085  Bitmap aResultBitmap(aSize, 24);
1086  AlphaMask aResultAlpha(aSize);
1087  {
1088  BitmapScopedWriteAccess pResultBitmapAccess(aResultBitmap);
1089  AlphaScopedWriteAccess pResultAlphaAccess(aResultAlpha);
1090 
1091  Bitmap::ScopedReadAccess pReadAccess(aBitmap);
1092 
1093  for (tools::Long nY = 0; nY < aSize.Height(); ++nY)
1094  {
1095  Scanline aResultScan = pResultBitmapAccess->GetScanline(nY);
1096  Scanline aResultScanAlpha = pResultAlphaAccess->GetScanline(nY);
1097 
1098  Scanline aReadScan = pReadAccess->GetScanline(nY);
1099 
1100  for (tools::Long nX = 0; nX < aSize.Width(); ++nX)
1101  {
1102  const BitmapColor aColor = pReadAccess->GetPixelFromData(aReadScan, nX);
1103  BitmapColor aResultColor(aColor.GetRed(), aColor.GetGreen(), aColor.GetBlue());
1104  BitmapColor aResultColorAlpha(255 - aColor.GetAlpha(), 255 - aColor.GetAlpha(), 255 - aColor.GetAlpha());
1105 
1106  pResultBitmapAccess->SetPixelOnData(aResultScan, nX, aResultColor);
1107  pResultAlphaAccess->SetPixelOnData(aResultScanAlpha, nX, aResultColorAlpha);
1108  }
1109  }
1110  }
1111  if (rInput.IsTransparent())
1112  rResult = BitmapEx(aResultBitmap, rInput.GetAlpha());
1113  else
1114  rResult = BitmapEx(aResultBitmap, aResultAlpha);
1115  return true;
1116 }
1117 
1118 } // end vcl::bitmap
1119 
1120 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
void loadFromSvg(SvStream &rStream, const OUString &sPath, BitmapEx &rBitmapEx, double fScalingFactor)
Definition: BitmapTools.cxx:66
sal_uInt8 premultiply(sal_uInt8 c, sal_uInt8 a)
sal_uInt8 GetIndexFromData(const sal_uInt8 *pData, tools::Long nX) const
Bitmap GetMask() const
Definition: BitmapEx.cxx:253
ImageLoadFlags
Definition: ImageTree.hxx:31
sal_uInt8 GetIndex() const
Definition: BitmapColor.hxx:70
void expand(const B2DTuple &rTuple)
tools::Long Height() const
sal_uInt8 GetAlpha() const
sal_uInt8 GetRed() const
double getHeight() const
OUString DetermineIconTheme() const
Determine which icon theme should be used.
void DrawAlphaBitmapAndAlphaGradient(BitmapEx &rBitmapEx, bool bFixedTransparence, float fTransparence, AlphaMask &rNewMask)
signed char sal_Int8
sal_uInt8 unpremultiply(sal_uInt8 c, sal_uInt8 a)
Bitmap const & GetBitmap() const
Definition: alpha.cxx:73
long Long
const StyleSettings & GetStyleSettings() const
static const AllSettings & GetSettings()
Gets the application's settings.
Definition: svapp.cxx:724
double getX() const
lookup_table get_unpremultiply_table()
sal_uInt8(* lookup_table)[256]
Definition: BitmapTools.hxx:29
double getY() const
B2DVector getRange() const
BitmapReadAccess * AcquireReadAccess()
::BitmapEx bitmapExFromXBitmap(const uno::Reference< rendering::XIntegerReadOnlyBitmap > &xInputBitmap)
float x
double getMaxX() const
void SetPixelOnData(sal_uInt8 *pData, tools::Long nX, const BitmapColor &rBitmapColor)
static VCL_DLLPUBLIC ImageTree & get()
Definition: ImageTree.cxx:16
bool IsAlpha() const
Definition: BitmapEx.cxx:221
bool CombineSimple(const Bitmap &rMask, BmpCombine eCombine)
Perform boolean operations with another bitmap.
double getWidth() const
void DrawAndClipBitmap(const Point &rPos, const Size &rSize, const BitmapEx &rBitmap, BitmapEx &aBmpEx, basegfx::B2DPolyPolygon const &rClipPath)
const BorderLinePrimitive2D *pCandidateB assert(pCandidateA)
void SetPixelIndex(tools::Long nY, tools::Long nX, sal_uInt8 cIndex)
Scanline GetScanline(tools::Long nY) const
sal_uInt64 remainingSize()
double getMaxY() const
sal_uInt8 GetBlue() const
B2IRange fround(const B2DRange &rRange)
float y
constexpr OUStringLiteral aData
css::uno::Sequence< Primitive2DReference > Primitive2DSequence
BitmapEx CreateFromData(RawBitmap &&rawBitmap)
Copy block of image data into the bitmap.
VCL_DLLPUBLIC bool loadImage(OUString const &name, OUString const &style, BitmapEx &bitmap, bool localized, const ImageLoadFlags eFlags=ImageLoadFlags::NONE)
Definition: ImageTree.cxx:45
sal_uInt8 * Scanline
Definition: Scanline.hxx:25
void SetScaleX(const Fraction &rScaleX)
Definition: mapmod.cxx:108
bool IsEmpty() const
bool HasPalette() const
uno_Any a
ScanlineFormat GetScanlineFormat() const
BitmapColor GetColor(tools::Long nY, tools::Long nX) const
void SetOrigin(const Point &rOrigin)
Definition: mapmod.cxx:102
void CanvasCairoExtractBitmapData(BitmapEx const &aBmpEx, Bitmap &aBitmap, unsigned char *&data, bool &bHasAlpha, tools::Long &rnWidth, tools::Long &rnHeight)
tools::Long Width() const
tools::Long Width() const
::rtl::Reference< Content > pContent
TransparentType GetTransparentType() const
Definition: bitmapex.hxx:74
void SetScaleY(const Fraction &rScaleY)
Definition: mapmod.cxx:115
bool isHistorical8x8(const BitmapEx &rBitmapEx, Color &o_rBack, Color &o_rFront)
css::uno::Sequence< sal_Int8 > GetMaskDIB(BitmapEx const &aBmpEx)
static void ReleaseAccess(BitmapInfoAccess *pAccess)
struct _cairo cairo_t
Definition: svpgdi.hxx:70
uno::Sequence< sal_Int8 > CanvasExtractBitmapData(BitmapEx const &rBitmapEx, const geometry::IntegerRectangle2D &rect)
bool IsTransparent() const
Definition: BitmapEx.cxx:216
Intended to be used to feed into CreateFromData to create a BitmapEx.
Definition: RawBitmap.hxx:21
short nBitCount
BitmapEx CanvasTransformBitmap(const BitmapEx &rBitmap, const ::basegfx::B2DHomMatrix &rTransform,::basegfx::B2DRectangle const &rDestRect,::basegfx::B2DHomMatrix const &rLocalTransform)
sal_uInt16 GetPaletteEntryCount() const
void ReleaseAccess(BitmapReadAccess *pAccess)
Definition: alpha.cxx:176
std::size_t ReadBytes(void *pData, std::size_t nSize)
Bitmap GetBitmap(Color aTransparentReplaceColor) const
Definition: BitmapEx.cxx:231
sal_uInt8 GetGreen() const
BitmapEx createHistorical8x8FromArray(std::array< sal_uInt8, 64 > const &pArray, Color aColorPix, Color aColorBack)
const Color & GetTransparentColor() const
Definition: bitmapex.hxx:93
#define ENSURE_OR_THROW(c, m)
lookup_table get_premultiply_table()
css::uno::Reference< css::graphic::XPrimitive2D > Primitive2DReference
vcl::ScopedBitmapAccess< BitmapWriteAccess, AlphaMask,&AlphaMask::AcquireAlphaWriteAccess > AlphaScopedWriteAccess
std::unique_ptr< char[]> aBuffer
double getMinY() const
AlphaMask GetAlpha() const
Definition: BitmapEx.cxx:263
#define SAL_WARN_IF(condition, area, stream)
unsigned char sal_uInt8
const ::std::vector< Color > ImpSvNumberformatScan::StandardColor COL_WHITE
const BitmapPalette & GetPalette() const
#define SAL_INFO(area, stream)
bool convertBitmap32To24Plus8(BitmapEx const &rInput, BitmapEx &rResult)
tools::Long Height() const
static bool readAlpha(BitmapReadAccess const *pAlphaReadAcc, tools::Long nY, const tools::Long nWidth, unsigned char *data, tools::Long nOff)
sal_uInt64 Tell() const
void * p
Reference< XComponentContext > getProcessComponentContext()
const ::std::vector< Color > ImpSvNumberformatScan::StandardColor COL_BLACK
BitmapColor GetPixelFromData(const sal_uInt8 *pData, tools::Long nX) const
BitmapEx loadFromName(const OUString &rFileName, const ImageLoadFlags eFlags)
Definition: BitmapTools.cxx:46
double getMinX() const
const BitmapColor & GetPaletteColor(sal_uInt16 nColor) const
bool WriteDIB(const Bitmap &rSource, SvStream &rOStm, bool bCompressed, bool bFileHeader)
Definition: dibtools.cxx:1859
const Size & GetSizePixel() const
Definition: bitmapex.hxx:84
struct _cairo_surface cairo_surface_t
Definition: svpgdi.hxx:71
BitmapColor GetPixel(tools::Long nY, tools::Long nX) const
Bitmap CreateMask(const Color &rTransColor, sal_uInt8 nTol=0) const
Create on-off mask from bitmap.
const void * GetData()