diff --git a/libs/libkis/Channel.cpp b/libs/libkis/Channel.cpp index 609176622f..9702b50147 100644 --- a/libs/libkis/Channel.cpp +++ b/libs/libkis/Channel.cpp @@ -1,232 +1,232 @@ /* * Copyright (c) 2016 Boudewijn Rempt * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser 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 Lesser 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 "Channel.h" #include #include #include #include #include #include #include #include #ifdef HAVE_OPENEXR #include #endif struct Channel::Private { Private() {} KisNodeSP node; KoChannelInfo *channel; }; Channel::Channel(KisNodeSP node, KoChannelInfo *channel, QObject *parent) : QObject(parent) , d(new Private) { d->node = node; d->channel = channel; } Channel::~Channel() { delete d; } bool Channel::operator==(const Channel &other) const { return (d->node == other.d->node && d->channel == other.d->channel); } bool Channel::operator!=(const Channel &other) const { return !(operator==(other)); } bool Channel::visible() const { if (!d->node || !d->channel) return false; if (!d->node->inherits("KisLayer")) return false; for (uint i = 0; i < d->node->colorSpace()->channelCount(); ++i) { if (d->node->colorSpace()->channels()[i] == d->channel) { KisLayerSP layer = qobject_cast(d->node.data()); QBitArray flags = layer->channelFlags(); return flags.testBit(i); } } return false; } void Channel::setVisible(bool value) { if (!d->node || !d->channel) return; if (!d->node->inherits("KisLayer")) return; for (uint i = 0; i < d->node->colorSpace()->channelCount(); ++i) { if (d->node->colorSpace()->channels()[i] == d->channel) { QBitArray flags = d->node->colorSpace()->channelFlags(true, true); flags.setBit(i, value); KisLayerSP layer = qobject_cast(d->node.data()); layer->setChannelFlags(flags); break; } } } QString Channel::name() const { return d->channel->name(); } int Channel::position() const { return d->channel->pos(); } int Channel::channelSize() const { return d->channel->size(); } QRect Channel::bounds() const { if (!d->node || !d->channel) return QRect(); QRect rect = d->node->exactBounds(); KisPaintDeviceSP dev; if (d->node->colorSpace()->colorDepthId() == Integer8BitsColorDepthID) { dev = new KisPaintDevice(KoColorSpaceRegistry::instance()->alpha8()); } else if (d->node->colorSpace()->colorDepthId() == Integer16BitsColorDepthID) { dev = new KisPaintDevice(KoColorSpaceRegistry::instance()->alpha16()); } #ifdef HAVE_OPENEXR else if (d->node->colorSpace()->colorDepthId() == Float16BitsColorDepthID) { dev = new KisPaintDevice(KoColorSpaceRegistry::instance()->alpha16f()); } #endif else if (d->node->colorSpace()->colorDepthId() == Float32BitsColorDepthID) { dev = new KisPaintDevice(KoColorSpaceRegistry::instance()->alpha32f()); } KisSequentialConstIterator srcIt(d->node->projection(), rect); KisSequentialIterator dstIt(dev, rect); while(srcIt.nextPixel() && dstIt.nextPixel()) { const quint8 *srcPtr = srcIt.rawDataConst(); memcpy(dstIt.rawData(), srcPtr + d->channel->pos(), d->channel->size()); } if (dev) { return dev->exactBounds(); } return QRect(); } QByteArray Channel::pixelData(const QRect &rect) const { QByteArray ba; if (!d->node || !d->channel) return ba; QDataStream stream(&ba, QIODevice::WriteOnly); KisSequentialConstIterator srcIt(d->node->projection(), rect); if (d->node->colorSpace()->colorDepthId() == Integer8BitsColorDepthID) { while(srcIt.nextPixel()) { - stream << (quint8) *srcIt.rawDataConst(); + stream << (quint8) *srcIt.rawDataConst() + (d->channel->pos() * d->channel->size()); } } else if (d->node->colorSpace()->colorDepthId() == Integer16BitsColorDepthID) { while(srcIt.nextPixel()) { - stream << (quint16) *srcIt.rawDataConst(); + stream << (quint16) *srcIt.rawDataConst() + (d->channel->pos() * d->channel->size()); } } #ifdef HAVE_OPENEXR else if (d->node->colorSpace()->colorDepthId() == Float16BitsColorDepthID) { while(srcIt.nextPixel()) { - half h = (half)*srcIt.rawDataConst(); + half h = (half)*srcIt.rawDataConst() + (d->channel->pos() * d->channel->size()); stream << (float)h; } } #endif else if (d->node->colorSpace()->colorDepthId() == Float32BitsColorDepthID) { while(srcIt.nextPixel()) { - stream << (float) *srcIt.rawDataConst(); + stream << (float) *srcIt.rawDataConst() + (d->channel->pos() * d->channel->size()); } } return ba; } void Channel::setPixelData(QByteArray value, const QRect &rect) { if (!d->node || !d->channel || d->node->paintDevice() == 0) return; QDataStream stream(&value, QIODevice::ReadOnly); KisSequentialIterator dstIt(d->node->paintDevice(), rect); if (d->node->colorSpace()->colorDepthId() == Integer8BitsColorDepthID) { while (dstIt.nextPixel()) { quint8 v; stream >> v; - *dstIt.rawData() = v ; + *(dstIt.rawData() + (d->channel->pos() * d->channel->size())) = v ; } } else if (d->node->colorSpace()->colorDepthId() == Integer16BitsColorDepthID) { while (dstIt.nextPixel()) { quint16 v; stream >> v; - *dstIt.rawData() = v ; + *(dstIt.rawData() + (d->channel->pos() * d->channel->size())) = v ; } } #ifdef HAVE_OPENEXR else if (d->node->colorSpace()->colorDepthId() == Float16BitsColorDepthID) { while (dstIt.nextPixel()) { float f; stream >> f; half v = f; - *dstIt.rawData() = v ; + *(dstIt.rawData() + (d->channel->pos() * d->channel->size())) = v ; } } #endif else if (d->node->colorSpace()->colorDepthId() == Float32BitsColorDepthID) { while (dstIt.nextPixel()) { float v; stream >> v; - *dstIt.rawData() = v ; + *(dstIt.rawData() + (d->channel->pos() * d->channel->size())) = v ; } } }