Commit 255251c6 authored by Boudewijn Rempt's avatar Boudewijn Rempt

Add blackpoint compensation to all color conversion API, for real

parent 8b07e9b1
......@@ -33,12 +33,14 @@
KisColorSpaceConvertVisitor::KisColorSpaceConvertVisitor(KisImageWSP image,
const KoColorSpace *srcColorSpace,
const KoColorSpace *dstColorSpace,
KoColorConversionTransformation::Intent renderingIntent)
KoColorConversionTransformation::Intent renderingIntent,
bool blackpointCompensation)
: KisNodeVisitor()
, m_image(image)
, m_srcColorSpace(srcColorSpace)
, m_dstColorSpace(dstColorSpace)
, m_renderingIntent(renderingIntent)
, m_blackpointCompensation(blackpointCompensation)
{
}
......@@ -110,7 +112,7 @@ bool KisColorSpaceConvertVisitor::convertPaintDevice(KisLayer* layer)
m_image->undoAdapter()->addCommand(propsCommand);
if (layer->original()) {
KUndo2Command* cmd = layer->original()->convertTo(m_dstColorSpace, m_renderingIntent);
KUndo2Command* cmd = layer->original()->convertTo(m_dstColorSpace, m_renderingIntent, m_blackpointCompensation);
if (cmd)
m_image->undoAdapter()->addCommand(cmd);
else
......@@ -118,7 +120,7 @@ bool KisColorSpaceConvertVisitor::convertPaintDevice(KisLayer* layer)
}
if (layer->paintDevice()) {
KUndo2Command* cmd = layer->paintDevice()->convertTo(m_dstColorSpace, m_renderingIntent);
KUndo2Command* cmd = layer->paintDevice()->convertTo(m_dstColorSpace, m_renderingIntent, m_blackpointCompensation);
if (cmd)
m_image->undoAdapter()->addCommand(cmd);
else
......@@ -126,7 +128,7 @@ bool KisColorSpaceConvertVisitor::convertPaintDevice(KisLayer* layer)
}
if (layer->projection()) {
KUndo2Command* cmd = layer->projection()->convertTo(m_dstColorSpace, m_renderingIntent);
KUndo2Command* cmd = layer->projection()->convertTo(m_dstColorSpace, m_renderingIntent, m_blackpointCompensation);
if (cmd)
m_image->undoAdapter()->addCommand(cmd);
else
......
......@@ -37,7 +37,8 @@ public:
KisColorSpaceConvertVisitor(KisImageWSP image,
const KoColorSpace *srcColorSpace,
const KoColorSpace *dstColorSpace,
KoColorConversionTransformation::Intent renderingIntent);
KoColorConversionTransformation::Intent renderingIntent,
bool blackpointCompensation);
virtual ~KisColorSpaceConvertVisitor();
public:
......@@ -72,6 +73,7 @@ private:
const KoColorSpace *m_srcColorSpace;
const KoColorSpace *m_dstColorSpace;
KoColorConversionTransformation::Intent m_renderingIntent;
bool m_blackpointCompensation;
QBitArray m_emptyChannelFlags;
};
......
......@@ -82,7 +82,7 @@ quint8* KisFixedPaintDevice::data() const
return const_cast<quint8*>(m_data.data());
}
void KisFixedPaintDevice::convertTo(const KoColorSpace* dstColorSpace, KoColorConversionTransformation::Intent renderingIntent)
void KisFixedPaintDevice::convertTo(const KoColorSpace* dstColorSpace, KoColorConversionTransformation::Intent renderingIntent, bool blackpointCompensation)
{
if (*m_colorSpace == *dstColorSpace) {
return;
......@@ -93,7 +93,8 @@ void KisFixedPaintDevice::convertTo(const KoColorSpace* dstColorSpace, KoColorCo
m_colorSpace->convertPixelsTo(data(), dstData.data(),
dstColorSpace,
size,
renderingIntent);
renderingIntent,
blackpointCompensation);
m_colorSpace = dstColorSpace;
m_data = dstData;
......@@ -138,7 +139,7 @@ QImage KisFixedPaintDevice::convertToQImage(const KoColorProfile * dstProfile)
QImage KisFixedPaintDevice::convertToQImage(const KoColorProfile * dstProfile, qint32 x1, qint32 y1, qint32 w, qint32 h)
{
Q_ASSERT( m_bounds.contains(QRect(x1,y1,w,h)) );
if (w < 0)
return QImage();
......@@ -197,7 +198,7 @@ void KisFixedPaintDevice::fill(qint32 x, qint32 y, qint32 w, qint32 h, const qui
memcpy(dabPointer, fillPixel, pixelSize);
dabPointer += pixelSize;
}
} else {
int deviceWidth = bounds().width();
quint8* rowPointer = dabPointer + ((y - bounds().y()) * deviceWidth + (x - bounds().x())) * pixelSize;
......@@ -227,8 +228,8 @@ void KisFixedPaintDevice::readBytes(quint8* dstData, qint32 x, qint32 y, qint32
if (rc == m_bounds) {
memcpy(dstData, dabPointer, pixelSize * w * h);
}
else
}
else
{
int deviceWidth = bounds().width();
quint8* rowPointer = dabPointer + ((y - bounds().y()) * deviceWidth + (x - bounds().x())) * pixelSize;
......@@ -245,14 +246,14 @@ void KisFixedPaintDevice::mirror(bool horizontal, bool vertical)
if (!horizontal && !vertical){
return;
}
int pixelSize = m_colorSpace->pixelSize();
int w = m_bounds.width();
int h = m_bounds.height();
if (horizontal){
int rowSize = pixelSize * w;
quint8 * dabPointer = data();
quint8 * row = new quint8[ rowSize ];
quint8 * mirror = 0;
......@@ -267,28 +268,28 @@ void KisFixedPaintDevice::mirror(bool horizontal, bool vertical)
mirror -= pixelSize;
}
}
delete [] row;
}
if (vertical){
int rowsToMove = h / 2;
int rowSize = pixelSize * w;
quint8 * startRow = data();
quint8 * endRow = data() + (h-1) * w * pixelSize;
quint8 * row = new quint8[ rowSize ];
for (int y = 0; y < rowsToMove; y++){
memcpy(row, startRow, rowSize);
memcpy(startRow, endRow, rowSize);
memcpy(endRow, row, rowSize);
startRow += rowSize;
endRow -= rowSize;
}
delete [] row;
}
}
......@@ -66,8 +66,8 @@ public:
* It is useful to know the accumulated memory size in pixels (not in bytes) for optimizations to avoid re-allocation.
*/
int allocatedPixels() const;
/**
* @return the pixelSize associated with this fixed paint device.
*/
......@@ -103,11 +103,13 @@ public:
* and the device is not empty
*/
void readBytes(quint8 * dstData, qint32 x, qint32 y, qint32 w, qint32 h) const;
/**
* Converts the paint device to a different colorspace
*/
void convertTo(const KoColorSpace * dstColorSpace, KoColorConversionTransformation::Intent renderingIntent = KoColorConversionTransformation::IntentPerceptual);
void convertTo(const KoColorSpace * dstColorSpace,
KoColorConversionTransformation::Intent renderingIntent = KoColorConversionTransformation::IntentPerceptual,
bool blackpointCompensation = false);
/**
* Fill this paint device with the data from image
......@@ -156,12 +158,12 @@ public:
*/
void fill(qint32 x, qint32 y, qint32 w, qint32 h, const quint8 *fillPixel);
/**
* Mirrors the device.
*/
void mirror( bool horizontal = false, bool vertical = true );
private:
KisFixedPaintDevice& operator=(const KisFixedPaintDevice& rhs);
......
......@@ -690,7 +690,7 @@ void KisImage::shear(double angleX, double angleY)
angleX, angleY, QPointF());
}
void KisImage::convertImageColorSpace(const KoColorSpace *dstColorSpace, KoColorConversionTransformation::Intent renderingIntent)
void KisImage::convertImageColorSpace(const KoColorSpace *dstColorSpace, KoColorConversionTransformation::Intent renderingIntent, bool blackpointCompensation)
{
if (*m_d->colorSpace == *dstColorSpace) return;
......@@ -700,7 +700,7 @@ void KisImage::convertImageColorSpace(const KoColorSpace *dstColorSpace, KoColor
undoAdapter()->addCommand(new KisImageLockCommand(KisImageWSP(this), true));
undoAdapter()->addCommand(new KisImageSetProjectionColorSpaceCommand(KisImageWSP(this), dstColorSpace));
KisColorSpaceConvertVisitor visitor(this, srcColorSpace, dstColorSpace, renderingIntent);
KisColorSpaceConvertVisitor visitor(this, srcColorSpace, dstColorSpace, renderingIntent, blackpointCompensation);
m_d->rootLayer->accept(visitor);
undoAdapter()->addCommand(new KisImageLockCommand(KisImageWSP(this), false));
......
......@@ -227,7 +227,7 @@ public:
/**
* Convert the image and all its layers to the dstColorSpace
*/
void convertImageColorSpace(const KoColorSpace *dstColorSpace, KoColorConversionTransformation::Intent renderingIntent = KoColorConversionTransformation::IntentPerceptual);
void convertImageColorSpace(const KoColorSpace *dstColorSpace, KoColorConversionTransformation::Intent renderingIntent = KoColorConversionTransformation::IntentPerceptual, bool blackpointCompensation = false);
/**
* Set the color space of the projection (and the root layer)
......
......@@ -112,7 +112,7 @@ public:
}
QImage createThumbnail(qint32 w, qint32 h, KoColorConversionTransformation::Intent renderingIntent) {
QImage createThumbnail(qint32 w, qint32 h, KoColorConversionTransformation::Intent renderingIntent, bool blackpointCompensation) {
QImage thumbnail;
if(m_data->m_thumbnailsValid) {
......@@ -124,7 +124,7 @@ public:
}
if(thumbnail.isNull()) {
thumbnail = m_paintDevice->createThumbnail(w, h, QRect(), renderingIntent);
thumbnail = m_paintDevice->createThumbnail(w, h, QRect(), renderingIntent, blackpointCompensation);
cacheThumbnail(w, h, thumbnail);
}
......@@ -559,10 +559,10 @@ bool KisPaintDevice::read(KoStore *store)
return retval;
}
KUndo2Command* KisPaintDevice::convertTo(const KoColorSpace * dstColorSpace, KoColorConversionTransformation::Intent renderingIntent)
KUndo2Command* KisPaintDevice::convertTo(const KoColorSpace * dstColorSpace, KoColorConversionTransformation::Intent renderingIntent, bool blackpointCompensation)
{
m_d->cache.invalidate();
dbgImage << this << colorSpace()->id() << dstColorSpace->id() << renderingIntent;
dbgImage << this << colorSpace()->id() << dstColorSpace->id() << renderingIntent << blackpointCompensation;
if (*colorSpace() == *dstColorSpace) {
return 0;
}
......@@ -598,7 +598,7 @@ KUndo2Command* KisPaintDevice::convertTo(const KoColorSpace * dstColorSpace, KoC
const quint8 *srcData = srcIt->oldRawData();
quint8 *dstData = dstIt->rawData();
m_d->colorSpace->convertPixelsTo(srcData, dstData, dstColorSpace, columns, renderingIntent);
m_d->colorSpace->convertPixelsTo(srcData, dstData, dstColorSpace, columns, renderingIntent, blackpointCompensation);
column += columns;
columnsRemaining -= columns;
......@@ -668,7 +668,7 @@ void KisPaintDevice::convertFromQImage(const QImage& _image, const KoColorProfil
m_d->cache.invalidate();
}
QImage KisPaintDevice::convertToQImage(const KoColorProfile *dstProfile, KoColorConversionTransformation::Intent renderingIntent) const
QImage KisPaintDevice::convertToQImage(const KoColorProfile *dstProfile, KoColorConversionTransformation::Intent renderingIntent, bool blackpointCompensation) const
{
qint32 x1;
qint32 y1;
......@@ -684,10 +684,10 @@ QImage KisPaintDevice::convertToQImage(const KoColorProfile *dstProfile, KoColor
w = rc.width();
h = rc.height();
return convertToQImage(dstProfile, x1, y1, w, h, renderingIntent);
return convertToQImage(dstProfile, x1, y1, w, h, renderingIntent, blackpointCompensation);
}
QImage KisPaintDevice::convertToQImage(const KoColorProfile * dstProfile, qint32 x1, qint32 y1, qint32 w, qint32 h, KoColorConversionTransformation::Intent renderingIntent) const
QImage KisPaintDevice::convertToQImage(const KoColorProfile * dstProfile, qint32 x1, qint32 y1, qint32 w, qint32 h, KoColorConversionTransformation::Intent renderingIntent, bool blackpointCompensation) const
{
if (w < 0)
......@@ -709,7 +709,7 @@ QImage KisPaintDevice::convertToQImage(const KoColorProfile * dstProfile, qint3
// XXX: Is this really faster than converting line by line and building the QImage directly?
// This copies potentially a lot of data.
readBytes(data, x1, y1, w, h);
QImage image = colorSpace()->convertToQImage(data, w, h, dstProfile, renderingIntent);
QImage image = colorSpace()->convertToQImage(data, w, h, dstProfile, renderingIntent, blackpointCompensation);
delete[] data;
return image;
......@@ -761,16 +761,16 @@ KisPaintDeviceSP KisPaintDevice::createThumbnailDevice(qint32 w, qint32 h, QRect
}
QImage KisPaintDevice::createThumbnail(qint32 w, qint32 h, QRect rect, KoColorConversionTransformation::Intent renderingIntent)
QImage KisPaintDevice::createThumbnail(qint32 w, qint32 h, QRect rect, KoColorConversionTransformation::Intent renderingIntent, bool blackpointCompensation)
{
KisPaintDeviceSP dev = createThumbnailDevice(w, h, rect);
QImage thumbnail = dev->convertToQImage(KoColorSpaceRegistry::instance()->rgb8()->profile(), renderingIntent);
QImage thumbnail = dev->convertToQImage(KoColorSpaceRegistry::instance()->rgb8()->profile(), renderingIntent, blackpointCompensation);
return thumbnail;
}
QImage KisPaintDevice::createThumbnail(qint32 w, qint32 h, KoColorConversionTransformation::Intent renderingIntent)
QImage KisPaintDevice::createThumbnail(qint32 w, qint32 h, KoColorConversionTransformation::Intent renderingIntent, bool blackpointCompensation)
{
return m_d->cache.createThumbnail(w, h, renderingIntent);
return m_d->cache.createThumbnail(w, h, renderingIntent, blackpointCompensation);
}
KisHLineIteratorSP KisPaintDevice::createHLineIteratorNG(qint32 x, qint32 y, qint32 w)
......
......@@ -406,7 +406,7 @@ public:
*
* @return a command that can be used to undo the conversion.
*/
KUndo2Command* convertTo(const KoColorSpace * dstColorSpace, KoColorConversionTransformation::Intent renderingIntent = KoColorConversionTransformation::IntentPerceptual);
KUndo2Command* convertTo(const KoColorSpace * dstColorSpace, KoColorConversionTransformation::Intent renderingIntent = KoColorConversionTransformation::IntentPerceptual, bool blackpointCompensation = false);
/**
* Changes the profile of the colorspace of this paint device to the given
......@@ -431,7 +431,7 @@ public:
* case it's up to the color strategy to choose a profile (most
* like sRGB).
*/
virtual QImage convertToQImage(const KoColorProfile *dstProfile, qint32 x, qint32 y, qint32 w, qint32 h, KoColorConversionTransformation::Intent renderingIntent = KoColorConversionTransformation::IntentPerceptual) const;
virtual QImage convertToQImage(const KoColorProfile *dstProfile, qint32 x, qint32 y, qint32 w, qint32 h, KoColorConversionTransformation::Intent renderingIntent = KoColorConversionTransformation::IntentPerceptual, bool blackpointCompensation = false) const;
/**
* Create an RGBA QImage from a rectangle in the paint device. The
......@@ -441,7 +441,7 @@ public:
* case it's up to the color strategy to choose a profile (most
* like sRGB).
*/
virtual QImage convertToQImage(const KoColorProfile * dstProfile, KoColorConversionTransformation::Intent renderingIntent = KoColorConversionTransformation::IntentPerceptual) const;
virtual QImage convertToQImage(const KoColorProfile * dstProfile, KoColorConversionTransformation::Intent renderingIntent = KoColorConversionTransformation::IntentPerceptual, bool blackpointCompensation = false) const;
/**
* Creates a paint device thumbnail of the paint device, retaining
......@@ -465,12 +465,12 @@ public:
* @param maxh: maximum height
* @param rect: only this rect will be used for the thumbnail
*/
virtual QImage createThumbnail(qint32 maxw, qint32 maxh, QRect rect, KoColorConversionTransformation::Intent renderingIntent = KoColorConversionTransformation::IntentPerceptual);
virtual QImage createThumbnail(qint32 maxw, qint32 maxh, QRect rect, KoColorConversionTransformation::Intent renderingIntent = KoColorConversionTransformation::IntentPerceptual, bool blackpointCompensation = false);
/**
* Cached version of createThumbnail(qint32 maxw, qint32 maxh, const KisSelection *selection, QRect rect)
*/
virtual QImage createThumbnail(qint32 maxw, qint32 maxh, KoColorConversionTransformation::Intent renderingIntent = KoColorConversionTransformation::IntentPerceptual);
virtual QImage createThumbnail(qint32 maxw, qint32 maxh, KoColorConversionTransformation::Intent renderingIntent = KoColorConversionTransformation::IntentPerceptual, bool blackpointCompensation = false);
/**
* Fill c and opacity with the values found at x and y.
......
......@@ -98,6 +98,7 @@ public:
KoShapeManager *shapeManager;
KoColorProfile *monitorProfile;
KoColorConversionTransformation::Intent renderingIntent;
bool blackpointCompensation;
bool currentCanvasIsOpenGL;
bool currentCanvasUsesOpenGLShaders;
KoToolProxy *toolProxy;
......@@ -337,7 +338,7 @@ void KisCanvas2::createQPainterCanvas()
KisQPainterCanvas * canvasWidget = new KisQPainterCanvas(this, m_d->coordinatesConverter, m_d->view);
m_d->prescaledProjection = new KisPrescaledProjection();
m_d->prescaledProjection->setCoordinatesConverter(m_d->coordinatesConverter);
m_d->prescaledProjection->setMonitorProfile(m_d->monitorProfile, m_d->renderingIntent);
m_d->prescaledProjection->setMonitorProfile(m_d->monitorProfile, m_d->renderingIntent, m_d->blackpointCompensation);
canvasWidget->setPrescaledProjection(m_d->prescaledProjection);
setCanvasWidget(canvasWidget);
}
......@@ -348,7 +349,7 @@ void KisCanvas2::createOpenGLCanvas()
m_d->currentCanvasIsOpenGL = true;
// XXX: The image isn't done loading here!
m_d->openGLImageTextures = KisOpenGLImageTextures::getImageTextures(m_d->view->image(), m_d->monitorProfile, m_d->renderingIntent);
m_d->openGLImageTextures = KisOpenGLImageTextures::getImageTextures(m_d->view->image(), m_d->monitorProfile, m_d->renderingIntent, m_d->blackpointCompensation);
KisOpenGLCanvas2 * canvasWidget = new KisOpenGLCanvas2(this, m_d->coordinatesConverter, m_d->view, m_d->openGLImageTextures);
m_d->currentCanvasUsesOpenGLShaders = m_d->openGLImageTextures->usingHDRExposureProgram();
setCanvasWidget(canvasWidget);
......@@ -362,6 +363,7 @@ void KisCanvas2::createCanvas(bool useOpenGL)
KisConfig cfg;
const KoColorProfile *profile = m_d->view->resourceProvider()->currentDisplayProfile();
m_d->monitorProfile = const_cast<KoColorProfile*>(profile);
m_d->blackpointCompensation = cfg.useBlackPointCompensation();
m_d->renderingIntent = (KoColorConversionTransformation::Intent)cfg.renderIntent();
if (useOpenGL) {
......@@ -477,26 +479,28 @@ void KisCanvas2::startUpdateInPatches(QRect imageRect)
}
void KisCanvas2::setMonitorProfile(KoColorProfile* monitorProfile,
KoColorConversionTransformation::Intent renderingIntent)
KoColorConversionTransformation::Intent renderingIntent,
bool blackpointCompensation)
{
KisImageWSP image = this->image();
m_d->monitorProfile = monitorProfile;
m_d->renderingIntent = renderingIntent;
m_d->blackpointCompensation = blackpointCompensation;
image->barrierLock();
if (m_d->currentCanvasIsOpenGL) {
#ifdef HAVE_OPENGL
Q_ASSERT(m_d->openGLImageTextures);
m_d->openGLImageTextures->setMonitorProfile(monitorProfile, renderingIntent);
m_d->openGLImageTextures->setMonitorProfile(monitorProfile, renderingIntent, blackpointCompensation);
#else
Q_ASSERT_X(0, "KisCanvas2::setMonitorProfile", "Bad use of setMonitorProfile(). It shouldn't have happened =(");
#endif
} else {
Q_ASSERT(m_d->prescaledProjection);
m_d->prescaledProjection->setMonitorProfile(monitorProfile, renderingIntent);
m_d->prescaledProjection->setMonitorProfile(monitorProfile, renderingIntent, blackpointCompensation);
}
startUpdateInPatches(image->bounds());
......
......@@ -175,7 +175,8 @@ public slots:
void startUpdateInPatches(QRect imageRect);
void setMonitorProfile(KoColorProfile* monitorProfile,
KoColorConversionTransformation::Intent renderingIntent);
KoColorConversionTransformation::Intent renderingIntent,
bool blackpointCompensation);
......
......@@ -109,7 +109,8 @@ KisImagePyramid::~KisImagePyramid()
}
void KisImagePyramid::setMonitorProfile(const KoColorProfile* monitorProfile,
KoColorConversionTransformation::Intent renderingIntent)
KoColorConversionTransformation::Intent renderingIntent,
bool blackpointCompensation)
{
m_monitorProfile = monitorProfile;
/**
......@@ -118,6 +119,7 @@ void KisImagePyramid::setMonitorProfile(const KoColorProfile* monitorProfile,
*/
m_monitorColorSpace = KoColorSpaceRegistry::instance()->rgb8(monitorProfile);
m_renderingIntent = renderingIntent;
m_blackpointCompensation = blackpointCompensation;
rebuildPyramid();
}
......@@ -200,7 +202,7 @@ void KisImagePyramid::retrieveImageData(const QRect &rect)
}
quint8 *dstBytes = m_monitorColorSpace->allocPixelBuffer(numPixels);
projectionCs->convertPixelsTo(originalBytes, dstBytes, m_monitorColorSpace, numPixels, m_renderingIntent);
projectionCs->convertPixelsTo(originalBytes, dstBytes, m_monitorColorSpace, numPixels, m_renderingIntent, m_blackpointCompensation);
m_pyramid[ORIGINAL_INDEX]->writeBytes(dstBytes, rect);
......@@ -223,15 +225,15 @@ void KisImagePyramid::recalculateCache(KisPPUpdateInfoSP info)
}
#ifdef DEBUG_PYRAMID
QImage image = m_pyramid[ORIGINAL_INDEX]->convertToQImage(m_monitorProfile, m_renderingIntent);
QImage image = m_pyramid[ORIGINAL_INDEX]->convertToQImage(m_monitorProfile, m_renderingIntent, m_blackpointCompensation);
image.save("./PYRAMID_BASE.png");
image = m_pyramid[1]->convertToQImage(m_monitorProfile, m_renderingIntent);
image = m_pyramid[1]->convertToQImage(m_monitorProfile, m_renderingIntent, m_blackpointCompensation);
image.save("./LEVEL1.png");
image = m_pyramid[2]->convertToQImage(m_monitorProfile, m_renderingIntent);
image = m_pyramid[2]->convertToQImage(m_monitorProfile, m_renderingIntent, m_blackpointCompensation);
image.save("./LEVEL2.png");
image = m_pyramid[3]->convertToQImage(m_monitorProfile, m_renderingIntent);
image = m_pyramid[3]->convertToQImage(m_monitorProfile, m_renderingIntent, m_blackpointCompensation);
image.save("./LEVEL3.png");
#endif
}
......
......@@ -40,7 +40,7 @@ public:
void setImage(KisImageWSP newImage);
void setImageSize(qint32 w, qint32 h);
void setMonitorProfile(const KoColorProfile* monitorProfile, KoColorConversionTransformation::Intent renderingIntent);
void setMonitorProfile(const KoColorProfile* monitorProfile, KoColorConversionTransformation::Intent renderingIntent, bool blackpointCompensation);
/// we don't own the display filter, it's the docker that owns it!
void setDisplayFilter(KisDisplayFilter *displayFilter);
......@@ -76,6 +76,7 @@ public:
void alignSourceRect(QRect& rect, qreal scale);
private:
void retrieveImageData(const QRect &rect);
void rebuildPyramid();
void clearPyramid();
......@@ -121,7 +122,7 @@ private:
KisDisplayFilter *m_displayFilter;
KoColorConversionTransformation::Intent m_renderingIntent;
bool m_blackpointCompensation;
/**
......
......@@ -278,9 +278,9 @@ QRect KisPrescaledProjection::preScale(const QRect & rc)
return QRect();
}
void KisPrescaledProjection::setMonitorProfile(const KoColorProfile *monitorProfile, KoColorConversionTransformation::Intent renderingIntent)
void KisPrescaledProjection::setMonitorProfile(const KoColorProfile *monitorProfile, KoColorConversionTransformation::Intent renderingIntent, bool blackpointCompensation)
{
m_d->projectionBackend->setMonitorProfile(monitorProfile, renderingIntent);
m_d->projectionBackend->setMonitorProfile(monitorProfile, renderingIntent, blackpointCompensation);
}
void KisPrescaledProjection::setDisplayFilter(KisDisplayFilter *displayFilter)
......
......@@ -113,7 +113,7 @@ public slots:
/**
* Set the current monitor profile
*/
void setMonitorProfile(const KoColorProfile *monitorProfile, KoColorConversionTransformation::Intent renderingIntent);
void setMonitorProfile(const KoColorProfile *monitorProfile, KoColorConversionTransformation::Intent renderingIntent, bool blackpointCompensation);
void setDisplayFilter(KisDisplayFilter *displayFilter);
......
......@@ -43,7 +43,7 @@ public:
*/
virtual void setImage(KisImageWSP image) = 0;
virtual void setImageSize(qint32 w, qint32 h) = 0;
virtual void setMonitorProfile(const KoColorProfile* monitorProfile, KoColorConversionTransformation::Intent renderingIntent) = 0;
virtual void setMonitorProfile(const KoColorProfile* monitorProfile, KoColorConversionTransformation::Intent renderingIntent, bool blackpointCompensation) = 0;
virtual void setDisplayFilter(KisDisplayFilter *displayFilter) = 0;
/**
......
......@@ -88,7 +88,7 @@ bool KisOpenGLImageTextures::imageCanShareTextures(KisImageWSP image)
return !image->colorSpace()->hasHighDynamicRange() || imageCanUseHDRExposureProgram(image);
}
KisOpenGLImageTexturesSP KisOpenGLImageTextures::getImageTextures(KisImageWSP image, KoColorProfile *monitorProfile, KoColorConversionTransformation::Intent renderingIntent)
KisOpenGLImageTexturesSP KisOpenGLImageTextures::getImageTextures(KisImageWSP image, KoColorProfile *monitorProfile, KoColorConversionTransformation::Intent renderingIntent, bool blackpointCompensation)
{
KisOpenGL::makeContextCurrent();
......@@ -97,7 +97,7 @@ KisOpenGLImageTexturesSP KisOpenGLImageTextures::getImageTextures(KisImageWSP im
if (it != imageTexturesMap.end()) {
KisOpenGLImageTexturesSP textures = it.value();
textures->setMonitorProfile(monitorProfile, renderingIntent);
textures->setMonitorProfile(monitorProfile, renderingIntent, blackpointCompensation);
return textures;
} else {
......@@ -283,18 +283,19 @@ void KisOpenGLImageTextures::slotImageSizeChanged(qint32 /*w*/, qint32 /*h*/)
createImageTextureTiles();
}
void KisOpenGLImageTextures::setMonitorProfile(const KoColorProfile *monitorProfile, KoColorConversionTransformation::Intent renderingIntent)
void KisOpenGLImageTextures::setMonitorProfile(const KoColorProfile *monitorProfile, KoColorConversionTransformation::Intent renderingIntent, bool blackpointCompensation)
{
if (monitorProfile != m_monitorProfile ||
renderingIntent != m_renderingIntent) {
renderingIntent != m_renderingIntent ||
blackpointCompensation != m_blackpointCompensation ) {
m_monitorProfile = monitorProfile;
m_renderingIntent = renderingIntent;
m_blackpointCompensation = blackpointCompensation;
#ifdef __GNUC__
#warning "FIXME: m_renderingIntent is currently unused"
#warning "FIXME: m_renderingIntent and blackpoint compensation is currently unused"
#else
#pragma WARNING( "FIXME: m_renderingIntent is currently unused") { )
#pragma WARNING( "FIXME: m_renderingIntent and blackpoint compensation is currently unused") { )
#endif
}
}
......
......@@ -59,7 +59,7 @@ public:
* @param image The image
* @param monitorProfile The profile of the display device
*/
static KisOpenGLImageTexturesSP getImageTextures(KisImageWSP image, KoColorProfile *monitorProfile, KoColorConversionTransformation::Intent renderingIntent);
static KisOpenGLImageTexturesSP getImageTextures(KisImageWSP image, KoColorProfile *monitorProfile, KoColorConversionTransformation::Intent renderingIntent, bool blackpointCompensation);
/**
* Default constructor.
......@@ -75,7 +75,7 @@ public:
* Set the color profile of the display device.
* @param profile The color profile of the display device
*/
void setMonitorProfile(const KoColorProfile *monitorProfile, KoColorConversionTransformation::Intent renderingIntent);
void setMonitorProfile(const KoColorProfile *monitorProfile, KoColorConversionTransformation::Intent renderingIntent, bool blackpointCompensation);
/**
* set the (ocio) display filter.
......@@ -159,6 +159,7 @@ private:
QRect m_storedImageBounds;
const KoColorProfile *m_monitorProfile;
KoColorConversionTransformation::Intent m_renderingIntent;
bool m_blackpointCompensation;
GLuint m_backgroundTexture;
KisGLTexturesInfo m_texturesInfo;
......
......@@ -28,13 +28,19 @@
class KoColorConversionFromAlphaTransformation : public KoColorConversionTransformation
{
public:
KoColorConversionFromAlphaTransformation(const KoColorSpace* srcCs, const KoColorSpace* dstCs, Intent renderingIntent = IntentPerceptual);
KoColorConversionFromAlphaTransformation(const KoColorSpace* srcCs, const KoColorSpace* dstCs,
Intent renderingIntent = IntentPerceptual,
bool blackpointCompensation);
virtual void transform(const quint8 *src, quint8 *dst, qint32 nPixels) const;
};