1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
|
/*
* Copyright (c) 2002 Patrick Julien <freak@codepimps.org>
* Copyright (c) 2004 Cyrille Berger <cberger@cberger.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU 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 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.
*/
#ifndef KIS_ABSTRACT_COLORSPACE_H_
#define KIS_ABSTRACT_COLORSPACE_H_
#include <strings.h>
#include <tqmap.h>
#include <tqcolor.h>
#include <tqstringlist.h>
#include <tqpair.h>
#include "kis_global.h"
#include "kis_channelinfo.h"
#include "kis_profile.h"
#include "kis_id.h"
#include "kis_composite_op.h"
#include "kis_colorspace.h"
#include "koffice_export.h"
class TQPainter;
class KisPixelRO;
class KisColorSpaceFactoryRegistry;
/**
* A colorspace strategy is the definition of a certain color model
* in Chalk.
*/
class KRITA_EXPORT KisAbstractColorSpace : public KisColorSpace {
public:
/**
* @param id The unique human and machine readable identifiation of this colorspace
* @param cmType the lcms type indentification for this colorspace, may be 0
* @param colorSpaceSignature the icc identification for this colorspace, may be 0
* @param parent the registry that owns this instance
* @param profile the profile this colorspace uses for transforms
*/
KisAbstractColorSpace(const KisID & id,
DWORD cmType,
icColorSpaceSignature colorSpaceSignature,
KisColorSpaceFactoryRegistry * parent,
KisProfile *profile);
void init();
virtual ~KisAbstractColorSpace();
virtual bool operator==(const KisAbstractColorSpace& rhs) const {
return (m_id == rhs.m_id && m_profile == rhs.m_profile);
}
//================== Information about this color strategy ========================//
public:
//========== Channels =====================================================//
// Return a vector describing all the channels this color model has.
virtual TQValueVector<KisChannelInfo *> channels() const = 0;
virtual TQ_UINT32 nChannels() const = 0;
virtual TQ_UINT32 nColorChannels() const = 0;
virtual TQ_UINT32 nSubstanceChannels() const { return 0; };
virtual TQ_UINT32 pixelSize() const = 0;
virtual TQString channelValueText(const TQ_UINT8 *pixel, TQ_UINT32 channelIndex) const = 0;
virtual TQString normalisedChannelValueText(const TQ_UINT8 *pixel, TQ_UINT32 channelIndex) const = 0;
virtual TQ_UINT8 scaleToU8(const TQ_UINT8 * srcPixel, TQ_INT32 channelPos) = 0;
virtual TQ_UINT16 scaleToU16(const TQ_UINT8 * srcPixel, TQ_INT32 channelPos) = 0;
virtual void getSingleChannelPixel(TQ_UINT8 *dstPixel, const TQ_UINT8 *srcPixel, TQ_UINT32 channelIndex);
//========== Identification ===============================================//
virtual KisID id() const { return m_id; }
void setColorSpaceType(TQ_UINT32 type) { m_cmType = type; }
TQ_UINT32 colorSpaceType() { return m_cmType; }
virtual icColorSpaceSignature colorSpaceSignature() { return m_colorSpaceSignature; }
//========== Capabilities =================================================//
virtual KisCompositeOpList userVisiblecompositeOps() const = 0;
/**
* Returns true if the colorspace supports channel values outside the
* (normalised) range 0 to 1.
*/
virtual bool hasHighDynamicRange() const { return false; }
//========== Display profiles =============================================//
virtual KisProfile * getProfile() const { return m_profile; };
//================= Conversion functions ==================================//
virtual void fromTQColor(const TQColor& c, TQ_UINT8 *dst, KisProfile * profile = 0);
virtual void fromTQColor(const TQColor& c, TQ_UINT8 opacity, TQ_UINT8 *dst, KisProfile * profile = 0);
virtual void toTQColor(const TQ_UINT8 *src, TQColor *c, KisProfile * profile = 0);
virtual void toTQColor(const TQ_UINT8 *src, TQColor *c, TQ_UINT8 *opacity, KisProfile * profile = 0);
virtual void toLabA16(const TQ_UINT8 * src, TQ_UINT8 * dst, const TQ_UINT32 nPixels) const;
virtual void fromLabA16(const TQ_UINT8 * src, TQ_UINT8 * dst, const TQ_UINT32 nPixels) const;
virtual TQImage convertToTQImage(const TQ_UINT8 *data, TQ_INT32 width, TQ_INT32 height,
KisProfile * dstProfile,
TQ_INT32 renderingIntent = INTENT_PERCEPTUAL,
float exposure = 0.0f);
virtual bool convertPixelsTo(const TQ_UINT8 * src,
TQ_UINT8 * dst, KisColorSpace * dstColorSpace,
TQ_UINT32 numPixels,
TQ_INT32 renderingIntent = INTENT_PERCEPTUAL);
//============================== Manipulation fucntions ==========================//
//
// The manipulation functions have default implementations that _convert_ the pixel
// to a TQColor and back. Reimplement these methods in your color strategy!
//
virtual KisColorAdjustment *createBrightnessContrastAdjustment(TQ_UINT16 *transferValues);
virtual KisColorAdjustment *createDesaturateAdjustment();
virtual KisColorAdjustment *createPerChannelAdjustment(TQ_UINT16 **transferValues);
virtual void applyAdjustment(const TQ_UINT8 *src, TQ_UINT8 *dst, KisColorAdjustment *, TQ_INT32 nPixels);
virtual void invertColor(TQ_UINT8 * src, TQ_INT32 nPixels);
virtual TQ_UINT8 difference(const TQ_UINT8* src1, const TQ_UINT8* src2);
virtual void mixColors(const TQ_UINT8 **colors, const TQ_UINT8 *weights, TQ_UINT32 nColors, TQ_UINT8 *dst) const;
virtual void convolveColors(TQ_UINT8** colors, TQ_INT32* kernelValues, KisChannelInfo::enumChannelFlags channelFlags, TQ_UINT8 *dst, TQ_INT32 factor, TQ_INT32 offset, TQ_INT32 nPixels) const;
virtual void darken(const TQ_UINT8 * src, TQ_UINT8 * dst, TQ_INT32 shade, bool compensate, double compensation, TQ_INT32 nPixels) const;
virtual TQ_UINT8 intensity8(const TQ_UINT8 * src) const;
virtual KisID mathToolboxID() const;
virtual void bitBlt(TQ_UINT8 *dst,
TQ_INT32 dststride,
KisColorSpace * srcSpace,
const TQ_UINT8 *src,
TQ_INT32 srcRowStride,
const TQ_UINT8 *srcAlphaMask,
TQ_INT32 maskRowStride,
TQ_UINT8 opacity,
TQ_INT32 rows,
TQ_INT32 cols,
const KisCompositeOp& op);
//========================== END of Public API ========================================//
protected:
/**
* Compose two byte arrays containing pixels in the same color
* model together.
*/
virtual void bitBlt(TQ_UINT8 *dst,
TQ_INT32 dstRowSize,
const TQ_UINT8 *src,
TQ_INT32 srcRowStride,
const TQ_UINT8 *srcAlphaMask,
TQ_INT32 maskRowStride,
TQ_UINT8 opacity,
TQ_INT32 rows,
TQ_INT32 cols,
const KisCompositeOp& op) = 0;
virtual cmsHTRANSFORM createTransform(KisColorSpace * dstColorSpace,
KisProfile * srcProfile,
KisProfile * dstProfile,
TQ_INT32 renderingIntent);
virtual void compositeCopy(TQ_UINT8 *dstRowStart, TQ_INT32 dstRowStride, const TQ_UINT8 *srcRowStart, TQ_INT32 srcRowStride, const TQ_UINT8 *maskRowStart, TQ_INT32 maskRowStride, TQ_INT32 rows, TQ_INT32 numColumns, TQ_UINT8 opacity);
// So I don't need to re-implement it everywhere.
template <typename ColorType,
typename NativeMult, typename Uint8ToNative, typename NativeOpacityTest,
int AlphaPos, int NonAlphaSize, int TotalSize>
void abstractCompositeAlphaDarken(TQ_UINT8 *dstRowStart, TQ_INT32 dstRowStride,
const TQ_UINT8 *srcRowStart, TQ_INT32 srcRowStride,
const TQ_UINT8 *maskRowStart, TQ_INT32 maskRowStride,
TQ_INT32 rows, TQ_INT32 numColumns, TQ_UINT8 opacity,
NativeMult nativeMult, Uint8ToNative uint8ToNative,
NativeOpacityTest nativeOpacityTest) {
while (rows > 0) {
const ColorType *src = reinterpret_cast<const ColorType*>(srcRowStart);
ColorType *dst = reinterpret_cast<ColorType*>(dstRowStart);
const TQ_UINT8 *mask = maskRowStart;
TQ_INT32 columns = numColumns;
while (columns > 0) {
ColorType srcAlpha = src[AlphaPos];
ColorType dstAlpha = dst[AlphaPos];
// apply the alphamask
if(mask != 0)
{
if(*mask != OPACITY_OPAQUE)
srcAlpha = nativeMult(srcAlpha, uint8ToNative(*mask));
mask++;
}
if (opacity != OPACITY_OPAQUE) {
srcAlpha = nativeMult(srcAlpha, uint8ToNative(opacity));
}
// not transparent
if (nativeOpacityTest(srcAlpha) && srcAlpha >= dstAlpha) {
dst[AlphaPos] = srcAlpha;
memcpy(dst, src, NonAlphaSize * sizeof(ColorType));
}
columns--;
src += TotalSize;
dst += TotalSize;
}
rows--;
srcRowStart += srcRowStride;
dstRowStart += dstRowStride;
if(maskRowStart)
maskRowStart += maskRowStride;
}
}
protected:
TQStringList m_profileFilenames;
TQ_UINT8 * m_qcolordata; // A small buffer for conversion from and to qcolor.
TQ_INT32 m_alphaPos; // The position in _bytes_ of the alpha channel
TQ_INT32 m_alphaSize; // The width in _bytes_ of the alpha channel
TQValueVector<KisChannelInfo *> m_channels;
KisColorSpaceFactoryRegistry * m_parent;
private:
cmsHTRANSFORM m_defaultToRGB; // Default transform to 8 bit sRGB
cmsHTRANSFORM m_defaultFromRGB; // Default transform from 8 bit sRGB
cmsHPROFILE m_lastRGBProfile; // Last used profile to transform to/from RGB
cmsHTRANSFORM m_lastToRGB; // Last used transform to transform to RGB
cmsHTRANSFORM m_lastFromRGB; // Last used transform to transform from RGB
cmsHTRANSFORM m_defaultToLab;
cmsHTRANSFORM m_defaultFromLab;
KisProfile * m_profile;
KisColorSpace *m_lastUsedDstColorSpace;
cmsHTRANSFORM m_lastUsedTransform;
KisID m_id;
DWORD m_cmType; // The colorspace type as defined by littlecms
icColorSpaceSignature m_colorSpaceSignature; // The colorspace signature as defined in icm/icc files
// cmsHTRANSFORM is a void *, so this should work.
typedef TQMap<KisColorSpace *, cmsHTRANSFORM> TransformMap;
TransformMap m_transforms; // Cache for existing transforms
KisAbstractColorSpace(const KisAbstractColorSpace&);
KisAbstractColorSpace& operator=(const KisAbstractColorSpace&);
TQMemArray<TQ_UINT8> m_conversionCache; // XXX: This will be a bad problem when we have threading.
};
#endif // KIS_STRATEGY_COLORSPACE_H_
|