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>
13 #include <vcl/bitmapaccess.hxx>
15 
16 #include <bitmapwriteaccess.hxx>
17 #include <bitmap/Octree.hxx>
18 
20 {
21  Bitmap aBitmap = aBitmapEx.GetBitmap();
22 
23  bool bRet = false;
24 
25  if (aBitmap.GetColorCount() <= sal_Int64(mnNewColorCount))
26  {
27  bRet = true;
28  }
29  else
30  {
31  Bitmap aNewBmp;
32  Bitmap::ScopedReadAccess pRAcc(aBitmap);
33  const sal_uInt16 nColorCount = std::min(mnNewColorCount, sal_uInt16(256));
34  sal_uInt16 nBitCount = 0;
35 
36  if (nColorCount <= 2)
37  nBitCount = 1;
38  else if (nColorCount <= 16)
39  nBitCount = 4;
40  else
41  nBitCount = 8;
42 
43  if (pRAcc)
44  {
45  Octree aOct(*pRAcc, nColorCount);
46  const BitmapPalette& rPal = aOct.GetPalette();
47 
48  aNewBmp = Bitmap(aBitmap.GetSizePixel(), nBitCount, &rPal);
49  BitmapScopedWriteAccess pWAcc(aNewBmp);
50 
51  if (pWAcc)
52  {
53  const long nWidth = pRAcc->Width();
54  const long nHeight = pRAcc->Height();
55 
56  if (pRAcc->HasPalette())
57  {
58  for (long nY = 0; nY < nHeight; nY++)
59  {
60  Scanline pScanline = pWAcc->GetScanline(nY);
61  Scanline pScanlineRead = pRAcc->GetScanline(nY);
62  for (long nX = 0; nX < nWidth; nX++)
63  {
64  auto c = pRAcc->GetPaletteColor(
65  pRAcc->GetIndexFromData(pScanlineRead, nX));
66  pWAcc->SetPixelOnData(
67  pScanline, nX,
68  BitmapColor(static_cast<sal_uInt8>(aOct.GetBestPaletteIndex(c))));
69  }
70  }
71  }
72  else
73  {
74  for (long nY = 0; nY < nHeight; nY++)
75  {
76  Scanline pScanline = pWAcc->GetScanline(nY);
77  Scanline pScanlineRead = pRAcc->GetScanline(nY);
78  for (long nX = 0; nX < nWidth; nX++)
79  {
80  auto c = pRAcc->GetPixelFromData(pScanlineRead, nX);
81  pWAcc->SetPixelOnData(
82  pScanline, nX,
83  BitmapColor(static_cast<sal_uInt8>(aOct.GetBestPaletteIndex(c))));
84  }
85  }
86  }
87 
88  pWAcc.reset();
89  bRet = true;
90  }
91 
92  pRAcc.reset();
93  }
94 
95  if (bRet)
96  {
97  const MapMode aMap(aBitmap.GetPrefMapMode());
98  const Size aSize(aBitmap.GetPrefSize());
99 
100  aBitmap = aNewBmp;
101 
102  aBitmap.SetPrefMapMode(aMap);
103  aBitmap.SetPrefSize(aSize);
104  }
105  }
106 
107  if (bRet)
108  return BitmapEx(aBitmap);
109 
110  return BitmapEx();
111 }
112 
113 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
Scanline GetScanline(long nY) const
sal_Int64 GetColorCount() const
Definition: bitmap.hxx:576
Size GetSizePixel() const
long Width() const
const Size & GetPrefSize() const
Definition: bitmap.hxx:566
Bitmap GetBitmap(const Color *pTransReplaceColor=nullptr) const
Definition: bitmapex.cxx:236
const MapMode & GetPrefMapMode() const
Definition: bitmap.hxx:556
void SetPrefMapMode(const MapMode &rMapMode)
Definition: bitmap.hxx:561
sal_uInt8 * Scanline
Definition: Scanline.hxx:25
bool HasPalette() const
virtual BitmapEx execute(BitmapEx const &rBitmapEx) const override
long Height() const
BitmapColor GetPixelFromData(const sal_uInt8 *pData, 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
sal_uInt8 GetIndexFromData(const sal_uInt8 *pData, long nX) const