15#include <QDomDocument>
72 , m_channelCount(channelCount)
78 m_channelCount(rhs.m_channelCount),
79 m_curves(rhs.m_curves),
80 m_transfers(rhs.m_transfers)
96 const QString
name = QLatin1String(
"curve") + QString::number(i);
114 const QString
name = QLatin1String(
"curve") + QString::number(i);
129 for (
int i = 0; i <
m_curves.size(); ++i) {
130 const QString
name = QLatin1String(
"curve") + QString::number(i);
176 quint16 numTransfers = 0;
177 quint16 numTransfersWithAlpha = 0;
178 int activeCurve = -1;
180 version = root.attribute(
"version").toInt();
182 QDomElement e = root.firstChild().toElement();
183 QString attributeName;
186 QRegExp curveRegexp(
"curve(\\d+)");
188 while (!e.isNull()) {
189 if ((attributeName = e.attribute(
"name")) ==
"activeCurve") {
190 activeCurve = e.text().toInt();
191 }
else if ((attributeName = e.attribute(
"name")) ==
"nTransfers") {
192 numTransfers = e.text().toUShort();
193 }
else if ((attributeName = e.attribute(
"name")) ==
"nTransfersWithAlpha") {
194 numTransfersWithAlpha = e.text().toUShort();
196 if (curveRegexp.indexIn(attributeName, 0) != -1) {
198 index = curveRegexp.cap(1).toUShort();
199 index = qMin(index, quint16(
curves.count()));
201 if (!e.text().isEmpty()) {
204 curves.insert(index, curve);
207 e = e.nextSiblingElement();
214 if (numTransfersWithAlpha > numTransfers) {
215 e = root.firstChild().toElement();
216 while (!e.isNull()) {
217 if ((attributeName = e.attribute(
"name")) ==
"alphaCurve") {
218 if (!e.text().isEmpty()) {
222 e = e.nextSiblingElement();
227 if(
getString(
"legacy") ==
"brightnesscontrast") {
233 int extraChannels = 5;
239 for(
int c = 0; c < extraChannels; c ++) {
260 const QString &
value)
262 QDomText text = doc.createTextNode(
value);
263 QDomElement t = doc.createElement(
"param");
264 t.setAttribute(
"name", name);
282 root.setAttribute(
"version",
version());
297 for (
int i = 0; i <
m_curves.size(); ++i) {
298 QString
name = QLatin1String(
"curve") + QString::number(i);
319 if (
name ==
"nTransfers") {
322 const qint32 newChannelCount =
value.toInt();
336 const QString
name = QLatin1String(
"curve") + QString::number(i);
344 const QString
name = QLatin1String(
"curve") + QString::number(i);
356 if (
name ==
"activeCurve") {
378 QRegExp rx(
"curve(\\d+)");
379 if (rx.indexIn(
name, 0) == -1) {
383 curveIndex = rx.cap(1).toUShort();
403 QHBoxLayout * layout =
new QHBoxLayout(
this);
405 layout->setContentsMargins(0,0,0,0);
406 layout->addWidget(
m_page);
411 for (
int i = 0; i < virtualChannelCount; i++) {
429 if (keys.size() > 0) {
459 for (
int i = 0; i < virtualChannelCount; i++) {
472 if (cfg->
curves().empty()) {
482 if (!defaults->curves().isEmpty()) {
487 QMessageBox::warning(
this, i18nc(
"@title:window",
"Krita"), i18n(
"The current configuration was created for a different colorspace and cannot be used. All curves will be reset."));
488 warnKrita <<
"WARNING: trying to load a curve with invalid number of channels!";
494 for (
int ch = 0; ch < cfg->
curves().size(); ch++) {
503 auto compareChannels =
505 return lhs.
type() == rhs.type() &&
520 for (
auto detectedIt = detectedCurves.begin(); detectedIt != detectedCurves.end(); ++detectedIt) {
523 return compareChannels(*detectedIt, info);
526 const int srcIndex = std::distance(detectedCurves.begin(), detectedIt);
530 warnKrita <<
"WARNING: failed to find mapping of the channel in the filter configuration:";
531 warnKrita <<
"WARNING: channel:" <<
ppVar(detectedIt->name()) <<
ppVar(detectedIt->type())<<
ppVar(detectedIt->pixelIndex());
534 for (
auto it = detectedCurves.begin(); it != detectedCurves.end(); ++it) {
535 warnKrita <<
"WARNING: detected channels" << std::distance(detectedCurves.begin(), it) <<
":" << it->name();
546 const int activeChannel =
547 config->hasProperty(
"activeCurve") ?
548 qBound(0, config->getInt(
"activeCurve"),
m_curves.size()) :
570 if (orient == Qt::Horizontal) {
571 i = &x; inc = 1; col = 0;
572 width = 256; height = 1;
574 i = &y; inc = -1; col = 255;
575 width = 1; height = 256;
578 QPixmap gradientpix(width, height);
579 QPainter
p(&gradientpix);
580 p.setPen(QPen(QColor(0, 0, 0), 1, Qt::SolidLine));
581 for (; *i < 256; (*i)++, col += inc) {
582 p.setPen(QColor(col, col, col));
592 QPixmap pix(256, height);
596 bool logarithmic =
m_page->chkLogarithmic->isChecked();
604 QPalette appPalette = QApplication::palette();
606 pix.fill(QColor(appPalette.color(QPalette::Base)));
609 p.setPen(QColor(appPalette.color(QPalette::Text)));
624 double factor = (double)height / highest;
625 for (i = 0; i < bins; ++i) {
629 double factor = (double)height / (
double)log(highest);
630 for (i = 0; i < bins; ++i) {
643 const int virtualChannel =
m_page->cmbChannel->itemData(index).toInt();
667 m_page->cmbChannel->setCurrentIndex(index);
683 auto defaultCurves = defaults->curves();
float value(const T *src, size_t ch)
const KoID GrayAColorModelID("GRAYA", ki18n("Grayscale/Alpha"))
const KoID AlphaColorModelID("A", ki18n("Alpha mask"))
const KoID CMYKAColorModelID("CMYKA", ki18n("CMYK/Alpha"))
const KoID LABAColorModelID("LABA", ki18n("L*a*b*/Alpha"))
connect(this, SIGNAL(optionsChanged()), this, SLOT(saveOptions()))
quint32 getHighest()
This function return the highest value of the histogram.
void setChannel(qint32 channel)
quint32 getValue(quint8 i)
void setHistogramType(enumHistogramType type)
KoHistogramProducer * producer()
enumHistogramType getHistogramType()
Calculations calculations()
void setProperty(const QString &name, const QVariant &value) override
QList< KisCubicCurve > m_curves
QVector< QVector< quint16 > > m_transfers
const QVector< QVector< quint16 > > & transfers() const
void setActiveCurve(int value)
bool curveIndexFromCurvePropertyName(const QString &name, int &curveIndex) const
Takes a curve property name with format "curve#", where # is the index of the channel and puts the in...
void setCurves(QList< KisCubicCurve > &curves)
bool isCompatible(const KisPaintDeviceSP) const override
~KisMultiChannelFilterConfiguration() override
void fromLegacyXML(const QDomElement &root) override
QString toXML() const override
KisMultiChannelFilterConfiguration(int channelCount, const QString &name, qint32 version, KisResourcesInterfaceSP resourcesInterface)
virtual KisCubicCurve getDefaultCurve()=0
void updateTransfer(int index)
const QList< KisCubicCurve > & curves() const
virtual bool compareTo(const KisPropertiesConfiguration *rhs) const override
void fromXML(const QDomElement &e) override
bool needsTransparentPixels(const KisFilterConfigurationSP config, const KoColorSpace *cs) const override
static QVector< VirtualChannelInfo > getVirtualChannels(const KoColorSpace *cs, int maxChannels=-1)
static int findChannel(const QVector< VirtualChannelInfo > &virtualChannels, const VirtualChannelInfo::Type &channelType)
KisMultiChannelFilter(const KoID &id, const QString &entry)
virtual const KoColorSpace * compositionSourceColorSpace() const
QRect exactBounds() const
virtual KoID colorModelId() const =0
virtual quint32 channelCount() const =0
T get(const QString &id) const
QList< QString > keysCompatibleWith(const KoColorSpace *colorSpace, bool isStrict=false) const
returns a list, sorted by preference: higher preference comes first
static KoHistogramProducerFactoryRegistry * instance()
virtual KoHistogramProducer * generate()=0
Factory method, generates a new KoHistogramProducer.
virtual qint32 numberOfBins()=0
#define KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(cond, val)
#define KIS_SAFE_ASSERT_RECOVER_RETURN(cond)
const KoID FiltersCategoryAdjustId("adjust_filters", ki18nc("The category of color adjustment filters, like levels. Verb.", "Adjust"))
void addParamNode(QDomDocument &doc, QDomElement &root, const QString &name, const QString &value)
QVector< VirtualChannelInfo > getVirtualChannels(const KoColorSpace *cs, int maxChannels, bool supportsLightness, bool supportsHue, bool supportsSaturation)
int findChannel(const QVector< VirtualChannelInfo > &virtualChannels, const VirtualChannelInfo::Type &channelType)
void setSupportsPainting(bool v)
void setColorSpaceIndependence(ColorSpaceIndependence v)
void setVersion(qint32 version)
virtual bool compareTo(const KisPropertiesConfiguration *rhs) const override
void removeProperty(const QString &name)
QString getString(const QString &name, const QString &def=QString()) const