File indexing completed on 2024-05-12 15:58:16
0001 /* 0002 * SPDX-FileCopyrightText: 2009 Boudewijn Rempt <boud@valdyas.org> 0003 * 0004 * SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 #ifndef KIS_FIXED_PAINT_DEVICE_H 0007 #define KIS_FIXED_PAINT_DEVICE_H 0008 0009 #include <kritaimage_export.h> 0010 #include <KoColorSpace.h> 0011 #include "kis_shared.h" 0012 #include <kis_shared_ptr.h> 0013 0014 #include <QRect> 0015 #include <QImage> 0016 #include "KisOptimizedByteArray.h" 0017 0018 class KoColor; 0019 0020 0021 /** 0022 * A fixed paint device is a simple paint device that consists of an array 0023 * of bytes and a rectangle. It cannot grow, it cannot shrink, all you can 0024 * do is fill the paint device with the right bytes and use it as an argument 0025 * to KisPainter or use the bytes as an argument to KoColorSpace functions. 0026 */ 0027 class KRITAIMAGE_EXPORT KisFixedPaintDevice : public KisShared 0028 { 0029 0030 public: 0031 0032 KisFixedPaintDevice(const KoColorSpace* colorSpace, 0033 KisOptimizedByteArray::MemoryAllocatorSP allocator = KisOptimizedByteArray::MemoryAllocatorSP()); 0034 virtual ~KisFixedPaintDevice(); 0035 0036 /** 0037 * Deep copy the fixed paint device, including the data. 0038 */ 0039 KisFixedPaintDevice(const KisFixedPaintDevice& rhs); 0040 0041 /** 0042 * Deep copy the fixed paint device, including the data. 0043 */ 0044 KisFixedPaintDevice& operator=(const KisFixedPaintDevice& rhs); 0045 0046 /** 0047 * setRect sets the rect of the fixed paint device to rect. 0048 * This will _not_ create the associated data area. 0049 * 0050 * @param rc the bounds in pixels. The x,y of the rect represent the origin 0051 * of the fixed paint device. 0052 */ 0053 void setRect(const QRect& rc); 0054 0055 /** 0056 * setColorSpace reassigns the color space of the paint device 0057 * **without** converting or reallocating the buffer. One needs 0058 * to update the buffer manually after that. 0059 */ 0060 void setColorSpace(const KoColorSpace *cs); 0061 0062 /** 0063 * @return the rect that the data represents 0064 */ 0065 QRect bounds() const; 0066 0067 /** 0068 * @return the amount of allocated pixels (you can fake the size with setRect/bounds) 0069 * It is useful to know the accumulated memory size in pixels (not in bytes) for optimizations to avoid re-allocation. 0070 */ 0071 int allocatedPixels() const; 0072 0073 0074 /** 0075 * @return the pixelSize associated with this fixed paint device. 0076 */ 0077 quint32 pixelSize() const; 0078 0079 const KoColorSpace* colorSpace() const { 0080 return m_colorSpace; 0081 } 0082 0083 /** 0084 * initializes the paint device. 0085 * 0086 * @param defaultValue the default byte with which all pixels will be filled. 0087 * @return false if the allocation failed. 0088 */ 0089 bool initialize(quint8 defaultValue = 0); 0090 0091 /** 0092 * Changed the size of the internal buffer to accommodate the exact number of bytes 0093 * needed to store area bounds(). The allocated data is *not* initialized! 0094 */ 0095 void reallocateBufferWithoutInitialization(); 0096 0097 /** 0098 * If the size of the internal buffer is smaller than the one needed to accommodate 0099 * bounds(), resize the buffer. Otherwise, do nothing. The allocated data is neither 0100 * copying or initialized! 0101 */ 0102 void lazyGrowBufferWithoutInitialization(); 0103 0104 /** 0105 * @return a pointer to the beginning of the data associated with this fixed paint device. 0106 */ 0107 quint8* data(); 0108 0109 const quint8* constData() const; 0110 0111 quint8* data() const; 0112 0113 /** 0114 * Read the bytes representing the rectangle described by x, y, w, h into 0115 * data. If data is not big enough, Krita will gladly overwrite the rest 0116 * of your precious memory. 0117 * 0118 * Since this is a copy, you need to make sure you have enough memory. 0119 * 0120 * The reading is done only if the rectangular area x,y,w,h is inside the bounds of the device 0121 * and the device is not empty 0122 */ 0123 void readBytes(quint8 * dstData, qint32 x, qint32 y, qint32 w, qint32 h) const; 0124 0125 /** 0126 * Converts the paint device to a different colorspace 0127 */ 0128 void convertTo(const KoColorSpace * dstColorSpace = 0, 0129 KoColorConversionTransformation::Intent renderingIntent = KoColorConversionTransformation::internalRenderingIntent(), 0130 KoColorConversionTransformation::ConversionFlags conversionFlags = KoColorConversionTransformation::internalConversionFlags()); 0131 0132 /** 0133 * Set color profile for the device without converting actual pixel data 0134 */ 0135 void setProfile(const KoColorProfile *profile); 0136 0137 /** 0138 * Fill this paint device with the data from image 0139 * 0140 * @param image the image 0141 * @param srcProfileName name of the RGB profile to interpret the image as. 0 is interpreted as sRGB 0142 */ 0143 virtual void convertFromQImage(const QImage& image, const QString &srcProfileName); 0144 0145 /** 0146 * Create an RGBA QImage from a rectangle in the paint device. 0147 * 0148 * @param dstProfile RGB profile to use in conversion. May be 0, in which 0149 * case it's up to the color strategy to choose a profile (most 0150 * like sRGB). 0151 * @param x Left coordinate of the rectangle 0152 * @param y Top coordinate of the rectangle 0153 * @param w Width of the rectangle in pixels 0154 * @param h Height of the rectangle in pixels 0155 * @param renderingIntent Rendering intent 0156 * @param conversionFlags Conversion flags 0157 */ 0158 virtual QImage convertToQImage(const KoColorProfile *dstProfile, qint32 x, qint32 y, qint32 w, qint32 h, 0159 KoColorConversionTransformation::Intent renderingIntent = KoColorConversionTransformation::internalRenderingIntent(), 0160 KoColorConversionTransformation::ConversionFlags conversionFlags = KoColorConversionTransformation::internalConversionFlags()) const; 0161 0162 /** 0163 * Create an RGBA QImage from a rectangle in the paint device. The 0164 * rectangle is defined by the parent image's bounds. 0165 * 0166 * @param dstProfile RGB profile to use in conversion. May be 0, in which 0167 * case it's up to the color strategy to choose a profile (most 0168 * like sRGB). 0169 * @param renderingIntent The rendering intent of conversion. 0170 * @param conversionFlags The conversion flags. 0171 */ 0172 virtual QImage convertToQImage(const KoColorProfile *dstProfile, 0173 KoColorConversionTransformation::Intent renderingIntent = KoColorConversionTransformation::internalRenderingIntent(), 0174 KoColorConversionTransformation::ConversionFlags conversionFlags = KoColorConversionTransformation::internalConversionFlags()) const; 0175 0176 /** 0177 * Clear the given rectangle to transparent black. 0178 * 0179 * XXX: this will not (yet) expand the paint device to contain the specified rect 0180 * but if the paintdevice has not been initialized, it will be. 0181 */ 0182 void clear(const QRect & rc); 0183 0184 /** 0185 * Fill the given rectangle with the given pixel. This does not take the 0186 * selection into account. 0187 * 0188 * XXX: this will not (yet) expand the paint device to contain the specified rect 0189 * but if the paintdevice has not been initialized, it will be. 0190 */ 0191 void fill(qint32 x, qint32 y, qint32 w, qint32 h, const quint8 *fillPixel); 0192 0193 void fill(const QRect &rc, const KoColor &color); 0194 0195 0196 /** 0197 * Mirrors the device. 0198 */ 0199 void mirror(bool horizontal, bool vertical); 0200 0201 private: 0202 0203 const KoColorSpace* m_colorSpace; 0204 QRect m_bounds; 0205 KisOptimizedByteArray m_data; 0206 }; 0207 0208 #endif