5
#include <qimageformatplugin.h>
6
#include <qvaluestack.h>
7
#include <qvaluevector.h>
12
// Safe readBlock helper functions
13
class SafeDataStream {
15
SafeDataStream(QIODevice* device)
16
: mDevice(device), mFailed(false) {}
18
bool failed() const { return mFailed; }
19
QIODevice* device() const { return mDevice; }
21
SafeDataStream& readRawBytes(char* data, uint length) {
22
if (mFailed) return *this;
23
int read_length=mDevice->readBlock(data, length);
24
if (read_length==-1) mFailed=true;
25
if ((uint)read_length!=length) mFailed=true;
29
SafeDataStream& operator>>(Q_INT8& value) {
30
return readRawBytes((char*)&value, 1);
33
SafeDataStream& operator>>(Q_UINT32& value) {
34
if (mFailed) return *this;
35
uchar *p = (uchar *)(&value);
37
if (mDevice->readBlock( b, 4 )==4) {
48
SafeDataStream& operator>>(Q_INT32& value) {
49
return *this >>((Q_UINT32&)value);
52
SafeDataStream& operator>>(float& value) {
53
return *this >>((Q_UINT32&)value);
56
SafeDataStream& operator>>(char*& value) {
57
if (mFailed) return *this;
61
if (mFailed) return *this;
66
if (mDevice->atEnd() ) {
71
value = new char[len];
77
return readRawBytes(value, len);
80
SafeDataStream& readBytes(char*& data, uint& len) {
81
if (mFailed) return *this;
84
if (mFailed) return *this;
91
return readRawBytes(data, len);
94
// This method is usefull to debug with gdb. Do not inline it!
102
//! Plug-in for loading a GIMP XCF image file directly.
104
* This class uses the Qt 3.0 Image format plug-in loader to provide
105
* the ability to read The GIMP XCF image files. This plug-in will
106
* be dynamically loaded as needed.
108
class XCFImageFormat : public QImageFormatPlugin {
111
* Each layer in an XCF file is stored as a matrix of
112
* 64-pixel by 64-pixel images. The GIMP has a sophisticated
113
* method of handling very large images as well as implementing
114
* parallel processing on a tile-by-tile basis. Here, though,
115
* we just read them in en-masse and store them in a matrix.
117
typedef QValueVector< QValueVector< QImage > > Tiles;
120
* Each GIMP image is composed of one or more layers. A layer can
121
* be one of any three basic types: RGB, grayscale or indexed. With an
122
* optional alpha channel, there are six possible types altogether.
124
* Note: there is only ever one instance of this structure. The
125
* layer info is discarded after it is merged into the final QImage.
128
Q_UINT32 width; //!< Width of the layer
129
Q_UINT32 height; //!< Height of the layer
130
Q_INT32 type; //!< Type of the layer (GimpImageType)
131
char* name; //!< Name of the layer
132
Q_UINT32 hierarchy_offset; //!< File position of Tile hierarchy
133
Q_UINT32 mask_offset; //!< File position of mask image
135
uint nrows; //!< Number of rows of tiles (y direction)
136
uint ncols; //!< Number of columns of tiles (x direction)
138
Tiles image_tiles; //!< The basic image
139
//! For Grayscale and Indexed images, the alpha channel is stored
140
//! separately (in this data structure, anyway).
142
Tiles mask_tiles; //!< The layer mask (optional)
144
//! Additional information about a layer mask.
148
Q_UINT32 show_masked;
149
uchar red, green, blue;
153
bool active; //!< Is this layer the active layer?
154
Q_UINT32 opacity; //!< The opacity of the layer
155
Q_UINT32 visible; //!< Is the layer visible?
156
Q_UINT32 linked; //!< Is this layer linked (geometrically)
157
Q_UINT32 preserve_transparency; //!< Preserve alpha when drawing on layer?
158
Q_UINT32 apply_mask; //!< Apply the layer mask?
159
Q_UINT32 edit_mask; //!< Is the layer mask the being edited?
160
Q_UINT32 show_mask; //!< Show the layer mask rather than the image?
161
Q_INT32 x_offset; //!< x offset of the layer relative to the image
162
Q_INT32 y_offset; //!< y offset of the layer relative to the image
163
Q_UINT32 mode; //!< Combining mode of layer (LayerModeEffects)
164
Q_UINT32 tattoo; //!< (unique identifier?)
166
//! As each tile is read from the file, it is buffered here.
167
uchar tile[TILE_WIDTH * TILE_HEIGHT * sizeof(QRgb)];
169
//! The data from tile buffer is copied to the Tile by this
170
//! method. Depending on the type of the tile (RGB, Grayscale,
171
//! Indexed) and use (image or mask), the bytes in the buffer are
172
//! copied in different ways.
173
void (*assignBytes)( Layer& layer, uint i, uint j );
175
//! Construct a layer.
176
Layer ( void ) : name( 0 ) {}
177
//! Destruct the layer.
178
~Layer ( void ) { if ( name != 0 ) delete[] name; }
182
* The in-memory representation of the XCF Image. It contains a few
183
* metadata items, but is mostly a container for the layer information.
186
Q_UINT32 width; //!< width of the XCF image
187
Q_UINT32 height; //!< height of the XCF image
188
Q_INT32 type; //!< type of the XCF image (GimpImageBaseType)
190
Q_UINT8 compression; //!< tile compression method (CompressionType)
191
float x_resolution; //!< x resolution in dots per inch
192
float y_resolution; //!< y resolution in dots per inch
193
Q_INT32 tattoo; //!< (unique identifier?)
194
Q_UINT32 unit; //!< Units of The GIMP (inch, mm, pica, etc...)
195
Q_INT32 num_colors; //!< number of colors in an indexed image
196
QValueVector< QRgb > palette; //!< indexed image color palette
198
int num_layers; //!< number of layers
199
Layer layer; //!< most recently read layer
201
bool initialized; //!< Is the QImage initialized?
202
QImage image; //!< final QImage
204
//! Simple constructor.
205
XCFImage ( void ) : initialized( false ) {}
208
//! The bottom-most layer is copied into the final QImage by this
210
typedef void (*PixelCopyOperation) ( Layer& layer, uint i, uint j, int k, int l,
211
QImage& image, int m, int n );
213
//! Higher layers are merged into the the final QImage by this routine.
214
typedef void (*PixelMergeOperation) ( Layer& layer, uint i, uint j, int k, int l,
215
QImage& image, int m, int n );
217
//! In layer DISSOLVE mode, a random number is chosen to compare to a
218
//! pixel's alpha. If the alpha is greater than the random number, the
219
//! pixel is drawn. This table merely contains the random number seeds
220
//! for each ROW of an image. Therefore, the random numbers chosen
221
//! are consistent from run to run.
223
static int random_table[RANDOM_TABLE_SIZE];
225
//! This table provides the add_pixel saturation values (i.e. 250 + 250 = 255).
227
static int add_lut[256][256];
229
//! Layer mode static data.
231
bool affect_alpha; //!< Does this mode affect the source alpha?
234
//! Array of layer mode structures for the modes described by
235
//! LayerModeEffects.
236
static LayerModes layer_modes[];
240
* The constructor for the XCF image loader. This initializes the
241
* tables used in the layer merging routines.
247
* The image loader makes no (direct) use of dynamic memory
248
* and the Qt infrastructure takes care of constructing and destructing
249
* the loader so there is not much to do here.
251
~XCFImageFormat () {}
254
* You can query Qt about the types of image file formats it knows about
255
* via QImage::inputFormats or QImage::inputFormatList().
256
* This method returns "xcf".
258
QStringList keys () const {
259
return QStringList() << "XCF";
263
* This method installs the XCF reader on demand.
265
bool installIOHandler ( const QString& );
267
static void registerFormat();
270
static void readXCF ( QImageIO* image_io );
272
static void writeXCF ( QImageIO* ) {}
274
static void initializeImage ( XCFImage& xcf_image );
275
static void composeTiles ( XCFImage& xcf_image );
276
static bool loadImageProperties ( SafeDataStream& xcf_io, XCFImage& image );
277
static bool loadLayer ( SafeDataStream& xcf_io, XCFImage& xcf_image );
278
static bool loadLayerProperties ( SafeDataStream& xcf_io, Layer& layer );
279
static bool loadChannelProperties ( SafeDataStream& xcf_io, Layer& layer );
280
static bool loadHierarchy ( SafeDataStream& xcf_io, Layer& layer );
281
static bool loadMask ( SafeDataStream& xcf_io, Layer& layer );
282
static bool loadLevel ( SafeDataStream& xcf_io, Layer& layer, Q_INT32 bpp );
283
static bool loadTileRLE ( SafeDataStream& xcf_io, uchar* tile, int size,
284
int data_length, Q_INT32 bpp );
285
static bool loadProperty ( SafeDataStream& xcf_io, PropType& type,
287
static void setGrayPalette ( QImage& image );
288
static void setPalette ( XCFImage& xcf_image, QImage& image );
289
static void assignImageBytes ( Layer& layer, uint i, uint j );
290
static void assignMaskBytes ( Layer& layer, uint i, uint j );
292
static void copyLayerToImage ( XCFImage& xcf_image );
293
static void copyRGBToRGB ( Layer& layer, uint i, uint j, int k, int l,
294
QImage& image, int m, int n );
295
static void copyGrayToGray ( Layer& layer, uint i, uint j, int k, int l,
296
QImage& image, int m, int n );
297
static void copyGrayToRGB ( Layer& layer, uint i, uint j, int k, int l,
298
QImage& image, int m, int n );
299
static void copyGrayAToRGB ( Layer& layer, uint i, uint j, int k, int l,
300
QImage& image, int m, int n );
301
static void copyIndexedToIndexed ( Layer& layer, uint i, uint j, int k, int l,
302
QImage& image, int m, int n );
303
static void copyIndexedAToIndexed ( Layer& layer, uint i, uint j, int k, int l,
304
QImage& image, int m, int n );
305
static void copyIndexedAToRGB ( Layer& layer, uint i, uint j, int k, int l,
306
QImage& image, int m, int n );
308
static void mergeLayerIntoImage ( XCFImage& xcf_image );
309
static void mergeRGBToRGB ( Layer& layer, uint i, uint j, int k, int l,
310
QImage& image, int m, int n );
311
static void mergeGrayToGray ( Layer& layer, uint i, uint j, int k, int l,
312
QImage& image, int m, int n );
313
static void mergeGrayAToGray ( Layer& layer, uint i, uint j, int k, int l,
314
QImage& image, int m, int n );
315
static void mergeGrayToRGB ( Layer& layer, uint i, uint j, int k, int l,
316
QImage& image, int m, int n );
317
static void mergeGrayAToRGB ( Layer& layer, uint i, uint j, int k, int l,
318
QImage& image, int m, int n );
319
static void mergeIndexedToIndexed ( Layer& layer, uint i, uint j, int k, int l,
320
QImage& image, int m, int n );
321
static void mergeIndexedAToIndexed ( Layer& layer, uint i, uint j, int k, int l,
322
QImage& image, int m, int n );
323
static void mergeIndexedAToRGB ( Layer& layer, uint i, uint j, int k, int l,
324
QImage& image, int m, int n );
326
static void dissolveRGBPixels ( QImage& image, int x, int y );
327
static void dissolveAlphaPixels ( QImage& image, int x, int y );