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 <tools/helpers.hxx>
12 #include <vcl/bitmap.hxx>
13 #include <vcl/bitmapex.hxx>
14 #include <vcl/bitmapaccess.hxx>
15 #include <vcl/BitmapConvolutionMatrixFilter.hxx>
16 #include <vcl/BitmapSharpenFilter.hxx>
18 #include <bitmapwriteaccess.hxx>
21 BitmapEx
BitmapConvolutionMatrixFilter::execute(BitmapEx
const& rBitmapEx
) const
23 Bitmap
aBitmap(rBitmapEx
.GetBitmap());
25 const long nDivisor
= 8;
26 Bitmap::ScopedReadAccess
pReadAcc(aBitmap
);
31 Bitmap
aNewBmp(aBitmap
.GetSizePixel(), 24);
32 BitmapScopedWriteAccess
pWriteAcc(aNewBmp
);
36 const long nWidth
= pWriteAcc
->Width(), nWidth2
= nWidth
+ 2;
37 const long nHeight
= pWriteAcc
->Height(), nHeight2
= nHeight
+ 2;
38 std::unique_ptr
<long[]> pColm(new long[nWidth2
]);
39 std::unique_ptr
<long[]> pRows(new long[nHeight2
]);
40 std::unique_ptr
<BitmapColor
[]> pColRow1(new BitmapColor
[nWidth2
]);
41 std::unique_ptr
<BitmapColor
[]> pColRow2(new BitmapColor
[nWidth2
]);
42 std::unique_ptr
<BitmapColor
[]> pColRow3(new BitmapColor
[nWidth2
]);
43 BitmapColor
* pRowTmp1
= pColRow1
.get();
44 BitmapColor
* pRowTmp2
= pColRow2
.get();
45 BitmapColor
* pRowTmp3
= pColRow3
.get();
47 long nY
, nX
, i
, nSumR
, nSumG
, nSumB
, nMatrixVal
, nTmp
;
48 std::array
<std::array
<long, 256>, 9> aKoeff
;
51 // create LUT of products of matrix value and possible color component values
52 for (nY
= 0; nY
< 9; nY
++)
54 for (nX
= nTmp
= 0, nMatrixVal
= mrMatrix
[nY
]; nX
< 256; nX
++, nTmp
+= nMatrixVal
)
56 aKoeff
[nY
][nX
] = nTmp
;
61 for (i
= 0; i
< nWidth2
; i
++)
63 pColm
[i
] = (i
> 0) ? (i
- 1) : 0;
66 pColm
[nWidth
+ 1] = pColm
[nWidth
];
69 for (i
= 0; i
< nHeight2
; i
++)
71 pRows
[i
] = (i
> 0) ? (i
- 1) : 0;
74 pRows
[nHeight
+ 1] = pRows
[nHeight
];
76 // read first three rows of bitmap color
77 for (i
= 0; i
< nWidth2
; i
++)
79 pColRow1
[i
] = pReadAcc
->GetColor(pRows
[0], pColm
[i
]);
80 pColRow2
[i
] = pReadAcc
->GetColor(pRows
[1], pColm
[i
]);
81 pColRow3
[i
] = pReadAcc
->GetColor(pRows
[2], pColm
[i
]);
85 for (nY
= 0; nY
< nHeight
;)
87 Scanline pScanline
= pWriteAcc
->GetScanline(nY
);
88 for (nX
= 0; nX
< nWidth
; nX
++)
91 pTmp
= aKoeff
[0].data();
92 pColor
= pRowTmp1
+ nX
;
93 nSumR
= pTmp
[pColor
->GetRed()];
94 nSumG
= pTmp
[pColor
->GetGreen()];
95 nSumB
= pTmp
[pColor
->GetBlue()];
97 pTmp
= aKoeff
[1].data();
98 nSumR
+= pTmp
[(++pColor
)->GetRed()];
99 nSumG
+= pTmp
[pColor
->GetGreen()];
100 nSumB
+= pTmp
[pColor
->GetBlue()];
102 pTmp
= aKoeff
[2].data();
103 nSumR
+= pTmp
[(++pColor
)->GetRed()];
104 nSumG
+= pTmp
[pColor
->GetGreen()];
105 nSumB
+= pTmp
[pColor
->GetBlue()];
108 pTmp
= aKoeff
[3].data();
109 pColor
= pRowTmp2
+ nX
;
110 nSumR
+= pTmp
[pColor
->GetRed()];
111 nSumG
+= pTmp
[pColor
->GetGreen()];
112 nSumB
+= pTmp
[pColor
->GetBlue()];
114 pTmp
= aKoeff
[4].data();
115 nSumR
+= pTmp
[(++pColor
)->GetRed()];
116 nSumG
+= pTmp
[pColor
->GetGreen()];
117 nSumB
+= pTmp
[pColor
->GetBlue()];
119 pTmp
= aKoeff
[5].data();
120 nSumR
+= pTmp
[(++pColor
)->GetRed()];
121 nSumG
+= pTmp
[pColor
->GetGreen()];
122 nSumB
+= pTmp
[pColor
->GetBlue()];
125 pTmp
= aKoeff
[6].data();
126 pColor
= pRowTmp3
+ nX
;
127 nSumR
+= pTmp
[pColor
->GetRed()];
128 nSumG
+= pTmp
[pColor
->GetGreen()];
129 nSumB
+= pTmp
[pColor
->GetBlue()];
131 pTmp
= aKoeff
[7].data();
132 nSumR
+= pTmp
[(++pColor
)->GetRed()];
133 nSumG
+= pTmp
[pColor
->GetGreen()];
134 nSumB
+= pTmp
[pColor
->GetBlue()];
136 pTmp
= aKoeff
[8].data();
137 nSumR
+= pTmp
[(++pColor
)->GetRed()];
138 nSumG
+= pTmp
[pColor
->GetGreen()];
139 nSumB
+= pTmp
[pColor
->GetBlue()];
141 // calculate destination color
142 pWriteAcc
->SetPixelOnData(
144 BitmapColor(static_cast<sal_uInt8
>(MinMax(nSumR
/ nDivisor
, 0, 255)),
145 static_cast<sal_uInt8
>(MinMax(nSumG
/ nDivisor
, 0, 255)),
146 static_cast<sal_uInt8
>(MinMax(nSumB
/ nDivisor
, 0, 255))));
151 if (pRowTmp1
== pColRow1
.get())
153 pRowTmp1
= pColRow2
.get();
154 pRowTmp2
= pColRow3
.get();
155 pRowTmp3
= pColRow1
.get();
157 else if (pRowTmp1
== pColRow2
.get())
159 pRowTmp1
= pColRow3
.get();
160 pRowTmp2
= pColRow1
.get();
161 pRowTmp3
= pColRow2
.get();
165 pRowTmp1
= pColRow1
.get();
166 pRowTmp2
= pColRow2
.get();
167 pRowTmp3
= pColRow3
.get();
170 for (i
= 0; i
< nWidth2
; i
++)
172 pRowTmp3
[i
] = pReadAcc
->GetColor(pRows
[nY
+ 2], pColm
[i
]);
186 const MapMode
aMap(aBitmap
.GetPrefMapMode());
187 const Size
aPrefSize(aBitmap
.GetPrefSize());
191 aBitmap
.SetPrefMapMode(aMap
);
192 aBitmap
.SetPrefSize(aPrefSize
);
197 return BitmapEx(aBitmap
);
202 static const long g_SharpenMatrix
[] = { -1, -1, -1, -1, 16, -1, -1, -1, -1 };
204 BitmapSharpenFilter::BitmapSharpenFilter()
205 : BitmapConvolutionMatrixFilter(g_SharpenMatrix
)
208 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */