summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--canvas/source/cairo/cairo_canvashelper.cxx288
-rw-r--r--include/vcl/BitmapTools.hxx6
-rw-r--r--vcl/source/bitmap/BitmapTools.cxx291
3 files changed, 303 insertions, 282 deletions
diff --git a/canvas/source/cairo/cairo_canvashelper.cxx b/canvas/source/cairo/cairo_canvashelper.cxx
index bba59a15c475..2ed3d0472c04 100644
--- a/canvas/source/cairo/cairo_canvashelper.cxx
+++ b/canvas/source/cairo/cairo_canvashelper.cxx
@@ -48,6 +48,7 @@
#include <tools/diagnose_ex.h>
#include <vcl/bitmapex.hxx>
#include <vcl/bitmapaccess.hxx>
+#include <vcl/BitmapTools.hxx>
#include <vcl/canvastools.hxx>
#include <vcl/virdev.hxx>
@@ -328,71 +329,6 @@ namespace cairocanvas
return ::BitmapEx();
}
- static sal_uInt8 lcl_GetColor(BitmapColor const& rColor)
- {
- sal_uInt8 nTemp(0);
- if (rColor.IsIndex())
- {
- nTemp = rColor.GetIndex();
- }
- else
- {
- nTemp = rColor.GetBlue();
- // greyscale expected here, or what would non-grey colors mean?
- assert(rColor.GetRed() == nTemp && rColor.GetGreen() == nTemp);
- }
- return nTemp;
- }
-
- static bool readAlpha( BitmapReadAccess const * pAlphaReadAcc, long nY, const long nWidth, unsigned char* data, long nOff )
- {
- bool bIsAlpha = false;
- long nX;
- int nAlpha;
- Scanline pReadScan;
-
- nOff += 3;
-
- switch( pAlphaReadAcc->GetScanlineFormat() )
- {
- case ScanlineFormat::N8BitTcMask:
- pReadScan = pAlphaReadAcc->GetScanline( nY );
- for( nX = 0; nX < nWidth; nX++ )
- {
- nAlpha = data[ nOff ] = 255 - ( *pReadScan++ );
- if( nAlpha != 255 )
- bIsAlpha = true;
- nOff += 4;
- }
- break;
- case ScanlineFormat::N8BitPal:
- pReadScan = pAlphaReadAcc->GetScanline( nY );
- for( nX = 0; nX < nWidth; nX++ )
- {
- BitmapColor const& rColor(
- pAlphaReadAcc->GetPaletteColor(*pReadScan));
- pReadScan++;
- nAlpha = data[ nOff ] = 255 - lcl_GetColor(rColor);
- if( nAlpha != 255 )
- bIsAlpha = true;
- nOff += 4;
- }
- break;
- default:
- SAL_INFO( "canvas.cairo", "fallback to GetColor for alpha - slow, format: " << static_cast<int>(pAlphaReadAcc->GetScanlineFormat()) );
- for( nX = 0; nX < nWidth; nX++ )
- {
- nAlpha = data[ nOff ] = 255 - pAlphaReadAcc->GetColor( nY, nX ).GetIndex();
- if( nAlpha != 255 )
- bIsAlpha = true;
- nOff += 4;
- }
- }
-
- return bIsAlpha;
- }
-
-
/** surfaceFromXBitmap Create a surface from XBitmap
* @param xBitmap bitmap image that will be used for the surface
* @param rDevice reference to the device into which we want to draw
@@ -427,232 +363,20 @@ namespace cairocanvas
if( !pSurface )
{
- AlphaMask aAlpha = aBmpEx.GetAlpha();
-
- ::BitmapReadAccess* pBitmapReadAcc = aBitmap.AcquireReadAccess();
- ::BitmapReadAccess* pAlphaReadAcc = nullptr;
- const long nWidth = pBitmapReadAcc->Width();
- const long nHeight = pBitmapReadAcc->Height();
- long nX, nY;
- bool bIsAlpha = false;
-
- if( aBmpEx.IsTransparent() || aBmpEx.IsAlpha() )
- pAlphaReadAcc = aAlpha.AcquireReadAccess();
-
- data = static_cast<unsigned char*>(malloc( nWidth*nHeight*4 ));
-
- long nOff = 0;
- ::Color aColor;
- unsigned int nAlpha = 255;
-
- for( nY = 0; nY < nHeight; nY++ )
- {
- ::Scanline pReadScan;
-
- switch( pBitmapReadAcc->GetScanlineFormat() )
- {
- case ScanlineFormat::N8BitPal:
- pReadScan = pBitmapReadAcc->GetScanline( nY );
- if( pAlphaReadAcc )
- if( readAlpha( pAlphaReadAcc, nY, nWidth, data, nOff ) )
- bIsAlpha = true;
-
- for( nX = 0; nX < nWidth; nX++ )
- {
-#ifdef OSL_BIGENDIAN
- if( pAlphaReadAcc )
- nAlpha = data[ nOff++ ];
- else
- nAlpha = data[ nOff++ ] = 255;
-#else
- if( pAlphaReadAcc )
- nAlpha = data[ nOff + 3 ];
- else
- nAlpha = data[ nOff + 3 ] = 255;
-#endif
- aColor = pBitmapReadAcc->GetPaletteColor(*pReadScan++).GetColor();
-
-#ifdef OSL_BIGENDIAN
- data[ nOff++ ] = sal::static_int_cast<unsigned char>(( nAlpha*( aColor.GetRed() ) )/255 );
- data[ nOff++ ] = sal::static_int_cast<unsigned char>(( nAlpha*( aColor.GetGreen() ) )/255 );
- data[ nOff++ ] = sal::static_int_cast<unsigned char>(( nAlpha*( aColor.GetBlue() ) )/255 );
-#else
- data[ nOff++ ] = sal::static_int_cast<unsigned char>(( nAlpha*( aColor.GetBlue() ) )/255 );
- data[ nOff++ ] = sal::static_int_cast<unsigned char>(( nAlpha*( aColor.GetGreen() ) )/255 );
- data[ nOff++ ] = sal::static_int_cast<unsigned char>(( nAlpha*( aColor.GetRed() ) )/255 );
- nOff++;
-#endif
- }
- break;
- case ScanlineFormat::N24BitTcBgr:
- pReadScan = pBitmapReadAcc->GetScanline( nY );
- if( pAlphaReadAcc )
- if( readAlpha( pAlphaReadAcc, nY, nWidth, data, nOff ) )
- bIsAlpha = true;
-
- for( nX = 0; nX < nWidth; nX++ )
- {
-#ifdef OSL_BIGENDIAN
- if( pAlphaReadAcc )
- nAlpha = data[ nOff ];
- else
- nAlpha = data[ nOff ] = 255;
- data[ nOff + 3 ] = sal::static_int_cast<unsigned char>(( nAlpha*( *pReadScan++ ) )/255 );
- data[ nOff + 2 ] = sal::static_int_cast<unsigned char>(( nAlpha*( *pReadScan++ ) )/255 );
- data[ nOff + 1 ] = sal::static_int_cast<unsigned char>(( nAlpha*( *pReadScan++ ) )/255 );
- nOff += 4;
-#else
- if( pAlphaReadAcc )
- nAlpha = data[ nOff + 3 ];
- else
- nAlpha = data[ nOff + 3 ] = 255;
- data[ nOff++ ] = sal::static_int_cast<unsigned char>(( nAlpha*( *pReadScan++ ) )/255 );
- data[ nOff++ ] = sal::static_int_cast<unsigned char>(( nAlpha*( *pReadScan++ ) )/255 );
- data[ nOff++ ] = sal::static_int_cast<unsigned char>(( nAlpha*( *pReadScan++ ) )/255 );
- nOff++;
-#endif
- }
- break;
- case ScanlineFormat::N24BitTcRgb:
- pReadScan = pBitmapReadAcc->GetScanline( nY );
- if( pAlphaReadAcc )
- if( readAlpha( pAlphaReadAcc, nY, nWidth, data, nOff ) )
- bIsAlpha = true;
-
- for( nX = 0; nX < nWidth; nX++ )
- {
-#ifdef OSL_BIGENDIAN
- if( pAlphaReadAcc )
- nAlpha = data[ nOff++ ];
- else
- nAlpha = data[ nOff++ ] = 255;
- data[ nOff++ ] = sal::static_int_cast<unsigned char>(( nAlpha*( *pReadScan++ ) )/255 );
- data[ nOff++ ] = sal::static_int_cast<unsigned char>(( nAlpha*( *pReadScan++ ) )/255 );
- data[ nOff++ ] = sal::static_int_cast<unsigned char>(( nAlpha*( *pReadScan++ ) )/255 );
-#else
- if( pAlphaReadAcc )
- nAlpha = data[ nOff + 3 ];
- else
- nAlpha = data[ nOff + 3 ] = 255;
- data[ nOff++ ] = sal::static_int_cast<unsigned char>(( nAlpha*( pReadScan[ 2 ] ) )/255 );
- data[ nOff++ ] = sal::static_int_cast<unsigned char>(( nAlpha*( pReadScan[ 1 ] ) )/255 );
- data[ nOff++ ] = sal::static_int_cast<unsigned char>(( nAlpha*( pReadScan[ 0 ] ) )/255 );
- pReadScan += 3;
- nOff++;
-#endif
- }
- break;
- case ScanlineFormat::N32BitTcBgra:
- pReadScan = pBitmapReadAcc->GetScanline( nY );
- if( pAlphaReadAcc )
- if( readAlpha( pAlphaReadAcc, nY, nWidth, data, nOff ) )
- bIsAlpha = true;
-
- for( nX = 0; nX < nWidth; nX++ )
- {
-#ifdef OSL_BIGENDIAN
- if( pAlphaReadAcc )
- nAlpha = data[ nOff++ ];
- else
- nAlpha = data[ nOff++ ] = 255;
- data[ nOff++ ] = sal::static_int_cast<unsigned char>(( nAlpha*( pReadScan[ 2 ] ) )/255 );
- data[ nOff++ ] = sal::static_int_cast<unsigned char>(( nAlpha*( pReadScan[ 1 ] ) )/255 );
- data[ nOff++ ] = sal::static_int_cast<unsigned char>(( nAlpha*( pReadScan[ 0 ] ) )/255 );
- pReadScan += 4;
-#else
- if( pAlphaReadAcc )
- nAlpha = data[ nOff + 3 ];
- else
- nAlpha = data[ nOff + 3 ] = 255;
- data[ nOff++ ] = sal::static_int_cast<unsigned char>(( nAlpha*( *pReadScan++ ) )/255 );
- data[ nOff++ ] = sal::static_int_cast<unsigned char>(( nAlpha*( *pReadScan++ ) )/255 );
- data[ nOff++ ] = sal::static_int_cast<unsigned char>(( nAlpha*( *pReadScan++ ) )/255 );
- pReadScan++;
- nOff++;
-#endif
- }
- break;
- case ScanlineFormat::N32BitTcRgba:
- pReadScan = pBitmapReadAcc->GetScanline( nY );
- if( pAlphaReadAcc )
- if( readAlpha( pAlphaReadAcc, nY, nWidth, data, nOff ) )
- bIsAlpha = true;
-
- for( nX = 0; nX < nWidth; nX++ )
- {
-#ifdef OSL_BIGENDIAN
- if( pAlphaReadAcc )
- nAlpha = data[ nOff ++ ];
- else
- nAlpha = data[ nOff ++ ] = 255;
- data[ nOff++ ] = sal::static_int_cast<unsigned char>(( nAlpha*( *pReadScan++ ) )/255 );
- data[ nOff++ ] = sal::static_int_cast<unsigned char>(( nAlpha*( *pReadScan++ ) )/255 );
- data[ nOff++ ] = sal::static_int_cast<unsigned char>(( nAlpha*( *pReadScan++ ) )/255 );
- pReadScan++;
-#else
- if( pAlphaReadAcc )
- nAlpha = data[ nOff + 3 ];
- else
- nAlpha = data[ nOff + 3 ] = 255;
- data[ nOff++ ] = sal::static_int_cast<unsigned char>(( nAlpha*( pReadScan[ 2 ] ) )/255 );
- data[ nOff++ ] = sal::static_int_cast<unsigned char>(( nAlpha*( pReadScan[ 1 ] ) )/255 );
- data[ nOff++ ] = sal::static_int_cast<unsigned char>(( nAlpha*( pReadScan[ 0 ] ) )/255 );
- pReadScan += 4;
- nOff++;
-#endif
- }
- break;
- default:
- SAL_INFO( "canvas.cairo", "fallback to GetColor - slow, format: " << static_cast<int>(pBitmapReadAcc->GetScanlineFormat()) );
-
- if( pAlphaReadAcc )
- if( readAlpha( pAlphaReadAcc, nY, nWidth, data, nOff ) )
- bIsAlpha = true;
-
- for( nX = 0; nX < nWidth; nX++ )
- {
- aColor = pBitmapReadAcc->GetColor( nY, nX ).GetColor();
-
- // cairo need premultiplied color values
- // TODO(rodo) handle endianness
-#ifdef OSL_BIGENDIAN
- if( pAlphaReadAcc )
- nAlpha = data[ nOff++ ];
- else
- nAlpha = data[ nOff++ ] = 255;
- data[ nOff++ ] = sal::static_int_cast<unsigned char>(( nAlpha*aColor.GetRed() )/255 );
- data[ nOff++ ] = sal::static_int_cast<unsigned char>(( nAlpha*aColor.GetGreen() )/255 );
- data[ nOff++ ] = sal::static_int_cast<unsigned char>(( nAlpha*aColor.GetBlue() )/255 );
-#else
- if( pAlphaReadAcc )
- nAlpha = data[ nOff + 3 ];
- else
- nAlpha = data[ nOff + 3 ] = 255;
- data[ nOff++ ] = sal::static_int_cast<unsigned char>(( nAlpha*aColor.GetBlue() )/255 );
- data[ nOff++ ] = sal::static_int_cast<unsigned char>(( nAlpha*aColor.GetGreen() )/255 );
- data[ nOff++ ] = sal::static_int_cast<unsigned char>(( nAlpha*aColor.GetRed() )/255 );
- nOff ++;
-#endif
- }
- }
- }
-
- ::Bitmap::ReleaseAccess( pBitmapReadAcc );
- if( pAlphaReadAcc )
- aAlpha.ReleaseAccess( pAlphaReadAcc );
+ vcl::bitmap::CanvasCairoExtractBitmapData(aBmpEx, aBitmap, data, bHasAlpha);
+ const long nWidth = aBmpEx.GetPrefSize().Width();
+ const long nHeight = aBmpEx.GetPrefSize().Height();
SurfaceSharedPtr pImageSurface = rSurfaceProvider->getOutputDevice()->CreateSurface(
CairoSurfaceSharedPtr(
cairo_image_surface_create_for_data(
data,
- bIsAlpha ? CAIRO_FORMAT_ARGB32 : CAIRO_FORMAT_RGB24,
+ bHasAlpha ? CAIRO_FORMAT_ARGB32 : CAIRO_FORMAT_RGB24,
nWidth, nHeight, nWidth*4 ),
&cairo_surface_destroy) );
pSurface = pImageSurface;
- bHasAlpha = bIsAlpha;
-
- SAL_INFO( "canvas.cairo","image: " << nWidth << " x " << nHeight << " alpha: " << bIsAlpha << " alphaRead " << std::hex << pAlphaReadAcc);
+ SAL_INFO( "canvas.cairo","image: " << nWidth << " x " << nHeight << " alpha: " << bHasAlpha);
}
}
diff --git a/include/vcl/BitmapTools.hxx b/include/vcl/BitmapTools.hxx
index 3a1692730393..9c347d275f4b 100644
--- a/include/vcl/BitmapTools.hxx
+++ b/include/vcl/BitmapTools.hxx
@@ -98,6 +98,12 @@ VCL_DLLPUBLIC void DrawAndClipBitmap(const Point& rPos, const Size& rSize, const
VCL_DLLPUBLIC css::uno::Sequence< sal_Int8 > GetMaskDIB(BitmapEx const & aBmpEx);
+/**
+ * @param data will be filled with alpha data, if xBitmap is alpha/transparent image
+ * @param bHasAlpha will be set to true if resulting surface has alpha
+ **/
+VCL_DLLPUBLIC void CanvasCairoExtractBitmapData( BitmapEx & rBmpEx, Bitmap & rBitmap, unsigned char*& data, bool& bHasAlpha );
+
}} // end vcl::bitmap
#endif // INCLUDED_VCL_BITMAP_TOOLS_HXX
diff --git a/vcl/source/bitmap/BitmapTools.cxx b/vcl/source/bitmap/BitmapTools.cxx
index 3abd1ca537b9..816bad119e13 100644
--- a/vcl/source/bitmap/BitmapTools.cxx
+++ b/vcl/source/bitmap/BitmapTools.cxx
@@ -648,6 +648,297 @@ css::uno::Sequence< sal_Int8 > GetMaskDIB(BitmapEx const & aBmpEx)
return css::uno::Sequence< sal_Int8 >();
}
+static sal_uInt8 lcl_GetColor(BitmapColor const& rColor)
+{
+ sal_uInt8 nTemp(0);
+ if (rColor.IsIndex())
+ {
+ nTemp = rColor.GetIndex();
+ }
+ else
+ {
+ nTemp = rColor.GetBlue();
+ // greyscale expected here, or what would non-grey colors mean?
+ assert(rColor.GetRed() == nTemp && rColor.GetGreen() == nTemp);
+ }
+ return nTemp;
+}
+
+
+static bool readAlpha( BitmapReadAccess const * pAlphaReadAcc, long nY, const long nWidth, unsigned char* data, long nOff )
+{
+ bool bIsAlpha = false;
+ long nX;
+ int nAlpha;
+ Scanline pReadScan;
+
+ nOff += 3;
+
+ switch( pAlphaReadAcc->GetScanlineFormat() )
+ {
+ case ScanlineFormat::N8BitTcMask:
+ pReadScan = pAlphaReadAcc->GetScanline( nY );
+ for( nX = 0; nX < nWidth; nX++ )
+ {
+ nAlpha = data[ nOff ] = 255 - ( *pReadScan++ );
+ if( nAlpha != 255 )
+ bIsAlpha = true;
+ nOff += 4;
+ }
+ break;
+ case ScanlineFormat::N8BitPal:
+ pReadScan = pAlphaReadAcc->GetScanline( nY );
+ for( nX = 0; nX < nWidth; nX++ )
+ {
+ BitmapColor const& rColor(
+ pAlphaReadAcc->GetPaletteColor(*pReadScan));
+ pReadScan++;
+ nAlpha = data[ nOff ] = 255 - lcl_GetColor(rColor);
+ if( nAlpha != 255 )
+ bIsAlpha = true;
+ nOff += 4;
+ }
+ break;
+ default:
+ SAL_INFO( "canvas.cairo", "fallback to GetColor for alpha - slow, format: " << static_cast<int>(pAlphaReadAcc->GetScanlineFormat()) );
+ for( nX = 0; nX < nWidth; nX++ )
+ {
+ nAlpha = data[ nOff ] = 255 - pAlphaReadAcc->GetColor( nY, nX ).GetIndex();
+ if( nAlpha != 255 )
+ bIsAlpha = true;
+ nOff += 4;
+ }
+ }
+
+ return bIsAlpha;
+}
+
+
+
+/**
+ * @param data will be filled with alpha data, if xBitmap is alpha/transparent image
+ * @param bHasAlpha will be set to true if resulting surface has alpha
+ **/
+void CanvasCairoExtractBitmapData( BitmapEx & aBmpEx, Bitmap & aBitmap, unsigned char*& data, bool& bHasAlpha )
+{
+ AlphaMask aAlpha = aBmpEx.GetAlpha();
+
+ ::BitmapReadAccess* pBitmapReadAcc = aBitmap.AcquireReadAccess();
+ ::BitmapReadAccess* pAlphaReadAcc = nullptr;
+ const long nWidth = pBitmapReadAcc->Width();
+ const long nHeight = pBitmapReadAcc->Height();
+ long nX, nY;
+ bool bIsAlpha = false;
+
+ if( aBmpEx.IsTransparent() || aBmpEx.IsAlpha() )
+ pAlphaReadAcc = aAlpha.AcquireReadAccess();
+
+ data = static_cast<unsigned char*>(malloc( nWidth*nHeight*4 ));
+
+ long nOff = 0;
+ ::Color aColor;
+ unsigned int nAlpha = 255;
+
+ for( nY = 0; nY < nHeight; nY++ )
+ {
+ ::Scanline pReadScan;
+
+ switch( pBitmapReadAcc->GetScanlineFormat() )
+ {
+ case ScanlineFormat::N8BitPal:
+ pReadScan = pBitmapReadAcc->GetScanline( nY );
+ if( pAlphaReadAcc )
+ if( readAlpha( pAlphaReadAcc, nY, nWidth, data, nOff ) )
+ bIsAlpha = true;
+
+ for( nX = 0; nX < nWidth; nX++ )
+ {
+#ifdef OSL_BIGENDIAN
+ if( pAlphaReadAcc )
+ nAlpha = data[ nOff++ ];
+ else
+ nAlpha = data[ nOff++ ] = 255;
+#else
+ if( pAlphaReadAcc )
+ nAlpha = data[ nOff + 3 ];
+ else
+ nAlpha = data[ nOff + 3 ] = 255;
+#endif
+ aColor = pBitmapReadAcc->GetPaletteColor(*pReadScan++).GetColor();
+
+#ifdef OSL_BIGENDIAN
+ data[ nOff++ ] = sal::static_int_cast<unsigned char>(( nAlpha*( aColor.GetRed() ) )/255 );
+ data[ nOff++ ] = sal::static_int_cast<unsigned char>(( nAlpha*( aColor.GetGreen() ) )/255 );
+ data[ nOff++ ] = sal::static_int_cast<unsigned char>(( nAlpha*( aColor.GetBlue() ) )/255 );
+#else
+ data[ nOff++ ] = sal::static_int_cast<unsigned char>(( nAlpha*( aColor.GetBlue() ) )/255 );
+ data[ nOff++ ] = sal::static_int_cast<unsigned char>(( nAlpha*( aColor.GetGreen() ) )/255 );
+ data[ nOff++ ] = sal::static_int_cast<unsigned char>(( nAlpha*( aColor.GetRed() ) )/255 );
+ nOff++;
+#endif
+ }
+ break;
+ case ScanlineFormat::N24BitTcBgr:
+ pReadScan = pBitmapReadAcc->GetScanline( nY );
+ if( pAlphaReadAcc )
+ if( readAlpha( pAlphaReadAcc, nY, nWidth, data, nOff ) )
+ bIsAlpha = true;
+
+ for( nX = 0; nX < nWidth; nX++ )
+ {
+#ifdef OSL_BIGENDIAN
+ if( pAlphaReadAcc )
+ nAlpha = data[ nOff ];
+ else
+ nAlpha = data[ nOff ] = 255;
+ data[ nOff + 3 ] = sal::static_int_cast<unsigned char>(( nAlpha*( *pReadScan++ ) )/255 );
+ data[ nOff + 2 ] = sal::static_int_cast<unsigned char>(( nAlpha*( *pReadScan++ ) )/255 );
+ data[ nOff + 1 ] = sal::static_int_cast<unsigned char>(( nAlpha*( *pReadScan++ ) )/255 );
+ nOff += 4;
+#else
+ if( pAlphaReadAcc )
+ nAlpha = data[ nOff + 3 ];
+ else
+ nAlpha = data[ nOff + 3 ] = 255;
+ data[ nOff++ ] = sal::static_int_cast<unsigned char>(( nAlpha*( *pReadScan++ ) )/255 );
+ data[ nOff++ ] = sal::static_int_cast<unsigned char>(( nAlpha*( *pReadScan++ ) )/255 );
+ data[ nOff++ ] = sal::static_int_cast<unsigned char>(( nAlpha*( *pReadScan++ ) )/255 );
+ nOff++;
+#endif
+ }
+ break;
+ case ScanlineFormat::N24BitTcRgb:
+ pReadScan = pBitmapReadAcc->GetScanline( nY );
+ if( pAlphaReadAcc )
+ if( readAlpha( pAlphaReadAcc, nY, nWidth, data, nOff ) )
+ bIsAlpha = true;
+
+ for( nX = 0; nX < nWidth; nX++ )
+ {
+#ifdef OSL_BIGENDIAN
+ if( pAlphaReadAcc )
+ nAlpha = data[ nOff++ ];
+ else
+ nAlpha = data[ nOff++ ] = 255;
+ data[ nOff++ ] = sal::static_int_cast<unsigned char>(( nAlpha*( *pReadScan++ ) )/255 );
+ data[ nOff++ ] = sal::static_int_cast<unsigned char>(( nAlpha*( *pReadScan++ ) )/255 );
+ data[ nOff++ ] = sal::static_int_cast<unsigned char>(( nAlpha*( *pReadScan++ ) )/255 );
+#else
+ if( pAlphaReadAcc )
+ nAlpha = data[ nOff + 3 ];
+ else
+ nAlpha = data[ nOff + 3 ] = 255;
+ data[ nOff++ ] = sal::static_int_cast<unsigned char>(( nAlpha*( pReadScan[ 2 ] ) )/255 );
+ data[ nOff++ ] = sal::static_int_cast<unsigned char>(( nAlpha*( pReadScan[ 1 ] ) )/255 );
+ data[ nOff++ ] = sal::static_int_cast<unsigned char>(( nAlpha*( pReadScan[ 0 ] ) )/255 );
+ pReadScan += 3;
+ nOff++;
+#endif
+ }
+ break;
+ case ScanlineFormat::N32BitTcBgra:
+ pReadScan = pBitmapReadAcc->GetScanline( nY );
+ if( pAlphaReadAcc )
+ if( readAlpha( pAlphaReadAcc, nY, nWidth, data, nOff ) )
+ bIsAlpha = true;
+
+ for( nX = 0; nX < nWidth; nX++ )
+ {
+#ifdef OSL_BIGENDIAN
+ if( pAlphaReadAcc )
+ nAlpha = data[ nOff++ ];
+ else
+ nAlpha = data[ nOff++ ] = 255;
+ data[ nOff++ ] = sal::static_int_cast<unsigned char>(( nAlpha*( pReadScan[ 2 ] ) )/255 );
+ data[ nOff++ ] = sal::static_int_cast<unsigned char>(( nAlpha*( pReadScan[ 1 ] ) )/255 );
+ data[ nOff++ ] = sal::static_int_cast<unsigned char>(( nAlpha*( pReadScan[ 0 ] ) )/255 );
+ pReadScan += 4;
+#else
+ if( pAlphaReadAcc )
+ nAlpha = data[ nOff + 3 ];
+ else
+ nAlpha = data[ nOff + 3 ] = 255;
+ data[ nOff++ ] = sal::static_int_cast<unsigned char>(( nAlpha*( *pReadScan++ ) )/255 );
+ data[ nOff++ ] = sal::static_int_cast<unsigned char>(( nAlpha*( *pReadScan++ ) )/255 );
+ data[ nOff++ ] = sal::static_int_cast<unsigned char>(( nAlpha*( *pReadScan++ ) )/255 );
+ pReadScan++;
+ nOff++;
+#endif
+ }
+ break;
+ case ScanlineFormat::N32BitTcRgba:
+ pReadScan = pBitmapReadAcc->GetScanline( nY );
+ if( pAlphaReadAcc )
+ if( readAlpha( pAlphaReadAcc, nY, nWidth, data, nOff ) )
+ bIsAlpha = true;
+
+ for( nX = 0; nX < nWidth; nX++ )
+ {
+#ifdef OSL_BIGENDIAN
+ if( pAlphaReadAcc )
+ nAlpha = data[ nOff ++ ];
+ else
+ nAlpha = data[ nOff ++ ] = 255;
+ data[ nOff++ ] = sal::static_int_cast<unsigned char>(( nAlpha*( *pReadScan++ ) )/255 );
+ data[ nOff++ ] = sal::static_int_cast<unsigned char>(( nAlpha*( *pReadScan++ ) )/255 );
+ data[ nOff++ ] = sal::static_int_cast<unsigned char>(( nAlpha*( *pReadScan++ ) )/255 );
+ pReadScan++;
+#else
+ if( pAlphaReadAcc )
+ nAlpha = data[ nOff + 3 ];
+ else
+ nAlpha = data[ nOff + 3 ] = 255;
+ data[ nOff++ ] = sal::static_int_cast<unsigned char>(( nAlpha*( pReadScan[ 2 ] ) )/255 );
+ data[ nOff++ ] = sal::static_int_cast<unsigned char>(( nAlpha*( pReadScan[ 1 ] ) )/255 );
+ data[ nOff++ ] = sal::static_int_cast<unsigned char>(( nAlpha*( pReadScan[ 0 ] ) )/255 );
+ pReadScan += 4;
+ nOff++;
+#endif
+ }
+ break;
+ default:
+ SAL_INFO( "canvas.cairo", "fallback to GetColor - slow, format: " << static_cast<int>(pBitmapReadAcc->GetScanlineFormat()) );
+
+ if( pAlphaReadAcc )
+ if( readAlpha( pAlphaReadAcc, nY, nWidth, data, nOff ) )
+ bIsAlpha = true;
+
+ for( nX = 0; nX < nWidth; nX++ )
+ {
+ aColor = pBitmapReadAcc->GetColor( nY, nX ).GetColor();
+
+ // cairo need premultiplied color values
+ // TODO(rodo) handle endianness
+#ifdef OSL_BIGENDIAN
+ if( pAlphaReadAcc )
+ nAlpha = data[ nOff++ ];
+ else
+ nAlpha = data[ nOff++ ] = 255;
+ data[ nOff++ ] = sal::static_int_cast<unsigned char>(( nAlpha*aColor.GetRed() )/255 );
+ data[ nOff++ ] = sal::static_int_cast<unsigned char>(( nAlpha*aColor.GetGreen() )/255 );
+ data[ nOff++ ] = sal::static_int_cast<unsigned char>(( nAlpha*aColor.GetBlue() )/255 );
+#else
+ if( pAlphaReadAcc )
+ nAlpha = data[ nOff + 3 ];
+ else
+ nAlpha = data[ nOff + 3 ] = 255;
+ data[ nOff++ ] = sal::static_int_cast<unsigned char>(( nAlpha*aColor.GetBlue() )/255 );
+ data[ nOff++ ] = sal::static_int_cast<unsigned char>(( nAlpha*aColor.GetGreen() )/255 );
+ data[ nOff++ ] = sal::static_int_cast<unsigned char>(( nAlpha*aColor.GetRed() )/255 );
+ nOff ++;
+#endif
+ }
+ }
+ }
+
+ ::Bitmap::ReleaseAccess( pBitmapReadAcc );
+ if( pAlphaReadAcc )
+ aAlpha.ReleaseAccess( pAlphaReadAcc );
+
+ bHasAlpha = bIsAlpha;
+
+}
+
}} // end vcl::bitmap
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */