LibreOffice Module vcl (master)  1
BitmapSepiaFilter.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
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/.
8  *
9  */
10 
11 #include <sal/config.h>
12 
13 #include <algorithm>
14 
15 #include <vcl/bitmap.hxx>
16 #include <vcl/bitmapex.hxx>
17 #include <vcl/bitmapaccess.hxx>
19 
20 #include <bitmapwriteaccess.hxx>
21 
23 {
24  Bitmap aBitmap(rBitmapEx.GetBitmap());
25  Bitmap::ScopedReadAccess pReadAcc(aBitmap);
26  bool bRet = false;
27 
28  if (pReadAcc)
29  {
30  const long nSepia
31  = 10000 - 100 * std::clamp(mnSepiaPercent, sal_uInt16(0), sal_uInt16(100));
32  BitmapPalette aSepiaPal(256);
33 
34  for (sal_uInt16 i = 0; i < 256; i++)
35  {
36  BitmapColor& rCol = aSepiaPal[i];
37  const sal_uInt8 cSepiaValue = static_cast<sal_uInt8>(nSepia * i / 10000);
38 
39  rCol.SetRed(static_cast<sal_uInt8>(i));
40  rCol.SetGreen(cSepiaValue);
41  rCol.SetBlue(cSepiaValue);
42  }
43 
44  Bitmap aNewBmp(aBitmap.GetSizePixel(), 8, &aSepiaPal);
45  BitmapScopedWriteAccess pWriteAcc(aNewBmp);
46 
47  if (pWriteAcc)
48  {
49  BitmapColor aCol(sal_uInt8(0));
50  const long nWidth = pWriteAcc->Width();
51  const long nHeight = pWriteAcc->Height();
52 
53  if (pReadAcc->HasPalette())
54  {
55  const sal_uInt16 nPalCount = pReadAcc->GetPaletteEntryCount();
56  std::unique_ptr<sal_uInt8[]> pIndexMap(new sal_uInt8[nPalCount]);
57  for (sal_uInt16 i = 0; i < nPalCount; i++)
58  {
59  pIndexMap[i] = pReadAcc->GetPaletteColor(i).GetLuminance();
60  }
61 
62  for (long nY = 0; nY < nHeight; nY++)
63  {
64  Scanline pScanline = pWriteAcc->GetScanline(nY);
65  Scanline pScanlineRead = pReadAcc->GetScanline(nY);
66  for (long nX = 0; nX < nWidth; nX++)
67  {
68  aCol.SetIndex(pIndexMap[pReadAcc->GetIndexFromData(pScanlineRead, nX)]);
69  pWriteAcc->SetPixelOnData(pScanline, nX, aCol);
70  }
71  }
72  }
73  else
74  {
75  for (long nY = 0; nY < nHeight; nY++)
76  {
77  Scanline pScanline = pWriteAcc->GetScanline(nY);
78  Scanline pScanlineRead = pReadAcc->GetScanline(nY);
79  for (long nX = 0; nX < nWidth; nX++)
80  {
81  aCol.SetIndex(pReadAcc->GetPixelFromData(pScanlineRead, nX).GetLuminance());
82  pWriteAcc->SetPixelOnData(pScanline, nX, aCol);
83  }
84  }
85  }
86 
87  pWriteAcc.reset();
88  bRet = true;
89  }
90 
91  pReadAcc.reset();
92 
93  if (bRet)
94  {
95  const MapMode aMap(aBitmap.GetPrefMapMode());
96  const Size aPrefSize(aBitmap.GetPrefSize());
97 
98  aBitmap = aNewBmp;
99 
100  aBitmap.SetPrefMapMode(aMap);
101  aBitmap.SetPrefSize(aPrefSize);
102  }
103  }
104 
105  if (bRet)
106  return rBitmapEx;
107 
108  return BitmapEx();
109 }
110 
111 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
void SetBlue(sal_uInt8 nBlue)
Bitmap GetBitmap(const Color *pTransReplaceColor=nullptr) const
Definition: bitmapex.cxx:236
sal_uInt8 * Scanline
Definition: Scanline.hxx:25
int i
void SetRed(sal_uInt8 nRed)
void SetIndex(sal_uInt8 cIndex)
Definition: BitmapColor.hxx:66
unsigned char sal_uInt8
void SetGreen(sal_uInt8 nGreen)
virtual BitmapEx execute(BitmapEx const &rBitmapEx) const override