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 <sal/config.h>
15 #include <vcl/bitmap.hxx>
16 #include <vcl/bitmapex.hxx>
17 #include <vcl/bitmapaccess.hxx>
18 #include <vcl/BitmapSobelGreyFilter.hxx>
20 #include <bitmapwriteaccess.hxx>
22 BitmapEx
BitmapSobelGreyFilter::execute(BitmapEx
const& rBitmapEx
) const
24 Bitmap
aBitmap(rBitmapEx
.GetBitmap());
26 bool bRet
= aBitmap
.ImplMakeGreyscales(256);
32 Bitmap::ScopedReadAccess
pReadAcc(aBitmap
);
36 Bitmap
aNewBmp(aBitmap
.GetSizePixel(), 8, &pReadAcc
->GetPalette());
37 BitmapScopedWriteAccess
pWriteAcc(aNewBmp
);
41 BitmapColor
aGrey(sal_uInt8(0));
42 const tools::Long nWidth
= pWriteAcc
->Width();
43 const tools::Long nHeight
= pWriteAcc
->Height();
44 const tools::Long nMask111
= -1, nMask121
= 0, nMask131
= 1;
45 const tools::Long nMask211
= -2, nMask221
= 0, nMask231
= 2;
46 const tools::Long nMask311
= -1, nMask321
= 0, nMask331
= 1;
47 const tools::Long nMask112
= 1, nMask122
= 2, nMask132
= 1;
48 const tools::Long nMask212
= 0, nMask222
= 0, nMask232
= 0;
49 const tools::Long nMask312
= -1, nMask322
= -2, nMask332
= -1;
50 tools::Long nGrey11
, nGrey12
, nGrey13
;
51 tools::Long nGrey21
, nGrey22
, nGrey23
;
52 tools::Long nGrey31
, nGrey32
, nGrey33
;
53 std::unique_ptr
<long[]> pHMap(new long[nWidth
+ 2]);
54 std::unique_ptr
<long[]> pVMap(new long[nHeight
+ 2]);
55 tools::Long nX
, nY
, nSum1
, nSum2
;
57 // fill mapping tables
60 for (nX
= 1; nX
<= nWidth
; nX
++)
65 pHMap
[nWidth
+ 1] = nWidth
- 1;
69 for (nY
= 1; nY
<= nHeight
; nY
++)
74 pVMap
[nHeight
+ 1] = nHeight
- 1;
76 for (nY
= 0; nY
< nHeight
; nY
++)
78 nGrey11
= pReadAcc
->GetPixel(pVMap
[nY
], pHMap
[0]).GetIndex();
79 nGrey12
= pReadAcc
->GetPixel(pVMap
[nY
], pHMap
[1]).GetIndex();
80 nGrey13
= pReadAcc
->GetPixel(pVMap
[nY
], pHMap
[2]).GetIndex();
81 nGrey21
= pReadAcc
->GetPixel(pVMap
[nY
+ 1], pHMap
[0]).GetIndex();
82 nGrey22
= pReadAcc
->GetPixel(pVMap
[nY
+ 1], pHMap
[1]).GetIndex();
83 nGrey23
= pReadAcc
->GetPixel(pVMap
[nY
+ 1], pHMap
[2]).GetIndex();
84 nGrey31
= pReadAcc
->GetPixel(pVMap
[nY
+ 2], pHMap
[0]).GetIndex();
85 nGrey32
= pReadAcc
->GetPixel(pVMap
[nY
+ 2], pHMap
[1]).GetIndex();
86 nGrey33
= pReadAcc
->GetPixel(pVMap
[nY
+ 2], pHMap
[2]).GetIndex();
88 Scanline pScanline
= pWriteAcc
->GetScanline(nY
);
89 for (nX
= 0; nX
< nWidth
; nX
++)
93 nSum1
+= nMask111
* nGrey11
;
94 nSum2
+= nMask112
* nGrey11
;
96 nSum1
+= nMask121
* nGrey12
;
97 nSum2
+= nMask122
* nGrey12
;
99 nSum1
+= nMask131
* nGrey13
;
100 nSum2
+= nMask132
* nGrey13
;
102 nSum1
+= nMask211
* nGrey21
;
103 nSum2
+= nMask212
* nGrey21
;
105 nSum1
+= nMask221
* nGrey22
;
106 nSum2
+= nMask222
* nGrey22
;
108 nSum1
+= nMask231
* nGrey23
;
109 nSum2
+= nMask232
* nGrey23
;
111 nSum1
+= nMask311
* nGrey31
;
112 nSum2
+= nMask312
* nGrey31
;
114 nSum1
+= nMask321
* nGrey32
;
115 nSum2
+= nMask322
* nGrey32
;
117 nSum1
+= nMask331
* nGrey33
;
118 nSum2
+= nMask332
* nGrey33
;
120 nSum1
= static_cast<tools::Long
>(
121 sqrt(static_cast<double>(nSum1
* nSum1
+ nSum2
* nSum2
)));
123 aGrey
.SetIndex(~static_cast<sal_uInt8
>(
124 std::clamp(nSum1
, tools::Long(0), tools::Long(255))));
125 pWriteAcc
->SetPixelOnData(pScanline
, nX
, aGrey
);
127 if (nX
< (nWidth
- 1))
129 const tools::Long nNextX
= pHMap
[nX
+ 3];
133 nGrey13
= pReadAcc
->GetPixel(pVMap
[nY
], nNextX
).GetIndex();
136 nGrey23
= pReadAcc
->GetPixel(pVMap
[nY
+ 1], nNextX
).GetIndex();
139 nGrey33
= pReadAcc
->GetPixel(pVMap
[nY
+ 2], nNextX
).GetIndex();
154 const MapMode
aMap(aBitmap
.GetPrefMapMode());
155 const Size
aPrefSize(aBitmap
.GetPrefSize());
159 aBitmap
.SetPrefMapMode(aMap
);
160 aBitmap
.SetPrefSize(aPrefSize
);
166 return BitmapEx(aBitmap
);
171 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */