File indexing completed on 2024-05-26 04:33:03
0001 /* 0002 * This file is part of Krita 0003 * 0004 * SPDX-FileCopyrightText: 2004 Cyrille Berger <cberger@cberger.net> 0005 * 0006 * SPDX-License-Identifier: GPL-2.0-or-later 0007 */ 0008 0009 #include "colorsfilters.h" 0010 0011 0012 #include <math.h> 0013 0014 #include <stdlib.h> 0015 #include <string.h> 0016 0017 #include <QSlider> 0018 #include <QPoint> 0019 #include <QColor> 0020 0021 #include <klocalizedstring.h> 0022 0023 #include <kis_debug.h> 0024 #include <kpluginfactory.h> 0025 0026 #include "KoBasicHistogramProducers.h" 0027 #include <KoColorSpace.h> 0028 #include <KoColorTransformation.h> 0029 #include <filter/kis_filter_category_ids.h> 0030 #include <filter/kis_filter_configuration.h> 0031 #include <kis_paint_device.h> 0032 #include <kis_processing_information.h> 0033 #include <KisDocument.h> 0034 #include <kis_image.h> 0035 #include <kis_layer.h> 0036 #include <kis_global.h> 0037 #include <kis_types.h> 0038 #include <kis_selection.h> 0039 #include <kis_histogram.h> 0040 #include <filter/kis_filter_registry.h> 0041 #include <kis_painter.h> 0042 #include <KoUpdater.h> 0043 #include <KoColorSpaceConstants.h> 0044 #include <KoCompositeOp.h> 0045 #include <KisSequentialIteratorProgress.h> 0046 0047 0048 #include "kis_hsv_adjustment_filter.h" 0049 #include "kis_perchannel_filter.h" 0050 #include "kis_cross_channel_filter.h" 0051 #include "kis_color_balance_filter.h" 0052 #include "kis_desaturate_filter.h" 0053 0054 K_PLUGIN_FACTORY_WITH_JSON(ColorsFiltersFactory, "kritacolorsfilter.json", registerPlugin<ColorsFilters>();) 0055 0056 ColorsFilters::ColorsFilters(QObject *parent, const QVariantList &) 0057 : QObject(parent) 0058 { 0059 KisFilterRegistry * manager = KisFilterRegistry::instance(); 0060 manager->add(new KisAutoContrast()); 0061 manager->add(new KisPerChannelFilter()); 0062 manager->add(new KisCrossChannelFilter()); 0063 manager->add(new KisDesaturateFilter()); 0064 manager->add(new KisHSVAdjustmentFilter()); 0065 manager->add(new KisColorBalanceFilter()); 0066 0067 } 0068 0069 ColorsFilters::~ColorsFilters() 0070 { 0071 } 0072 0073 0074 //================================================================== 0075 0076 0077 KisAutoContrast::KisAutoContrast() : KisFilter(id(), FiltersCategoryAdjustId, i18n("&Auto Contrast")) 0078 { 0079 setSupportsPainting(false); 0080 setSupportsThreading(false); 0081 setSupportsAdjustmentLayers(false); 0082 setColorSpaceIndependence(TO_LAB16); 0083 setShowConfigurationWidget(false); 0084 } 0085 0086 void KisAutoContrast::processImpl(KisPaintDeviceSP device, 0087 const QRect& applyRect, 0088 const KisFilterConfigurationSP config, 0089 KoUpdater* progressUpdater) const 0090 { 0091 Q_ASSERT(device != 0); 0092 Q_UNUSED(config); 0093 // initialize 0094 KoHistogramProducer *producer = new KoGenericLabHistogramProducer(); 0095 KisHistogram histogram(device, applyRect, producer, LINEAR); 0096 int minvalue = int(255 * histogram.calculations().getMin() + 0.5); 0097 int maxvalue = int(255 * histogram.calculations().getMax() + 0.5); 0098 0099 if (maxvalue > 255) 0100 maxvalue = 255; 0101 0102 histogram.setChannel(0); 0103 int twoPercent = int(0.005 * histogram.calculations().getCount()); 0104 int pixCount = 0; 0105 int binnum = 0; 0106 0107 while (binnum < histogram.producer()->numberOfBins()) { 0108 pixCount += histogram.getValue(binnum); 0109 if (pixCount > twoPercent) { 0110 minvalue = binnum; 0111 break; 0112 } 0113 binnum++; 0114 } 0115 pixCount = 0; 0116 binnum = histogram.producer()->numberOfBins() - 1; 0117 while (binnum > 0) { 0118 pixCount += histogram.getValue(binnum); 0119 if (pixCount > twoPercent) { 0120 maxvalue = binnum; 0121 break; 0122 } 0123 binnum--; 0124 } 0125 // build the transferfunction 0126 int diff = maxvalue - minvalue; 0127 0128 QScopedArrayPointer<quint16> transfer(new quint16[256]); 0129 for (int i = 0; i < 255; i++) 0130 transfer[i] = 0xFFFF; 0131 0132 if (diff != 0) { 0133 for (int i = 0; i < minvalue; i++) 0134 transfer[i] = 0x0; 0135 for (int i = minvalue; i < maxvalue; i++) { 0136 qint32 val = int((0xFFFF * (i - minvalue)) / diff); 0137 if (val > 0xFFFF) 0138 val = 0xFFFF; 0139 if (val < 0) 0140 val = 0; 0141 0142 transfer[i] = val; 0143 } 0144 for (int i = maxvalue; i < 256; i++) 0145 transfer[i] = 0xFFFF; 0146 } 0147 // apply 0148 QScopedPointer<KoColorTransformation> adj(device->colorSpace()->createBrightnessContrastAdjustment(transfer.data())); 0149 KIS_SAFE_ASSERT_RECOVER_RETURN(adj); 0150 0151 KisSequentialIteratorProgress it(device, applyRect, progressUpdater); 0152 0153 quint32 npix = it.nConseqPixels(); 0154 while(it.nextPixels(npix)) { 0155 0156 // adjust 0157 npix = it.nConseqPixels(); 0158 adj->transform(it.oldRawData(), it.rawData(), npix); 0159 } 0160 } 0161 0162 #include "colorsfilters.moc"