diff --git a/src/imageformats/gimp_p.h b/src/imageformats/gimp_p.h --- a/src/imageformats/gimp_p.h +++ b/src/imageformats/gimp_p.h @@ -56,16 +56,6 @@ INDEXED } GimpImageBaseType; -//! Type of individual layers in an XCF file. - -typedef enum { - RGB_GIMAGE, - RGBA_GIMAGE, - GRAY_GIMAGE, - GRAYA_GIMAGE, - INDEXED_GIMAGE, - INDEXEDA_GIMAGE -} GimpImageType; // From GIMP "libgimp/gimpenums.h" v2.4 @@ -96,49 +86,6 @@ GRAIN_MERGE_MODE } LayerModeEffects; -// From GIMP "xcf.c" v1.2 - -//! Properties which can be stored in an XCF file. - -typedef enum { - PROP_END = 0, - PROP_COLORMAP = 1, - PROP_ACTIVE_LAYER = 2, - PROP_ACTIVE_CHANNEL = 3, - PROP_SELECTION = 4, - PROP_FLOATING_SELECTION = 5, - PROP_OPACITY = 6, - PROP_MODE = 7, - PROP_VISIBLE = 8, - PROP_LINKED = 9, - PROP_PRESERVE_TRANSPARENCY = 10, - PROP_APPLY_MASK = 11, - PROP_EDIT_MASK = 12, - PROP_SHOW_MASK = 13, - PROP_SHOW_MASKED = 14, - PROP_OFFSETS = 15, - PROP_COLOR = 16, - PROP_COMPRESSION = 17, - PROP_GUIDES = 18, - PROP_RESOLUTION = 19, - PROP_TATTOO = 20, - PROP_PARASITES = 21, - PROP_UNIT = 22, - PROP_PATHS = 23, - PROP_USER_UNIT = 24, - MAX_SUPPORTED_PROPTYPE // should always be at the end so its value is last + 1 -} PropType; - -// From GIMP "xcf.c" v1.2 - -//! Compression type used in layer tiles. - -typedef enum { - COMPRESS_NONE = 0, - COMPRESS_RLE = 1, - COMPRESS_ZLIB = 2, - COMPRESS_FRACTAL = 3 /* Unused. */ -} CompressionType; // From GIMP "paint_funcs.c" v1.2 diff --git a/src/imageformats/xcf.cpp b/src/imageformats/xcf.cpp --- a/src/imageformats/xcf.cpp +++ b/src/imageformats/xcf.cpp @@ -28,11 +28,15 @@ #include #include #include +#include #include #include "gimp_p.h" +Q_DECLARE_LOGGING_CATEGORY(XCFPLUGIN) +Q_LOGGING_CATEGORY(XCFPLUGIN, "xcfplugin", QtWarningMsg) + const float INCHESPERMETER = (100.0f / 2.54f); /*! @@ -46,7 +50,143 @@ class XCFImageFormat { + Q_GADGET public: + + //! Properties which can be stored in an XCF file. + enum PropType { + PROP_END = 0, + PROP_COLORMAP = 1, + PROP_ACTIVE_LAYER = 2, + PROP_ACTIVE_CHANNEL = 3, + PROP_SELECTION = 4, + PROP_FLOATING_SELECTION = 5, + PROP_OPACITY = 6, + PROP_MODE = 7, + PROP_VISIBLE = 8, + PROP_LINKED = 9, + PROP_LOCK_ALPHA = 10, + PROP_APPLY_MASK = 11, + PROP_EDIT_MASK = 12, + PROP_SHOW_MASK = 13, + PROP_SHOW_MASKED = 14, + PROP_OFFSETS = 15, + PROP_COLOR = 16, + PROP_COMPRESSION = 17, + PROP_GUIDES = 18, + PROP_RESOLUTION = 19, + PROP_TATTOO = 20, + PROP_PARASITES = 21, + PROP_UNIT = 22, + PROP_PATHS = 23, + PROP_USER_UNIT = 24, + PROP_VECTORS = 25, + PROP_TEXT_LAYER_FLAGS = 26, + PROP_OLD_SAMPLE_POINTS = 27, + PROP_LOCK_CONTENT = 28, + PROP_GROUP_ITEM = 29, + PROP_ITEM_PATH = 30, + PROP_GROUP_ITEM_FLAGS = 31, + PROP_LOCK_POSITION = 32, + PROP_FLOAT_OPACITY = 33, + PROP_COLOR_TAG = 34, + PROP_COMPOSITE_MODE = 35, + PROP_COMPOSITE_SPACE = 36, + PROP_BLEND_SPACE = 37, + PROP_FLOAT_COLOR = 38, + PROP_SAMPLE_POINTS = 39, + MAX_SUPPORTED_PROPTYPE // should always be at the end so its value is last + 1 + }; + Q_ENUM(PropType); + + //! Compression type used in layer tiles. + enum XcfCompressionType { + COMPRESS_INVALID = -1, /* our own */ + COMPRESS_NONE = 0, + COMPRESS_RLE = 1, + COMPRESS_ZLIB = 2, /* unused */ + COMPRESS_FRACTAL = 3 /* unused */ + }; + Q_ENUM(XcfCompressionType); + + enum LayerModeType { + GIMP_LAYER_MODE_NORMAL_LEGACY, + GIMP_LAYER_MODE_DISSOLVE, + GIMP_LAYER_MODE_BEHIND_LEGACY, + GIMP_LAYER_MODE_MULTIPLY_LEGACY, + GIMP_LAYER_MODE_SCREEN_LEGACY, + GIMP_LAYER_MODE_OVERLAY_LEGACY, + GIMP_LAYER_MODE_DIFFERENCE_LEGACY, + GIMP_LAYER_MODE_ADDITION_LEGACY, + GIMP_LAYER_MODE_SUBTRACT_LEGACY, + GIMP_LAYER_MODE_DARKEN_ONLY_LEGACY, + GIMP_LAYER_MODE_LIGHTEN_ONLY_LEGACY, + GIMP_LAYER_MODE_HSV_HUE_LEGACY, + GIMP_LAYER_MODE_HSV_SATURATION_LEGACY, + GIMP_LAYER_MODE_HSL_COLOR_LEGACY, + GIMP_LAYER_MODE_HSV_VALUE_LEGACY, + GIMP_LAYER_MODE_DIVIDE_LEGACY, + GIMP_LAYER_MODE_DODGE_LEGACY, + GIMP_LAYER_MODE_BURN_LEGACY, + GIMP_LAYER_MODE_HARDLIGHT_LEGACY, + GIMP_LAYER_MODE_SOFTLIGHT_LEGACY, + GIMP_LAYER_MODE_GRAIN_EXTRACT_LEGACY, + GIMP_LAYER_MODE_GRAIN_MERGE_LEGACY, + GIMP_LAYER_MODE_COLOR_ERASE_LEGACY, + GIMP_LAYER_MODE_OVERLAY, + GIMP_LAYER_MODE_LCH_HUE, + GIMP_LAYER_MODE_LCH_CHROMA, + GIMP_LAYER_MODE_LCH_COLOR, + GIMP_LAYER_MODE_LCH_LIGHTNESS, + GIMP_LAYER_MODE_NORMAL, + GIMP_LAYER_MODE_BEHIND, + GIMP_LAYER_MODE_MULTIPLY, + GIMP_LAYER_MODE_SCREEN, + GIMP_LAYER_MODE_DIFFERENCE, + GIMP_LAYER_MODE_ADDITION, + GIMP_LAYER_MODE_SUBTRACT, + GIMP_LAYER_MODE_DARKEN_ONLY, + GIMP_LAYER_MODE_LIGHTEN_ONLY, + GIMP_LAYER_MODE_HSV_HUE, + GIMP_LAYER_MODE_HSV_SATURATION, + GIMP_LAYER_MODE_HSL_COLOR, + GIMP_LAYER_MODE_HSV_VALUE, + GIMP_LAYER_MODE_DIVIDE, + GIMP_LAYER_MODE_DODGE, + GIMP_LAYER_MODE_BURN, + GIMP_LAYER_MODE_HARDLIGHT, + GIMP_LAYER_MODE_SOFTLIGHT, + GIMP_LAYER_MODE_GRAIN_EXTRACT, + GIMP_LAYER_MODE_GRAIN_MERGE, + GIMP_LAYER_MODE_VIVID_LIGHT, + GIMP_LAYER_MODE_PIN_LIGHT, + GIMP_LAYER_MODE_LINEAR_LIGHT, + GIMP_LAYER_MODE_HARD_MIX, + GIMP_LAYER_MODE_EXCLUSION, + GIMP_LAYER_MODE_LINEAR_BURN, + GIMP_LAYER_MODE_LUMA_DARKEN_ONLY, + GIMP_LAYER_MODE_LUMA_LIGHTEN_ONLY, + GIMP_LAYER_MODE_LUMINANCE, + GIMP_LAYER_MODE_COLOR_ERASE, + GIMP_LAYER_MODE_ERASE, + GIMP_LAYER_MODE_MERGE, + GIMP_LAYER_MODE_SPLIT, + GIMP_LAYER_MODE_PASS_THROUGH, + }; + Q_ENUM(LayerModeType); + + //! Type of individual layers in an XCF file. + enum GimpImageType { + RGB_GIMAGE, + RGBA_GIMAGE, + GRAY_GIMAGE, + GRAYA_GIMAGE, + INDEXED_GIMAGE, + INDEXEDA_GIMAGE + }; + Q_ENUM(GimpImageType); + + XCFImageFormat(); bool readXCF(QIODevice *device, QImage *image); @@ -66,8 +206,8 @@ quint32 height; //!< Height of the layer qint32 type; //!< Type of the layer (GimpImageType) char *name; //!< Name of the layer - quint32 hierarchy_offset; //!< File position of Tile hierarchy - quint32 mask_offset; //!< File position of mask image + qint64 hierarchy_offset; //!< File position of Tile hierarchy + qint64 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) @@ -87,6 +227,8 @@ quint32 tattoo; } mask_channel; + XcfCompressionType compression = COMPRESS_INVALID; //!< tile compression method (CompressionType) + bool active; //!< Is this layer the active layer? quint32 opacity = 255; //!< The opacity of the layer quint32 visible = 1; //!< Is the layer visible? @@ -127,11 +269,12 @@ class XCFImage { public: + qint32 precision = 0; quint32 width; //!< width of the XCF image quint32 height; //!< height of the XCF image qint32 type; //!< type of the XCF image (GimpImageBaseType) - quint8 compression; //!< tile compression method (CompressionType) + quint8 compression = COMPRESS_RLE; //!< tile compression method (CompressionType) float x_resolution = -1;//!< x resolution in dots per inch float y_resolution = -1;//!< y resolution in dots per inch qint32 tattoo; //!< (unique identifier?) @@ -148,6 +291,18 @@ XCFImage(void) : initialized(false) {} }; + static qint64 readOffsetPtr(QDataStream &stream) { + if (stream.version() >= 11) { + qint64 ret; + stream >> ret; + return ret; + } else { + quint32 ret; + stream >> ret; + return ret; + } + } + //! 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 @@ -320,20 +475,41 @@ XCFImage xcf_image; QDataStream xcf_io(device); - char tag[14];; + char tag[14]; if (xcf_io.readRawData(tag, sizeof(tag)) != sizeof(tag)) { -// qDebug() << "XCF: read failure on header tag"; + qCDebug(XCFPLUGIN) << "XCF: read failure on header tag"; return false; } if (qstrncmp(tag, "gimp xcf", 8) != 0) { -// qDebug() << "XCF: read called on non-XCF file"; + qCDebug(XCFPLUGIN) << "XCF: read called on non-XCF file"; + return false; + } + + bool ok; + xcf_io.setVersion(QByteArray(tag, sizeof(tag)).right(3).toInt(&ok)); // the tag ends with v### + if (!ok) { + qCDebug(XCFPLUGIN) << "Failed to parse version" << QByteArray(tag, sizeof(tag)); + return false; + } + qCDebug(XCFPLUGIN) << "version" << xcf_io.version(); + + if (xcf_io.version() > 11) { + qCDebug(XCFPLUGIN) << "Unsupported version" << xcf_io.version(); return false; } xcf_io >> xcf_image.width >> xcf_image.height >> xcf_image.type; -// qDebug() << tag << " " << xcf_image.width << " " << xcf_image.height << " " << xcf_image.type; + if (xcf_io.version() >= 4) { + xcf_io >> xcf_image.precision; + qCDebug(XCFPLUGIN) << "Precision" << xcf_image.precision; + if (xcf_io.version() < 7) { + qCDebug(XCFPLUGIN) << "Conversion of image precision not supported"; + } + } + + qCDebug(XCFPLUGIN) << tag << " " << xcf_image.width << " " << xcf_image.height << " " << xcf_image.type; if (!loadImageProperties(xcf_io, xcf_image)) { return false; } @@ -344,12 +520,10 @@ // all the data of all layers before beginning to construct the // merged image). - QStack layer_offsets; + QStack layer_offsets; while (true) { - qint32 layer_offset; - - xcf_io >> layer_offset; + qint64 layer_offset = readOffsetPtr(xcf_io); if (layer_offset == 0) { break; @@ -361,12 +535,13 @@ xcf_image.num_layers = layer_offsets.size(); if (layer_offsets.size() == 0) { -// qDebug() << "XCF: no layers!"; return false; + qCDebug(XCFPLUGIN) << "XCF: no layers!"; return false; } + qCDebug(XCFPLUGIN) << xcf_image.num_layers << "layers"; // Load each layer and add it to the image while (!layer_offsets.isEmpty()) { - qint32 layer_offset = layer_offsets.pop(); + qint64 layer_offset = layer_offsets.pop(); xcf_io.device()->seek(layer_offset); @@ -376,7 +551,7 @@ } if (!xcf_image.initialized) { -// qDebug() << "XCF: no visible layers!"; + qCDebug(XCFPLUGIN) << "XCF: no visible layers!"; return false; } @@ -399,7 +574,7 @@ quint32 rawType; if (!loadProperty(xcf_io, type, bytes, rawType)) { -// qDebug() << "XCF: error loading global image properties"; + qCDebug(XCFPLUGIN) << "XCF: error loading global image properties"; return false; } @@ -469,8 +644,8 @@ break; default: -// qDebug() << "XCF: unimplemented image property" << rawType -// << ", size " << bytes.size() << endl; + qCDebug(XCFPLUGIN) << "XCF: unimplemented image property" << type << "(" << rawType << ")" + << ", size " << bytes.size(); break; } } @@ -542,7 +717,7 @@ delete[] unit_strings; if (xcf_io.device()->atEnd()) { -// qDebug() << "XCF: read failure on property " << type; + qCDebug(XCFPLUGIN) << "XCF: read failure on property " << type; return false; } } @@ -556,7 +731,7 @@ data = new char[size]; const quint32 dataRead = xcf_io.readRawData(data, size); if (dataRead < size) { -// qDebug() << "XCF: loadProperty read less data than expected" << data_length << dataRead; + qCDebug(XCFPLUGIN) << "XCF: loadProperty read less data than expected" << size << dataRead; memset(&data[dataRead], 0, size - dataRead); } } @@ -585,15 +760,19 @@ xcf_io >> layer.width >> layer.height >> layer.type >> layer.name; + // Don't want to keep passing this around, dumb XCF format + layer.compression = XcfCompressionType(xcf_image.compression); + if (!loadLayerProperties(xcf_io, layer)) { return false; } -#if 0 - cout << "layer: \"" << layer.name << "\", size: " << layer.width << " x " - << layer.height << ", type: " << layer.type << ", mode: " << layer.mode + + qCDebug(XCFPLUGIN) + << "layer: \"" << layer.name << "\", size: " << layer.width << " x " + << layer.height << ", type: " << GimpImageType(layer.type) << ", mode: " << layer.mode << ", opacity: " << layer.opacity << ", visible: " << layer.visible - << ", offset: " << layer.x_offset << ", " << layer.y_offset << endl; -#endif + << ", offset: " << layer.x_offset << ", " << layer.y_offset; + // Skip reading the rest of it if it is not visible. Typically, when // you export an image from the The GIMP it flattens (or merges) only // the visible layers into the output image. @@ -604,7 +783,8 @@ // If there are any more layers, merge them into the final QImage. - xcf_io >> layer.hierarchy_offset >> layer.mask_offset; + layer.hierarchy_offset = readOffsetPtr(xcf_io); + layer.mask_offset = readOffsetPtr(xcf_io); // Allocate the individual tile QImages based on the size and type // of this layer. @@ -672,7 +852,7 @@ quint32 rawType; if (!loadProperty(xcf_io, type, bytes, rawType)) { -// qDebug() << "XCF: error loading layer properties"; + qCDebug(XCFPLUGIN) << "XCF: error loading layer properties"; return false; } @@ -699,7 +879,7 @@ property >> layer.linked; break; - case PROP_PRESERVE_TRANSPARENCY: + case PROP_LOCK_ALPHA: property >> layer.preserve_transparency; break; @@ -722,7 +902,7 @@ case PROP_MODE: property >> layer.mode; if (layer.mode >= countof(layer_modes)) { - qWarning() << "Found layer with unsupported mode" << layer.mode << "Defaulting to mode 0"; + qCDebug(XCFPLUGIN) << "Found layer with unsupported mode" << LayerModeType(layer.mode) << "Defaulting to mode 0"; layer.mode = 0; } break; @@ -732,8 +912,8 @@ break; default: -// qDebug() << "XCF: unimplemented layer property " << rawType -// << ", size " << bytes.size() << endl; + qCDebug(XCFPLUGIN) << "XCF: unimplemented layer property " << type << "(" << rawType << ")" + << ", size " << bytes.size(); break; } } @@ -751,9 +931,9 @@ layer.nrows = (layer.height + TILE_HEIGHT - 1) / TILE_HEIGHT; layer.ncols = (layer.width + TILE_WIDTH - 1) / TILE_WIDTH; - //qDebug() << "IMAGE: height=" << xcf_image.height << ", width=" << xcf_image.width; - //qDebug() << "LAYER: height=" << layer.height << ", width=" << layer.width; - //qDebug() << "LAYER: rows=" << layer.nrows << ", columns=" << layer.ncols; + qCDebug(XCFPLUGIN) << "IMAGE: height=" << xcf_image.height << ", width=" << xcf_image.width; + qCDebug(XCFPLUGIN) << "LAYER: height=" << layer.height << ", width=" << layer.width; + qCDebug(XCFPLUGIN) << "LAYER: rows=" << layer.nrows << ", columns=" << layer.ncols; // SANITY CHECK: Catch corrupted XCF image file where the width or height // of a tile is reported are bogus. See Bug# 234030. @@ -992,47 +1172,49 @@ { qint32 width; qint32 height; - qint32 bpp; - quint32 offset; + quint32 bpp; + + xcf_io >> width >> height >> bpp; + qint64 offset = readOffsetPtr(xcf_io); - xcf_io >> width >> height >> bpp >> offset; + qCDebug(XCFPLUGIN) << "width" << width << "height" << height << "bpp" << bpp << "offset" << offset; // make sure bpp is correct and complain if it is not switch (layer.type) { case RGB_GIMAGE: if (bpp != 3) { - qWarning() << "Found layer of type RGB but with bpp != 3" << bpp; - bpp = 3; + qCDebug(XCFPLUGIN) << "Found layer of type RGB but with bpp != 3" << bpp; + return false; } break; case RGBA_GIMAGE: if (bpp != 4) { - qWarning() << "Found layer of type RGBA but with bpp != 4" << bpp; - bpp = 4; + qCDebug(XCFPLUGIN) << "Found layer of type RGBA but with bpp != 4, got" << bpp << "bpp"; + return true; } break; case GRAY_GIMAGE: if (bpp != 1) { - qWarning() << "Found layer of type Gray but with bpp != 1" << bpp; - bpp = 1; + qCDebug(XCFPLUGIN) << "Found layer of type Gray but with bpp != 1" << bpp; + return false; } break; case GRAYA_GIMAGE: if (bpp != 2) { - qWarning() << "Found layer of type Gray+Alpha but with bpp != 2" << bpp; - bpp = 2; + qCDebug(XCFPLUGIN) << "Found layer of type Gray+Alpha but with bpp != 2" << bpp; + return false; } break; case INDEXED_GIMAGE: if (bpp != 1) { - qWarning() << "Found layer of type Indexed but with bpp != 1" << bpp; - bpp = 1; + qCDebug(XCFPLUGIN) << "Found layer of type Indexed but with bpp != 1" << bpp; + return false; } break; case INDEXEDA_GIMAGE: if (bpp != 2) { - qWarning() << "Found layer of type Indexed+Alpha but with bpp != 2" << bpp; - bpp = 2; + qCDebug(XCFPLUGIN) << "Found layer of type Indexed+Alpha but with bpp != 2" << bpp; + return false; } break; } @@ -1046,7 +1228,7 @@ xcf_io >> junk; if (xcf_io.device()->atEnd()) { -// qDebug() << "XCF: read failure on layer " << layer.name << " level offsets"; + qCDebug(XCFPLUGIN) << "XCF: read failure on layer " << layer.name << " level offsets"; return false; } } while (junk != 0); @@ -1074,9 +1256,9 @@ { qint32 width; qint32 height; - quint32 offset; - xcf_io >> width >> height >> offset; + xcf_io >> width >> height; + qint64 offset = readOffsetPtr(xcf_io); if (offset == 0) { // offset 0 with rowsxcols != 0 is probably an error since it means we have tiles @@ -1096,24 +1278,47 @@ for (uint i = 0; i < layer.ncols; i++) { if (offset == 0) { -// qDebug() << "XCF: incorrect number of tiles in layer " << layer.name; + qCDebug(XCFPLUGIN) << "XCF: incorrect number of tiles in layer " << layer.name; return false; } qint64 saved_pos = xcf_io.device()->pos(); - quint32 offset2; - xcf_io >> offset2; + qint64 offset2 = readOffsetPtr(xcf_io); // Evidently, RLE can occasionally expand a tile instead of compressing it! - if (offset2 == 0) { offset2 = offset + (uint)(TILE_WIDTH * TILE_HEIGHT * 4 * 1.5); } xcf_io.device()->seek(offset); - int size = layer.image_tiles[j][i].width() * layer.image_tiles[j][i].height(); - if (!loadTileRLE(xcf_io, layer.tile, size, offset2 - offset, bpp)) { + switch (layer.compression) { + case COMPRESS_NONE: { + if (xcf_io.version() > 11) { + qCDebug(XCFPLUGIN) << "Component reading not supported yet"; + return false; + } + const int data_size = bpp * TILE_WIDTH * TILE_HEIGHT; + if (data_size > int(sizeof(layer.tile))) { + qCDebug(XCFPLUGIN) << "Tile data too big, we can only fit" << sizeof(layer.tile) << "but need" << data_size; + return false; + } + int dataRead = xcf_io.readRawData(reinterpret_cast(layer.tile), data_size); + if (dataRead < data_size) { + qCDebug(XCFPLUGIN) << "short read, expected" << data_size << "got" << dataRead; + return false; + } + break; + } + case COMPRESS_RLE: { + int size = layer.image_tiles[j][i].width() * layer.image_tiles[j][i].height(); + if (!loadTileRLE(xcf_io, layer.tile, size, offset2 - offset, bpp)) { + return true; + } + break; + } + default: + qCDebug(XCFPLUGIN) << "Unhandled compression" << layer.compression; return false; } @@ -1124,7 +1329,7 @@ layer.assignBytes(layer, i, j); xcf_io.device()->seek(saved_pos); - xcf_io >> offset; + offset = readOffsetPtr(xcf_io); } } @@ -1151,8 +1356,7 @@ return false; } - quint32 hierarchy_offset; - xcf_io >> hierarchy_offset; + qint64 hierarchy_offset = readOffsetPtr(xcf_io); xcf_io.device()->seek(hierarchy_offset); layer.assignBytes = assignMaskBytes; @@ -1197,21 +1401,26 @@ uchar *xcfdatalimit; if (data_length < 0 || data_length > int(TILE_WIDTH * TILE_HEIGHT * 4 * 1.5)) { -// qDebug() << "XCF: invalid tile data length" << data_length; + qCDebug(XCFPLUGIN) << "XCF: invalid tile data length" << data_length; return false; } xcfdata = xcfodata = new uchar[data_length]; const int dataRead = xcf_io.readRawData((char *)xcfdata, data_length); + if (dataRead <= 0) { + delete[] xcfodata; + qCDebug(XCFPLUGIN) << "XCF: read failure on tile" << dataRead; + return false; + } + if (dataRead < data_length) { -// qDebug() << "XCF: read less data than expected" << data_length << dataRead; memset(&xcfdata[dataRead], 0, data_length - dataRead); } if (!xcf_io.device()->isOpen()) { delete[] xcfodata; -// qDebug() << "XCF: read failure on tile"; + qCDebug(XCFPLUGIN) << "XCF: read failure on tile"; return false; } @@ -1296,7 +1505,7 @@ bogus_rle: -// qDebug() << "The run length encoding could not be decoded properly"; + qCDebug(XCFPLUGIN) << "The run length encoding could not be decoded properly"; delete[] xcfodata; return false; } @@ -1316,7 +1525,7 @@ quint32 rawType; if (!loadProperty(xcf_io, type, bytes, rawType)) { -// qDebug() << "XCF: error loading channel properties"; + qCDebug(XCFPLUGIN) << "XCF: error loading channel properties"; return false; } @@ -1349,8 +1558,8 @@ break; default: -// qDebug() << "XCF: unimplemented channel property " << rawType -// << ", size " << bytes.size() << endl; + qCDebug(XCFPLUGIN) << "XCF: unimplemented channel property " << type << "(" << rawType << ")" + << ", size " << bytes.size(); break; } } @@ -2759,7 +2968,7 @@ bool XCFHandler::canRead(QIODevice *device) { if (!device) { - qWarning("DDSHandler::canRead() called with no device"); + qCDebug(XCFPLUGIN) << "XCFHandler::canRead() called with no device"; return false; } @@ -2815,3 +3024,6 @@ handler->setFormat(format); return handler; } + +// Just so I can get enum values printed +#include "xcf.moc"