File indexing completed on 2024-12-22 04:15:24

0001 /*
0002  *  SPDX-FileCopyrightText: 2014 Manuel Riecke <spell1337@gmail.com>
0003  * 
0004  *  SPDX-License-Identifier: GPL-2.0-or-later
0005  */
0006 
0007 #include "posterize.h"
0008 #include <stdlib.h>
0009 #include <vector>
0010 
0011 #include <QPoint>
0012 #include <QTime>
0013 
0014 #include <klocalizedstring.h>
0015 
0016 #include <kis_debug.h>
0017 #include <kpluginfactory.h>
0018 
0019 #include <kis_processing_information.h>
0020 #include <kis_types.h>
0021 #include <kis_selection.h>
0022 #include <kis_layer.h>
0023 #include <filter/kis_filter_category_ids.h>
0024 #include <filter/kis_filter_registry.h>
0025 #include <kis_global.h>
0026 
0027 #include <KoColorSpaceMaths.h>
0028 #include <filter/kis_color_transformation_configuration.h>
0029 #include <widgets/kis_multi_integer_filter_widget.h>
0030 
0031 K_PLUGIN_FACTORY_WITH_JSON(PosterizeFactory, "kritaposterize.json", registerPlugin<Posterize>();)
0032 
0033 Posterize::Posterize(QObject *parent, const QVariantList &)
0034     : QObject(parent)
0035 {
0036     KisFilterRegistry::instance()->add(KisFilterSP(new KisFilterPosterize()));
0037 }
0038 
0039 Posterize::~Posterize()
0040 {
0041 }
0042 
0043 KisFilterPosterize::KisFilterPosterize() : KisColorTransformationFilter(id(), FiltersCategoryArtisticId, i18n("&Posterize..."))
0044 {
0045     setColorSpaceIndependence(FULLY_INDEPENDENT);
0046     setSupportsPainting(true);
0047     setShowConfigurationWidget(true);
0048 }
0049 
0050 KoColorTransformation* KisFilterPosterize::createTransformation(const KoColorSpace* cs, const KisFilterConfigurationSP config) const
0051 {
0052     return new KisPosterizeColorTransformation(config->getInt("steps", 16), cs);
0053 }
0054 
0055 KisPosterizeColorTransformation::KisPosterizeColorTransformation(int steps, const KoColorSpace* cs) : m_colorSpace(cs), m_psize(cs->pixelSize())
0056 {
0057     m_step = KoColorSpaceMathsTraits<quint16>::max / steps;
0058     m_halfStep = m_step / 2;
0059     m_fromConversion = KoColorSpaceRegistry::instance()->createColorConverter(
0060         m_colorSpace,
0061         KoColorSpaceRegistry::instance()->rgb16("sRGB-elle-V2-srgbtrc.icc"),
0062         KoColorConversionTransformation::internalRenderingIntent(),
0063         KoColorConversionTransformation::internalConversionFlags());
0064     m_toConversion = KoColorSpaceRegistry::instance()->createColorConverter(
0065         KoColorSpaceRegistry::instance()->rgb16("sRGB-elle-V2-srgbtrc.icc"),
0066         m_colorSpace,
0067         KoColorConversionTransformation::internalRenderingIntent(),
0068         KoColorConversionTransformation::internalConversionFlags());
0069 }
0070 
0071 KisPosterizeColorTransformation::~KisPosterizeColorTransformation()
0072 {
0073     delete m_fromConversion;
0074     delete m_toConversion;
0075 }
0076 
0077 KisConfigWidget* KisFilterPosterize::createConfigurationWidget(QWidget* parent, const KisPaintDeviceSP dev, bool) const
0078 {
0079     Q_UNUSED(dev);
0080     vKisIntegerWidgetParam param;
0081     param.push_back(KisIntegerWidgetParam(2, 128, 16, i18n("Steps"), "steps"));
0082     return new KisMultiIntegerFilterWidget(id().id(), parent, id().id(), param);
0083 }
0084 
0085 KisFilterConfigurationSP KisFilterPosterize::defaultConfiguration(KisResourcesInterfaceSP resourcesInterface) const
0086 {
0087     KisFilterConfigurationSP config = factoryConfiguration(resourcesInterface);
0088     config->setProperty("steps", 16);
0089     return config;
0090 }
0091 
0092 void KisPosterizeColorTransformation::transform(const quint8* src, quint8* dst, qint32 nPixels) const
0093 {
0094     quint16 m_rgba[4];
0095     quint16 m_mod[4];
0096 
0097     while (nPixels--) {
0098         m_fromConversion->transform(src, reinterpret_cast<quint8 *>(m_rgba), 1);
0099 
0100         m_mod[0] = m_rgba[0] % m_step;
0101         m_mod[1] = m_rgba[1] % m_step;
0102         m_mod[2] = m_rgba[2] % m_step;
0103         m_mod[3] = m_rgba[3] % m_step;
0104 
0105         m_rgba[0] = m_rgba[0] + (m_mod[0] > m_halfStep ? m_step - m_mod[0] : -m_mod[0]);
0106         m_rgba[1] = m_rgba[1] + (m_mod[1] > m_halfStep ? m_step - m_mod[1] : -m_mod[1]);
0107         m_rgba[2] = m_rgba[2] + (m_mod[2] > m_halfStep ? m_step - m_mod[2] : -m_mod[2]);
0108         m_rgba[3] = m_rgba[3] + (m_mod[3] > m_halfStep ? m_step - m_mod[3] : -m_mod[3]);
0109 
0110         m_toConversion->transform(reinterpret_cast<quint8 *>(m_rgba), dst, 1);
0111         src += m_psize;
0112         dst += m_psize;
0113     }
0114 }
0115 
0116 #include "posterize.moc"