Commit 97796f04 authored by Carl Olsson's avatar Carl Olsson Committed by Boudewijn Rempt

Initial hacked-in gradientmap threshold blending.

parent 103d4b79
...@@ -144,20 +144,20 @@ QGradient* KoStopGradient::toQGradient() const ...@@ -144,20 +144,20 @@ QGradient* KoStopGradient::toQGradient() const
return gradient; return gradient;
} }
void KoStopGradient::colorAt(KoColor& dst, qreal t) const bool KoStopGradient::stopsAt(KoGradientStop &leftStop, KoGradientStop &rightStop, qreal t) const
{ {
KoColor buffer;
if (! m_stops.count()) if (! m_stops.count())
return; return false;
if (t <= m_stops.first().first || m_stops.count() == 1) { if (t <= m_stops.first().first || m_stops.count() == 1) {
// we have only one stop or t is before the first stop // we have only one stop or t is before the first stop
// -> use the color of the first stop leftStop = m_stops.first();
dst.fromKoColor(m_stops.first().second); rightStop = KoGradientStop(-std::numeric_limits<double>::infinity(), leftStop.second);
return true;
} else if (t >= m_stops.last().first) { } else if (t >= m_stops.last().first) {
// t is after the last stop // t is after the last stop
// -> use the color of the last stop rightStop = m_stops.last();
dst.fromKoColor(m_stops.last().second); leftStop = KoGradientStop(std::numeric_limits<double>::infinity(), rightStop.second);
return true;
} else { } else {
// we have at least two color stops // we have at least two color stops
// -> find the two stops which frame our t // -> find the two stops which frame our t
...@@ -170,53 +170,59 @@ void KoStopGradient::colorAt(KoColor& dst, qreal t) const ...@@ -170,53 +170,59 @@ void KoStopGradient::colorAt(KoColor& dst, qreal t) const
break; break;
} }
//if ( *buffer.colorSpace() != *colorSpace()) { leftStop = *(stop - 1);
// buffer = KoColor(colorSpace()); rightStop = *(stop);
//} return true;
//hack to get a color space with the bitdepth of the gradients(8bit), but with the colour profile of the image// }
const KoColorSpace* mixSpace = KoColorSpaceRegistry::instance()->rgb8(dst.colorSpace()->profile()); }
const KoGradientStop& leftStop = *(stop - 1); void KoStopGradient::colorAt(KoColor& dst, qreal t) const
const KoGradientStop& rightStop = *(stop); {
KoColor buffer;
KoColor startDummy, endDummy; KoGradientStop leftStop, rightStop;
if (mixSpace){ if (!stopsAt(leftStop, rightStop, t)) return;
startDummy = KoColor(leftStop.second, mixSpace);
endDummy = KoColor(rightStop.second, mixSpace);
} else {
startDummy = leftStop.second;
endDummy = rightStop.second;
}
const quint8 *colors[2];
colors[0] = startDummy.data();
colors[1] = endDummy.data();
qreal localT;
qreal stopDistance = rightStop.first - leftStop.first;
if (stopDistance < DBL_EPSILON) {
localT = 0.5;
} else {
localT = (t - leftStop.first) / stopDistance;
}
qint16 colorWeights[2];
colorWeights[0] = static_cast<quint8>((1.0 - localT) * 255 + 0.5);
colorWeights[1] = 255 - colorWeights[0];
const KoColorSpace* mixSpace = KoColorSpaceRegistry::instance()->rgb8(dst.colorSpace()->profile());
//check if our mixspace exists, it doesn't at startup. KoColor startDummy, endDummy;
if (mixSpace){ if (mixSpace){
if (*buffer.colorSpace() != *mixSpace) { startDummy = KoColor(leftStop.second, mixSpace);
buffer = KoColor(mixSpace); endDummy = KoColor(rightStop.second, mixSpace);
} } else {
mixSpace->mixColorsOp()->mixColors(colors, colorWeights, 2, buffer.data()); startDummy = leftStop.second;
} endDummy = rightStop.second;
else { }
buffer = KoColor(colorSpace()); const quint8 *colors[2];
colorSpace()->mixColorsOp()->mixColors(colors, colorWeights, 2, buffer.data()); colors[0] = startDummy.data();
} colors[1] = endDummy.data();
qreal localT;
qreal stopDistance = rightStop.first - leftStop.first;
if (stopDistance < DBL_EPSILON) {
localT = 0.5;
} else {
localT = (t - leftStop.first) / stopDistance;
}
qint16 colorWeights[2];
colorWeights[0] = static_cast<quint8>((1.0 - localT) * 255 + 0.5);
colorWeights[1] = 255 - colorWeights[0];
dst.fromKoColor(buffer);
//check if our mixspace exists, it doesn't at startup.
if (mixSpace){
if (*buffer.colorSpace() != *mixSpace) {
buffer = KoColor(mixSpace);
}
mixSpace->mixColorsOp()->mixColors(colors, colorWeights, 2, buffer.data());
}
else {
buffer = KoColor(colorSpace());
colorSpace()->mixColorsOp()->mixColors(colors, colorWeights, 2, buffer.data());
} }
dst.fromKoColor(buffer);
} }
KoStopGradient * KoStopGradient::fromQGradient(const QGradient * gradient) KoStopGradient * KoStopGradient::fromQGradient(const QGradient * gradient)
......
...@@ -51,6 +51,9 @@ public: ...@@ -51,6 +51,9 @@ public:
/// reimplemented /// reimplemented
QGradient* toQGradient() const override; QGradient* toQGradient() const override;
/// Find stops surrounding position, returns false if position outside gradient
bool stopsAt(KoGradientStop& leftStop, KoGradientStop& rightStop, qreal t) const;
/// reimplemented /// reimplemented
void colorAt(KoColor&, qreal t) const override; void colorAt(KoColor&, qreal t) const override;
......
...@@ -69,13 +69,28 @@ void KritaFilterGradientMap::processImpl(KisPaintDeviceSP device, ...@@ -69,13 +69,28 @@ void KritaFilterGradientMap::processImpl(KisPaintDeviceSP device,
} }
KoStopGradient gradient = KoStopGradient::fromXML(doc.firstChildElement()); KoStopGradient gradient = KoStopGradient::fromXML(doc.firstChildElement());
bool threshold = true;
KoColor outColor(Qt::white, device->colorSpace()); KoColor outColor(Qt::white, device->colorSpace());
KisSequentialIteratorProgress it(device, applyRect, progressUpdater); KisSequentialIteratorProgress it(device, applyRect, progressUpdater);
quint8 grey; qreal grey;
const int pixelSize = device->colorSpace()->pixelSize(); const int pixelSize = device->colorSpace()->pixelSize();
while (it.nextPixel()) { while (it.nextPixel()) {
grey = device->colorSpace()->intensity8(it.oldRawData()); grey = qreal(device->colorSpace()->intensity8(it.oldRawData())) / 255;
gradient.colorAt(outColor,(qreal)grey/255); if (threshold) {
KoGradientStop leftStop, rightStop;
if (!gradient.stopsAt(leftStop, rightStop, grey)) continue;
qreal localT = (grey - leftStop.first) / (rightStop.first - leftStop.first);
if (localT < qreal(rand()) / qreal(RAND_MAX)) {
outColor = leftStop.second;
}
else {
outColor = rightStop.second;
}
}
else {
gradient.colorAt(outColor, grey);
}
outColor.setOpacity(qMin(KoColor(it.oldRawData(), device->colorSpace()).opacityF(), outColor.opacityF())); outColor.setOpacity(qMin(KoColor(it.oldRawData(), device->colorSpace()).opacityF(), outColor.opacityF()));
outColor.convertTo(device->colorSpace()); outColor.convertTo(device->colorSpace());
memcpy(it.rawData(), outColor.data(), pixelSize); memcpy(it.rawData(), outColor.data(), pixelSize);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment