LibreOffice Module vcl (master)  1
BitmapMosaicFilter.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 = false;
22 
23  if (mnTileWidth > 1 || mnTileHeight > 1)
24  {
25  std::unique_ptr<Bitmap> pNewBmp;
26  BitmapReadAccess* pReadAcc;
27  BitmapWriteAccess* pWriteAcc;
28 
29  if (aBitmap.GetBitCount() > 8)
30  {
31  pReadAcc = pWriteAcc = aBitmap.AcquireWriteAccess();
32  }
33  else
34  {
35  pNewBmp.reset(new Bitmap(aBitmap.GetSizePixel(), 24));
36  pReadAcc = aBitmap.AcquireReadAccess();
37  pWriteAcc = pNewBmp->AcquireWriteAccess();
38  }
39 
40  bool bConditionsMet = false;
41  tools::Long nWidth(0);
42  tools::Long nHeight(0);
43  if (pReadAcc && pWriteAcc)
44  {
45  nWidth = pReadAcc->Width();
46  nHeight = pReadAcc->Height();
47  bConditionsMet = (nWidth > 0 && nHeight > 0);
48  }
49 
50  if (bConditionsMet)
51  {
52  BitmapColor aCol;
53  tools::Long nX, nY, nX1, nX2, nY1, nY2, nSumR, nSumG, nSumB;
54  double fArea_1;
55 
56  nY1 = 0;
57  nY2 = mnTileHeight - 1;
58 
59  if (nY2 >= nHeight)
60  nY2 = nHeight - 1;
61 
62  do
63  {
64  nX1 = 0;
65  nX2 = mnTileWidth - 1;
66 
67  if (nX2 >= nWidth)
68  nX2 = nWidth - 1;
69 
70  fArea_1 = 1.0 / ((nX2 - nX1 + 1) * (nY2 - nY1 + 1));
71 
72  if (!pNewBmp)
73  {
74  do
75  {
76  for (nY = nY1, nSumR = nSumG = nSumB = 0; nY <= nY2; nY++)
77  {
78  Scanline pScanlineRead = pReadAcc->GetScanline(nY);
79  for (nX = nX1; nX <= nX2; nX++)
80  {
81  aCol = pReadAcc->GetPixelFromData(pScanlineRead, nX);
82  nSumR += aCol.GetRed();
83  nSumG += aCol.GetGreen();
84  nSumB += aCol.GetBlue();
85  }
86  }
87 
88  aCol.SetRed(static_cast<sal_uInt8>(nSumR * fArea_1));
89  aCol.SetGreen(static_cast<sal_uInt8>(nSumG * fArea_1));
90  aCol.SetBlue(static_cast<sal_uInt8>(nSumB * fArea_1));
91 
92  for (nY = nY1; nY <= nY2; nY++)
93  {
94  Scanline pScanline = pWriteAcc->GetScanline(nY);
95  for (nX = nX1; nX <= nX2; nX++)
96  pWriteAcc->SetPixelOnData(pScanline, nX, aCol);
97  }
98 
99  nX1 += mnTileWidth;
100  nX2 += mnTileWidth;
101 
102  if (nX2 >= nWidth)
103  {
104  nX2 = nWidth - 1;
105  fArea_1 = 1.0 / ((nX2 - nX1 + 1) * (nY2 - nY1 + 1));
106  }
107  } while (nX1 < nWidth);
108  }
109  else
110  {
111  do
112  {
113  for (nY = nY1, nSumR = nSumG = nSumB = 0; nY <= nY2; nY++)
114  {
115  Scanline pScanlineRead = pReadAcc->GetScanline(nY);
116  for (nX = nX1; nX <= nX2; nX++)
117  {
118  const BitmapColor& rCol = pReadAcc->GetPaletteColor(
119  pReadAcc->GetIndexFromData(pScanlineRead, nX));
120  nSumR += rCol.GetRed();
121  nSumG += rCol.GetGreen();
122  nSumB += rCol.GetBlue();
123  }
124  }
125 
126  aCol.SetRed(static_cast<sal_uInt8>(nSumR * fArea_1));
127  aCol.SetGreen(static_cast<sal_uInt8>(nSumG * fArea_1));
128  aCol.SetBlue(static_cast<sal_uInt8>(nSumB * fArea_1));
129 
130  for (nY = nY1; nY <= nY2; nY++)
131  {
132  Scanline pScanline = pWriteAcc->GetScanline(nY);
133  for (nX = nX1; nX <= nX2; nX++)
134  pWriteAcc->SetPixelOnData(pScanline, nX, aCol);
135  }
136 
137  nX1 += mnTileWidth;
138  nX2 += mnTileWidth;
139 
140  if (nX2 >= nWidth)
141  {
142  nX2 = nWidth - 1;
143  fArea_1 = 1.0 / ((nX2 - nX1 + 1) * (nY2 - nY1 + 1));
144  }
145  } while (nX1 < nWidth);
146  }
147 
148  nY1 += mnTileHeight;
149  nY2 += mnTileHeight;
150 
151  if (nY2 >= nHeight)
152  nY2 = nHeight - 1;
153 
154  } while (nY1 < nHeight);
155 
156  bRet = true;
157  }
158 
159  Bitmap::ReleaseAccess(pReadAcc);
160 
161  if (pNewBmp)
162  {
163  Bitmap::ReleaseAccess(pWriteAcc);
164 
165  if (bRet)
166  {
167  const MapMode aMap(aBitmap.GetPrefMapMode());
168  const Size aPrefSize(aBitmap.GetPrefSize());
169 
170  aBitmap = *pNewBmp;
171 
172  aBitmap.SetPrefMapMode(aMap);
173  aBitmap.SetPrefSize(aPrefSize);
174  }
175  }
176  }
177 
178  if (bRet)
179  return BitmapEx(aBitmap);
180 
181  return BitmapEx();
182 }
183 
184 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
sal_uInt8 GetIndexFromData(const sal_uInt8 *pData, tools::Long nX) const
tools::Long Height() const
sal_uInt8 GetRed() const
void SetBlue(sal_uInt8 nBlue)
long Long
HashMap_OWString_Interface aMap
void SetPixelOnData(sal_uInt8 *pData, tools::Long nX, const BitmapColor &rBitmapColor)
Scanline GetScanline(tools::Long nY) const
virtual BitmapEx execute(BitmapEx const &rBitmapEx) const override
sal_uInt8 GetBlue() const
sal_uInt8 * Scanline
Definition: Scanline.hxx:25
tools::Long Width() const
void SetRed(sal_uInt8 nRed)
static void ReleaseAccess(BitmapInfoAccess *pAccess)
Bitmap GetBitmap(Color aTransparentReplaceColor) const
Definition: BitmapEx.cxx:231
sal_uInt8 GetGreen() const
void SetGreen(sal_uInt8 nGreen)
BitmapColor GetPixelFromData(const sal_uInt8 *pData, tools::Long nX) const
const BitmapColor & GetPaletteColor(sal_uInt16 nColor) const