~ubuntu-branches/ubuntu/edgy/gwenview/edgy

« back to all changes in this revision

Viewing changes to src/gvcore/qxcfi.h

  • Committer: Bazaar Package Importer
  • Author(s): Jonathan Riddell
  • Date: 2005-12-06 17:59:19 UTC
  • mfrom: (1.1.3 upstream) (2.1.1 sarge)
  • Revision ID: james.westby@ubuntu.com-20051206175919-8yv9nfmw0pws6p52
Tags: 1.3.1-0ubuntu1
* Sync with Debian
* Edit kde.mk for .pot generation

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
namespace Gwenview {
 
11
 
 
12
// Safe readBlock helper functions
 
13
class SafeDataStream {
 
14
public:
 
15
  SafeDataStream(QIODevice* device)
 
16
  : mDevice(device), mFailed(false) {}
 
17
 
 
18
  bool failed() const { return mFailed; }
 
19
  QIODevice* device() const { return mDevice; }
 
20
 
 
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;
 
26
        return *this;
 
27
  }
 
28
 
 
29
  SafeDataStream& operator>>(Q_INT8& value) {
 
30
        return readRawBytes((char*)&value, 1);
 
31
  }
 
32
 
 
33
  SafeDataStream& operator>>(Q_UINT32& value) {
 
34
        if (mFailed) return *this;
 
35
        uchar *p = (uchar *)(&value);
 
36
        char b[4];
 
37
        if (mDevice->readBlock( b, 4 )==4) {
 
38
          *p++ = b[3];
 
39
          *p++ = b[2];
 
40
          *p++ = b[1];
 
41
          *p   = b[0];
 
42
        } else {
 
43
          mFailed=true;
 
44
        }
 
45
        return *this;
 
46
  }
 
47
 
 
48
  SafeDataStream& operator>>(Q_INT32& value) {
 
49
        return *this >>((Q_UINT32&)value);
 
50
  }
 
51
 
 
52
  SafeDataStream& operator>>(float& value) {
 
53
        return *this >>((Q_UINT32&)value);
 
54
  }
 
55
 
 
56
  SafeDataStream& operator>>(char*& value) {
 
57
        if (mFailed) return *this;
 
58
        
 
59
        Q_UINT32 len;
 
60
        *this >> len;
 
61
        if (mFailed) return *this;
 
62
        if ( len == 0 ) {
 
63
          value = 0;
 
64
          return *this;
 
65
        }
 
66
        if (mDevice->atEnd() ) {
 
67
          value = 0;
 
68
          mFailed=true;
 
69
          return *this;
 
70
        }
 
71
        value = new char[len];
 
72
        Q_CHECK_PTR( value );
 
73
        if ( !value ) {
 
74
          mFailed=true;
 
75
          return *this;
 
76
        }
 
77
        return readRawBytes(value, len);
 
78
  }
 
79
 
 
80
  SafeDataStream& readBytes(char*& data, uint& len) {
 
81
        if (mFailed) return *this;
 
82
 
 
83
        *this >> len;
 
84
        if (mFailed) return *this;
 
85
        data=new char[len];
 
86
        Q_CHECK_PTR( data );
 
87
        if ( !data ) {
 
88
          mFailed=true;
 
89
          return *this;
 
90
        }
 
91
        return readRawBytes(data, len);
 
92
  }
 
93
 
 
94
  // This method is usefull to debug with gdb. Do not inline it!
 
95
  int at() const;
 
96
 
 
97
private:
 
98
  QIODevice* mDevice;
 
99
  bool mFailed;
 
100
};
 
101
 
 
102
//! Plug-in for loading a GIMP XCF image file directly.
 
103
/*!
 
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.
 
107
 */
 
108
class XCFImageFormat : public QImageFormatPlugin {
 
109
 
 
110
  /*!
 
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.
 
116
   */
 
117
  typedef QValueVector< QValueVector< QImage > > Tiles;
 
118
 
 
119
  /*!
 
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.
 
123
   *
 
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.
 
126
   */
 
127
  struct Layer {
 
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
 
134
 
 
135
    uint nrows;                 //!< Number of rows of tiles (y direction)
 
136
    uint ncols;                 //!< Number of columns of tiles (x direction)
 
137
 
 
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).
 
141
    Tiles alpha_tiles;
 
142
    Tiles mask_tiles;           //!< The layer mask (optional)
 
143
 
 
144
    //! Additional information about a layer mask.
 
145
    struct {
 
146
      Q_UINT32 opacity;
 
147
      Q_UINT32 visible;
 
148
      Q_UINT32 show_masked;
 
149
      uchar red, green, blue;
 
150
      Q_UINT32 tattoo;
 
151
    } mask_channel;
 
152
 
 
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?)
 
165
 
 
166
    //! As each tile is read from the file, it is buffered here.
 
167
    uchar tile[TILE_WIDTH * TILE_HEIGHT * sizeof(QRgb)];
 
168
 
 
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 );
 
174
 
 
175
    //! Construct a layer.
 
176
    Layer ( void ) : name( 0 ) {}
 
177
    //! Destruct the layer.
 
178
    ~Layer ( void ) { if ( name != 0 ) delete[] name; }
 
179
  };
 
180
 
 
181
  /*!
 
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.
 
184
   */
 
185
  struct XCFImage {
 
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)
 
189
 
 
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
 
197
 
 
198
    int num_layers;             //!< number of layers
 
199
    Layer layer;                //!< most recently read layer
 
200
 
 
201
    bool initialized;           //!< Is the QImage initialized?
 
202
    QImage image;               //!< final QImage
 
203
 
 
204
    //! Simple constructor.
 
205
    XCFImage ( void ) : initialized( false ) {}
 
206
  };
 
207
 
 
208
  //! The bottom-most layer is copied into the final QImage by this
 
209
  //! routine.
 
210
  typedef void (*PixelCopyOperation) ( Layer& layer, uint i, uint j, int k, int l,
 
211
                                       QImage& image, int m, int n );
 
212
 
 
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 );
 
216
 
 
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.
 
222
 
 
223
  static int random_table[RANDOM_TABLE_SIZE];
 
224
 
 
225
  //! This table provides the add_pixel saturation values (i.e. 250 + 250 = 255).
 
226
 
 
227
  static int add_lut[256][256];
 
228
 
 
229
  //! Layer mode static data.
 
230
  typedef struct {
 
231
    bool affect_alpha;          //!< Does this mode affect the source alpha?
 
232
  } LayerModes;
 
233
 
 
234
  //! Array of layer mode structures for the modes described by
 
235
  //! LayerModeEffects.
 
236
  static LayerModes layer_modes[];
 
237
 
 
238
public:
 
239
  /*!
 
240
   * The constructor for the XCF image loader. This initializes the
 
241
   * tables used in the layer merging routines.
 
242
   */
 
243
  XCFImageFormat ();
 
244
  
 
245
 
 
246
  /*!
 
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.
 
250
   */
 
251
  ~XCFImageFormat () {}
 
252
 
 
253
  /*!
 
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".
 
257
   */
 
258
  QStringList keys () const {
 
259
    return QStringList() << "XCF";
 
260
  }
 
261
 
 
262
  /*!
 
263
   * This method installs the XCF reader on demand.
 
264
   */
 
265
  bool installIOHandler ( const QString& ); 
 
266
 
 
267
  static void registerFormat();
 
268
 
 
269
private:
 
270
  static void readXCF ( QImageIO* image_io );
 
271
#ifdef TMP_WRITE
 
272
  static void writeXCF ( QImageIO* ) {}
 
273
#endif
 
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,
 
286
                             QByteArray& bytes );
 
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 );
 
291
 
 
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 );
 
307
 
 
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 );
 
325
 
 
326
  static void dissolveRGBPixels ( QImage& image, int x, int y );
 
327
  static void dissolveAlphaPixels ( QImage& image, int x, int y );
 
328
};
 
329
 
 
330
} // namespace
 
331
#endif
 
332