summaryrefslogtreecommitdiff
path: root/vcl/source/bitmap
diff options
context:
space:
mode:
authorNoel Grandin <noel.grandin@collabora.co.uk>2023-08-02 15:26:06 +0200
committerNoel Grandin <noel.grandin@collabora.co.uk>2023-08-02 18:22:28 +0200
commitf76acf9bd97e65ba50303b6e5a25e5877996ebe1 (patch)
treefa753dff999f5f78b203cdd18fe8cb0295e13156 /vcl/source/bitmap
parent76f50549f4898313ef4a18ce32d1f0a625ce766d (diff)
tdf#156525 Save as > HTML loses drawing object as invalid gif
regression from commit 1c7cbd685633d44eac554629572f3401c450f855 Author: Noel Grandin <noel.grandin@collabora.co.uk> Date: Sun May 7 16:56:21 2023 +0200 use AlphaMask for variables when calling GetAlphaMask where after my change, the code is now calling Bitmap::Replace(AlphaMask,...) instead of Bitmap::Replace(Bitmap,...) and those two methods do quite different things. However, we have to (*) restore Bitmap::Replace(Bitmap,...) which was removed in commit 8270eb5d5600cc84dbf5f0e339f90c4519ef88bb Author: Noel Grandin <noel.grandin@collabora.co.uk> Date: Fri May 19 13:35:31 2023 +0200 loplugin:unusedmethods (*) restore BitmapWriteAccess::SetPaletteEntryCount which was removed in commit 74cd0d0b281f8df75612bfb600df2eae62c4d21d Author: Noel Grandin <noel.grandin@collabora.co.uk> Date: Thu Jun 29 13:53:30 2023 +0200 loplugin:unusedmethods (*) Invert the mask/alpha layer, since after commit 81994cb2b8b32453a92bcb011830fcb884f22ff3 Author: Noel Grandin <noelgrandin@gmail.com> Date: Fri Apr 16 20:33:10 2021 +0200 Convert internal vcl bitmap formats transparency->alpha (II) we are dealing with real alpha, and not transparency. Also add an assert in GIFWriter::WriteAccess, since it is a logic error to get here and have the image in the wrong format. Change-Id: I0e09b3ca82af0bd5b58d80e0a6eac4c7bdf7c48e Reviewed-on: https://gerrit.libreoffice.org/c/core/+/155254 Tested-by: Jenkins Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
Diffstat (limited to 'vcl/source/bitmap')
-rw-r--r--vcl/source/bitmap/bitmappaint.cxx75
1 files changed, 75 insertions, 0 deletions
diff --git a/vcl/source/bitmap/bitmappaint.cxx b/vcl/source/bitmap/bitmappaint.cxx
index 487e6d1a6ad6..91a43b951748 100644
--- a/vcl/source/bitmap/bitmappaint.cxx
+++ b/vcl/source/bitmap/bitmappaint.cxx
@@ -884,6 +884,81 @@ vcl::Region Bitmap::CreateRegion(const Color& rColor, const tools::Rectangle& rR
return aRegion;
}
+bool Bitmap::ReplaceMask(const AlphaMask& rMask, const Color& rReplaceColor)
+{
+ ScopedReadAccess pMaskAcc(const_cast<AlphaMask&>(rMask));
+ BitmapScopedWriteAccess pAcc(*this);
+
+ if (!pMaskAcc || !pAcc)
+ return false;
+
+ const tools::Long nWidth = std::min(pMaskAcc->Width(), pAcc->Width());
+ const tools::Long nHeight = std::min(pMaskAcc->Height(), pAcc->Height());
+ const BitmapColor aMaskWhite(pMaskAcc->GetBestMatchingColor(COL_WHITE));
+ BitmapColor aReplace;
+
+ if (pAcc->HasPalette())
+ {
+ const sal_uInt16 nActColors = pAcc->GetPaletteEntryCount();
+ const sal_uInt16 nMaxColors = 1 << pAcc->GetBitCount();
+
+ // default to the nearest color
+ aReplace = pAcc->GetBestMatchingColor(rReplaceColor);
+
+ // for paletted images without a matching palette entry
+ // look for an unused palette entry (NOTE: expensive!)
+ if (pAcc->GetPaletteColor(aReplace.GetIndex()) != BitmapColor(rReplaceColor))
+ {
+ // if the palette has empty entries use the last one
+ if (nActColors < nMaxColors)
+ {
+ pAcc->SetPaletteEntryCount(nActColors + 1);
+ pAcc->SetPaletteColor(nActColors, rReplaceColor);
+ aReplace = BitmapColor(static_cast<sal_uInt8>(nActColors));
+ }
+ else
+ {
+ std::unique_ptr<bool[]> pFlags(new bool[nMaxColors]);
+
+ // Set all entries to false
+ std::fill(pFlags.get(), pFlags.get() + nMaxColors, false);
+
+ for (tools::Long nY = 0; nY < nHeight; nY++)
+ {
+ Scanline pScanline = pAcc->GetScanline(nY);
+ for (tools::Long nX = 0; nX < nWidth; nX++)
+ pFlags[pAcc->GetIndexFromData(pScanline, nX)] = true;
+ }
+
+ for (sal_uInt16 i = 0; i < nMaxColors; i++)
+ {
+ // Hurray, we do have an unused entry
+ if (!pFlags[i])
+ {
+ pAcc->SetPaletteColor(i, rReplaceColor);
+ aReplace = BitmapColor(static_cast<sal_uInt8>(i));
+ }
+ }
+ }
+ }
+ }
+ else
+ aReplace = rReplaceColor;
+
+ for (tools::Long nY = 0; nY < nHeight; nY++)
+ {
+ Scanline pScanline = pAcc->GetScanline(nY);
+ Scanline pScanlineMask = pMaskAcc->GetScanline(nY);
+ for (tools::Long nX = 0; nX < nWidth; nX++)
+ {
+ if (pMaskAcc->GetPixelFromData(pScanlineMask, nX) == aMaskWhite)
+ pAcc->SetPixelOnData(pScanline, nX, aReplace);
+ }
+ }
+
+ return true;
+}
+
bool Bitmap::Replace(const AlphaMask& rAlpha, const Color& rMergeColor)
{
Bitmap aNewBmp(GetSizePixel(), vcl::PixelFormat::N24_BPP);