improve the bitmap->alpha conversion

we do not need to go via this complex luminance calculation, we
just want the red channel of the RGB data.

This is also what the skia backends do, ever since
    commit 2fcfbd73768b69ba58607a054e7f851be2942992
    Author: Luboš Luňák <l.lunak@collabora.com>
    Date:   Fri Apr 3 22:50:12 2020 +0200
    no gray conversion needed for VCL alpha hacks

Change-Id: Ie4a7adcc7c488d241ec58e64a130da544c3d39d0
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/184944
Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
Tested-by: Jenkins
This commit is contained in:
Noel Grandin 2025-05-04 23:18:39 +02:00
parent b87e2d3c25
commit 7f33bccce7
2 changed files with 109 additions and 2 deletions

View File

@ -580,6 +580,7 @@ public:
SAL_DLLPRIVATE void ImplSetSalBitmap( const std::shared_ptr<SalBitmap>& xImpBmp );
SAL_DLLPRIVATE bool ImplMakeGreyscales();
SAL_DLLPRIVATE bool ImplMake8BitNoConversion();
private:
SAL_DLLPRIVATE bool ImplConvertUp(vcl::PixelFormat ePixelFormat, Color const* pExtColor = nullptr);

View File

@ -861,10 +861,13 @@ bool Bitmap::Convert( BmpConversion eConversion )
break;
case BmpConversion::N8BitGreys:
case BmpConversion::N8BitNoConversion:
bRet = ImplMakeGreyscales();
break;
case BmpConversion::N8BitNoConversion:
bRet = ImplMake8BitNoConversion();
break;
case BmpConversion::N8BitColors:
{
if( nBitCount < 8 )
@ -1016,7 +1019,110 @@ bool Bitmap::ImplMakeGreyscales()
return true;
}
bool Bitmap::ImplConvertUp(vcl::PixelFormat ePixelFormat, Color const * pExtColor)
// Used for the bitmap->alpha layer conversion, just takes the red channel
bool Bitmap::ImplMake8BitNoConversion()
{
BitmapScopedReadAccess pReadAcc(*this);
if (!pReadAcc)
return false;
const BitmapPalette& rPal = GetGreyPalette(256);
bool bPalDiffers
= !pReadAcc->HasPalette() || (rPal.GetEntryCount() != pReadAcc->GetPaletteEntryCount());
if (!bPalDiffers)
bPalDiffers = (rPal != pReadAcc->GetPalette());
if (!bPalDiffers)
return true;
const auto ePixelFormat = vcl::PixelFormat::N8_BPP;
Bitmap aNewBmp(GetSizePixel(), ePixelFormat, &rPal);
BitmapScopedWriteAccess pWriteAcc(aNewBmp);
if (!pWriteAcc)
return false;
const tools::Long nWidth = pWriteAcc->Width();
const tools::Long nHeight = pWriteAcc->Height();
if (pReadAcc->HasPalette())
{
for (tools::Long nY = 0; nY < nHeight; nY++)
{
Scanline pScanline = pWriteAcc->GetScanline(nY);
Scanline pScanlineRead = pReadAcc->GetScanline(nY);
for (tools::Long nX = 0; nX < nWidth; nX++)
{
const sal_uInt8 cIndex = pReadAcc->GetIndexFromData(pScanlineRead, nX);
pWriteAcc->SetPixelOnData(
pScanline, nX,
BitmapColor(pReadAcc->GetPaletteColor(cIndex).GetRed()));
}
}
}
else if (pReadAcc->GetScanlineFormat() == ScanlineFormat::N24BitTcBgr
&& pWriteAcc->GetScanlineFormat() == ScanlineFormat::N8BitPal)
{
for (tools::Long nY = 0; nY < nHeight; nY++)
{
Scanline pReadScan = pReadAcc->GetScanline(nY);
Scanline pWriteScan = pWriteAcc->GetScanline(nY);
for (tools::Long nX = 0; nX < nWidth; nX++)
{
pReadScan++;
pReadScan++;
const sal_uLong nR = *pReadScan++;
*pWriteScan++ = static_cast<sal_uInt8>(nR);
}
}
}
else if (pReadAcc->GetScanlineFormat() == ScanlineFormat::N24BitTcRgb
&& pWriteAcc->GetScanlineFormat() == ScanlineFormat::N8BitPal)
{
for (tools::Long nY = 0; nY < nHeight; nY++)
{
Scanline pReadScan = pReadAcc->GetScanline(nY);
Scanline pWriteScan = pWriteAcc->GetScanline(nY);
for (tools::Long nX = 0; nX < nWidth; nX++)
{
const sal_uLong nR = *pReadScan++;
pReadScan++;
pReadScan++;
*pWriteScan++ = static_cast<sal_uInt8>(nR);
}
}
}
else
{
for (tools::Long nY = 0; nY < nHeight; nY++)
{
Scanline pScanline = pWriteAcc->GetScanline(nY);
Scanline pScanlineRead = pReadAcc->GetScanline(nY);
for (tools::Long nX = 0; nX < nWidth; nX++)
pWriteAcc->SetPixelOnData(
pScanline, nX,
BitmapColor(pReadAcc->GetPixelFromData(pScanlineRead, nX).GetRed()));
}
}
pWriteAcc.reset();
pReadAcc.reset();
const MapMode aMap(maPrefMapMode);
const Size aSize(maPrefSize);
*this = std::move(aNewBmp);
maPrefMapMode = aMap;
maPrefSize = aSize;
return true;
}
bool Bitmap::ImplConvertUp(vcl::PixelFormat ePixelFormat, Color const* pExtColor)
{
SAL_WARN_IF(ePixelFormat <= getPixelFormat(), "vcl", "New pixel format must be greater!" );