1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
11 #include <vcl/bitmap.hxx>
12 #include <vcl/bitmapex.hxx>
13 #include <vcl/BitmapMedianFilter.hxx>
15 #include <bitmap/BitmapWriteAccess.hxx>
20 if ((t = b - a) < 0) \
26 #define MN3(a, b, c) \
29 #define MX3(a, b, c) \
32 #define MNMX3(a, b, c) \
35 #define MNMX4(a, b, c, d) \
40 #define MNMX5(a, b, c, d, e) \
45 #define MNMX6(a, b, c, d, e, f) \
52 BitmapEx
BitmapMedianFilter::execute(BitmapEx
const& rBitmapEx
) const
54 Bitmap
aBitmap(rBitmapEx
.GetBitmap());
56 Bitmap::ScopedReadAccess
pReadAcc(aBitmap
);
61 Bitmap
aNewBmp(aBitmap
.GetSizePixel(), vcl::PixelFormat::N24_BPP
);
62 BitmapScopedWriteAccess
pWriteAcc(aNewBmp
);
66 const tools::Long nWidth
= pWriteAcc
->Width(), nWidth2
= nWidth
+ 2;
67 const tools::Long nHeight
= pWriteAcc
->Height(), nHeight2
= nHeight
+ 2;
68 std::unique_ptr
<tools::Long
[]> pColm(new tools::Long
[nWidth2
]);
69 std::unique_ptr
<tools::Long
[]> pRows(new tools::Long
[nHeight2
]);
70 std::unique_ptr
<BitmapColor
[]> pColRow1(new BitmapColor
[nWidth2
]);
71 std::unique_ptr
<BitmapColor
[]> pColRow2(new BitmapColor
[nWidth2
]);
72 std::unique_ptr
<BitmapColor
[]> pColRow3(new BitmapColor
[nWidth2
]);
73 BitmapColor
* pRowTmp1
= pColRow1
.get();
74 BitmapColor
* pRowTmp2
= pColRow2
.get();
75 BitmapColor
* pRowTmp3
= pColRow3
.get();
77 tools::Long nY
, nX
, i
;
78 tools::Long nR1
, nR2
, nR3
, nR4
, nR5
, nR6
, nR7
, nR8
, nR9
;
79 tools::Long nG1
, nG2
, nG3
, nG4
, nG5
, nG6
, nG7
, nG8
, nG9
;
80 tools::Long nB1
, nB2
, nB3
, nB4
, nB5
, nB6
, nB7
, nB8
, nB9
;
83 for (i
= 0; i
< nWidth2
; i
++)
84 pColm
[i
] = (i
> 0) ? (i
- 1) : 0;
86 pColm
[nWidth
+ 1] = pColm
[nWidth
];
89 for (i
= 0; i
< nHeight2
; i
++)
90 pRows
[i
] = (i
> 0) ? (i
- 1) : 0;
92 pRows
[nHeight
+ 1] = pRows
[nHeight
];
94 // read first three rows of bitmap color
97 for (i
= 0; i
< nWidth2
; i
++)
99 pColRow1
[i
] = pReadAcc
->GetColor(pRows
[0], pColm
[i
]);
100 pColRow2
[i
] = pReadAcc
->GetColor(pRows
[1], pColm
[i
]);
101 pColRow3
[i
] = pReadAcc
->GetColor(pRows
[2], pColm
[i
]);
105 // do median filtering
106 for (nY
= 0; nY
< nHeight
;)
108 Scanline pScanline
= pWriteAcc
->GetScanline(nY
);
109 for (nX
= 0; nX
< nWidth
; nX
++)
111 pColor
= pRowTmp1
+ nX
;
112 nR1
= pColor
->GetRed();
113 nG1
= pColor
->GetGreen();
114 nB1
= pColor
->GetBlue();
115 nR2
= (++pColor
)->GetRed();
116 nG2
= pColor
->GetGreen();
117 nB2
= pColor
->GetBlue();
118 nR3
= (++pColor
)->GetRed();
119 nG3
= pColor
->GetGreen();
120 nB3
= pColor
->GetBlue();
122 pColor
= pRowTmp2
+ nX
;
123 nR4
= pColor
->GetRed();
124 nG4
= pColor
->GetGreen();
125 nB4
= pColor
->GetBlue();
126 nR5
= (++pColor
)->GetRed();
127 nG5
= pColor
->GetGreen();
128 nB5
= pColor
->GetBlue();
129 nR6
= (++pColor
)->GetRed();
130 nG6
= pColor
->GetGreen();
131 nB6
= pColor
->GetBlue();
133 pColor
= pRowTmp3
+ nX
;
134 nR7
= pColor
->GetRed();
135 nG7
= pColor
->GetGreen();
136 nB7
= pColor
->GetBlue();
137 nR8
= (++pColor
)->GetRed();
138 nG8
= pColor
->GetGreen();
139 nB8
= pColor
->GetBlue();
140 nR9
= (++pColor
)->GetRed();
141 nG9
= pColor
->GetGreen();
142 nB9
= pColor
->GetBlue();
144 MNMX6(nR1
, nR2
, nR3
, nR4
, nR5
, nR6
);
145 MNMX5(nR7
, nR2
, nR3
, nR4
, nR5
);
146 MNMX4(nR8
, nR2
, nR3
, nR4
);
147 MNMX3(nR9
, nR2
, nR3
);
149 MNMX6(nG1
, nG2
, nG3
, nG4
, nG5
, nG6
);
150 MNMX5(nG7
, nG2
, nG3
, nG4
, nG5
);
151 MNMX4(nG8
, nG2
, nG3
, nG4
);
152 MNMX3(nG9
, nG2
, nG3
);
154 MNMX6(nB1
, nB2
, nB3
, nB4
, nB5
, nB6
);
155 MNMX5(nB7
, nB2
, nB3
, nB4
, nB5
);
156 MNMX4(nB8
, nB2
, nB3
, nB4
);
157 MNMX3(nB9
, nB2
, nB3
);
159 // set destination color
160 pWriteAcc
->SetPixelOnData(pScanline
, nX
,
161 BitmapColor(static_cast<sal_uInt8
>(nR2
),
162 static_cast<sal_uInt8
>(nG2
),
163 static_cast<sal_uInt8
>(nB2
)));
168 if (pRowTmp1
== pColRow1
.get())
170 pRowTmp1
= pColRow2
.get();
171 pRowTmp2
= pColRow3
.get();
172 pRowTmp3
= pColRow1
.get();
174 else if (pRowTmp1
== pColRow2
.get())
176 pRowTmp1
= pColRow3
.get();
177 pRowTmp2
= pColRow1
.get();
178 pRowTmp3
= pColRow2
.get();
182 pRowTmp1
= pColRow1
.get();
183 pRowTmp2
= pColRow2
.get();
184 pRowTmp3
= pColRow3
.get();
187 for (i
= 0; i
< nWidth2
; i
++)
188 pRowTmp3
[i
] = pReadAcc
->GetColor(pRows
[nY
+ 2], pColm
[i
]);
201 const MapMode
aMap(aBitmap
.GetPrefMapMode());
202 const Size
aPrefSize(aBitmap
.GetPrefSize());
206 aBitmap
.SetPrefMapMode(aMap
);
207 aBitmap
.SetPrefSize(aPrefSize
);
212 return BitmapEx(aBitmap
);
217 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */