From 267c6f2ac71f92999e969232431ba04678e7437e Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Mon, 15 Apr 2024 07:54:39 +0200 Subject: Adding upstream version 4:24.2.0. Signed-off-by: Daniel Baumann --- vcl/source/bitmap/bitmappalette.cxx | 242 ++++++++++++++++++++++++++++++++++++ 1 file changed, 242 insertions(+) create mode 100644 vcl/source/bitmap/bitmappalette.cxx (limited to 'vcl/source/bitmap/bitmappalette.cxx') diff --git a/vcl/source/bitmap/bitmappalette.cxx b/vcl/source/bitmap/bitmappalette.cxx new file mode 100644 index 0000000000..43eae34754 --- /dev/null +++ b/vcl/source/bitmap/bitmappalette.cxx @@ -0,0 +1,242 @@ +/* -*- 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/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +class ImplBitmapPalette +{ +public: + ImplBitmapPalette(std::initializer_list aBitmapColor) + : maBitmapColor(aBitmapColor) + { + } + ImplBitmapPalette(const BitmapColor* first, const BitmapColor* last) + : maBitmapColor(first, last) + { + } + ImplBitmapPalette() {} + ImplBitmapPalette(sal_uInt16 nCount) + : maBitmapColor(nCount) + { + } + std::vector& GetBitmapData() { return maBitmapColor; } + const std::vector& GetBitmapData() const { return maBitmapColor; } + bool operator==(const ImplBitmapPalette& rBitmapPalette) const + { + return maBitmapColor == rBitmapPalette.maBitmapColor; + } + +private: + std::vector maBitmapColor; +}; + +namespace +{ +BitmapPalette::ImplType& GetGlobalDefault() +{ + static BitmapPalette::ImplType gDefault; + return gDefault; +} +} + +BitmapPalette::BitmapPalette() + : mpImpl(GetGlobalDefault()) +{ +} + +BitmapPalette::BitmapPalette(const BitmapPalette& rOther) + : mpImpl(rOther.mpImpl) +{ +} + +BitmapPalette::BitmapPalette(BitmapPalette&& rOther) noexcept + : mpImpl(std::move(rOther.mpImpl)) +{ +} + +BitmapPalette::BitmapPalette(std::initializer_list aBitmapColor) + : mpImpl(aBitmapColor) +{ +} + +BitmapPalette::BitmapPalette(const BitmapColor* first, const BitmapColor* last) + : mpImpl({ first, last }) +{ +} + +BitmapPalette::BitmapPalette(sal_uInt16 nCount) + : mpImpl(nCount) +{ +} + +BitmapPalette::~BitmapPalette() {} + +BitmapPalette& BitmapPalette::operator=(const BitmapPalette& rOther) +{ + mpImpl = rOther.mpImpl; + return *this; +} + +BitmapPalette& BitmapPalette::operator=(BitmapPalette&& rOther) noexcept +{ + mpImpl = std::move(rOther.mpImpl); + return *this; +} + +const BitmapColor* BitmapPalette::ImplGetColorBuffer() const +{ + return mpImpl->GetBitmapData().data(); +} + +BitmapColor* BitmapPalette::ImplGetColorBuffer() { return mpImpl->GetBitmapData().data(); } + +BitmapChecksum BitmapPalette::GetChecksum() const +{ + auto const& rBitmapData = mpImpl->GetBitmapData(); + return rtl_crc32(0, rBitmapData.data(), rBitmapData.size() * sizeof(BitmapColor)); +} + +bool BitmapPalette::operator==(const BitmapPalette& rOther) const +{ + return mpImpl == rOther.mpImpl; +} + +bool BitmapPalette::operator!() const { return mpImpl->GetBitmapData().empty(); } + +sal_uInt16 BitmapPalette::GetEntryCount() const { return mpImpl->GetBitmapData().size(); } + +void BitmapPalette::SetEntryCount(sal_uInt16 nCount) { mpImpl->GetBitmapData().resize(nCount); } + +const BitmapColor& BitmapPalette::operator[](sal_uInt16 nIndex) const +{ + assert(nIndex < mpImpl->GetBitmapData().size() && "Palette index is out of range"); + return mpImpl->GetBitmapData()[nIndex]; +} + +BitmapColor& BitmapPalette::operator[](sal_uInt16 nIndex) +{ + assert(nIndex < mpImpl->GetBitmapData().size() && "Palette index is out of range"); + return mpImpl->GetBitmapData()[nIndex]; +} + +/// Returns the BitmapColor (i.e. palette index) that is either an exact match +/// of the required color, or failing that, the entry that is the closest i.e. least error +/// as measured by Color::GetColorError. +sal_uInt16 BitmapPalette::GetBestIndex(const BitmapColor& rCol) const +{ + auto const& rBitmapColor = mpImpl->GetBitmapData(); + sal_uInt16 nRetIndex = 0; + + if (!rBitmapColor.empty()) + { + for (size_t j = 0; j < rBitmapColor.size(); ++j) + { + if (rCol == rBitmapColor[j]) + { + return j; + } + } + + sal_uInt16 nLastErr = SAL_MAX_UINT16; + for (size_t i = 0; i < rBitmapColor.size(); ++i) + { + const sal_uInt16 nActErr = rCol.GetColorError(rBitmapColor[i]); + if (nActErr < nLastErr) + { + nLastErr = nActErr; + nRetIndex = i; + } + } + } + + return nRetIndex; +} + +/// Returns the BitmapColor (i.e. palette index) that is an exact match +/// of the required color. Returns SAL_MAX_UINT16 if nothing found. +sal_uInt16 BitmapPalette::GetMatchingIndex(const BitmapColor& rCol) const +{ + auto const& rBitmapColor = mpImpl->GetBitmapData(); + + for (size_t j = 0; j < rBitmapColor.size(); ++j) + { + if (rCol == rBitmapColor[j]) + { + return j; + } + } + + return SAL_MAX_UINT16; +} + +bool BitmapPalette::IsGreyPaletteAny() const +{ + auto const& rBitmapColor = mpImpl->GetBitmapData(); + const int nEntryCount = GetEntryCount(); + if (!nEntryCount) // NOTE: an empty palette means 1:1 mapping + return true; + // See above: only certain entry values will result in a valid call to GetGreyPalette + if (nEntryCount == 2 || nEntryCount == 4 || nEntryCount == 16 || nEntryCount == 256) + { + const BitmapPalette& rGreyPalette = Bitmap::GetGreyPalette(nEntryCount); + if (rGreyPalette == *this) + return true; + } + + bool bRet = false; + // TODO: is it worth to compare the entries for the general case? + if (nEntryCount == 2) + { + const BitmapColor& rCol0(rBitmapColor[0]); + const BitmapColor& rCol1(rBitmapColor[1]); + bRet = rCol0.GetRed() == rCol0.GetGreen() && rCol0.GetRed() == rCol0.GetBlue() + && rCol1.GetRed() == rCol1.GetGreen() && rCol1.GetRed() == rCol1.GetBlue(); + } + return bRet; +} + +bool BitmapPalette::IsGreyPalette8Bit() const +{ + auto const& rBitmapColor = mpImpl->GetBitmapData(); + const int nEntryCount = GetEntryCount(); + if (!nEntryCount) // NOTE: an empty palette means 1:1 mapping + return true; + if (nEntryCount != 256) + return false; + for (sal_uInt16 i = 0; i < 256; ++i) + { + if (rBitmapColor[i] != BitmapColor(i, i, i)) + return false; + } + return true; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ -- cgit v1.2.3