1 /*
2  *  Copyright (c) 2009 Boudewijn Rempt <boud@valdyas.org>
3  *
4  *  This program is free software; you can redistribute it and/or modify
5  *  it under the terms of the GNU General Public License as published by
6  *  the Free Software Foundation; either version 2 of the License, or
7  *  (at your option) any later version.
8  *
9  *  This program is distributed in the hope that it will be useful,
10  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  *  GNU General Public License for more details.
13  *
14  *  You should have received a copy of the GNU General Public License
15  *  along with this program; if not, write to the Free Software
16  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  */
18 #ifndef KIS_FIXED_PAINT_DEVICE_H
19 #define KIS_FIXED_PAINT_DEVICE_H
20 
21 #include <kritaimage_export.h>
22 #include <KoColorSpace.h>
23 #include "kis_shared.h"
24 #include <kis_shared_ptr.h>
25 
26 #include <QRect>
27 #include <QImage>
28 #include "KisOptimizedByteArray.h"
29 
30 class KoColor;
31 
32 
33 /**
34  * A fixed paint device is a simple paint device that consists of an array
35  * of bytes and a rectangle. It cannot grow, it cannot shrink, all you can
36  * do is fill the paint device with the right bytes and use it as an argument
37  * to KisPainter or use the bytes as an argument to KoColorSpace functions.
38  */
39 class KRITAIMAGE_EXPORT KisFixedPaintDevice : public KisShared
40 {
41 
42 public:
43 
44     KisFixedPaintDevice(const KoColorSpace* colorSpace,
45                         KisOptimizedByteArray::MemoryAllocatorSP allocator = KisOptimizedByteArray::MemoryAllocatorSP());
46     virtual ~KisFixedPaintDevice();
47 
48     /**
49      * Deep copy the fixed paint device, including the data.
50      */
51     KisFixedPaintDevice(const KisFixedPaintDevice& rhs);
52 
53     /**
54      * Deep copy the fixed paint device, including the data.
55      */
56     KisFixedPaintDevice& operator=(const KisFixedPaintDevice& rhs);
57 
58     /**
59      * setRect sets the rect of the fixed paint device to rect.
60      * This will _not_ create the associated data area.
61      *
62      * @param rc the bounds in pixels. The x,y of the rect represent the origin
63      * of the fixed paint device.
64      */
65     void setRect(const QRect& rc);
66 
67     /**
68      * @return the rect that the data represents
69      */
70     QRect bounds() const;
71 
72     /**
73      * @return the amount of allocated pixels (you can fake the size with setRect/bounds)
74      * It is useful to know the accumulated memory size in pixels (not in bytes) for optimizations to avoid re-allocation.
75      */
76     int allocatedPixels() const;
77 
78 
79     /**
80      * @return the pixelSize associated with this fixed paint device.
81      */
82     quint32 pixelSize() const;
83 
colorSpace()84     const KoColorSpace* colorSpace() const {
85         return m_colorSpace;
86     }
87 
88     /**
89      * initializes the paint device.
90      *
91      * @param defaultValue the default byte with which all pixels will be filled.
92      * @return false if the allocation failed.
93      */
94     bool initialize(quint8 defaultValue = 0);
95 
96     /**
97      * Changed the size of the internal buffer to accommodate the exact number of bytes
98      * needed to store area bounds(). The allocated data is *not* initialized!
99      */
100     void reallocateBufferWithoutInitialization();
101 
102     /**
103      * If the size of the internal buffer is smaller than the one needed to accommodate
104      * bounds(), resize the buffer. Otherwise, do nothing. The allocated data is neither
105      * copying or initialized!
106      */
107     void lazyGrowBufferWithoutInitialization();
108 
109     /**
110      * @return a pointer to the beginning of the data associated with this fixed paint device.
111      */
112     quint8* data();
113 
114     const quint8* constData() const;
115 
116     quint8* data() const;
117 
118     /**
119      * Read the bytes representing the rectangle described by x, y, w, h into
120      * data. If data is not big enough, Krita will gladly overwrite the rest
121      * of your precious memory.
122      *
123      * Since this is a copy, you need to make sure you have enough memory.
124      *
125      * The reading is done only if the rectangular area x,y,w,h is inside the bounds of the device
126      * and the device is not empty
127      */
128     void readBytes(quint8 * dstData, qint32 x, qint32 y, qint32 w, qint32 h) const;
129 
130     /**
131      *   Converts the paint device to a different colorspace
132      */
133     void convertTo(const KoColorSpace * dstColorSpace = 0,
134                    KoColorConversionTransformation::Intent renderingIntent = KoColorConversionTransformation::internalRenderingIntent(),
135                    KoColorConversionTransformation::ConversionFlags conversionFlags = KoColorConversionTransformation::internalConversionFlags());
136 
137     /**
138      * Set color profile for the device without converting actual pixel data
139      */
140     void setProfile(const KoColorProfile *profile);
141 
142     /**
143      * Fill this paint device with the data from image
144      *
145      * @param image the image
146      * @param srcProfileName name of the RGB profile to interpret the image as. 0 is interpreted as sRGB
147      */
148     virtual void convertFromQImage(const QImage& image, const QString &srcProfileName);
149 
150     /**
151      * Create an RGBA QImage from a rectangle in the paint device.
152      *
153      * @param dstProfile RGB profile to use in conversion. May be 0, in which
154      * case it's up to the color strategy to choose a profile (most
155      * like sRGB).
156      * @param x Left coordinate of the rectangle
157      * @param y Top coordinate of the rectangle
158      * @param w Width of the rectangle in pixels
159      * @param h Height of the rectangle in pixels
160      * @param renderingIntent Rendering intent
161      * @param conversionFlags Conversion flags
162      */
163     virtual QImage convertToQImage(const KoColorProfile *dstProfile, qint32 x, qint32 y, qint32 w, qint32 h,
164                                    KoColorConversionTransformation::Intent renderingIntent = KoColorConversionTransformation::internalRenderingIntent(),
165                                    KoColorConversionTransformation::ConversionFlags conversionFlags = KoColorConversionTransformation::internalConversionFlags()) const;
166 
167     /**
168      * Create an RGBA QImage from a rectangle in the paint device. The
169      * rectangle is defined by the parent image's bounds.
170      *
171      * @param dstProfile RGB profile to use in conversion. May be 0, in which
172      * case it's up to the color strategy to choose a profile (most
173      * like sRGB).
174      * @param renderingIntent The rendering intent of conversion.
175      * @param conversionFlags The conversion flags.
176      */
177     virtual QImage convertToQImage(const KoColorProfile *dstProfile,
178                                    KoColorConversionTransformation::Intent renderingIntent = KoColorConversionTransformation::internalRenderingIntent(),
179                                    KoColorConversionTransformation::ConversionFlags conversionFlags = KoColorConversionTransformation::internalConversionFlags()) const;
180 
181     /**
182      * Clear the given rectangle to transparent black.
183      *
184      * XXX: this will not (yet) expand the paint device to contain the specified rect
185      * but if the paintdevice has not been initialized, it will be.
186      */
187     void clear(const QRect & rc);
188 
189     /**
190      * Fill the given rectangle with the given pixel. This does not take the
191      * selection into account.
192      *
193      * XXX: this will not (yet) expand the paint device to contain the specified rect
194      * but if the paintdevice has not been initialized, it will be.
195      */
196     void fill(qint32 x, qint32 y, qint32 w, qint32 h, const quint8 *fillPixel);
197 
198     void fill(const QRect &rc, const KoColor &color);
199 
200 
201     /**
202      * Mirrors the device.
203      */
204     void mirror(bool horizontal, bool vertical);
205 
206 private:
207 
208     const KoColorSpace* m_colorSpace;
209     QRect m_bounds;
210     KisOptimizedByteArray m_data;
211 };
212 
213 #endif
214