posterize.cpp 4.61 KB
Newer Older
Halla Rempt's avatar
Halla Rempt committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
/*
 *  Copyright (c) 2014 Manuel Riecke <spell1337@gmail.com>
 * 
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 */

#include "posterize.h"
#include <stdlib.h>
#include <vector>

#include <QPoint>
#include <QTime>

26
#include <klocalizedstring.h>
27

Halla Rempt's avatar
Halla Rempt committed
28 29 30 31 32 33 34
#include <kis_debug.h>
#include <kpluginfactory.h>

#include <kis_processing_information.h>
#include <kis_types.h>
#include <kis_selection.h>
#include <kis_layer.h>
35
#include <filter/kis_filter_category_ids.h>
Halla Rempt's avatar
Halla Rempt committed
36 37 38 39
#include <filter/kis_filter_registry.h>
#include <kis_global.h>

#include <KoColorSpaceMaths.h>
40
#include <filter/kis_color_transformation_configuration.h>
Halla Rempt's avatar
Halla Rempt committed
41 42
#include <widgets/kis_multi_integer_filter_widget.h>

Sven Langkamp's avatar
Sven Langkamp committed
43
K_PLUGIN_FACTORY_WITH_JSON(PosterizeFactory, "kritaposterize.json", registerPlugin<Posterize>();)
Halla Rempt's avatar
Halla Rempt committed
44 45 46 47 48 49 50 51 52 53 54

Posterize::Posterize(QObject *parent, const QVariantList &)
    : QObject(parent)
{
    KisFilterRegistry::instance()->add(KisFilterSP(new KisFilterPosterize()));
}

Posterize::~Posterize()
{
}

55
KisFilterPosterize::KisFilterPosterize() : KisColorTransformationFilter(id(), FiltersCategoryArtisticId, i18n("&Posterize..."))
Halla Rempt's avatar
Halla Rempt committed
56 57 58 59 60 61
{
    setColorSpaceIndependence(FULLY_INDEPENDENT);
    setSupportsPainting(true);
    setShowConfigurationWidget(true);
}

62
KoColorTransformation* KisFilterPosterize::createTransformation(const KoColorSpace* cs, const KisFilterConfigurationSP config) const
Halla Rempt's avatar
Halla Rempt committed
63 64 65 66 67 68 69 70 71 72
{
    return new KisPosterizeColorTransformation(config->getInt("steps", 16), cs);
}

KisPosterizeColorTransformation::KisPosterizeColorTransformation(int steps, const KoColorSpace* cs) : m_colorSpace(cs), m_psize(cs->pixelSize())
{
    m_step = KoColorSpaceMathsTraits<quint16>::max / steps;
    m_halfStep = m_step / 2;
}

73
KisConfigWidget* KisFilterPosterize::createConfigurationWidget(QWidget* parent, const KisPaintDeviceSP dev, bool) const
Halla Rempt's avatar
Halla Rempt committed
74 75 76 77 78 79 80
{
    Q_UNUSED(dev);
    vKisIntegerWidgetParam param;
    param.push_back(KisIntegerWidgetParam(2, 128, 16, i18n("Steps"), "steps"));
    return new KisMultiIntegerFilterWidget(id().id(), parent, id().id(), param);
}

81
KisFilterConfigurationSP KisFilterPosterize::factoryConfiguration() const
Halla Rempt's avatar
Halla Rempt committed
82
{
83
    KisColorTransformationConfigurationSP config = new KisColorTransformationConfiguration(id().id(), 0);
Halla Rempt's avatar
Halla Rempt committed
84 85 86 87 88 89 90 91
    config->setProperty("steps", 16);
    return config;
}

void KisPosterizeColorTransformation::transform(const quint8* src, quint8* dst, qint32 nPixels) const
{
    quint16 m_rgba[4];
    quint16 m_mod[4];
92 93 94 95 96 97 98 99 100 101 102 103
    KoColorConversionTransformation* t =
            KoColorSpaceRegistry::instance()->createColorConverter(m_colorSpace,
                                                                   KoColorSpaceRegistry::instance()->rgb16("sRGB-elle-V2-srgbtrc.icc"),
                                                                   KoColorConversionTransformation::internalRenderingIntent(),
                                                                   KoColorConversionTransformation::internalConversionFlags());
    KoColorConversionTransformation* b =
            KoColorSpaceRegistry::instance()->createColorConverter(
                KoColorSpaceRegistry::instance()->rgb16("sRGB-elle-V2-srgbtrc.icc"),
                m_colorSpace,
                KoColorConversionTransformation::internalRenderingIntent(),
                KoColorConversionTransformation::internalConversionFlags());

Halla Rempt's avatar
Halla Rempt committed
104
    while (nPixels--) {
105
        t->transform(src, reinterpret_cast<quint8 *>(m_rgba), 1);
Halla Rempt's avatar
Halla Rempt committed
106 107 108 109 110 111 112 113 114 115 116

        m_mod[0] = m_rgba[0] % m_step;
        m_mod[1] = m_rgba[1] % m_step;
        m_mod[2] = m_rgba[2] % m_step;
        m_mod[3] = m_rgba[3] % m_step;

        m_rgba[0] = m_rgba[0] + (m_mod[0] > m_halfStep ? m_step - m_mod[0] : -m_mod[0]);
        m_rgba[1] = m_rgba[1] + (m_mod[1] > m_halfStep ? m_step - m_mod[1] : -m_mod[1]);
        m_rgba[2] = m_rgba[2] + (m_mod[2] > m_halfStep ? m_step - m_mod[2] : -m_mod[2]);
        m_rgba[3] = m_rgba[3] + (m_mod[3] > m_halfStep ? m_step - m_mod[3] : -m_mod[3]);

117
        b->transform(reinterpret_cast<quint8 *>(m_rgba), dst, 1);
Halla Rempt's avatar
Halla Rempt committed
118 119 120 121
        src += m_psize;
        dst += m_psize;
    }
}
122 123

#include "posterize.moc"