LibreOffice Module vcl (master)  1
BitmapSimpleColorQuantizationFilter.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  *
9  */
10 
11 #include <vcl/bitmap.hxx>
12 #include <vcl/bitmapex.hxx>
14 
16 #include <bitmap/Octree.hxx>
17 
19 {
20  Bitmap aBitmap = aBitmapEx.GetBitmap();
21 
22  bool bRet = false;
23 
24  if (vcl::numberOfColors(aBitmap.getPixelFormat()) <= sal_Int64(mnNewColorCount))
25  {
26  bRet = true;
27  }
28  else
29  {
30  Bitmap aNewBmp;
31  Bitmap::ScopedReadAccess pRAcc(aBitmap);
32  const sal_uInt16 nColorCount = std::min(mnNewColorCount, sal_uInt16(256));
33  auto ePixelFormat = vcl::PixelFormat::INVALID;
34 
35  if (nColorCount <= 2)
36  ePixelFormat = vcl::PixelFormat::N1_BPP;
37  else
38  ePixelFormat = vcl::PixelFormat::N8_BPP;
39 
40  if (pRAcc)
41  {
42  Octree aOct(*pRAcc, nColorCount);
43  const BitmapPalette& rPal = aOct.GetPalette();
44 
45  aNewBmp = Bitmap(aBitmap.GetSizePixel(), ePixelFormat, &rPal);
46  BitmapScopedWriteAccess pWAcc(aNewBmp);
47 
48  if (pWAcc)
49  {
50  const tools::Long nWidth = pRAcc->Width();
51  const tools::Long nHeight = pRAcc->Height();
52 
53  if (pRAcc->HasPalette())
54  {
55  for (tools::Long nY = 0; nY < nHeight; nY++)
56  {
57  Scanline pScanline = pWAcc->GetScanline(nY);
58  Scanline pScanlineRead = pRAcc->GetScanline(nY);
59  for (tools::Long nX = 0; nX < nWidth; nX++)
60  {
61  auto c = pRAcc->GetPaletteColor(
62  pRAcc->GetIndexFromData(pScanlineRead, nX));
63  pWAcc->SetPixelOnData(
64  pScanline, nX,
65  BitmapColor(static_cast<sal_uInt8>(aOct.GetBestPaletteIndex(c))));
66  }
67  }
68  }
69  else
70  {
71  for (tools::Long nY = 0; nY < nHeight; nY++)
72  {
73  Scanline pScanline = pWAcc->GetScanline(nY);
74  Scanline pScanlineRead = pRAcc->GetScanline(nY);
75  for (tools::Long nX = 0; nX < nWidth; nX++)
76  {
77  auto c = pRAcc->GetPixelFromData(pScanlineRead, nX);
78  pWAcc->SetPixelOnData(
79  pScanline, nX,
80  BitmapColor(static_cast<sal_uInt8>(aOct.GetBestPaletteIndex(c))));
81  }
82  }
83  }
84 
85  pWAcc.reset();
86  bRet = true;
87  }
88 
89  pRAcc.reset();
90  }
91 
92  if (bRet)
93  {
94  const MapMode aMap(aBitmap.GetPrefMapMode());
95  const Size aSize(aBitmap.GetPrefSize());
96 
97  aBitmap = aNewBmp;
98 
99  aBitmap.SetPrefMapMode(aMap);
100  aBitmap.SetPrefSize(aSize);
101  }
102  }
103 
104  if (bRet)
105  return BitmapEx(aBitmap);
106 
107  return BitmapEx();
108 }
109 
110 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
sal_uInt8 GetIndexFromData(const sal_uInt8 *pData, tools::Long nX) const
tools::Long Height() const
long Long
Size GetSizePixel() const
const Size & GetPrefSize() const
HashMap_OWString_Interface aMap
Scanline GetScanline(tools::Long nY) const
const MapMode & GetPrefMapMode() const
void SetPrefMapMode(const MapMode &rMapMode)
sal_uInt8 * Scanline
Definition: Scanline.hxx:26
vcl::PixelFormat getPixelFormat() const
bool HasPalette() const
tools::Long Width() const
Bitmap GetBitmap(Color aTransparentReplaceColor) const
Definition: BitmapEx.cxx:203
virtual BitmapEx execute(BitmapEx const &rBitmapEx) const override
BitmapColor GetPixelFromData(const sal_uInt8 *pData, tools::Long nX) const
const BitmapColor & GetPaletteColor(sal_uInt16 nColor) const
constexpr sal_Int64 numberOfColors(PixelFormat ePixelFormat)
Definition: BitmapTypes.hxx:40
sal_uInt16 GetBestPaletteIndex(const BitmapColor &rColor)
Definition: Octree.cxx:212
const BitmapPalette & GetPalette()
Definition: Octree.cxx:204