From deaa9689e217e9f7fb1cab1243a8763e40da5324 Mon Sep 17 00:00:00 2001 From: Thorsten Behrens Date: Thu, 13 Jun 2013 12:47:02 +0200 Subject: Add some error handling to bitmap conversion. Fixup for 7cf2b5809f7137acc7a5eed9159042b3d748da01, makes sure cairo has all data committed to the surface, and handle random errors. Change-Id: I39e5b5777968c4563a8ce3870bac3d4182090f3b --- canvas/source/cairo/cairo_canvasbitmap.cxx | 55 +++++++++++++++++------------- 1 file changed, 31 insertions(+), 24 deletions(-) (limited to 'canvas') diff --git a/canvas/source/cairo/cairo_canvasbitmap.cxx b/canvas/source/cairo/cairo_canvasbitmap.cxx index 496b5cfe794d..277c1333f4c9 100644 --- a/canvas/source/cairo/cairo_canvasbitmap.cxx +++ b/canvas/source/cairo/cairo_canvasbitmap.cxx @@ -172,39 +172,46 @@ namespace cairocanvas ::AlphaMask aMask( aSize ); BitmapWriteAccess *pRGBWrite( aRGB.AcquireWriteAccess() ); - BitmapWriteAccess *pMaskWrite( aMask.AcquireWriteAccess() ); - - unsigned char *pSrc = cairo_image_surface_get_data( pPixels ); - unsigned int nStride = cairo_image_surface_get_stride( pPixels ); - for( unsigned long y = 0; y < (unsigned long) aSize.Height(); y++ ) + if( pRGBWrite ) { - sal_uInt32 *pPix = (sal_uInt32 *)(pSrc + nStride * y); - for( unsigned long x = 0; x < (unsigned long) aSize.Width(); x++ ) + BitmapWriteAccess *pMaskWrite( aMask.AcquireWriteAccess() ); + if( pMaskWrite ) { - sal_uInt8 nAlpha = (*pPix >> 24); - sal_uInt8 nR = (*pPix >> 16) & 0xff; - sal_uInt8 nG = (*pPix >> 8) & 0xff; - sal_uInt8 nB = *pPix & 0xff; - if( nAlpha != 0 && nAlpha != 255 ) + cairo_surface_flush(pPixels); + unsigned char *pSrc = cairo_image_surface_get_data( pPixels ); + unsigned int nStride = cairo_image_surface_get_stride( pPixels ); + for( unsigned long y = 0; y < (unsigned long) aSize.Height(); y++ ) { -// fprintf (stderr, "From A(0x%.2x) 0x%.2x 0x%.2x 0x%.2x -> ", -// nAlpha, nR, nG, nB ); - // Cairo uses pre-multiplied alpha - we do not => re-multiply - nR = (sal_uInt8) MinMax( ((sal_uInt32)nR * 255) / nAlpha, 0, 255 ); - nG = (sal_uInt8) MinMax( ((sal_uInt32)nG * 255) / nAlpha, 0, 255 ); - nB = (sal_uInt8) MinMax( ((sal_uInt32)nB * 255) / nAlpha, 0, 255 ); -// fprintf (stderr, "0x%.2x 0x%.2x 0x%.2x\n", nR, nG, nB ); + sal_uInt32 *pPix = (sal_uInt32 *)(pSrc + nStride * y); + for( unsigned long x = 0; x < (unsigned long) aSize.Width(); x++ ) + { + sal_uInt8 nAlpha = (*pPix >> 24); + sal_uInt8 nR = (*pPix >> 16) & 0xff; + sal_uInt8 nG = (*pPix >> 8) & 0xff; + sal_uInt8 nB = *pPix & 0xff; + if( nAlpha != 0 && nAlpha != 255 ) + { + // Cairo uses pre-multiplied alpha - we do not => re-multiply + nR = (sal_uInt8) MinMax( ((sal_uInt32)nR * 255) / nAlpha, 0, 255 ); + nG = (sal_uInt8) MinMax( ((sal_uInt32)nG * 255) / nAlpha, 0, 255 ); + nB = (sal_uInt8) MinMax( ((sal_uInt32)nB * 255) / nAlpha, 0, 255 ); + } + pRGBWrite->SetPixel( y, x, BitmapColor( nR, nG, nB ) ); + pMaskWrite->SetPixelIndex( y, x, 255 - nAlpha ); + pPix++; + } } - pRGBWrite->SetPixel( y, x, BitmapColor( nR, nG, nB ) ); - pMaskWrite->SetPixelIndex( y, x, 255 - nAlpha ); - pPix++; + aMask.ReleaseAccess( pMaskWrite ); } + aRGB.ReleaseAccess( pRGBWrite ); } - aMask.ReleaseAccess( pMaskWrite ); - aRGB.ReleaseAccess( pRGBWrite ); + // ignore potential errors above. will get caller a + // uniformely white bitmap, but not that there would + // be error handling in calling code ... ::BitmapEx *pBitmapEx = new ::BitmapEx( aRGB, aMask ); + cairo_destroy( pCairo ); cairo_surface_destroy( pPixels ); aRV = uno::Any( reinterpret_cast( pBitmapEx ) ); -- cgit