summaryrefslogtreecommitdiffstats
path: root/kimgio/xcf.h
diff options
context:
space:
mode:
authortoma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2009-11-25 17:56:58 +0000
committertoma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2009-11-25 17:56:58 +0000
commitce4a32fe52ef09d8f5ff1dd22c001110902b60a2 (patch)
tree5ac38a06f3dde268dc7927dc155896926aaf7012 /kimgio/xcf.h
downloadtdelibs-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.h231
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