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/bitmapaccess.hxx>
14 #include <vcl/BitmapMedianFilter.hxx>
16 #include <bitmapwriteaccess.hxx>
21 if ((t = b - a) < 0) \
27 #define MN3(a, b, c) \
30 #define MX3(a, b, c) \
33 #define MNMX3(a, b, c) \
36 #define MNMX4(a, b, c, d) \
41 #define MNMX5(a, b, c, d, e) \
46 #define MNMX6(a, b, c, d, e, f) \
53 BitmapEx
BitmapMedianFilter::execute(BitmapEx
const& rBitmapEx
) const
55 Bitmap
aBitmap(rBitmapEx
.GetBitmap());
57 Bitmap::ScopedReadAccess
pReadAcc(aBitmap
);
62 Bitmap
aNewBmp(aBitmap
.GetSizePixel(), 24);
63 BitmapScopedWriteAccess
pWriteAcc(aNewBmp
);
67 const long nWidth
= pWriteAcc
->Width(), nWidth2
= nWidth
+ 2;
68 const long nHeight
= pWriteAcc
->Height(), nHeight2
= nHeight
+ 2;
69 std::unique_ptr
<long[]> pColm(new long[nWidth2
]);
70 std::unique_ptr
<long[]> pRows(new long[nHeight2
]);
71 std::unique_ptr
<BitmapColor
[]> pColRow1(new BitmapColor
[nWidth2
]);
72 std::unique_ptr
<BitmapColor
[]> pColRow2(new BitmapColor
[nWidth2
]);
73 std::unique_ptr
<BitmapColor
[]> pColRow3(new BitmapColor
[nWidth2
]);
74 BitmapColor
* pRowTmp1
= pColRow1
.get();
75 BitmapColor
* pRowTmp2
= pColRow2
.get();
76 BitmapColor
* pRowTmp3
= pColRow3
.get();
79 long nR1
, nR2
, nR3
, nR4
, nR5
, nR6
, nR7
, nR8
, nR9
;
80 long nG1
, nG2
, nG3
, nG4
, nG5
, nG6
, nG7
, nG8
, nG9
;
81 long nB1
, nB2
, nB3
, nB4
, nB5
, nB6
, nB7
, nB8
, nB9
;
84 for (i
= 0; i
< nWidth2
; i
++)
85 pColm
[i
] = (i
> 0) ? (i
- 1) : 0;
87 pColm
[nWidth
+ 1] = pColm
[nWidth
];
90 for (i
= 0; i
< nHeight2
; i
++)
91 pRows
[i
] = (i
> 0) ? (i
- 1) : 0;
93 pRows
[nHeight
+ 1] = pRows
[nHeight
];
95 // read first three rows of bitmap color
98 for (i
= 0; i
< nWidth2
; i
++)
100 pColRow1
[i
] = pReadAcc
->GetColor(pRows
[0], pColm
[i
]);
101 pColRow2
[i
] = pReadAcc
->GetColor(pRows
[1], pColm
[i
]);
102 pColRow3
[i
] = pReadAcc
->GetColor(pRows
[2], pColm
[i
]);
106 // do median filtering
107 for (nY
= 0; nY
< nHeight
;)
109 Scanline pScanline
= pWriteAcc
->GetScanline(nY
);
110 for (nX
= 0; nX
< nWidth
; nX
++)
112 pColor
= pRowTmp1
+ nX
;
113 nR1
= pColor
->GetRed();
114 nG1
= pColor
->GetGreen();
115 nB1
= pColor
->GetBlue();
116 nR2
= (++pColor
)->GetRed();
117 nG2
= pColor
->GetGreen();
118 nB2
= pColor
->GetBlue();
119 nR3
= (++pColor
)->GetRed();
120 nG3
= pColor
->GetGreen();
121 nB3
= pColor
->GetBlue();
123 pColor
= pRowTmp2
+ nX
;
124 nR4
= pColor
->GetRed();
125 nG4
= pColor
->GetGreen();
126 nB4
= pColor
->GetBlue();
127 nR5
= (++pColor
)->GetRed();
128 nG5
= pColor
->GetGreen();
129 nB5
= pColor
->GetBlue();
130 nR6
= (++pColor
)->GetRed();
131 nG6
= pColor
->GetGreen();
132 nB6
= pColor
->GetBlue();
134 pColor
= pRowTmp3
+ nX
;
135 nR7
= pColor
->GetRed();
136 nG7
= pColor
->GetGreen();
137 nB7
= pColor
->GetBlue();
138 nR8
= (++pColor
)->GetRed();
139 nG8
= pColor
->GetGreen();
140 nB8
= pColor
->GetBlue();
141 nR9
= (++pColor
)->GetRed();
142 nG9
= pColor
->GetGreen();
143 nB9
= pColor
->GetBlue();
145 MNMX6(nR1
, nR2
, nR3
, nR4
, nR5
, nR6
);
146 MNMX5(nR7
, nR2
, nR3
, nR4
, nR5
);
147 MNMX4(nR8
, nR2
, nR3
, nR4
);
148 MNMX3(nR9
, nR2
, nR3
);
150 MNMX6(nG1
, nG2
, nG3
, nG4
, nG5
, nG6
);
151 MNMX5(nG7
, nG2
, nG3
, nG4
, nG5
);
152 MNMX4(nG8
, nG2
, nG3
, nG4
);
153 MNMX3(nG9
, nG2
, nG3
);
155 MNMX6(nB1
, nB2
, nB3
, nB4
, nB5
, nB6
);
156 MNMX5(nB7
, nB2
, nB3
, nB4
, nB5
);
157 MNMX4(nB8
, nB2
, nB3
, nB4
);
158 MNMX3(nB9
, nB2
, nB3
);
160 // set destination color
161 pWriteAcc
->SetPixelOnData(pScanline
, nX
,
162 BitmapColor(static_cast<sal_uInt8
>(nR2
),
163 static_cast<sal_uInt8
>(nG2
),
164 static_cast<sal_uInt8
>(nB2
)));
169 if (pRowTmp1
== pColRow1
.get())
171 pRowTmp1
= pColRow2
.get();
172 pRowTmp2
= pColRow3
.get();
173 pRowTmp3
= pColRow1
.get();
175 else if (pRowTmp1
== pColRow2
.get())
177 pRowTmp1
= pColRow3
.get();
178 pRowTmp2
= pColRow1
.get();
179 pRowTmp3
= pColRow2
.get();
183 pRowTmp1
= pColRow1
.get();
184 pRowTmp2
= pColRow2
.get();
185 pRowTmp3
= pColRow3
.get();
188 for (i
= 0; i
< nWidth2
; i
++)
189 pRowTmp3
[i
] = pReadAcc
->GetColor(pRows
[nY
+ 2], pColm
[i
]);
202 const MapMode
aMap(aBitmap
.GetPrefMapMode());
203 const Size
aPrefSize(aBitmap
.GetPrefSize());
207 aBitmap
.SetPrefMapMode(aMap
);
208 aBitmap
.SetPrefSize(aPrefSize
);
213 return BitmapEx(aBitmap
);
218 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */