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