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/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <config_features.h>
22 #include <sal/log.hxx>
23 #include <osl/diagnose.h>
25 #include <tools/helpers.hxx>
27 #include <vcl/BitmapPalette.hxx>
28 #include <vcl/bitmapex.hxx>
29 #include <vcl/outdev.hxx>
32 #include <salinst.hxx>
34 class ImplBitmapPalette
37 ImplBitmapPalette(std::initializer_list
<BitmapColor
> aBitmapColor
)
38 : maBitmapColor(aBitmapColor
)
41 ImplBitmapPalette(const BitmapColor
* first
, const BitmapColor
* last
)
42 : maBitmapColor(first
, last
)
45 ImplBitmapPalette() {}
46 ImplBitmapPalette(sal_uInt16 nCount
)
47 : maBitmapColor(nCount
)
50 std::vector
<BitmapColor
>& GetBitmapData() { return maBitmapColor
; }
51 const std::vector
<BitmapColor
>& GetBitmapData() const { return maBitmapColor
; }
52 bool operator==(const ImplBitmapPalette
& rBitmapPalette
) const
54 return maBitmapColor
== rBitmapPalette
.maBitmapColor
;
58 std::vector
<BitmapColor
> maBitmapColor
;
63 BitmapPalette::ImplType
& GetGlobalDefault()
65 static BitmapPalette::ImplType gDefault
;
70 BitmapPalette::BitmapPalette()
71 : mpImpl(GetGlobalDefault())
75 BitmapPalette::BitmapPalette(const BitmapPalette
& rOther
)
76 : mpImpl(rOther
.mpImpl
)
80 BitmapPalette::BitmapPalette(BitmapPalette
&& rOther
) noexcept
81 : mpImpl(std::move(rOther
.mpImpl
))
85 BitmapPalette::BitmapPalette(std::initializer_list
<BitmapColor
> aBitmapColor
)
86 : mpImpl(aBitmapColor
)
90 BitmapPalette::BitmapPalette(const BitmapColor
* first
, const BitmapColor
* last
)
91 : mpImpl({ first
, last
})
95 BitmapPalette::BitmapPalette(sal_uInt16 nCount
)
100 BitmapPalette::~BitmapPalette() {}
102 BitmapPalette
& BitmapPalette::operator=(const BitmapPalette
& rOther
)
104 mpImpl
= rOther
.mpImpl
;
108 BitmapPalette
& BitmapPalette::operator=(BitmapPalette
&& rOther
) noexcept
110 mpImpl
= std::move(rOther
.mpImpl
);
114 const BitmapColor
* BitmapPalette::ImplGetColorBuffer() const
116 return mpImpl
->GetBitmapData().data();
119 BitmapColor
* BitmapPalette::ImplGetColorBuffer() { return mpImpl
->GetBitmapData().data(); }
121 BitmapChecksum
BitmapPalette::GetChecksum() const
123 auto const& rBitmapData
= mpImpl
->GetBitmapData();
124 return rtl_crc32(0, rBitmapData
.data(), rBitmapData
.size() * sizeof(BitmapColor
));
127 bool BitmapPalette::operator==(const BitmapPalette
& rOther
) const
129 return mpImpl
== rOther
.mpImpl
;
132 bool BitmapPalette::operator!() const { return mpImpl
->GetBitmapData().empty(); }
134 sal_uInt16
BitmapPalette::GetEntryCount() const { return mpImpl
->GetBitmapData().size(); }
136 void BitmapPalette::SetEntryCount(sal_uInt16 nCount
) { mpImpl
->GetBitmapData().resize(nCount
); }
138 const BitmapColor
& BitmapPalette::operator[](sal_uInt16 nIndex
) const
140 assert(nIndex
< mpImpl
->GetBitmapData().size() && "Palette index is out of range");
141 return mpImpl
->GetBitmapData()[nIndex
];
144 BitmapColor
& BitmapPalette::operator[](sal_uInt16 nIndex
)
146 assert(nIndex
< mpImpl
->GetBitmapData().size() && "Palette index is out of range");
147 return mpImpl
->GetBitmapData()[nIndex
];
150 /// Returns the BitmapColor (i.e. palette index) that is either an exact match
151 /// of the required color, or failing that, the entry that is the closest i.e. least error
152 /// as measured by Color::GetColorError.
153 sal_uInt16
BitmapPalette::GetBestIndex(const BitmapColor
& rCol
) const
155 auto const& rBitmapColor
= mpImpl
->GetBitmapData();
156 sal_uInt16 nRetIndex
= 0;
158 if (!rBitmapColor
.empty())
160 for (size_t j
= 0; j
< rBitmapColor
.size(); ++j
)
162 if (rCol
== rBitmapColor
[j
])
168 sal_uInt16 nLastErr
= SAL_MAX_UINT16
;
169 for (size_t i
= 0; i
< rBitmapColor
.size(); ++i
)
171 const sal_uInt16 nActErr
= rCol
.GetColorError(rBitmapColor
[i
]);
172 if (nActErr
< nLastErr
)
183 /// Returns the BitmapColor (i.e. palette index) that is an exact match
184 /// of the required color. Returns SAL_MAX_UINT16 if nothing found.
185 sal_uInt16
BitmapPalette::GetMatchingIndex(const BitmapColor
& rCol
) const
187 auto const& rBitmapColor
= mpImpl
->GetBitmapData();
189 for (size_t j
= 0; j
< rBitmapColor
.size(); ++j
)
191 if (rCol
== rBitmapColor
[j
])
197 return SAL_MAX_UINT16
;
200 bool BitmapPalette::IsGreyPaletteAny() const
202 auto const& rBitmapColor
= mpImpl
->GetBitmapData();
203 const int nEntryCount
= GetEntryCount();
204 if (!nEntryCount
) // NOTE: an empty palette means 1:1 mapping
206 // See above: only certain entry values will result in a valid call to GetGreyPalette
207 if (nEntryCount
== 2 || nEntryCount
== 4 || nEntryCount
== 16 || nEntryCount
== 256)
209 const BitmapPalette
& rGreyPalette
= Bitmap::GetGreyPalette(nEntryCount
);
210 if (rGreyPalette
== *this)
215 // TODO: is it worth to compare the entries for the general case?
216 if (nEntryCount
== 2)
218 const BitmapColor
& rCol0(rBitmapColor
[0]);
219 const BitmapColor
& rCol1(rBitmapColor
[1]);
220 bRet
= rCol0
.GetRed() == rCol0
.GetGreen() && rCol0
.GetRed() == rCol0
.GetBlue()
221 && rCol1
.GetRed() == rCol1
.GetGreen() && rCol1
.GetRed() == rCol1
.GetBlue();
226 bool BitmapPalette::IsGreyPalette8Bit() const
228 auto const& rBitmapColor
= mpImpl
->GetBitmapData();
229 const int nEntryCount
= GetEntryCount();
230 if (!nEntryCount
) // NOTE: an empty palette means 1:1 mapping
232 if (nEntryCount
!= 256)
234 for (sal_uInt16 i
= 0; i
< 256; ++i
)
236 if (rBitmapColor
[i
] != BitmapColor(i
, i
, i
))
242 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */