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