Kaydet (Commit) 644188bf authored tarafından Stephan Bergmann's avatar Stephan Bergmann

Compute (un-)premultiply_table at compile time

Change-Id: I34e624fcd5d11d02c26e775f5acdddec1fca9d87
Reviewed-on: https://gerrit.libreoffice.org/64428
Tested-by: Jenkins
Reviewed-by: 's avatarStephan Bergmann <sbergman@redhat.com>
üst 1ee8d4f6
...@@ -28,10 +28,10 @@ namespace com { namespace sun { namespace star { namespace geometry { struct Int ...@@ -28,10 +28,10 @@ namespace com { namespace sun { namespace star { namespace geometry { struct Int
namespace vcl { namespace vcl {
namespace bitmap { namespace bitmap {
typedef sal_uInt8 (*lookup_table)[256]; typedef std::array<std::array<sal_uInt8, 256>, 256> lookup_table;
lookup_table VCL_DLLPUBLIC get_premultiply_table(); VCL_DLLPUBLIC lookup_table const & get_premultiply_table();
lookup_table VCL_DLLPUBLIC get_unpremultiply_table(); VCL_DLLPUBLIC lookup_table const & get_unpremultiply_table();
/** /**
* Intended to be used to feed into CreateFromData to create a BitmapEx. RGB data format. * Intended to be used to feed into CreateFromData to create a BitmapEx. RGB data format.
......
...@@ -1654,7 +1654,7 @@ void SvpSalGraphics::drawMask( const SalTwoRect& rTR, ...@@ -1654,7 +1654,7 @@ void SvpSalGraphics::drawMask( const SalTwoRect& rTR,
} }
sal_Int32 nStride; sal_Int32 nStride;
unsigned char *mask_data = aSurface.getBits(nStride); unsigned char *mask_data = aSurface.getBits(nStride);
vcl::bitmap::lookup_table unpremultiply_table = vcl::bitmap::get_unpremultiply_table(); vcl::bitmap::lookup_table const & unpremultiply_table = vcl::bitmap::get_unpremultiply_table();
for (long y = rTR.mnSrcY ; y < rTR.mnSrcY + rTR.mnSrcHeight; ++y) for (long y = rTR.mnSrcY ; y < rTR.mnSrcY + rTR.mnSrcHeight; ++y)
{ {
unsigned char *row = mask_data + (nStride*y); unsigned char *row = mask_data + (nStride*y);
...@@ -1762,7 +1762,7 @@ Color SvpSalGraphics::getPixel( long nX, long nY ) ...@@ -1762,7 +1762,7 @@ Color SvpSalGraphics::getPixel( long nX, long nY )
cairo_destroy(cr); cairo_destroy(cr);
cairo_surface_flush(target); cairo_surface_flush(target);
vcl::bitmap::lookup_table unpremultiply_table = vcl::bitmap::get_unpremultiply_table(); vcl::bitmap::lookup_table const & unpremultiply_table = vcl::bitmap::get_unpremultiply_table();
unsigned char *data = cairo_image_surface_get_data(target); unsigned char *data = cairo_image_surface_get_data(target);
sal_uInt8 a = data[SVP_CAIRO_ALPHA]; sal_uInt8 a = data[SVP_CAIRO_ALPHA];
sal_uInt8 b = unpremultiply_table[a][data[SVP_CAIRO_BLUE]]; sal_uInt8 b = unpremultiply_table[a][data[SVP_CAIRO_BLUE]];
...@@ -2096,8 +2096,9 @@ void SvpSalGraphics::releaseCairoContext(cairo_t* cr, bool bXorModeAllowed, cons ...@@ -2096,8 +2096,9 @@ void SvpSalGraphics::releaseCairoContext(cairo_t* cr, bool bXorModeAllowed, cons
sal_Int32 nUnscaledExtentsRight = nExtentsRight * m_fScale; sal_Int32 nUnscaledExtentsRight = nExtentsRight * m_fScale;
sal_Int32 nUnscaledExtentsTop = nExtentsTop * m_fScale; sal_Int32 nUnscaledExtentsTop = nExtentsTop * m_fScale;
sal_Int32 nUnscaledExtentsBottom = nExtentsBottom * m_fScale; sal_Int32 nUnscaledExtentsBottom = nExtentsBottom * m_fScale;
vcl::bitmap::lookup_table unpremultiply_table = vcl::bitmap::get_unpremultiply_table(); vcl::bitmap::lookup_table const & unpremultiply_table
vcl::bitmap::lookup_table premultiply_table = vcl::bitmap::get_premultiply_table(); = vcl::bitmap::get_unpremultiply_table();
vcl::bitmap::lookup_table const & premultiply_table = vcl::bitmap::get_premultiply_table();
for (sal_Int32 y = nUnscaledExtentsTop; y < nUnscaledExtentsBottom; ++y) for (sal_Int32 y = nUnscaledExtentsTop; y < nUnscaledExtentsBottom; ++y)
{ {
unsigned char *true_row = target_surface_data + (nStride*y); unsigned char *true_row = target_surface_data + (nStride*y);
......
...@@ -8,6 +8,11 @@ ...@@ -8,6 +8,11 @@
* *
*/ */
#include <sal/config.h>
#include <array>
#include <utility>
#include <vcl/BitmapTools.hxx> #include <vcl/BitmapTools.hxx>
#include <sal/log.hxx> #include <sal/log.hxx>
...@@ -268,7 +273,7 @@ BitmapEx* CreateFromCairoSurface(Size aSize, cairo_surface_t * pSurface) ...@@ -268,7 +273,7 @@ BitmapEx* CreateFromCairoSurface(Size aSize, cairo_surface_t * pSurface)
cairo_surface_flush(pPixels); cairo_surface_flush(pPixels);
unsigned char *pSrc = cairo_image_surface_get_data( pPixels ); unsigned char *pSrc = cairo_image_surface_get_data( pPixels );
unsigned int nStride = cairo_image_surface_get_stride( pPixels ); unsigned int nStride = cairo_image_surface_get_stride( pPixels );
vcl::bitmap::lookup_table unpremultiply_table = vcl::bitmap::get_unpremultiply_table(); vcl::bitmap::lookup_table const & unpremultiply_table = vcl::bitmap::get_unpremultiply_table();
for( unsigned long y = 0; y < static_cast<unsigned long>(aSize.Height()); y++ ) for( unsigned long y = 0; y < static_cast<unsigned long>(aSize.Height()); y++ )
{ {
sal_uInt32 *pPix = reinterpret_cast<sal_uInt32 *>(pSrc + nStride * y); sal_uInt32 *pPix = reinterpret_cast<sal_uInt32 *>(pSrc + nStride * y);
...@@ -727,7 +732,7 @@ void CanvasCairoExtractBitmapData( BitmapEx const & aBmpEx, Bitmap & aBitmap, un ...@@ -727,7 +732,7 @@ void CanvasCairoExtractBitmapData( BitmapEx const & aBmpEx, Bitmap & aBitmap, un
::Color aColor; ::Color aColor;
unsigned int nAlpha = 255; unsigned int nAlpha = 255;
vcl::bitmap::lookup_table premultiply_table = vcl::bitmap::get_premultiply_table(); vcl::bitmap::lookup_table const & premultiply_table = vcl::bitmap::get_premultiply_table();
for( nY = 0; nY < nHeight; nY++ ) for( nY = 0; nY < nHeight; nY++ )
{ {
::Scanline pReadScan; ::Scanline pReadScan;
...@@ -1046,45 +1051,51 @@ void CanvasCairoExtractBitmapData( BitmapEx const & aBmpEx, Bitmap & aBitmap, un ...@@ -1046,45 +1051,51 @@ void CanvasCairoExtractBitmapData( BitmapEx const & aBmpEx, Bitmap & aBitmap, un
return bRet; return bRet;
} }
static sal_uInt8 unpremultiply(sal_uInt8 c, sal_uInt8 a) static constexpr sal_uInt8 unpremultiply(sal_uInt8 c, sal_uInt8 a)
{ {
return (a == 0) ? 0 : (c * 255 + a / 2) / a; return (a == 0) ? 0 : (c * 255 + a / 2) / a;
} }
static sal_uInt8 premultiply(sal_uInt8 c, sal_uInt8 a) static constexpr sal_uInt8 premultiply(sal_uInt8 c, sal_uInt8 a)
{ {
return (c * a + 127) / 255; return (c * a + 127) / 255;
} }
lookup_table get_unpremultiply_table() template<int... Is> static constexpr std::array<sal_uInt8, 256> make_unpremultiply_table_row_(
int a, std::integer_sequence<int, Is...>)
{ {
static bool inited; return {unpremultiply(Is, a)...};
static sal_uInt8 unpremultiply_table[256][256]; }
if (!inited) template<int... Is> static constexpr lookup_table make_unpremultiply_table_(
{ std::integer_sequence<int, Is...>)
for (int a = 0; a < 256; ++a) {
for (int c = 0; c < 256; ++c) return {make_unpremultiply_table_row_(Is, std::make_integer_sequence<int, 256>{})...};
unpremultiply_table[a][c] = unpremultiply(c, a); }
inited = true;
}
lookup_table const & get_unpremultiply_table()
{
static constexpr auto unpremultiply_table = make_unpremultiply_table_(
std::make_integer_sequence<int, 256>{});
return unpremultiply_table; return unpremultiply_table;
} }
lookup_table get_premultiply_table() template<int... Is> static constexpr std::array<sal_uInt8, 256> make_premultiply_table_row_(
int a, std::integer_sequence<int, Is...>)
{ {
static bool inited; return {premultiply(Is, a)...};
static sal_uInt8 premultiply_table[256][256]; }
if (!inited) template<int... Is> static constexpr lookup_table make_premultiply_table_(
{ std::integer_sequence<int, Is...>)
for (int a = 0; a < 256; ++a) {
for (int c = 0; c < 256; ++c) return {make_premultiply_table_row_(Is, std::make_integer_sequence<int, 256>{})...};
premultiply_table[a][c] = premultiply(c, a); }
inited = true;
}
lookup_table const & get_premultiply_table()
{
static constexpr auto premultiply_table = make_premultiply_table_(
std::make_integer_sequence<int, 256>{});
return premultiply_table; return premultiply_table;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment