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::optional<Bitmap> pNewBmp;
26 BitmapReadAccess* pReadAcc;
27 BitmapWriteAccess* pWriteAcc;
28
30 {
31 pReadAcc = pWriteAcc = aBitmap.AcquireWriteAccess();
32 }
33 else
34 {
35 pNewBmp.emplace(aBitmap.GetSizePixel(), vcl::PixelFormat::N24_BPP);
36 pReadAcc = aBitmap.AcquireReadAccess();
37 pWriteAcc = pNewBmp->AcquireWriteAccess();
38 }
39
40 bool bConditionsMet = false;
41 sal_Int32 nWidth(0);
42 sal_Int32 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 sal_Int32 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 if (pWriteAcc == pReadAcc)
160 pWriteAcc = nullptr;
161 Bitmap::ReleaseAccess(pReadAcc);
162 Bitmap::ReleaseAccess(pWriteAcc);
163
164 if (pNewBmp)
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 * Scanline
Definition: Scanline.hxx:26
Bitmap GetBitmap(Color aTransparentReplaceColor) const
Definition: BitmapEx.cxx:217
tools::Long Height() const
tools::Long Width() const
const BitmapColor & GetPaletteColor(sal_uInt16 nColor) const
virtual BitmapEx execute(BitmapEx const &rBitmapEx) const override
void SetPixelOnData(sal_uInt8 *pData, tools::Long nX, const BitmapColor &rBitmapColor)
BitmapColor GetPixelFromData(const sal_uInt8 *pData, tools::Long nX) const
sal_uInt8 GetIndexFromData(const sal_uInt8 *pData, tools::Long nX) const
Scanline GetScanline(tools::Long nY) const
void SetPrefMapMode(const MapMode &rMapMode)
BitmapWriteAccess * AcquireWriteAccess()
const MapMode & GetPrefMapMode() const
Size GetSizePixel() const
static void ReleaseAccess(BitmapInfoAccess *pAccess)
BitmapReadAccess * AcquireReadAccess()
void SetPrefSize(const Size &rSize)
const Size & GetPrefSize() const
vcl::PixelFormat getPixelFormat() const
sal_uInt8 GetBlue() const
void SetGreen(sal_uInt8 nGreen)
void SetRed(sal_uInt8 nRed)
sal_uInt8 GetRed() const
sal_uInt8 GetGreen() const
void SetBlue(sal_uInt8 nBlue)
constexpr bool isPalettePixelFormat(PixelFormat ePixelFormat)
Is it a pixel format that forces creation of a palette.
Definition: BitmapTypes.hxx:28
HashMap_OWString_Interface aMap
unsigned char sal_uInt8