Krita Source Code Documentation
Loading...
Searching...
No Matches
KisChannelSeparator Class Reference

#include <kis_channel_separator.h>

Public Member Functions

 KisChannelSeparator (KisViewManager *view)
 
void separate (KoUpdater *progress, enumSepAlphaOptions alphaOps, enumSepSource sourceOps, bool downscale, bool toColor, bool activateCurrentChannel)
 
virtual ~KisChannelSeparator ()
 

Private Attributes

KisViewManagerm_viewManager
 

Detailed Description

Definition at line 28 of file kis_channel_separator.h.

Constructor & Destructor Documentation

◆ KisChannelSeparator()

KisChannelSeparator::KisChannelSeparator ( KisViewManager * view)

Definition at line 51 of file kis_channel_separator.cc.

52 : m_viewManager(view)
53{
54}
KisViewManager * m_viewManager

◆ ~KisChannelSeparator()

virtual KisChannelSeparator::~KisChannelSeparator ( )
inlinevirtual

Definition at line 34 of file kis_channel_separator.h.

34{}

Member Function Documentation

◆ separate()

void KisChannelSeparator::separate ( KoUpdater * progress,
enumSepAlphaOptions alphaOps,
enumSepSource sourceOps,
bool downscale,
bool toColor,
bool activateCurrentChannel )

We should process the entire image, even when its pixels are transparent, because we might be pulling colors from under a zero-alpha channel.

Definition at line 56 of file kis_channel_separator.cc.

57{
59 if (!image) return;
60
62
63 // Use the flattened image, if required
64 switch (sourceOps) {
65 case ALL_LAYERS:
66 // the content will be locked later
67 src = image->projection();
68 break;
69 case CURRENT_LAYER:
71 break;
72 default:
73 break;
74 }
75
76 if (!src) return;
77
78 progressUpdater->setProgress(1);
79
80 const KoColorSpace * dstCs = 0;
81
82 quint32 numberOfChannels = src->channelCount();
83 const KoColorSpace * srcCs = src->colorSpace();
84 const QList<KoChannelInfo *> channels = srcCs->channels();
85 vKisPaintDeviceSP paintDevices;
86
92 const QRect rect = image->bounds();
93
94 KisImageBarrierLock lock(image);
95 int i = 0;
96 for (QList<KoChannelInfo *>::const_iterator it = channels.constBegin(); it != channels.constEnd(); ++it) {
97
98
99 KoChannelInfo *ch = (*it);
100
101 bool channelToColor = (toColor && ch->channelType() != KoChannelInfo::ALPHA);
102
103 if (ch->channelType() == KoChannelInfo::ALPHA && alphaOps != CREATE_ALPHA_SEPARATION) {
104 continue;
105 }
106
107 qint32 channelSize = ch->size();
108 qint32 channelPos = ch->pos();
109 qint32 destSize = 1;
110
112 if (channelToColor) {
113 // We don't downscale if we separate to color channels
114 dev = new KisPaintDevice(srcCs);
115 } else {
116 if (channelSize == 1 || downscale) {
118 } else {
120 destSize = 2;
121 }
122 }
123
124 dstCs = dev->colorSpace();
125
126 paintDevices.push_back(dev);
127
128 KisHLineConstIteratorSP srcIt = src->createHLineConstIteratorNG(rect.x(), rect.y(), rect.width());
129 KisHLineIteratorSP dstIt = dev->createHLineIteratorNG(rect.x(), rect.y(), rect.width());
130
131 for (qint32 row = 0; row < rect.height(); ++row) {
132 do {
133 if (channelToColor) {
134 dstCs->singleChannelPixel(dstIt->rawData(), srcIt->oldRawData(), channelPos);
135
136 if (alphaOps == COPY_ALPHA_TO_SEPARATIONS) {
137 dstCs->setOpacity(dstIt->rawData(), srcCs->opacityU8(srcIt->oldRawData()), 1);
138 } else {
139 dstCs->setOpacity(dstIt->rawData(), OPACITY_OPAQUE_U8, 1);
140 }
141 } else {
142
143 // To grayscale
144
145 // Decide whether we need downscaling
146 if (channelSize == 1 && destSize == 1) {
147
148 // Both 8-bit channels
149 dstIt->rawData()[0] = srcIt->oldRawData()[channelPos];
150
151 if (alphaOps == COPY_ALPHA_TO_SEPARATIONS) {
152 dstCs->setOpacity(dstIt->rawData(), srcCs->opacityU8(srcIt->oldRawData()), 1);
153 } else {
154 dstCs->setOpacity(dstIt->rawData(), OPACITY_OPAQUE_U8, 1);
155 }
156 } else if (channelSize == 2 && destSize == 2) {
157
158 // Both 16-bit
159 dstIt->rawData()[0] = srcIt->oldRawData()[channelPos];
160 dstIt->rawData()[1] = srcIt->oldRawData()[channelPos + 1];
161
162 if (alphaOps == COPY_ALPHA_TO_SEPARATIONS) {
163 dstCs->setOpacity(dstIt->rawData(), srcCs->opacityU8(srcIt->oldRawData()), 1);
164 } else {
165 dstCs->setOpacity(dstIt->rawData(), OPACITY_OPAQUE_U8, 1);
166 }
167 } else if (channelSize != 1 && destSize == 1) {
168 // Downscale
169 memset(dstIt->rawData(), srcCs->scaleToU8(srcIt->oldRawData(), channelPos), 1);
170
171 dstCs->setOpacity(dstIt->rawData(), OPACITY_OPAQUE_U8, 1);
172 } else if (channelSize != 2 && destSize == 2) {
173 // Upscale
174 dstIt->rawData()[0] = srcCs->scaleToU8(srcIt->oldRawData(), channelPos);
175
176 dstCs->setOpacity(dstIt->rawData(), OPACITY_OPAQUE_U8, 1);
177
178 }
179 }
180
181 } while (dstIt->nextPixel() && srcIt->nextPixel());
182 dstIt->nextRow();
183 srcIt->nextRow();
184 }
185 ++i;
186
187 progressUpdater->setProgress((i * 100) / numberOfChannels);
188 if (progressUpdater->interrupted()) {
189 break;
190 }
191 }
192
193 vKisPaintDeviceSP::const_iterator paintDeviceIterator = paintDevices.cbegin();
194
195 if (!progressUpdater->interrupted()) {
197 adapter.beginMacro(kundo2_i18n("Separate Image"));
198
199 for (QList<KoChannelInfo *>::const_iterator it = channels.constBegin(); it != channels.constEnd(); ++it) {
200
201 KoChannelInfo *ch = (*it);
202 if (ch->channelType() == KoChannelInfo::ALPHA && alphaOps != CREATE_ALPHA_SEPARATION) {
203 // Don't make an separate separation of the alpha channel if the user didn't ask for it.
204 continue;
205 }
206
207 KisPaintLayerSP l = new KisPaintLayer(image, ch->name(), OPACITY_OPAQUE_U8, *paintDeviceIterator);
208
209 if (toColor && ch->channelType() != KoChannelInfo::ALPHA && activateCurrentChannel) {
210 QBitArray channelFlags(channels.count());
211 int i = 0;
212 for (QList<KoChannelInfo *>::const_iterator it2 = channels.constBegin(); it2 != channels.constEnd(); ++it2) {
213 channelFlags.setBit(i, (it == it2));
214 i++;
215 }
216 l->setChannelFlags(channelFlags);
217 }
218
219 adapter.addNode(l.data(), image->rootLayer(), 0);
220 ++paintDeviceIterator;
221 }
222
223 adapter.endMacro();
224 }
225
226 progressUpdater->setProgress(100);
227
228
229}
const KoID GrayAColorModelID("GRAYA", ki18n("Grayscale/Alpha"))
const KoID Integer8BitsColorDepthID("U8", ki18n("8-bit integer/channel"))
const KoID Integer16BitsColorDepthID("U16", ki18n("16-bit integer/channel"))
const quint8 OPACITY_OPAQUE_U8
#define downscale(quantum)
virtual const quint8 * oldRawData() const =0
virtual bool nextPixel()=0
virtual void nextRow()=0
KisGroupLayerSP rootLayer() const
KisPaintDeviceSP projection() const
QRect bounds() const override
KisHLineIteratorSP createHLineIteratorNG(qint32 x, qint32 y, qint32 w)
const KoColorSpace * colorSpace() const
KisPaintDeviceSP activeDevice()
Convenience method to get at the active paint device.
KisImageWSP image() const
Return the image this view is displaying.
@ ALPHA
The channel represents the opacity of a pixel.
qint32 size() const
qint32 pos() const
enumChannelType channelType() const
QString name() const
virtual void setOpacity(quint8 *pixels, quint8 alpha, qint32 nPixels) const =0
QList< KoChannelInfo * > channels
virtual quint8 scaleToU8(const quint8 *srcPixel, qint32 channelPos) const =0
virtual void singleChannelPixel(quint8 *dstPixel, const quint8 *srcPixel, quint32 channelIndex) const =0
virtual quint8 opacityU8(const quint8 *pixel) const =0
QString id() const
Definition KoID.cpp:63
@ CURRENT_LAYER
@ COPY_ALPHA_TO_SEPARATIONS
@ CREATE_ALPHA_SEPARATION
KUndo2MagicString kundo2_i18n(const char *text)
virtual void setChannelFlags(const QBitArray &channelFlags)
Definition kis_layer.cc:342
static KoColorSpaceRegistry * instance()

