Version 6.4.0.0.beta1, tag libreoffice-6.4.0.0.beta1
[LibreOffice.git] / vcl / source / bitmap / BitmapEmbossGreyFilter.cxx
blob4ea239b1a5497c6cbc3d8d435511f2c88cc633cd
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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/.
9 */
11 #include <sal/config.h>
13 #include <algorithm>
15 #include <tools/helpers.hxx>
16 #include <vcl/bitmap.hxx>
17 #include <vcl/bitmapex.hxx>
18 #include <vcl/bitmapaccess.hxx>
19 #include <vcl/BitmapEmbossGreyFilter.hxx>
21 #include <bitmapwriteaccess.hxx>
23 BitmapEx BitmapEmbossGreyFilter::execute(BitmapEx const& rBitmapEx) const
25 Bitmap aBitmap(rBitmapEx.GetBitmap());
27 bool bRet = aBitmap.ImplMakeGreyscales(256);
29 if (bRet)
31 bRet = false;
33 Bitmap::ScopedReadAccess pReadAcc(aBitmap);
35 if (pReadAcc)
37 Bitmap aNewBmp(aBitmap.GetSizePixel(), 8, &pReadAcc->GetPalette());
38 BitmapScopedWriteAccess pWriteAcc(aNewBmp);
40 if (pWriteAcc)
42 BitmapColor aGrey(sal_uInt8(0));
43 const long nWidth = pWriteAcc->Width();
44 const long nHeight = pWriteAcc->Height();
45 long nGrey11, nGrey12, nGrey13;
46 long nGrey21, nGrey22, nGrey23;
47 long nGrey31, nGrey32, nGrey33;
48 double fAzim = basegfx::deg2rad(mnAzimuthAngle100 * 0.01);
49 double fElev = basegfx::deg2rad(mnElevationAngle100 * 0.01);
50 std::unique_ptr<long[]> pHMap(new long[nWidth + 2]);
51 std::unique_ptr<long[]> pVMap(new long[nHeight + 2]);
52 long nX, nY, nNx, nNy, nDotL;
53 const long nLx = FRound(cos(fAzim) * cos(fElev) * 255.0);
54 const long nLy = FRound(sin(fAzim) * cos(fElev) * 255.0);
55 const long nLz = FRound(sin(fElev) * 255.0);
56 const auto nZ2 = ((6 * 255) / 4) * ((6 * 255) / 4);
57 const long nNzLz = ((6 * 255) / 4) * nLz;
58 const sal_uInt8 cLz = static_cast<sal_uInt8>(std::clamp(nLz, 0L, 255L));
60 // fill mapping tables
61 pHMap[0] = 0;
63 for (nX = 1; nX <= nWidth; nX++)
65 pHMap[nX] = nX - 1;
68 pHMap[nWidth + 1] = nWidth - 1;
70 pVMap[0] = 0;
72 for (nY = 1; nY <= nHeight; nY++)
74 pVMap[nY] = nY - 1;
77 pVMap[nHeight + 1] = nHeight - 1;
79 for (nY = 0; nY < nHeight; nY++)
81 nGrey11 = pReadAcc->GetPixel(pVMap[nY], pHMap[0]).GetIndex();
82 nGrey12 = pReadAcc->GetPixel(pVMap[nY], pHMap[1]).GetIndex();
83 nGrey13 = pReadAcc->GetPixel(pVMap[nY], pHMap[2]).GetIndex();
84 nGrey21 = pReadAcc->GetPixel(pVMap[nY + 1], pHMap[0]).GetIndex();
85 nGrey22 = pReadAcc->GetPixel(pVMap[nY + 1], pHMap[1]).GetIndex();
86 nGrey23 = pReadAcc->GetPixel(pVMap[nY + 1], pHMap[2]).GetIndex();
87 nGrey31 = pReadAcc->GetPixel(pVMap[nY + 2], pHMap[0]).GetIndex();
88 nGrey32 = pReadAcc->GetPixel(pVMap[nY + 2], pHMap[1]).GetIndex();
89 nGrey33 = pReadAcc->GetPixel(pVMap[nY + 2], pHMap[2]).GetIndex();
91 Scanline pScanline = pWriteAcc->GetScanline(nY);
92 for (nX = 0; nX < nWidth; nX++)
94 nNx = nGrey11 + nGrey21 + nGrey31 - nGrey13 - nGrey23 - nGrey33;
95 nNy = nGrey31 + nGrey32 + nGrey33 - nGrey11 - nGrey12 - nGrey13;
97 if (!nNx && !nNy)
99 aGrey.SetIndex(cLz);
101 else if ((nDotL = nNx * nLx + nNy * nLy + nNzLz) < 0)
103 aGrey.SetIndex(0);
105 else
107 const double fGrey
108 = nDotL / sqrt(static_cast<double>(nNx * nNx + nNy * nNy + nZ2));
109 aGrey.SetIndex(static_cast<sal_uInt8>(std::clamp(fGrey, 0.0, 255.0)));
112 pWriteAcc->SetPixelOnData(pScanline, nX, aGrey);
114 if (nX < (nWidth - 1))
116 const long nNextX = pHMap[nX + 3];
118 nGrey11 = nGrey12;
119 nGrey12 = nGrey13;
120 nGrey13 = pReadAcc->GetPixel(pVMap[nY], nNextX).GetIndex();
121 nGrey21 = nGrey22;
122 nGrey22 = nGrey23;
123 nGrey23 = pReadAcc->GetPixel(pVMap[nY + 1], nNextX).GetIndex();
124 nGrey31 = nGrey32;
125 nGrey32 = nGrey33;
126 nGrey33 = pReadAcc->GetPixel(pVMap[nY + 2], nNextX).GetIndex();
131 pHMap.reset();
132 pVMap.reset();
133 pWriteAcc.reset();
134 bRet = true;
137 pReadAcc.reset();
139 if (bRet)
141 const MapMode aMap(aBitmap.GetPrefMapMode());
142 const Size aPrefSize(aBitmap.GetPrefSize());
144 aBitmap = aNewBmp;
146 aBitmap.SetPrefMapMode(aMap);
147 aBitmap.SetPrefSize(aPrefSize);
152 if (bRet)
153 return BitmapEx(aBitmap);
155 return BitmapEx();
158 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */