You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
koffice/chalk/chalkcolor/kis_colorspace.h

451 lines
16 KiB

/*
* Copyright (c) 2005 Boudewijn Rempt <boud@valdyas.org>
*
* 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_COLORSPACE_H_
#define KIS_COLORSPACE_H_
#include <config.h>
#include LCMS_HEADER
#include <tqvaluevector.h>
#include <tqvaluelist.h>
#include "kis_composite_op.h"
#include "kis_channelinfo.h"
class DCOPObject;
class KisProfile;
class KisColorSpaceFactoryRegistry;
class KisMathToolbox;
class KisFilter;
class KisColorAdjustment
{
public:
KisColorAdjustment() {};
virtual ~KisColorAdjustment() {};
};
enum ColorSpaceIndependence {
FULLY_INDEPENDENT,
TO_LAB16,
TO_RGBA8,
TO_RGBA16
};
/**
* A colorspace is the definition of a certain color model
* in Chalk. This is the definition of the public API for
* colormodels.
*/
class KisColorSpace {
public:
KisColorSpace();
virtual ~KisColorSpace();
virtual DCOPObject * dcopObject();
virtual bool operator==(const KisColorSpace& rhs) const {
return id().id() == rhs.id().id();
}
public:
//========== Channels =====================================================//
/// Return a vector describing all the channels this color model has.
virtual TQValueVector<KisChannelInfo *> channels() const = 0;
/**
* The total number of channels for a single pixel in this color model
*/
virtual TQ_UINT32 nChannels() const = 0;
/**
* The total number of color channels (excludes alpha and substance) for a single
* pixel in this color model.
*/
virtual TQ_UINT32 nColorChannels() const = 0;
/**
* The total number of substance channels for a single pixel
* in this color model
*/
virtual TQ_UINT32 nSubstanceChannels() const { return 0; };
/**
* The size in bytes of a single pixel in this color model
*/
virtual TQ_UINT32 pixelSize() const = 0;
/**
* Return a string with the channel's value suitable for display in the gui.
*/
virtual TQString channelValueText(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 0 to 1, if appropriate.
*/
virtual TQString normalisedChannelValueText(const TQ_UINT8 *pixel, TQ_UINT32 channelIndex) const = 0;
/**
* Convert the value of the channel at the specified position into
* an 8-bit value. The position is not the number of bytes, but
* the position of the channel as defined in the channel info list.
*/
virtual TQ_UINT8 scaleToU8(const TQ_UINT8 * srcPixel, TQ_INT32 channelPos) = 0;
/**
* Convert the value of the channel at the specified position into
* a 16-bit value. This may be upscaling or downscaling, depending
* on the defined value of the channel
*/
virtual TQ_UINT16 scaleToU16(const TQ_UINT8 * srcPixel, TQ_INT32 channelPos) = 0;
/**
* Set dstPixel to the pixel containing only the given channel of srcPixel. The remaining channels
* should be set to whatever makes sense for 'empty' channels of this colour space,
* with the intent being that the pixel should look like it only has the given channel.
*/
virtual void getSingleChannelPixel(TQ_UINT8 *dstPixel, const TQ_UINT8 *srcPixel, TQ_UINT32 channelIndex) = 0;
//========== Identification ===============================================//
/**
* Chalk definition for use in .kra files and internally: unchanging name +
* i18n'able description.
*/
virtual KisID id() const = 0;
/**
* lcms colorspace type definition.
*/
virtual TQ_UINT32 colorSpaceType() = 0;
virtual icColorSpaceSignature colorSpaceSignature() = 0;
/**
* If false, images in this colorspace will degrade considerably by
* functions, tools and filters that have the given measure of colorspace
* independence.
*
* @param independence the measure to which this colorspace will suffer
* from the manipulations of the tool or filter asking
* @return false if no degradation will take place, true if degradation will
* take place
*/
virtual bool willDegrade(ColorSpaceIndependence independence) = 0;
//========== Capabilities =================================================//
/**
* Returns the list of user-visible composite ops supported by this colourspace. Internal
* ops such as COPY, CLEAR, and ERASE, are not included as these make no sense
* for layers in the full image model.
*/
virtual KisCompositeOpList userVisiblecompositeOps() const = 0;
/**
* Returns true if the colorspace supports channel values outside the
* (normalised) range 0 to 1.
*/
virtual bool hasHighDynamicRange() const = 0;
//========== Display profiles =============================================//
/**
* Return the profile of this color space. This may be 0
*/
virtual KisProfile * getProfile() const = 0;
//================= Conversion functions ==================================//
/**
* The fromTQColor methods take a given color defined as an RGB TQColor
* and fills a byte array with the corresponding color in the
* the colorspace managed by this strategy.
*
* @param c the TQColor that will be used to fill dst
* @param dst a pointer to a pixel
* @param profile the optional profile that describes the color values of TQColor
*/
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 corresponding color in the
* the colorspace managed by this strategy.
*
* @param c the TQColor that will be used to fill dst
* @param opacity the opacity of the color
* @param dst a pointer to a pixel
* @param profile the optional profile that describes the color values of TQColor
*/
virtual void fromTQColor(const TQColor& c, TQ_UINT8 opacity, TQ_UINT8 *dst, KisProfile * profile = 0) = 0;
/**
* The toTQColor methods take a byte array that is at least pixelSize() long
* and converts the contents to a TQColor, using the given profile as a source
* profile and the optional profile as a destination profile.
*
* @param src a pointer to the source pixel
* @param c the TQColor that will be filled with the color at src
* @param profile the optional profile that describes the color in c, for instance the monitor profile
*/
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 to a TQColor, using the given profile as a source
* profile and the option profile as a destination profile.
*
* @param src a pointer to the source pixel
* @param c the TQColor that will be filled with the color at src
* @param opacity a pointer to a byte that will be filled with the opacity a src
* @param profile the optional profile that describes the color in c, for instance the monitor profile
*/
virtual void toTQColor(const TQ_UINT8 *src, TQColor *c, TQ_UINT8 *opacity, KisProfile * profile = 0) = 0;
/**
* Convert the pixels in data to (8-bit BGRA) TQImage using the specified profiles.
* The pixels are supposed to be encoded in this color model. The default implementation
* will convert the pixels using either the profiles or the default profiles for the
* current colorstrategy and the RGBA colorstrategy. If that is not what you want,
* or if you think you can do better than lcms, reimplement this methods.
*
* @param data A pointer to a contiguous memory region containing width * height pixels
* @param width in pixels
* @param height in pixels
* @param dstProfile destination profile
* @param renderingIntent the rendering intent
* @param exposure The exposure setting for rendering a preview of a high dynamic range image.
*/
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 specified data to Lab. All colorspaces are guaranteed to support this
*
* @param src the source data
* @param dst the destination data
* @param nPixels the number of source pixels
*/
virtual void toLabA16(const TQ_UINT8 * src, TQ_UINT8 * dst, const TQ_UINT32 nPixels) const = 0;
/**
* Convert the specified data from Lab. to this colorspace. All colorspaces are
* guaranteed to support this.
*
* @param src the pixels in 16 bit lab format
* @param dst the destination data
* @param nPixels the number of pixels in the array
*/
virtual void fromLabA16(const TQ_UINT8 * src, TQ_UINT8 * dst, const TQ_UINT32 nPixels) const = 0;
/**
* Convert a byte array of srcLen pixels *src to the specified color space
* and put the converted bytes into the prepared byte array *dst.
*
* Returns false if the conversion failed, true if it succeeded
*/
virtual bool convertPixelsTo(const TQ_UINT8 * src,
TQ_UINT8 * dst, KisColorSpace * dstColorSpace,
TQ_UINT32 numPixels,
TQ_INT32 renderingIntent = INTENT_PERCEPTUAL) = 0;
//============================== Manipulation functions ==========================//
//
// The manipulation functions have default implementations that _convert_ the pixel
// to a TQColor and back. Reimplement these methods in your color strategy!
//
/**
* Get the alpha value of the given pixel, downscaled to an 8-bit value.
*/
virtual TQ_UINT8 getAlpha(const TQ_UINT8 * pixel) const = 0;
/**
* Set the alpha channel of the given run of pixels to the given value.
*
* pixels -- a pointer to the pixels that will have their alpha set to this value
* alpha -- a downscaled 8-bit value for opacity
* nPixels -- the number of pixels
*
*/
virtual void setAlpha(TQ_UINT8 * pixels, TQ_UINT8 alpha, TQ_INT32 nPixels) const = 0;
/**
* Multiply the alpha channel of the given run of pixels by the given value.
*
* pixels -- a pointer to the pixels that will have their alpha set to this value
* alpha -- a downscaled 8-bit value for opacity
* nPixels -- the number of pixels
*
*/
virtual void multiplyAlpha(TQ_UINT8 * pixels, TQ_UINT8 alpha, TQ_INT32 nPixels) = 0;
/**
* Applies the specified 8-bit alpha tqmask to the pixels. We assume that there are just
* as many alpha values as pixels but we do not check this; the alpha values
* are assumed to be 8-bits.
*/
virtual void applyAlphaU8Mask(TQ_UINT8 * pixels, TQ_UINT8 * alpha, TQ_INT32 nPixels) = 0;
/**
* Applies the inverted 8-bit alpha tqmask to the pixels. We assume that there are just
* as many alpha values as pixels but we do not check this; the alpha values
* are assumed to be 8-bits.
*/
virtual void applyInverseAlphaU8Mask(TQ_UINT8 * pixels, TQ_UINT8 * alpha, TQ_INT32 nPixels) = 0;
/**
* Create an adjustment object for adjusting the brightness and contrast
* transferValues is a 256 bins array with values from 0 to 0xFFFF
*/
virtual KisColorAdjustment *createBrightnessContrastAdjustment(TQ_UINT16 *transferValues) = 0;
/**
* Create an adjustment object for desaturating
*/
virtual KisColorAdjustment *createDesaturateAdjustment() = 0;
/**
* Create an adjustment object for adjusting individual channels
* transferValues is an array of nColorChannels number of 256 bins array with values from 0 to 0xFFFF
*/
virtual KisColorAdjustment *createPerChannelAdjustment(TQ_UINT16 **transferValues) = 0;
/**
* Apply the adjustment created with onr of the other functions
*/
virtual void applyAdjustment(const TQ_UINT8 *src, TQ_UINT8 *dst, KisColorAdjustment *, TQ_INT32 nPixels) = 0;
/**
* Invert color channels of the given pixels
*/
virtual void invertColor(TQ_UINT8 * src, TQ_INT32 nPixels) = 0;
// XXX: What with alpha channels? YYY: Add an overloaded function that takes alpha into account?
/**
* Get the difference between 2 colors, normalized in the range (0,255)
*/
virtual TQ_UINT8 difference(const TQ_UINT8* src1, const TQ_UINT8* src2) = 0;
/**
* Mix the colors given their weights and return in dst
* The sum of weights is assumed 255 */
virtual void mixColors(const TQ_UINT8 **colors, const TQ_UINT8 *weights, TQ_UINT32 nColors, TQ_UINT8 *dst) const = 0;
/**
* Convolve the given array of pointers to pixels and return the result
* in dst. The kernel values are clamped between -128 and 128
*/
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;
/**
* Darken all color channels with the given amount. If compensate is true,
* the compensation factor will be used to limit the darkening.
*
* (See the bumpmap filter)
*/
virtual void darken(const TQ_UINT8 * src, TQ_UINT8 * dst, TQ_INT32 shade, bool compensate, double compensation, TQ_INT32 nPixels) const = 0;
/**
* Calculate the intensity of the given pixel, scaled down to the range 0-255. XXX: Maybe this should be more flexible
*/
virtual TQ_UINT8 intensity8(const TQ_UINT8 * src) const = 0;
/**
* Create a mathematical toolbox compatible with this colorspace
*/
virtual KisID mathToolboxID() const =0;
/**
* Compose two arrays of pixels together. If source and target
* are not the same colour model, the source pixels will be
* converted to the target model.
*/
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;
/**
* The backgroundfilters will be run periodically on the newly
* created paint device. XXX: Currently this uses times and not
* threads.
*/
virtual TQValueList<KisFilter*> createBackgroundFilters()
{ return TQValueList<KisFilter*>(); };
private:
DCOPObject * m_dcop;
};
class KisColorSpaceFactory {
public:
/**
* Chalk definition for use in .kra files and internally: unchanging name +
* i18n'able description.
*/
virtual KisID id() const = 0;
/**
* lcms colorspace type definition.
*/
virtual TQ_UINT32 colorSpaceType() = 0;
virtual icColorSpaceSignature colorSpaceSignature() = 0;
virtual KisColorSpace *createColorSpace(KisColorSpaceFactoryRegistry * tqparent, KisProfile *) = 0;
/**
* Returns the default icc profile for use with this colorspace. This may be ""
*
& @return the default icc profile name
*/
virtual TQString defaultProfile() = 0;
};
#endif // KIS_COLORSPACE_H_