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) {
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"))
rgba palette[MAX_PALETTE]
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())