12#include <kpluginfactory.h>
35#include "palettize.moc"
62 const QString md5sum = this->
getString(
"md5sum");
65 return source.bestMatchLoadResult(md5sum,
"",
name) ;
77 resources << this->
palette(globalResourcesInterface);
96 paletteIconWidget->setFixedSize(32, 32);
110 offsetScaleSpinBox->setPrefix(QString(
"%1 ").arg(i18n(
"Offset Scale:")));
111 offsetScaleSpinBox->setRange(0.0, 1.0, 3);
112 offsetScaleSpinBox->setSingleStep(0.125);
119 alphaClipSpinBox->setPrefix(QString(
"%1 ").arg(i18n(
"Clip:")));
120 alphaClipSpinBox->setRange(0.0, 1.0, 3);
121 alphaClipSpinBox->setSingleStep(0.125);
124 alphaIndexSpinBox->setPrefix(QString(
"%1 ").arg(i18nc(
"Index as in Index Color",
"Index:")));
125 alphaIndexSpinBox->setRange(0, 255);
129 alphaIndexSpinBox->setMaximum(palette ?
int(palette->colorCount() - 1) : 0);
130 alphaIndexSpinBox->setValue(std::min(alphaIndexSpinBox->value(), alphaIndexSpinBox->maximum()));
143 colorspaceComboBox->setCurrentIndex(config->
getInt(
"colorspace"));
144 ditherGroupBox->setChecked(config->
getBool(
"ditherEnabled"));
145 ditherWidget->setConfiguration(*config,
"dither/");
146 colorModeComboBox->setCurrentIndex(config->
getInt(
"dither/colorMode"));
147 offsetScaleSpinBox->setValue(config->
getDouble(
"dither/offsetScale"));
148 alphaGroupBox->setChecked(config->
getBool(
"alphaEnabled"));
149 alphaModeComboBox->setCurrentIndex(config->
getInt(
"alphaMode"));
150 alphaClipSpinBox->setValue(config->
getDouble(
"alphaClip"));
151 alphaIndexSpinBox->setValue(config->
getInt(
"alphaIndex"));
152 alphaDitherWidget->setConfiguration(*config,
"alphaDither/");
164 config->setProperty(
"colorspace", colorspaceComboBox->currentIndex());
165 config->setProperty(
"ditherEnabled", ditherGroupBox->isChecked());
166 ditherWidget->configuration(*config,
"dither/");
167 config->setProperty(
"dither/colorMode", colorModeComboBox->currentIndex());
168 config->setProperty(
"dither/offsetScale", offsetScaleSpinBox->value());
169 config->setProperty(
"alphaEnabled", alphaGroupBox->isChecked());
170 config->setProperty(
"alphaMode", alphaModeComboBox->currentIndex());
171 config->setProperty(
"alphaClip", alphaClipSpinBox->value());
172 config->setProperty(
"alphaIndex", alphaIndexSpinBox->value());
173 alphaDitherWidget->configuration(*config,
"alphaDither/");
181 Q_UNUSED(useForMasks);
207 config->setProperty(
"palette",
"Default");
209 config->setProperty(
"ditherEnabled",
false);
212 config->setProperty(
"dither/offsetScale", 0.125);
213 config->setProperty(
"alphaEnabled",
true);
215 config->setProperty(
"alphaClip", 0.5);
216 config->setProperty(
"alphaIndex", 0);
230 const int searchColorspace = config->
getInt(
"colorspace");
231 const bool ditherEnabled = config->
getBool(
"ditherEnabled");
232 const int colorMode = config->
getInt(
"dither/colorMode");
233 const double offsetScale = config->
getDouble(
"dither/offsetScale");
234 const bool alphaEnabled = config->
getBool(
"alphaEnabled");
235 const int alphaMode = config->
getInt(
"alphaMode");
236 const double alphaClip = config->
getDouble(
"alphaClip");
237 const int alphaIndex = config->
getInt(
"alphaIndex");
246 using SearchColor = boost::geometry::model::point<quint16, 3, boost::geometry::cs::cartesian>;
247 struct ColorCandidate {
252 using SearchEntry = std::pair<SearchColor, ColorCandidate>;
253 boost::geometry::index::rtree<SearchEntry, boost::geometry::index::quadratic<16>> rtree;
258 for (
int row = 0; row < palette->rowCount(); ++row) {
259 for (
int column = 0; column < palette->columnCount(); ++column) {
260 KisSwatch swatch = palette->getColorGlobal(column, row);
264 SearchColor searchColor;
265 memcpy(&searchColor, workColor.
data(),
sizeof(SearchColor));
267 std::vector<SearchEntry> result;
268 rtree.query(boost::geometry::index::contains(searchColor), std::back_inserter(result));
269 if (result.empty()) rtree.insert(SearchEntry(searchColor, {color, index, 0.0}));
287 double threshold = 0.5;
289 threshold = ditherUtil.
threshold(QPoint(pixel.
x(), pixel.
y()));
295 for (
int channel = 0; channel < int(workColorspace->
channelCount()); ++channel) {
296 normalized[channel] += (threshold - 0.5) * offsetScale;
303 SearchColor searchColor;
304 memcpy(
reinterpret_cast<quint8 *
>(&searchColor), workColor.
data(),
sizeof(SearchColor));
305 std::vector<ColorCandidate> candidateColors;
306 candidateColors.reserve(
size_t(colorCount));
307 double distanceSum = 0.0;
308 for (
auto it = rtree.qbegin(boost::geometry::index::nearest(searchColor, colorCount)); it != rtree.qend() && candidateColors.size() < colorCount; ++it) {
309 ColorCandidate candidate = it->second;
310 candidate.distance = boost::geometry::distance(searchColor, it->first);
311 candidateColors.push_back(candidate);
312 distanceSum += candidate.distance;
319 const bool swap = candidateColors[0].index > candidateColors[1].index;
320 selected = swap ^ (candidateColors[swap].distance / distanceSum > threshold);
325 ColorCandidate &candidate = candidateColors[selected];
329 double newAlpha = oldAlpha;
332 newAlpha = oldAlpha < alphaClip? 0.0 : 1.0;
335 newAlpha = (candidate.index == alphaIndex ? 0.0 : 1.0);
338 newAlpha = oldAlpha < alphaDitherUtil.
threshold(QPoint(pixel.
x(), pixel.
y())) ? 0.0 : 1.0;
341 colorspace->setOpacity(candidate.color.data(), newAlpha, 1);
KisMagneticGraph::vertex_descriptor source(typename KisMagneticGraph::edge_descriptor e, KisMagneticGraph g)
qreal distance(const QPointF &p1, const QPointF &p2)
qreal threshold(const QPoint &pos)
void setConfiguration(const KisFilterConfiguration &config, const QString &prefix="")
KisFilterPalettizeConfiguration(const QString &name, qint32 version, KisResourcesInterfaceSP resourcesInterface)
KisFilterPalettizeConfiguration(const KisFilterPalettizeConfiguration &rhs)
KoResourceLoadResult palette(KisResourcesInterfaceSP resourcesInterface) const
KoColorSetSP palette() const
virtual KisFilterConfigurationSP clone() const override
QList< KoResourceLoadResult > linkedResources(KisResourcesInterfaceSP globalResourcesInterface) const override
KisConfigWidget * createConfigurationWidget(QWidget *parent, const KisPaintDeviceSP dev, bool useForMasks) const override
KisFilterConfigurationSP factoryConfiguration(KisResourcesInterfaceSP resourcesInterface) const override
KisFilterConfigurationSP defaultConfiguration(KisResourcesInterfaceSP resourcesInterface) const override
void processImpl(KisPaintDeviceSP device, const QRect &applyRect, const KisFilterConfigurationSP config, KoUpdater *progressUpdater) const override
void add(KisFilterSP item)
static KisFilterRegistry * instance()
static KisResourcesInterfaceSP instance()
const KoColorSpace * colorSpace() const
void setCurrentResource(KoResourceSP resource)
Sets the item representing the resource as selected.
KoResourceSP currentResource
void resourceSelected(KoResourceSP resource)
Emitted when a resource was selected.
ALWAYS_INLINE quint8 * rawData()
ALWAYS_INLINE int x() const
ALWAYS_INLINE const quint8 * oldRawData() const
ALWAYS_INLINE int y() const
virtual quint32 channelCount() const =0
virtual void normalisedChannelsValue(const quint8 *pixel, QVector< float > &channels) const =0
virtual void fromNormalisedChannelsValue(quint8 *pixel, const QVector< float > &values) const =0
void convertTo(const KoColorSpace *cs, KoColorConversionTransformation::Intent renderingIntent, KoColorConversionTransformation::ConversionFlags conversionFlags)
KoColor convertedTo(const KoColorSpace *cs, KoColorConversionTransformation::Intent renderingIntent, KoColorConversionTransformation::ConversionFlags conversionFlags) const
T get(const QString &id) const
Palettize(QObject *parent, const QVariantList &)
K_PLUGIN_FACTORY_WITH_JSON(KritaASCCDLFactory, "kritaasccdl.json", registerPlugin< KritaASCCDL >();) KritaASCCDL
#define KIS_SAFE_ASSERT_RECOVER_RETURN(cond)
#define KIS_SAFE_ASSERT_RECOVER_NOOP(cond)
const KoID FiltersCategoryMapId("map_filters", ki18nc("The category of mapping filters, like bump map or gradient filter map. Verb.", "Map"))
void setShowConfigurationWidget(bool v)
virtual KisFilterConfigurationSP factoryConfiguration(KisResourcesInterfaceSP resourcesInterface) const
void setSupportsPainting(bool v)
void setColorSpaceIndependence(ColorSpaceIndependence v)
bool hasLocalResourcesSnapshot() const
KisResourcesInterfaceSP resourcesInterface
QString getString(const QString &name, const QString &def=QString()) const
bool getBool(const QString &name, bool def=false) const
int getInt(const QString &name, int def=0) const
double getDouble(const QString &name, double def=0.0) const
const KoColorSpace * lab16(const QString &profileName=QString())
static KoColorSpaceRegistry * instance()
const KoColorSpace * rgb16(const QString &profileName=QString())