diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 09:06:44 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 09:06:44 +0000 |
commit | ed5640d8b587fbcfed7dd7967f3de04b37a76f26 (patch) | |
tree | 7a5f7c6c9d02226d7471cb3cc8fbbf631b415303 /vcl/source/bitmap/BitmapSimpleColorQuantizationFilter.cxx | |
parent | Initial commit. (diff) | |
download | libreoffice-ed5640d8b587fbcfed7dd7967f3de04b37a76f26.tar.xz libreoffice-ed5640d8b587fbcfed7dd7967f3de04b37a76f26.zip |
Adding upstream version 4:7.4.7.upstream/4%7.4.7upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'vcl/source/bitmap/BitmapSimpleColorQuantizationFilter.cxx')
-rw-r--r-- | vcl/source/bitmap/BitmapSimpleColorQuantizationFilter.cxx | 110 |
1 files changed, 110 insertions, 0 deletions
diff --git a/vcl/source/bitmap/BitmapSimpleColorQuantizationFilter.cxx b/vcl/source/bitmap/BitmapSimpleColorQuantizationFilter.cxx new file mode 100644 index 000000000..f825013d4 --- /dev/null +++ b/vcl/source/bitmap/BitmapSimpleColorQuantizationFilter.cxx @@ -0,0 +1,110 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + */ + +#include <vcl/bitmap.hxx> +#include <vcl/bitmapex.hxx> +#include <vcl/BitmapSimpleColorQuantizationFilter.hxx> + +#include <bitmap/BitmapWriteAccess.hxx> +#include <bitmap/Octree.hxx> + +BitmapEx BitmapSimpleColorQuantizationFilter::execute(BitmapEx const& aBitmapEx) const +{ + Bitmap aBitmap = aBitmapEx.GetBitmap(); + + bool bRet = false; + + if (vcl::numberOfColors(aBitmap.getPixelFormat()) <= sal_Int64(mnNewColorCount)) + { + bRet = true; + } + else + { + Bitmap aNewBmp; + Bitmap::ScopedReadAccess pRAcc(aBitmap); + const sal_uInt16 nColorCount = std::min(mnNewColorCount, sal_uInt16(256)); + auto ePixelFormat = vcl::PixelFormat::INVALID; + + if (nColorCount <= 2) + ePixelFormat = vcl::PixelFormat::N1_BPP; + else + ePixelFormat = vcl::PixelFormat::N8_BPP; + + if (pRAcc) + { + Octree aOct(*pRAcc, nColorCount); + const BitmapPalette& rPal = aOct.GetPalette(); + + aNewBmp = Bitmap(aBitmap.GetSizePixel(), ePixelFormat, &rPal); + BitmapScopedWriteAccess pWAcc(aNewBmp); + + if (pWAcc) + { + const sal_Int32 nWidth = pRAcc->Width(); + const sal_Int32 nHeight = pRAcc->Height(); + + if (pRAcc->HasPalette()) + { + for (sal_Int32 nY = 0; nY < nHeight; nY++) + { + Scanline pScanline = pWAcc->GetScanline(nY); + Scanline pScanlineRead = pRAcc->GetScanline(nY); + for (sal_Int32 nX = 0; nX < nWidth; nX++) + { + auto c = pRAcc->GetPaletteColor( + pRAcc->GetIndexFromData(pScanlineRead, nX)); + pWAcc->SetPixelOnData( + pScanline, nX, + BitmapColor(static_cast<sal_uInt8>(aOct.GetBestPaletteIndex(c)))); + } + } + } + else + { + for (sal_Int32 nY = 0; nY < nHeight; nY++) + { + Scanline pScanline = pWAcc->GetScanline(nY); + Scanline pScanlineRead = pRAcc->GetScanline(nY); + for (sal_Int32 nX = 0; nX < nWidth; nX++) + { + auto c = pRAcc->GetPixelFromData(pScanlineRead, nX); + pWAcc->SetPixelOnData( + pScanline, nX, + BitmapColor(static_cast<sal_uInt8>(aOct.GetBestPaletteIndex(c)))); + } + } + } + + pWAcc.reset(); + bRet = true; + } + + pRAcc.reset(); + } + + if (bRet) + { + const MapMode aMap(aBitmap.GetPrefMapMode()); + const Size aSize(aBitmap.GetPrefSize()); + + aBitmap = aNewBmp; + + aBitmap.SetPrefMapMode(aMap); + aBitmap.SetPrefSize(aSize); + } + } + + if (bRet) + return BitmapEx(aBitmap); + + return BitmapEx(); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |