~ubuntu-branches/ubuntu/intrepid/gwenview/intrepid

« back to all changes in this revision

Viewing changes to src/qxcfi.h

  • Committer: Bazaar Package Importer
  • Author(s): Christopher Martin
  • Date: 2005-04-06 11:33:06 UTC
  • mfrom: (1.2.1 upstream) (2.1.1 warty)
  • Revision ID: james.westby@ubuntu.com-20050406113306-7zovl7z0io5bacpd
Tags: 1.2.0-1
* New upstream release.
  + Fixes crashes when using "Back" to navigate. (Closes: #301811)
* Enable KIPI support.
* Add a doc-base file for the handbook.

Show diffs side-by-side

added added

removed removed

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