LibreOffice Module vcl (master)  1
BitmapPopArtFilter.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 
18 {
19  Bitmap aBitmap(rBitmapEx.GetBitmap());
20 
21  bool bRet = isPalettePixelFormat(aBitmap.getPixelFormat())
22  || aBitmap.Convert(BmpConversion::N8BitColors);
23 
24  if (bRet)
25  {
26  bRet = false;
27 
28  BitmapScopedWriteAccess pWriteAcc(aBitmap);
29 
30  if (pWriteAcc)
31  {
32  const tools::Long nWidth = pWriteAcc->Width();
33  const tools::Long nHeight = pWriteAcc->Height();
34  const int nEntryCount = 1 << pWriteAcc->GetBitCount();
35  int n = 0;
36  std::vector<PopArtEntry> aPopArtTable(nEntryCount);
37 
38  for (n = 0; n < nEntryCount; n++)
39  {
40  PopArtEntry& rEntry = aPopArtTable[n];
41  rEntry.mnIndex = static_cast<sal_uInt16>(n);
42  rEntry.mnCount = 0;
43  }
44 
45  // get pixel count for each palette entry
46  for (tools::Long nY = 0; nY < nHeight; nY++)
47  {
48  Scanline pScanline = pWriteAcc->GetScanline(nY);
49  for (tools::Long nX = 0; nX < nWidth; nX++)
50  {
51  aPopArtTable[pWriteAcc->GetIndexFromData(pScanline, nX)].mnCount++;
52  }
53  }
54 
55  // sort table
56  std::sort(aPopArtTable.begin(), aPopArtTable.end(),
57  [](const PopArtEntry& lhs, const PopArtEntry& rhs) {
58  return lhs.mnCount < rhs.mnCount;
59  });
60 
61  // get last used entry
62  sal_uLong nFirstEntry;
63  sal_uLong nLastEntry = 0;
64 
65  for (n = 0; n < nEntryCount; n++)
66  {
67  if (aPopArtTable[n].mnCount)
68  nLastEntry = n;
69  }
70 
71  // rotate palette (one entry)
72  const BitmapColor aFirstCol(pWriteAcc->GetPaletteColor(
73  sal::static_int_cast<sal_uInt16>(aPopArtTable[0].mnIndex)));
74 
75  for (nFirstEntry = 0; nFirstEntry < nLastEntry; nFirstEntry++)
76  {
77  pWriteAcc->SetPaletteColor(
78  sal::static_int_cast<sal_uInt16>(aPopArtTable[nFirstEntry].mnIndex),
79  pWriteAcc->GetPaletteColor(
80  sal::static_int_cast<sal_uInt16>(aPopArtTable[nFirstEntry + 1].mnIndex)));
81  }
82 
83  pWriteAcc->SetPaletteColor(
84  sal::static_int_cast<sal_uInt16>(aPopArtTable[nLastEntry].mnIndex), aFirstCol);
85 
86  // cleanup
87  pWriteAcc.reset();
88  bRet = true;
89  }
90  }
91 
92  if (bRet)
93  return BitmapEx(aBitmap);
94 
95  return BitmapEx();
96 }
97 
98 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
constexpr bool isPalettePixelFormat(PixelFormat ePixelFormat)
Is it a pixel format that forces creation of a palette.
Definition: BitmapTypes.hxx:29
sal_uIntPtr sal_uLong
long Long
sal_Int64 n
This template handles BitmapAccess the RAII way.
virtual BitmapEx execute(BitmapEx const &rBitmapEx) const override
sal_uInt8 * Scanline
Definition: Scanline.hxx:26
std::size_t mnCount
Bitmap GetBitmap(Color aTransparentReplaceColor) const
Definition: BitmapEx.cxx:229
int mnIndex