diff options
author | toma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2009-11-25 17:56:58 +0000 |
---|---|---|
committer | toma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2009-11-25 17:56:58 +0000 |
commit | ce4a32fe52ef09d8f5ff1dd22c001110902b60a2 (patch) | |
tree | 5ac38a06f3dde268dc7927dc155896926aaf7012 /kimgio/xcf.h | |
download | tdelibs-ce4a32fe52ef09d8f5ff1dd22c001110902b60a2.tar.gz tdelibs-ce4a32fe52ef09d8f5ff1dd22c001110902b60a2.zip |
Copy the KDE 3.5 branch to branches/trinity for new KDE 3.5 features.
BUG:215923
git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdelibs@1054174 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'kimgio/xcf.h')
-rw-r--r-- | kimgio/xcf.h | 231 |
1 files changed, 231 insertions, 0 deletions
diff --git a/kimgio/xcf.h b/kimgio/xcf.h new file mode 100644 index 000000000..69b434bd3 --- /dev/null +++ b/kimgio/xcf.h @@ -0,0 +1,231 @@ +#ifndef XCF_H +#define XCF_H +/* + * qxcfi.cpp: A Qt 3 plug-in for reading GIMP XCF image files + * Copyright (C) 2001 lignum Computing, Inc. <allen@lignumcomputing.com> + * Copyright (C) 2004 Melchior FRANZ <mfranz@kde.org> + * + * This plug-in is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#include <qimage.h> +#include <qiodevice.h> +#include <qvaluestack.h> +#include <qvaluevector.h> + +#include "gimp.h" + + +extern "C" { +void kimgio_xcf_read(QImageIO *); +void kimgio_xcf_write(QImageIO *); +} + +const float INCHESPERMETER = (100.0 / 2.54); + +/*! + * Each layer in an XCF file is stored as a matrix of + * 64-pixel by 64-pixel images. The GIMP has a sophisticated + * method of handling very large images as well as implementing + * parallel processing on a tile-by-tile basis. Here, though, + * we just read them in en-masse and store them in a matrix. + */ +typedef QValueVector<QValueVector<QImage> > Tiles; + + + +class XCFImageFormat { +public: + XCFImageFormat(); + void readXCF(QImageIO* image_io); + + +private: + /*! + * Each GIMP image is composed of one or more layers. A layer can + * be one of any three basic types: RGB, grayscale or indexed. With an + * optional alpha channel, there are six possible types altogether. + * + * Note: there is only ever one instance of this structure. The + * layer info is discarded after it is merged into the final QImage. + */ + class Layer { + public: + Q_UINT32 width; //!< Width of the layer + Q_UINT32 height; //!< Height of the layer + Q_INT32 type; //!< Type of the layer (GimpImageType) + char* name; //!< Name of the layer + Q_UINT32 hierarchy_offset; //!< File position of Tile hierarchy + Q_UINT32 mask_offset; //!< File position of mask image + + uint nrows; //!< Number of rows of tiles (y direction) + uint ncols; //!< Number of columns of tiles (x direction) + + Tiles image_tiles; //!< The basic image + //! For Grayscale and Indexed images, the alpha channel is stored + //! separately (in this data structure, anyway). + Tiles alpha_tiles; + Tiles mask_tiles; //!< The layer mask (optional) + + //! Additional information about a layer mask. + struct { + Q_UINT32 opacity; + Q_UINT32 visible; + Q_UINT32 show_masked; + uchar red, green, blue; + Q_UINT32 tattoo; + } mask_channel; + + bool active; //!< Is this layer the active layer? + Q_UINT32 opacity; //!< The opacity of the layer + Q_UINT32 visible; //!< Is the layer visible? + Q_UINT32 linked; //!< Is this layer linked (geometrically) + Q_UINT32 preserve_transparency; //!< Preserve alpha when drawing on layer? + Q_UINT32 apply_mask; //!< Apply the layer mask? + Q_UINT32 edit_mask; //!< Is the layer mask the being edited? + Q_UINT32 show_mask; //!< Show the layer mask rather than the image? + Q_INT32 x_offset; //!< x offset of the layer relative to the image + Q_INT32 y_offset; //!< y offset of the layer relative to the image + Q_UINT32 mode; //!< Combining mode of layer (LayerModeEffects) + Q_UINT32 tattoo; //!< (unique identifier?) + + //! As each tile is read from the file, it is buffered here. + uchar tile[TILE_WIDTH * TILE_HEIGHT * sizeof(QRgb)]; + + //! The data from tile buffer is copied to the Tile by this + //! method. Depending on the type of the tile (RGB, Grayscale, + //! Indexed) and use (image or mask), the bytes in the buffer are + //! copied in different ways. + void (*assignBytes)(Layer& layer, uint i, uint j); + + Layer(void) : name(0) {} + ~Layer(void) { delete[] name; } + }; + + + /*! + * The in-memory representation of the XCF Image. It contains a few + * metadata items, but is mostly a container for the layer information. + */ + class XCFImage { + public: + Q_UINT32 width; //!< width of the XCF image + Q_UINT32 height; //!< height of the XCF image + Q_INT32 type; //!< type of the XCF image (GimpImageBaseType) + + Q_UINT8 compression; //!< tile compression method (CompressionType) + float x_resolution; //!< x resolution in dots per inch + float y_resolution; //!< y resolution in dots per inch + Q_INT32 tattoo; //!< (unique identifier?) + Q_UINT32 unit; //!< Units of The GIMP (inch, mm, pica, etc...) + Q_INT32 num_colors; //!< number of colors in an indexed image + QValueVector<QRgb> palette; //!< indexed image color palette + + int num_layers; //!< number of layers + Layer layer; //!< most recently read layer + + bool initialized; //!< Is the QImage initialized? + QImage image; //!< final QImage + + XCFImage(void) : initialized(false) {} + }; + + + //! In layer DISSOLVE mode, a random number is chosen to compare to a + //! pixel's alpha. If the alpha is greater than the random number, the + //! pixel is drawn. This table merely contains the random number seeds + //! for each ROW of an image. Therefore, the random numbers chosen + //! are consistent from run to run. + static int random_table[RANDOM_TABLE_SIZE]; + + //! This table provides the add_pixel saturation values (i.e. 250 + 250 = 255). + //static int add_lut[256][256]; - this is so lame waste of 256k of memory + static int add_lut( int, int ); + + //! The bottom-most layer is copied into the final QImage by this + //! routine. + typedef void (*PixelCopyOperation)(Layer& layer, uint i, uint j, int k, int l, + QImage& image, int m, int n); + + //! Higher layers are merged into the the final QImage by this routine. + typedef void (*PixelMergeOperation)(Layer& layer, uint i, uint j, int k, int l, + QImage& image, int m, int n); + + //! Layer mode static data. + typedef struct { + bool affect_alpha; //!< Does this mode affect the source alpha? + } LayerModes; + + //! Array of layer mode structures for the modes described by + //! LayerModeEffects. + static const LayerModes layer_modes[]; + + bool loadImageProperties(QDataStream& xcf_io, XCFImage& image); + bool loadProperty(QDataStream& xcf_io, PropType& type, QByteArray& bytes); + bool loadLayer(QDataStream& xcf_io, XCFImage& xcf_image); + bool loadLayerProperties(QDataStream& xcf_io, Layer& layer); + bool composeTiles(XCFImage& xcf_image); + void setGrayPalette(QImage& image); + void setPalette(XCFImage& xcf_image, QImage& image); + static void assignImageBytes(Layer& layer, uint i, uint j); + bool loadHierarchy(QDataStream& xcf_io, Layer& layer); + bool loadLevel(QDataStream& xcf_io, Layer& layer, Q_INT32 bpp); + static void assignMaskBytes(Layer& layer, uint i, uint j); + bool loadMask(QDataStream& xcf_io, Layer& layer); + bool loadChannelProperties(QDataStream& xcf_io, Layer& layer); + bool initializeImage(XCFImage& xcf_image); + bool loadTileRLE(QDataStream& xcf_io, uchar* tile, int size, + int data_length, Q_INT32 bpp); + static void copyLayerToImage(XCFImage& xcf_image); + static void copyRGBToRGB(Layer& layer, uint i, uint j, int k, int l, + QImage& image, int m, int n); + + static void copyGrayToGray(Layer& layer, uint i, uint j, int k, int l, + QImage& image, int m, int n); + static void copyGrayToRGB(Layer& layer, uint i, uint j, int k, int l, + QImage& image, int m, int n); + static void copyGrayAToRGB(Layer& layer, uint i, uint j, int k, int l, + QImage& image, int m, int n); + static void copyIndexedToIndexed(Layer& layer, uint i, uint j, int k, int l, + QImage& image, int m, int n); + static void copyIndexedAToIndexed(Layer& layer, uint i, uint j, int k, int l, + QImage& image, int m, int n); + static void copyIndexedAToRGB(Layer& layer, uint i, uint j, int k, int l, + QImage& image, int m, int n); + + static void mergeLayerIntoImage(XCFImage& xcf_image); + static void mergeRGBToRGB(Layer& layer, uint i, uint j, int k, int l, + QImage& image, int m, int n); + static void mergeGrayToGray(Layer& layer, uint i, uint j, int k, int l, + QImage& image, int m, int n); + static void mergeGrayAToGray(Layer& layer, uint i, uint j, int k, int l, + QImage& image, int m, int n); + static void mergeGrayToRGB(Layer& layer, uint i, uint j, int k, int l, + QImage& image, int m, int n); + static void mergeGrayAToRGB(Layer& layer, uint i, uint j, int k, int l, + QImage& image, int m, int n); + static void mergeIndexedToIndexed(Layer& layer, uint i, uint j, int k, int l, + QImage& image, int m, int n); + static void mergeIndexedAToIndexed(Layer& layer, uint i, uint j, int k, int l, + QImage& image, int m, int n); + static void mergeIndexedAToRGB(Layer& layer, uint i, uint j, int k, int l, + QImage& image, int m, int n); + + static void dissolveRGBPixels(QImage& image, int x, int y); + static void dissolveAlphaPixels(QImage& image, int x, int y); +}; + +#endif |