krita

kis_abstract_colorspace.h

00001 /*
00002  *  Copyright (c) 2002 Patrick Julien  <freak@codepimps.org>
00003  *  Copyright (c) 2004 Cyrille Berger <cberger@cberger.net>
00004  *
00005  *  This program is free software; you can redistribute it and/or modify
00006  *  it under the terms of the GNU General Public License as published by
00007  *  the Free Software Foundation; either version 2 of the License, or
00008  *  (at your option) any later version.
00009  *
00010  *  This program is distributed in the hope that it will be useful,
00011  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013  *  GNU General Public License for more details.
00014  *
00015  *  You should have received a copy of the GNU General Public License
00016  *  along with this program; if not, write to the Free Software
00017  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00018  */
00019 #ifndef KIS_ABSTRACT_COLORSPACE_H_
00020 #define KIS_ABSTRACT_COLORSPACE_H_
00021 
00022 #include <strings.h>
00023 
00024 #include <qmap.h>
00025 #include <qcolor.h>
00026 #include <qstringlist.h>
00027 #include <qpair.h>
00028 
00029 #include "kis_global.h"
00030 #include "kis_channelinfo.h"
00031 #include "kis_profile.h"
00032 #include "kis_id.h"
00033 #include "kis_composite_op.h"
00034 #include "kis_colorspace.h"
00035 #include "koffice_export.h"
00036 
00037 
00038 class QPainter;
00039 class KisPixelRO;
00040 class KisColorSpaceFactoryRegistry;
00041 
00042 
00047 class KRITA_EXPORT KisAbstractColorSpace : public KisColorSpace {
00048 
00049 
00050 public:
00051 
00059     KisAbstractColorSpace(const KisID & id,
00060                           DWORD cmType,
00061                           icColorSpaceSignature colorSpaceSignature,
00062                           KisColorSpaceFactoryRegistry * parent,
00063                           KisProfile *profile);
00064 
00065     void init();
00066 
00067     virtual ~KisAbstractColorSpace();
00068 
00069     virtual bool operator==(const KisAbstractColorSpace& rhs) const {
00070         return (m_id == rhs.m_id && m_profile == rhs.m_profile);
00071     }
00072 
00073 
00074 //================== Information about this color strategy ========================//
00075 
00076 public:
00077 
00078 
00079     //========== Channels =====================================================//
00080 
00081     // Return a vector describing all the channels this color model has.
00082     virtual QValueVector<KisChannelInfo *> channels() const = 0;
00083 
00084     virtual Q_UINT32 nChannels() const = 0;
00085 
00086     virtual Q_UINT32 nColorChannels() const = 0;
00087 
00088     virtual Q_UINT32 nSubstanceChannels() const { return 0; };
00089 
00090     virtual Q_UINT32 pixelSize() const = 0;
00091 
00092     virtual QString channelValueText(const Q_UINT8 *pixel, Q_UINT32 channelIndex) const = 0;
00093 
00094     virtual QString normalisedChannelValueText(const Q_UINT8 *pixel, Q_UINT32 channelIndex) const = 0;
00095 
00096     virtual Q_UINT8 scaleToU8(const Q_UINT8 * srcPixel, Q_INT32 channelPos) = 0;
00097 
00098     virtual Q_UINT16 scaleToU16(const Q_UINT8 * srcPixel, Q_INT32 channelPos) = 0;
00099 
00100     virtual void getSingleChannelPixel(Q_UINT8 *dstPixel, const Q_UINT8 *srcPixel, Q_UINT32 channelIndex);
00101 
00102     //========== Identification ===============================================//
00103 
00104     virtual KisID id() const { return m_id; }
00105 
00106     void setColorSpaceType(Q_UINT32 type) { m_cmType = type; }
00107     Q_UINT32 colorSpaceType() { return m_cmType; }
00108 
00109     virtual icColorSpaceSignature colorSpaceSignature() { return m_colorSpaceSignature; }
00110 
00111     //========== Capabilities =================================================//
00112 
00113     virtual KisCompositeOpList userVisiblecompositeOps() const = 0;
00114 
00119     virtual bool hasHighDynamicRange() const { return false; }
00120 
00121     //========== Display profiles =============================================//
00122 
00123     virtual KisProfile * getProfile() const { return m_profile; };
00124 
00125 
00126 //================= Conversion functions ==================================//
00127 
00128 
00129     virtual void fromQColor(const QColor& c, Q_UINT8 *dst, KisProfile * profile = 0);
00130     virtual void fromQColor(const QColor& c, Q_UINT8 opacity, Q_UINT8 *dst, KisProfile * profile = 0);
00131 
00132     virtual void toQColor(const Q_UINT8 *src, QColor *c, KisProfile * profile = 0);
00133     virtual void toQColor(const Q_UINT8 *src, QColor *c, Q_UINT8 *opacity, KisProfile * profile = 0);
00134 
00135 
00136     virtual void toLabA16(const Q_UINT8 * src, Q_UINT8 * dst, const Q_UINT32 nPixels) const;
00137     virtual void fromLabA16(const Q_UINT8 * src, Q_UINT8 * dst, const Q_UINT32 nPixels) const;
00138 
00139     virtual QImage convertToQImage(const Q_UINT8 *data, Q_INT32 width, Q_INT32 height,
00140                                    KisProfile *  dstProfile,
00141                                    Q_INT32 renderingIntent = INTENT_PERCEPTUAL,
00142                                    float exposure = 0.0f);
00143 
00144     virtual bool convertPixelsTo(const Q_UINT8 * src,
00145                                  Q_UINT8 * dst, KisColorSpace * dstColorSpace,
00146                                  Q_UINT32 numPixels,
00147                                  Q_INT32 renderingIntent = INTENT_PERCEPTUAL);
00148 
00149 //============================== Manipulation fucntions ==========================//
00150 
00151 
00152 //
00153 // The manipulation functions have default implementations that _convert_ the pixel
00154 // to a QColor and back. Reimplement these methods in your color strategy!
00155 //
00156     virtual KisColorAdjustment *createBrightnessContrastAdjustment(Q_UINT16 *transferValues);
00157 
00158     virtual KisColorAdjustment *createDesaturateAdjustment();
00159 
00160     virtual KisColorAdjustment *createPerChannelAdjustment(Q_UINT16 **transferValues);
00161 
00162     virtual void applyAdjustment(const Q_UINT8 *src, Q_UINT8 *dst, KisColorAdjustment *, Q_INT32 nPixels);
00163 
00164     virtual void invertColor(Q_UINT8 * src, Q_INT32 nPixels);
00165     
00166     virtual Q_UINT8 difference(const Q_UINT8* src1, const Q_UINT8* src2);
00167 
00168     virtual void mixColors(const Q_UINT8 **colors, const Q_UINT8 *weights, Q_UINT32 nColors, Q_UINT8 *dst) const;
00169 
00170     virtual void convolveColors(Q_UINT8** colors, Q_INT32* kernelValues, KisChannelInfo::enumChannelFlags channelFlags, Q_UINT8 *dst, Q_INT32 factor, Q_INT32 offset, Q_INT32 nPixels) const;
00171 
00172     virtual void darken(const Q_UINT8 * src, Q_UINT8 * dst, Q_INT32 shade, bool compensate, double compensation, Q_INT32 nPixels) const;
00173 
00174     virtual Q_UINT8 intensity8(const Q_UINT8 * src) const;
00175     
00176     virtual KisID mathToolboxID() const;
00177 
00178     virtual void bitBlt(Q_UINT8 *dst,
00179                 Q_INT32 dststride,
00180                 KisColorSpace * srcSpace,
00181                 const Q_UINT8 *src,
00182                 Q_INT32 srcRowStride,
00183                 const Q_UINT8 *srcAlphaMask,
00184                 Q_INT32 maskRowStride,
00185                 Q_UINT8 opacity,
00186                 Q_INT32 rows,
00187                 Q_INT32 cols,
00188                 const KisCompositeOp& op);
00189 
00190 //========================== END of Public API ========================================//
00191 
00192 protected:
00193 
00194 
00199     virtual void bitBlt(Q_UINT8 *dst,
00200                 Q_INT32 dstRowSize,
00201                 const Q_UINT8 *src,
00202                 Q_INT32 srcRowStride,
00203                 const Q_UINT8 *srcAlphaMask,
00204                 Q_INT32 maskRowStride,
00205                 Q_UINT8 opacity,
00206                 Q_INT32 rows,
00207                 Q_INT32 cols,
00208                 const KisCompositeOp& op) = 0;
00209 
00210     virtual cmsHTRANSFORM createTransform(KisColorSpace * dstColorSpace,
00211                           KisProfile *  srcProfile,
00212                           KisProfile *  dstProfile,
00213                           Q_INT32 renderingIntent);
00214 
00215     virtual void compositeCopy(Q_UINT8 *dstRowStart, Q_INT32 dstRowStride, const Q_UINT8 *srcRowStart, Q_INT32 srcRowStride, const Q_UINT8 *maskRowStart, Q_INT32 maskRowStride, Q_INT32 rows, Q_INT32 numColumns, Q_UINT8 opacity);
00216 
00217 
00218     // So I don't need to re-implement it everywhere.
00219     template <typename ColorType,
00220               typename NativeMult, typename Uint8ToNative, typename NativeOpacityTest,
00221               int AlphaPos, int NonAlphaSize, int TotalSize>
00222     void abstractCompositeAlphaDarken(Q_UINT8 *dstRowStart, Q_INT32 dstRowStride,
00223                                       const Q_UINT8 *srcRowStart, Q_INT32 srcRowStride,
00224                                       const Q_UINT8 *maskRowStart, Q_INT32 maskRowStride,
00225                                       Q_INT32 rows, Q_INT32 numColumns, Q_UINT8 opacity,
00226                                       NativeMult nativeMult, Uint8ToNative uint8ToNative,
00227                                       NativeOpacityTest nativeOpacityTest) {
00228         while (rows > 0) {
00229 
00230             const ColorType *src = reinterpret_cast<const ColorType*>(srcRowStart);
00231             ColorType *dst = reinterpret_cast<ColorType*>(dstRowStart);
00232             const Q_UINT8 *mask = maskRowStart;
00233             Q_INT32 columns = numColumns;
00234 
00235             while (columns > 0) {
00236 
00237                 ColorType srcAlpha = src[AlphaPos];
00238                 ColorType dstAlpha = dst[AlphaPos];
00239 
00240                 // apply the alphamask
00241                 if(mask != 0)
00242                 {
00243                     if(*mask != OPACITY_OPAQUE)
00244                         srcAlpha = nativeMult(srcAlpha, uint8ToNative(*mask));
00245                     mask++;
00246                 }
00247 
00248                 if (opacity != OPACITY_OPAQUE) {
00249                     srcAlpha = nativeMult(srcAlpha, uint8ToNative(opacity));
00250                 }
00251 
00252                 // not transparent
00253                 if (nativeOpacityTest(srcAlpha) && srcAlpha >= dstAlpha) {
00254                     dst[AlphaPos] = srcAlpha;
00255                     memcpy(dst, src, NonAlphaSize * sizeof(ColorType));
00256                 }
00257 
00258                 columns--;
00259                 src += TotalSize;
00260                 dst += TotalSize;
00261             }
00262 
00263             rows--;
00264             srcRowStart += srcRowStride;
00265             dstRowStart += dstRowStride;
00266             if(maskRowStart)
00267                 maskRowStart += maskRowStride;
00268         }
00269     }
00270 
00271 protected:
00272 
00273     QStringList m_profileFilenames;
00274     Q_UINT8 * m_qcolordata; // A small buffer for conversion from and to qcolor.
00275     Q_INT32 m_alphaPos; // The position in _bytes_ of the alpha channel
00276     Q_INT32 m_alphaSize; // The width in _bytes_ of the alpha channel
00277 
00278     QValueVector<KisChannelInfo *> m_channels;
00279 
00280     KisColorSpaceFactoryRegistry * m_parent;
00281 
00282 private:
00283 
00284     cmsHTRANSFORM m_defaultToRGB;    // Default transform to 8 bit sRGB
00285     cmsHTRANSFORM m_defaultFromRGB;  // Default transform from 8 bit sRGB
00286 
00287     cmsHPROFILE   m_lastRGBProfile;  // Last used profile to transform to/from RGB
00288     cmsHTRANSFORM m_lastToRGB;       // Last used transform to transform to RGB
00289     cmsHTRANSFORM m_lastFromRGB;     // Last used transform to transform from RGB
00290 
00291     cmsHTRANSFORM m_defaultToLab;
00292     cmsHTRANSFORM m_defaultFromLab;
00293 
00294     KisProfile *  m_profile;
00295     KisColorSpace *m_lastUsedDstColorSpace;
00296     cmsHTRANSFORM m_lastUsedTransform;
00297 
00298     KisID m_id;
00299     DWORD m_cmType;                           // The colorspace type as defined by littlecms
00300     icColorSpaceSignature m_colorSpaceSignature; // The colorspace signature as defined in icm/icc files
00301 
00302     // cmsHTRANSFORM is a void *, so this should work.
00303     typedef QMap<KisColorSpace *, cmsHTRANSFORM>  TransformMap;
00304     TransformMap m_transforms; // Cache for existing transforms
00305 
00306     KisAbstractColorSpace(const KisAbstractColorSpace&);
00307     KisAbstractColorSpace& operator=(const KisAbstractColorSpace&);
00308 
00309     QMemArray<Q_UINT8> m_conversionCache; // XXX: This will be a bad problem when we have threading.
00310 };
00311 
00312 #endif // KIS_STRATEGY_COLORSPACE_H_
KDE Home | KDE Accessibility Home | Description of Access Keys