diff options
author | Caolán McNamara <caolanm@redhat.com> | 2018-12-01 19:41:15 +0000 |
---|---|---|
committer | Caolán McNamara <caolanm@redhat.com> | 2018-12-02 11:10:45 +0100 |
commit | 48d1df74036386ce19cfabd64d90afcd1532d5c9 (patch) | |
tree | 580e29dec6b1d8f56b90f8862b994f3946ac048c /vcl/source | |
parent | cd5bef5e19c2812386ab6afee4b3bc43fe5541b9 (diff) |
use same [un]premultiply
Change-Id: Idd1ca1243b64a9ec606382a0895e11376a2ec186
Reviewed-on: https://gerrit.libreoffice.org/64406
Tested-by: Jenkins
Reviewed-by: Caolán McNamara <caolanm@redhat.com>
Tested-by: Caolán McNamara <caolanm@redhat.com>
Diffstat (limited to 'vcl/source')
-rw-r--r-- | vcl/source/bitmap/BitmapTools.cxx | 123 |
1 files changed, 84 insertions, 39 deletions
diff --git a/vcl/source/bitmap/BitmapTools.cxx b/vcl/source/bitmap/BitmapTools.cxx index 317ef0495195..4bac9745795e 100644 --- a/vcl/source/bitmap/BitmapTools.cxx +++ b/vcl/source/bitmap/BitmapTools.cxx @@ -268,6 +268,7 @@ BitmapEx* CreateFromCairoSurface(Size aSize, cairo_surface_t * pSurface) cairo_surface_flush(pPixels); unsigned char *pSrc = cairo_image_surface_get_data( pPixels ); unsigned int nStride = cairo_image_surface_get_stride( pPixels ); + vcl::bitmap::lookup_table unpremultiply_table = vcl::bitmap::get_unpremultiply_table(); for( unsigned long y = 0; y < static_cast<unsigned long>(aSize.Height()); y++ ) { sal_uInt32 *pPix = reinterpret_cast<sal_uInt32 *>(pSrc + nStride * y); @@ -287,9 +288,9 @@ BitmapEx* CreateFromCairoSurface(Size aSize, cairo_surface_t * pSurface) if( nAlpha != 0 && nAlpha != 255 ) { // Cairo uses pre-multiplied alpha - we do not => re-multiply - nR = static_cast<sal_uInt8>(MinMax( (static_cast<sal_uInt32>(nR) * 255) / nAlpha, 0, 255 )); - nG = static_cast<sal_uInt8>(MinMax( (static_cast<sal_uInt32>(nG) * 255) / nAlpha, 0, 255 )); - nB = static_cast<sal_uInt8>(MinMax( (static_cast<sal_uInt32>(nB) * 255) / nAlpha, 0, 255 )); + nR = unpremultiply_table[nAlpha][nR]; + nG = unpremultiply_table[nAlpha][nG]; + nB = unpremultiply_table[nAlpha][nB]; } pRGBWrite->SetPixel( y, x, BitmapColor( nR, nG, nB ) ); pMaskWrite->SetPixelIndex( y, x, 255 - nAlpha ); @@ -726,6 +727,7 @@ void CanvasCairoExtractBitmapData( BitmapEx const & aBmpEx, Bitmap & aBitmap, un ::Color aColor; unsigned int nAlpha = 255; + vcl::bitmap::lookup_table premultiply_table = vcl::bitmap::get_premultiply_table(); for( nY = 0; nY < nHeight; nY++ ) { ::Scanline pReadScan; @@ -754,13 +756,13 @@ void CanvasCairoExtractBitmapData( BitmapEx const & aBmpEx, Bitmap & aBitmap, un 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 ); + data[ nOff++ ] = premultiply_table[nAlpha][aColor.GetRed()]; + data[ nOff++ ] = premultiply_table[nAlpha][aColor.GetGreen()]; + data[ nOff++ ] = premultiply_table[nAlpha][aColor.GetBlue()]; #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 ); + data[ nOff++ ] = premultiply_table[nAlpha][aColor.GetBlue()]; + data[ nOff++ ] = premultiply_table[nAlpha][aColor.GetGreen()]; + data[ nOff++ ] = premultiply_table[nAlpha][aColor.GetRed()]; nOff++; #endif } @@ -778,18 +780,18 @@ void CanvasCairoExtractBitmapData( BitmapEx const & aBmpEx, Bitmap & aBitmap, un 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 ); + data[ nOff + 3 ] = premultiply_table[nAlpha][*pReadScan++]; + data[ nOff + 2 ] = premultiply_table[nAlpha][*pReadScan++]; + data[ nOff + 1 ] = premultiply_table[nAlpha][*pReadScan++]; 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 ); + data[ nOff++ ] = premultiply_table[nAlpha][*pReadScan++]; + data[ nOff++ ] = premultiply_table[nAlpha][*pReadScan++]; + data[ nOff++ ] = premultiply_table[nAlpha][*pReadScan++]; nOff++; #endif } @@ -807,17 +809,17 @@ void CanvasCairoExtractBitmapData( BitmapEx const & aBmpEx, Bitmap & aBitmap, un 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 ); + data[ nOff++ ] = premultiply_table[nAlpha][*pReadScan++]; + data[ nOff++ ] = premultiply_table[nAlpha][*pReadScan++]; + data[ nOff++ ] = premultiply_table[nAlpha][*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 ); + data[ nOff++ ] = premultiply_table[nAlpha][pReadScan[ 2 ]]; + data[ nOff++ ] = premultiply_table[nAlpha][pReadScan[ 1 ]]; + data[ nOff++ ] = premultiply_table[nAlpha][pReadScan[ 0 ]]; pReadScan += 3; nOff++; #endif @@ -836,18 +838,18 @@ void CanvasCairoExtractBitmapData( BitmapEx const & aBmpEx, Bitmap & aBitmap, un 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 ); + data[ nOff++ ] = premultiply_table[nAlpha][pReadScan[ 2 ]]; + data[ nOff++ ] = premultiply_table[nAlpha][pReadScan[ 1 ]]; + data[ nOff++ ] = premultiply_table[nAlpha][pReadScan[ 0 ]]; 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 ); + data[ nOff++ ] = premultiply_table[nAlpha][*pReadScan++]; + data[ nOff++ ] = premultiply_table[nAlpha][*pReadScan++]; + data[ nOff++ ] = premultiply_table[nAlpha][*pReadScan++]; pReadScan++; nOff++; #endif @@ -866,18 +868,18 @@ void CanvasCairoExtractBitmapData( BitmapEx const & aBmpEx, Bitmap & aBitmap, un 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 ); + data[ nOff++ ] = premultiply_table[nAlpha][*pReadScan++]; + data[ nOff++ ] = premultiply_table[nAlpha][*pReadScan++]; + data[ nOff++ ] = premultiply_table[nAlpha][*pReadScan++]; 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 ); + data[ nOff++ ] = premultiply_table[nAlpha][pReadScan[ 2 ]]; + data[ nOff++ ] = premultiply_table[nAlpha][pReadScan[ 1 ]]; + data[ nOff++ ] = premultiply_table[nAlpha][pReadScan[ 0 ]]; pReadScan += 4; nOff++; #endif @@ -901,17 +903,17 @@ void CanvasCairoExtractBitmapData( BitmapEx const & aBmpEx, Bitmap & aBitmap, un 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 ); + data[ nOff++ ] = premultiply_table[nAlpha][aColor.GetRed()]; + data[ nOff++ ] = premultiply_table[nAlpha][aColor.GetGreen()]; + data[ nOff++ ] = premultiply_table[nAlpha][aColor.GetBlue()]; #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 ); + data[ nOff++ ] = premultiply_table[nAlpha][aColor.GetBlue()]; + data[ nOff++ ] = premultiply_table[nAlpha][aColor.GetGreen()]; + data[ nOff++ ] = premultiply_table[nAlpha][aColor.GetRed()]; nOff ++; #endif } @@ -1044,6 +1046,49 @@ void CanvasCairoExtractBitmapData( BitmapEx const & aBmpEx, Bitmap & aBitmap, un return bRet; } + static sal_uInt8 unpremultiply(sal_uInt8 c, sal_uInt8 a) + { + return (a == 0) ? 0 : (c * 255 + a / 2) / a; + } + + static sal_uInt8 premultiply(sal_uInt8 c, sal_uInt8 a) + { + return (c * a + 127) / 255; + } + + lookup_table get_unpremultiply_table() + { + static bool inited; + static sal_uInt8 unpremultiply_table[256][256]; + + if (!inited) + { + for (int a = 0; a < 256; ++a) + for (int c = 0; c < 256; ++c) + unpremultiply_table[a][c] = unpremultiply(c, a); + inited = true; + } + + return unpremultiply_table; + } + + lookup_table get_premultiply_table() + { + static bool inited; + static sal_uInt8 premultiply_table[256][256]; + + if (!inited) + { + for (int a = 0; a < 256; ++a) + for (int c = 0; c < 256; ++c) + premultiply_table[a][c] = premultiply(c, a); + inited = true; + } + + return premultiply_table; + } + + }} // end vcl::bitmap /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |