chalk

kis_abstract_colorspace.h
1/*
2 * Copyright (c) 2002 Patrick Julien <freak@codepimps.org>
3 * Copyright (c) 2004 Cyrille Berger <cberger@cberger.net>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 */
19#ifndef KIS_ABSTRACT_COLORSPACE_H_
20#define KIS_ABSTRACT_COLORSPACE_H_
21
22#include <strings.h>
23
24#include <tqmap.h>
25#include <tqcolor.h>
26#include <tqstringlist.h>
27#include <tqpair.h>
28
29#include "kis_global.h"
30#include "kis_channelinfo.h"
31#include "kis_profile.h"
32#include "kis_id.h"
33#include "kis_composite_op.h"
34#include "kis_colorspace.h"
35#include "koffice_export.h"
36
37
38class TQPainter;
39class KisPixelRO;
41
42
47class KRITA_EXPORT KisAbstractColorSpace : public KisColorSpace {
48
49
50public:
51
60 DWORD cmType,
61 icColorSpaceSignature colorSpaceSignature,
63 KisProfile *profile);
64
65 void init();
66
67 virtual ~KisAbstractColorSpace();
68
69 virtual bool operator==(const KisAbstractColorSpace& rhs) const {
70 return (m_id == rhs.m_id && m_profile == rhs.m_profile);
71 }
72
73
74//================== Information about this color strategy ========================//
75
76public:
77
78
79 //========== Channels =====================================================//
80
81 // Return a vector describing all the channels this color model has.
82 virtual TQValueVector<KisChannelInfo *> channels() const = 0;
83
84 virtual TQ_UINT32 nChannels() const = 0;
85
86 virtual TQ_UINT32 nColorChannels() const = 0;
87
88 virtual TQ_UINT32 nSubstanceChannels() const { return 0; };
89
90 virtual TQ_UINT32 pixelSize() const = 0;
91
92 virtual TQString channelValueText(const TQ_UINT8 *pixel, TQ_UINT32 channelIndex) const = 0;
93
94 virtual TQString normalisedChannelValueText(const TQ_UINT8 *pixel, TQ_UINT32 channelIndex) const = 0;
95
96 virtual TQ_UINT8 scaleToU8(const TQ_UINT8 * srcPixel, TQ_INT32 channelPos) = 0;
97
98 virtual TQ_UINT16 scaleToU16(const TQ_UINT8 * srcPixel, TQ_INT32 channelPos) = 0;
99
100 virtual void getSingleChannelPixel(TQ_UINT8 *dstPixel, const TQ_UINT8 *srcPixel, TQ_UINT32 channelIndex);
101
102 //========== Identification ===============================================//
103
104 virtual KisID id() const { return m_id; }
105
106 void setColorSpaceType(TQ_UINT32 type) { m_cmType = type; }
107 TQ_UINT32 colorSpaceType() { return m_cmType; }
108
109 virtual icColorSpaceSignature colorSpaceSignature() { return m_colorSpaceSignature; }
110
111 //========== Capabilities =================================================//
112
113 virtual KisCompositeOpList userVisiblecompositeOps() const = 0;
114
119 virtual bool hasHighDynamicRange() const { return false; }
120
121 //========== Display profiles =============================================//
122
123 virtual KisProfile * getProfile() const { return m_profile; };
124
125
126//================= Conversion functions ==================================//
127
128
129 virtual void fromTQColor(const TQColor& c, TQ_UINT8 *dst, KisProfile * profile = 0);
130 virtual void fromTQColor(const TQColor& c, TQ_UINT8 opacity, TQ_UINT8 *dst, KisProfile * profile = 0);
131
132 virtual void toTQColor(const TQ_UINT8 *src, TQColor *c, KisProfile * profile = 0);
133 virtual void toTQColor(const TQ_UINT8 *src, TQColor *c, TQ_UINT8 *opacity, KisProfile * profile = 0);
134
135
136 virtual void toLabA16(const TQ_UINT8 * src, TQ_UINT8 * dst, const TQ_UINT32 nPixels) const;
137 virtual void fromLabA16(const TQ_UINT8 * src, TQ_UINT8 * dst, const TQ_UINT32 nPixels) const;
138
139 virtual TQImage convertToTQImage(const TQ_UINT8 *data, TQ_INT32 width, TQ_INT32 height,
140 KisProfile * dstProfile,
141 TQ_INT32 renderingIntent = INTENT_PERCEPTUAL,
142 float exposure = 0.0f);
143
144 virtual bool convertPixelsTo(const TQ_UINT8 * src,
145 TQ_UINT8 * dst, KisColorSpace * dstColorSpace,
146 TQ_UINT32 numPixels,
147 TQ_INT32 renderingIntent = INTENT_PERCEPTUAL);
148
149//============================== Manipulation fucntions ==========================//
150
151
152//
153// The manipulation functions have default implementations that _convert_ the pixel
154// to a TQColor and back. Reimplement these methods in your color strategy!
155//
156 virtual KisColorAdjustment *createBrightnessContrastAdjustment(TQ_UINT16 *transferValues);
157
158 virtual KisColorAdjustment *createDesaturateAdjustment();
159
160 virtual KisColorAdjustment *createPerChannelAdjustment(TQ_UINT16 **transferValues);
161
162 virtual void applyAdjustment(const TQ_UINT8 *src, TQ_UINT8 *dst, KisColorAdjustment *, TQ_INT32 nPixels);
163
164 virtual void invertColor(TQ_UINT8 * src, TQ_INT32 nPixels);
165
166 virtual TQ_UINT8 difference(const TQ_UINT8* src1, const TQ_UINT8* src2);
167
168 virtual void mixColors(const TQ_UINT8 **colors, const TQ_UINT8 *weights, TQ_UINT32 nColors, TQ_UINT8 *dst) const;
169
170 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;
171
172 virtual void darken(const TQ_UINT8 * src, TQ_UINT8 * dst, TQ_INT32 shade, bool compensate, double compensation, TQ_INT32 nPixels) const;
173
174 virtual TQ_UINT8 intensity8(const TQ_UINT8 * src) const;
175
176 virtual KisID mathToolboxID() const;
177
178 virtual void bitBlt(TQ_UINT8 *dst,
179 TQ_INT32 dststride,
180 KisColorSpace * srcSpace,
181 const TQ_UINT8 *src,
182 TQ_INT32 srcRowStride,
183 const TQ_UINT8 *srcAlphaMask,
184 TQ_INT32 maskRowStride,
185 TQ_UINT8 opacity,
186 TQ_INT32 rows,
187 TQ_INT32 cols,
188 const KisCompositeOp& op);
189
190//========================== END of Public API ========================================//
191
192protected:
193
194
199 virtual void bitBlt(TQ_UINT8 *dst,
200 TQ_INT32 dstRowSize,
201 const TQ_UINT8 *src,
202 TQ_INT32 srcRowStride,
203 const TQ_UINT8 *srcAlphaMask,
204 TQ_INT32 maskRowStride,
205 TQ_UINT8 opacity,
206 TQ_INT32 rows,
207 TQ_INT32 cols,
208 const KisCompositeOp& op) = 0;
209
210 virtual cmsHTRANSFORM createTransform(KisColorSpace * dstColorSpace,
211 KisProfile * srcProfile,
212 KisProfile * dstProfile,
213 TQ_INT32 renderingIntent);
214
215 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);
216
217
218 // So I don't need to re-implement it everywhere.
219 template <typename ColorType,
220 typename NativeMult, typename Uint8ToNative, typename NativeOpacityTest,
221 int AlphaPos, int NonAlphaSize, int TotalSize>
222 void abstractCompositeAlphaDarken(TQ_UINT8 *dstRowStart, TQ_INT32 dstRowStride,
223 const TQ_UINT8 *srcRowStart, TQ_INT32 srcRowStride,
224 const TQ_UINT8 *maskRowStart, TQ_INT32 maskRowStride,
225 TQ_INT32 rows, TQ_INT32 numColumns, TQ_UINT8 opacity,
226 NativeMult nativeMult, Uint8ToNative uint8ToNative,
227 NativeOpacityTest nativeOpacityTest) {
228 while (rows > 0) {
229
230 const ColorType *src = reinterpret_cast<const ColorType*>(srcRowStart);
231 ColorType *dst = reinterpret_cast<ColorType*>(dstRowStart);
232 const TQ_UINT8 *mask = maskRowStart;
233 TQ_INT32 columns = numColumns;
234
235 while (columns > 0) {
236
237 ColorType srcAlpha = src[AlphaPos];
238 ColorType dstAlpha = dst[AlphaPos];
239
240 // apply the alphamask
241 if(mask != 0)
242 {
243 if(*mask != OPACITY_OPAQUE)
244 srcAlpha = nativeMult(srcAlpha, uint8ToNative(*mask));
245 mask++;
246 }
247
248 if (opacity != OPACITY_OPAQUE) {
249 srcAlpha = nativeMult(srcAlpha, uint8ToNative(opacity));
250 }
251
252 // not transparent
253 if (nativeOpacityTest(srcAlpha) && srcAlpha >= dstAlpha) {
254 dst[AlphaPos] = srcAlpha;
255 memcpy(dst, src, NonAlphaSize * sizeof(ColorType));
256 }
257
258 columns--;
259 src += TotalSize;
260 dst += TotalSize;
261 }
262
263 rows--;
264 srcRowStart += srcRowStride;
265 dstRowStart += dstRowStride;
266 if(maskRowStart)
267 maskRowStart += maskRowStride;
268 }
269 }
270
271protected:
272
273 TQStringList m_profileFilenames;
274 TQ_UINT8 * m_qcolordata; // A small buffer for conversion from and to qcolor.
275 TQ_INT32 m_alphaPos; // The position in _bytes_ of the alpha channel
276 TQ_INT32 m_alphaSize; // The width in _bytes_ of the alpha channel
277
278 TQValueVector<KisChannelInfo *> m_channels;
279
280 KisColorSpaceFactoryRegistry * m_parent;
281
282private:
283
284 cmsHTRANSFORM m_defaultToRGB; // Default transform to 8 bit sRGB
285 cmsHTRANSFORM m_defaultFromRGB; // Default transform from 8 bit sRGB
286
287 cmsHPROFILE m_lastRGBProfile; // Last used profile to transform to/from RGB
288 cmsHTRANSFORM m_lastToRGB; // Last used transform to transform to RGB
289 cmsHTRANSFORM m_lastFromRGB; // Last used transform to transform from RGB
290
291 cmsHTRANSFORM m_defaultToLab;
292 cmsHTRANSFORM m_defaultFromLab;
293
294 KisProfile * m_profile;
295 KisColorSpace *m_lastUsedDstColorSpace;
296 cmsHTRANSFORM m_lastUsedTransform;
297
298 KisID m_id;
299 DWORD m_cmType; // The colorspace type as defined by littlecms
300 icColorSpaceSignature m_colorSpaceSignature; // The colorspace signature as defined in icm/icc files
301
302 // cmsHTRANSFORM is a void *, so this should work.
303 typedef TQMap<KisColorSpace *, cmsHTRANSFORM> TransformMap;
304 TransformMap m_transforms; // Cache for existing transforms
305
306 KisAbstractColorSpace(const KisAbstractColorSpace&);
307 KisAbstractColorSpace& operator=(const KisAbstractColorSpace&);
308
309 TQMemArray<TQ_UINT8> m_conversionCache; // XXX: This will be a bad problem when we have threading.
310};
311
312#endif // KIS_STRATEGY_COLORSPACE_H_
virtual KisCompositeOpList userVisiblecompositeOps() const =0
Returns the list of user-visible composite ops supported by this colourspace.
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
Compose two byte arrays containing pixels in the same color model together.
virtual TQString normalisedChannelValueText(const TQ_UINT8 *pixel, TQ_UINT32 channelIndex) const =0
Return a string with the channel's value with integer channels normalised to the floating point range...
virtual TQ_UINT32 nSubstanceChannels() const
The total number of substance channels for a single pixel in this color model.
KisAbstractColorSpace(const KisID &id, DWORD cmType, icColorSpaceSignature colorSpaceSignature, KisColorSpaceFactoryRegistry *parent, KisProfile *profile)
TQ_UINT32 colorSpaceType()
lcms colorspace type definition.
virtual bool hasHighDynamicRange() const
Returns true if the colorspace supports channel values outside the (normalised) range 0 to 1.
virtual TQ_UINT32 nColorChannels() const =0
The total number of color channels (excludes alpha and substance) for a single pixel in this color mo...
virtual TQValueVector< KisChannelInfo * > channels() const =0
Return a vector describing all the channels this color model has.
virtual TQ_UINT16 scaleToU16(const TQ_UINT8 *srcPixel, TQ_INT32 channelPos)=0
Convert the value of the channel at the specified position into a 16-bit value.
virtual TQ_UINT8 scaleToU8(const TQ_UINT8 *srcPixel, TQ_INT32 channelPos)=0
Convert the value of the channel at the specified position into an 8-bit value.
virtual TQ_UINT32 nChannels() const =0
The total number of channels for a single pixel in this color model.
virtual TQString channelValueText(const TQ_UINT8 *pixel, TQ_UINT32 channelIndex) const =0
Return a string with the channel's value suitable for display in the gui.
virtual KisProfile * getProfile() const
Return the profile of this color space.
virtual KisID id() const
Chalk definition for use in .kra files and internally: unchanging name + i18n'able description.
virtual TQ_UINT32 pixelSize() const =0
The size in bytes of a single pixel in this color model.
A colorspace is the definition of a certain color model in Chalk.
virtual KisColorAdjustment * createDesaturateAdjustment()=0
Create an adjustment object for desaturating.
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)=0
Compose two arrays of pixels together.
virtual void toTQColor(const TQ_UINT8 *src, TQColor *c, KisProfile *profile=0)=0
The toTQColor methods take a byte array that is at least pixelSize() long and converts the contents t...
virtual void mixColors(const TQ_UINT8 **colors, const TQ_UINT8 *weights, TQ_UINT32 nColors, TQ_UINT8 *dst) const =0
Mix the colors given their weights and return in dst The sum of weights is assumed 255.
virtual void darken(const TQ_UINT8 *src, TQ_UINT8 *dst, TQ_INT32 shade, bool compensate, double compensation, TQ_INT32 nPixels) const =0
Darken all color channels with the given amount.
virtual TQ_UINT8 intensity8(const TQ_UINT8 *src) const =0
Calculate the intensity of the given pixel, scaled down to the range 0-255.
virtual void applyAdjustment(const TQ_UINT8 *src, TQ_UINT8 *dst, KisColorAdjustment *, TQ_INT32 nPixels)=0
Apply the adjustment created with onr of the other functions.
virtual void invertColor(TQ_UINT8 *src, TQ_INT32 nPixels)=0
Invert color channels of the given pixels.
virtual void fromTQColor(const TQColor &c, TQ_UINT8 *dst, KisProfile *profile=0)=0
The fromTQColor methods take a given color defined as an RGB TQColor and fills a byte array with the ...
virtual KisColorAdjustment * createBrightnessContrastAdjustment(TQ_UINT16 *transferValues)=0
Create an adjustment object for adjusting the brightness and contrast transferValues is a 256 bins ar...
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 =0
Convolve the given array of pointers to pixels and return the result in dst.
virtual bool convertPixelsTo(const TQ_UINT8 *src, TQ_UINT8 *dst, KisColorSpace *dstColorSpace, TQ_UINT32 numPixels, TQ_INT32 renderingIntent=INTENT_PERCEPTUAL)=0
Convert a byte array of srcLen pixels *src to the specified color space and put the converted bytes i...
virtual TQImage convertToTQImage(const TQ_UINT8 *data, TQ_INT32 width, TQ_INT32 height, KisProfile *dstProfile, TQ_INT32 renderingIntent=INTENT_PERCEPTUAL, float exposure=0.0f)=0
Convert the pixels in data to (8-bit BGRA) TQImage using the specified profiles.
virtual KisColorAdjustment * createPerChannelAdjustment(TQ_UINT16 **transferValues)=0
Create an adjustment object for adjusting individual channels transferValues is an array of nColorCha...
virtual void getSingleChannelPixel(TQ_UINT8 *dstPixel, const TQ_UINT8 *srcPixel, TQ_UINT32 channelIndex)=0
Set dstPixel to the pixel containing only the given channel of srcPixel.
virtual void toLabA16(const TQ_UINT8 *src, TQ_UINT8 *dst, const TQ_UINT32 nPixels) const =0
Convert the specified data to Lab.
virtual void fromLabA16(const TQ_UINT8 *src, TQ_UINT8 *dst, const TQ_UINT32 nPixels) const =0
Convert the specified data from Lab.
virtual KisID mathToolboxID() const =0
Create a mathematical toolbox compatible with this colorspace.
virtual TQ_UINT8 difference(const TQ_UINT8 *src1, const TQ_UINT8 *src2)=0
Get the difference between 2 colors, normalized in the range (0,255).
Chalk has a large number of extensible resources.
Definition kis_id.h:57