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 (aBitmap.GetColorCount() <= 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  sal_uInt16 nBitCount = 0;
34 
35  if (nColorCount <= 2)
36  nBitCount = 1;
37  else if (nColorCount <= 16)
38  nBitCount = 4;
39  else
40  nBitCount = 8;
41 
42  if (pRAcc)
43  {
44  Octree aOct(*pRAcc, nColorCount);
45  const BitmapPalette& rPal = aOct.GetPalette();
46 
47  aNewBmp = Bitmap(aBitmap.GetSizePixel(), nBitCount, &rPal);
48  BitmapScopedWriteAccess pWAcc(aNewBmp);
49 
50  if (pWAcc)
51  {
52  const tools::Long nWidth = pRAcc->Width();
53  const tools::Long nHeight = pRAcc->Height();
54 
55  if (pRAcc->HasPalette())
56  {
57  for (tools::Long nY = 0; nY < nHeight; nY++)
58  {
59  Scanline pScanline = pWAcc->GetScanline(nY);
60  Scanline pScanlineRead = pRAcc->GetScanline(nY);
61  for (tools::Long nX = 0; nX < nWidth; nX++)
62  {
63  auto c = pRAcc->GetPaletteColor(
64  pRAcc->GetIndexFromData(pScanlineRead, nX));
65  pWAcc->SetPixelOnData(
66  pScanline, nX,
67  BitmapColor(static_cast<sal_uInt8>(aOct.GetBestPaletteIndex(c))));
68  }
69  }
70  }
71  else
72  {
73  for (tools::Long nY = 0; nY < nHeight; nY++)
74  {
75  Scanline pScanline = pWAcc->GetScanline(nY);
76  Scanline pScanlineRead = pRAcc->GetScanline(nY);
77  for (tools::Long nX = 0; nX < nWidth; nX++)
78  {
79  auto c = pRAcc->GetPixelFromData(pScanlineRead, nX);
80  pWAcc->SetPixelOnData(
81  pScanline, nX,
82  BitmapColor(static_cast<sal_uInt8>(aOct.GetBestPaletteIndex(c))));
83  }
84  }
85  }
86 
87  pWAcc.reset();
88  bRet = true;
89  }
90 
91  pRAcc.reset();
92  }
93 
94  if (bRet)
95  {
96  const MapMode aMap(aBitmap.GetPrefMapMode());
97  const Size aSize(aBitmap.GetPrefSize());
98 
99  aBitmap = aNewBmp;
100 
101  aBitmap.SetPrefMapMode(aMap);
102  aBitmap.SetPrefSize(aSize);
103  }
104  }
105 
106  if (bRet)
107  return BitmapEx(aBitmap);
108 
109  return BitmapEx();
110 }
111 
112 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
sal_uInt8 GetIndexFromData(const sal_uInt8 *pData, tools::Long nX) const
tools::Long Height() const
sal_Int64 GetColorCount() const
Definition: bitmap.hxx:581
long Long
Size GetSizePixel() const
const Size & GetPrefSize() const
Definition: bitmap.hxx:571
HashMap_OWString_Interface aMap
Scanline GetScanline(tools::Long nY) const
const MapMode & GetPrefMapMode() const
Definition: bitmap.hxx:561
void SetPrefMapMode(const MapMode &rMapMode)
Definition: bitmap.hxx:566
sal_uInt8 * Scanline
Definition: Scanline.hxx:25
bool HasPalette() const
tools::Long Width() const
short nBitCount
Bitmap GetBitmap(Color aTransparentReplaceColor) const
Definition: BitmapEx.cxx:231
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
sal_uInt16 GetBestPaletteIndex(const BitmapColor &rColor)
Definition: Octree.cxx:212
const BitmapPalette & GetPalette()
Definition: Octree.cxx:204