References KisViewManager::activeDevice(), KisNodeCommandsAdapter::addNode(), ALL_LAYERS, KoChannelInfo::ALPHA, KisNodeCommandsAdapter::beginMacro(), KisImage::bounds(), KoColorSpace::channels, KoChannelInfo::channelType(), KisPaintDevice::colorSpace(), COPY_ALPHA_TO_SEPARATIONS, CREATE_ALPHA_SEPARATION, KisPaintDevice::createHLineIteratorNG(), CURRENT_LAYER, KisSharedPtr< T >::data(), downscale, KisNodeCommandsAdapter::endMacro(), GrayAColorModelID, KoID::id(), KisViewManager::image(), KoColorSpaceRegistry::instance(), Integer16BitsColorDepthID, Integer8BitsColorDepthID, KoUpdater::interrupted(), kundo2_i18n(), m_viewManager, KoChannelInfo::name(), KisBaseConstIteratorNG::nextPixel(), KisHLineConstIteratorNG::nextRow(), KisBaseConstAccessor::oldRawData(), OPACITY_OPAQUE_U8, KoColorSpace::opacityU8(), KoChannelInfo::pos(), KisImage::projection(), KisImage::rootLayer(), KoColorSpace::scaleToU8(), KisLayer::setChannelFlags(), KoColorSpace::setOpacity(), KoUpdater::setProgress(), KoColorSpace::singleChannelPixel(), and KoChannelInfo::size().

Member Data Documentation

◆ m_viewManager

KisViewManager* KisChannelSeparator::m_viewManager
private

Definition at line 40 of file kis_channel_separator.h.


The documentation for this class was generated from the following files: