25 #include <QtGui/QImage>
26 #include <QtGui/QPainter>
27 #include <QtCore/QIODevice>
28 #include <QtCore/QStack>
29 #include <QtCore/QVector>
35 bool XCFImageFormat::random_table_initialized;
40 const XCFImageFormat::LayerModes XCFImageFormat::layer_modes[] = {
67 inline QRgb
qRgba (
const QRgb& rgb,
int a )
69 return ((a & 0xff) << 24 | (rgb & RGB_MASK));
83 void XCFImageFormat::initializeRandomTable()
89 random_table[i] = rand();
93 int swap = i + rand() % (RANDOM_TABLE_SIZE - i);
94 tmp = random_table[i];
95 random_table[i] = random_table[swap];
96 random_table[swap] = tmp;
101 int XCFImageFormat::add_lut(
int a,
int b ) {
102 return qMin( a + b, 255 );
108 QDataStream xcf_io(device);
112 if (xcf_io.readRawData(tag,
sizeof(tag)) !=
sizeof(tag)) {
113 kDebug(399) <<
"XCF: read failure on header tag";
116 if (qstrncmp(tag,
"gimp xcf", 8) != 0) {
117 kDebug(399) <<
"XCF: read called on non-XCF file";
121 xcf_io >> xcf_image.width >> xcf_image.height >> xcf_image.type;
123 kDebug() << tag <<
" " << xcf_image.width <<
" " << xcf_image.height <<
" " << xcf_image.type;
124 if (!loadImageProperties(xcf_io, xcf_image))
133 QStack<qint32> layer_offsets;
138 xcf_io >> layer_offset;
140 if (layer_offset == 0)
143 layer_offsets.push(layer_offset);
146 xcf_image.num_layers = layer_offsets.size();
148 if (layer_offsets.size() == 0) {
149 kDebug(399) <<
"XCF: no layers!";
154 while (!layer_offsets.isEmpty()) {
155 qint32 layer_offset = layer_offsets.pop();
157 xcf_io.device()->seek(layer_offset);
159 if (!loadLayer(xcf_io, xcf_image))
163 if (!xcf_image.initialized) {
164 kDebug(399) <<
"XCF: no visible layers!";
168 *outImage = xcf_image.image;
180 bool XCFImageFormat::loadImageProperties(QDataStream& xcf_io, XCFImage& xcf_image)
186 if (!loadProperty(xcf_io, type, bytes)) {
187 kDebug(399) <<
"XCF: error loading global image properties";
191 QDataStream property(bytes);
198 property >> xcf_image.compression;
202 property >> xcf_image.x_resolution >> xcf_image.y_resolution;
206 property >> xcf_image.tattoo;
210 while (!property.atEnd()) {
214 property.readBytes(tag, size);
218 property >> flags >> data;
220 if (tag && strncmp(tag,
"gimp-comment", strlen(
"gimp-comment")) == 0)
221 xcf_image.image.setText(
"Comment", 0, data);
229 property >> xcf_image.unit;
239 property >> xcf_image.num_colors;
240 if(xcf_image.num_colors < 0 || xcf_image.num_colors > 65535)
243 xcf_image.palette.reserve(xcf_image.num_colors);
245 for (
int i = 0; i < xcf_image.num_colors; i++) {
247 property >> r >> g >> b;
248 xcf_image.palette.push_back( qRgb(r,g,b) );
253 kDebug(399) <<
"XCF: unimplemented image property" << type
254 <<
", size " << bytes.size() << endl;
267 bool XCFImageFormat::loadProperty(QDataStream& xcf_io,
PropType& type, QByteArray& bytes)
285 if(size > 65535 || size < 4)
288 size = 3 * ncolors + 4;
289 data =
new char[size];
294 data[2] = ncolors >> 8;
295 data[3] = ncolors & 255;
298 xcf_io.readRawData(data + 4, size - 4);
304 xcf_io >> size >> factor >> digits;
306 for (
int i = 0; i < 5; i++) {
309 xcf_io >> unit_strings;
311 delete[] unit_strings;
313 if (xcf_io.device()->atEnd()) {
314 kDebug(399) <<
"XCF: read failure on property " << type;
324 data =
new char[size];
325 xcf_io.readRawData(data, size);
328 if (size != 0 && data)
329 bytes = QByteArray(data,size);
345 bool XCFImageFormat::loadLayer(QDataStream& xcf_io, XCFImage& xcf_image)
347 Layer& layer(xcf_image.layer);
350 xcf_io >> layer.width >> layer.height >> layer.type >> layer.name;
352 if (!loadLayerProperties(xcf_io, layer))
355 cout <<
"layer: \"" << layer.name <<
"\", size: " << layer.width <<
" x "
356 << layer.height <<
", type: " << layer.type <<
", mode: " << layer.mode
357 <<
", opacity: " << layer.opacity <<
", visible: " << layer.visible
358 <<
", offset: " << layer.x_offset <<
", " << layer.y_offset << endl;
364 if (layer.visible == 0)
369 xcf_io >> layer.hierarchy_offset >> layer.mask_offset;
374 if( !composeTiles(xcf_image))
376 xcf_io.device()->seek(layer.hierarchy_offset);
382 layer.assignBytes = assignImageBytes;
384 if (!loadHierarchy(xcf_io, layer))
387 if (layer.mask_offset != 0) {
388 xcf_io.device()->seek(layer.mask_offset);
390 if (!loadMask(xcf_io, layer))
398 if (!xcf_image.initialized) {
399 if( !initializeImage(xcf_image))
401 copyLayerToImage(xcf_image);
402 xcf_image.initialized =
true;
404 mergeLayerIntoImage(xcf_image);
417 bool XCFImageFormat::loadLayerProperties(QDataStream& xcf_io, Layer& layer)
423 if (!loadProperty(xcf_io, type, bytes)) {
424 kDebug(399) <<
"XCF: error loading layer properties";
428 QDataStream property(bytes);
439 property >> layer.opacity;
443 property >> layer.visible;
447 property >> layer.linked;
451 property >> layer.preserve_transparency;
455 property >> layer.apply_mask;
459 property >> layer.edit_mask;
463 property >> layer.show_mask;
467 property >> layer.x_offset >> layer.y_offset;
471 property >> layer.mode;
475 property >> layer.tattoo;
479 kDebug(399) <<
"XCF: unimplemented layer property " << type
480 <<
", size " << bytes.size() << endl;
491 bool XCFImageFormat::composeTiles(XCFImage& xcf_image)
493 Layer& layer(xcf_image.layer);
504 if (layer.width > 32767 || layer.height > 32767 || layer.width * layer.height > 16384 * 16384)
507 layer.image_tiles.resize(layer.nrows);
510 layer.alpha_tiles.resize(layer.nrows);
512 if (layer.mask_offset != 0)
513 layer.mask_tiles.resize(layer.nrows);
515 for (
uint j = 0; j < layer.nrows; j++) {
516 layer.image_tiles[j].resize(layer.ncols);
519 layer.alpha_tiles[j].resize(layer.ncols);
521 if (layer.mask_offset != 0)
522 layer.mask_tiles[j].resize(layer.ncols);
525 for (
uint j = 0; j < layer.nrows; j++) {
526 for (
uint i = 0; i < layer.ncols; i++) {
537 switch (layer.type) {
539 layer.image_tiles[j][i] = QImage(tile_width, tile_height, QImage::Format_RGB32);
540 layer.image_tiles[j][i].setNumColors(0);
541 if( layer.image_tiles[j][i].isNull())
546 layer.image_tiles[j][i] = QImage(tile_width, tile_height, QImage::Format_ARGB32);
547 layer.image_tiles[j][i].setNumColors(0);
548 if( layer.image_tiles[j][i].isNull())
553 layer.image_tiles[j][i] = QImage(tile_width, tile_height, QImage::Format_Indexed8);
554 layer.image_tiles[j][i].setNumColors(256);
555 if( layer.image_tiles[j][i].isNull())
557 setGrayPalette(layer.image_tiles[j][i]);
561 layer.image_tiles[j][i] = QImage(tile_width, tile_height, QImage::Format_Indexed8);
562 layer.image_tiles[j][i].setNumColors(256);
563 if( layer.image_tiles[j][i].isNull())
565 setGrayPalette(layer.image_tiles[j][i]);
567 layer.alpha_tiles[j][i] = QImage(tile_width, tile_height, QImage::Format_Indexed8);
568 layer.alpha_tiles[j][i].setNumColors(256);
569 if( layer.alpha_tiles[j][i].isNull())
571 setGrayPalette(layer.alpha_tiles[j][i]);
575 layer.image_tiles[j][i] = QImage(tile_width, tile_height, QImage::Format_Indexed8);
576 layer.image_tiles[j][i].setNumColors(xcf_image.num_colors);
577 if( layer.image_tiles[j][i].isNull())
579 setPalette(xcf_image, layer.image_tiles[j][i]);
583 layer.image_tiles[j][i] = QImage(tile_width, tile_height, QImage::Format_Indexed8);
584 layer.image_tiles[j][i].setNumColors(xcf_image.num_colors);
585 if( layer.image_tiles[j][i].isNull())
587 setPalette(xcf_image, layer.image_tiles[j][i]);
589 layer.alpha_tiles[j][i] = QImage(tile_width, tile_height, QImage::Format_Indexed8);
590 layer.alpha_tiles[j][i].setNumColors(256);
591 if( layer.alpha_tiles[j][i].isNull())
593 setGrayPalette(layer.alpha_tiles[j][i]);
596 if (layer.mask_offset != 0) {
597 layer.mask_tiles[j][i] = QImage(tile_width, tile_height, QImage::Format_Indexed8);
598 layer.mask_tiles[j][i].setNumColors(256);
599 if( layer.mask_tiles[j][i].isNull())
601 setGrayPalette(layer.mask_tiles[j][i]);
615 void XCFImageFormat::setGrayPalette(QImage& image)
617 if (grayTable.isEmpty()) {
618 grayTable.resize(256);
620 for (
int i = 0; i < 256; i++)
621 grayTable[i] = qRgb(i, i, i);
624 image.setColorTable(grayTable);
633 void XCFImageFormat::setPalette(XCFImage& xcf_image, QImage& image)
635 Q_ASSERT (xcf_image.num_colors == xcf_image.palette.size());
637 image.setColorTable(xcf_image.palette);
648 void XCFImageFormat::assignImageBytes(Layer& layer,
uint i,
uint j)
650 QImage &image = layer.image_tiles[j][i];
651 uchar* tile = layer.tile;
652 const int width = image.width();
653 const int height = image.height();
654 const int bytesPerLine = image.bytesPerLine();
655 uchar *bits = image.bits();
657 switch (layer.type) {
659 for (
int y = 0; y < height; y++) {
660 QRgb *dataPtr = (QRgb *) (bits + y * bytesPerLine);
661 for (
int x = 0; x < width; x++) {
662 *dataPtr++ = qRgb(tile[0], tile[1], tile[2]);
663 tile +=
sizeof(QRgb);
669 for (
int y = 0; y < height; y++) {
670 QRgb *dataPtr = (QRgb *) (bits + y * bytesPerLine);
671 for (
int x = 0; x < width; x++) {
672 *dataPtr++ =
qRgba(tile[0], tile[1], tile[2], tile[3]);
673 tile +=
sizeof(QRgb);
680 for (
int y = 0; y < height; y++) {
681 uchar *dataPtr = bits + y * bytesPerLine;
682 for (
int x = 0; x < width; x++) {
683 *dataPtr++ = tile[0];
684 tile +=
sizeof(QRgb);
691 for (
int y = 0; y < height; y++) {
692 uchar *dataPtr = bits + y * bytesPerLine;
693 uchar *alphaPtr = layer.alpha_tiles[j][i].scanLine(y);
694 for (
int x = 0; x < width; x++) {
700 if (tile[0] < image.numColors())
706 tile +=
sizeof(QRgb);
722 bool XCFImageFormat::loadHierarchy(QDataStream& xcf_io, Layer& layer)
729 xcf_io >> width >> height >> bpp >> offset;
739 if (xcf_io.device()->atEnd()) {
740 kDebug(399) <<
"XCF: read failure on layer " << layer.name <<
" level offsets";
745 qint64 saved_pos = xcf_io.device()->pos();
747 xcf_io.device()->seek(offset);
748 if (!loadLevel(xcf_io, layer, bpp))
751 xcf_io.device()->seek(saved_pos);
764 bool XCFImageFormat::loadLevel(QDataStream& xcf_io, Layer& layer, qint32 bpp)
770 xcf_io >> width >> height >> offset;
775 for (
uint j = 0; j < layer.nrows; j++) {
776 for (
uint i = 0; i < layer.ncols; i++) {
779 kDebug(399) <<
"XCF: incorrect number of tiles in layer " << layer.name;
783 qint64 saved_pos = xcf_io.device()->pos();
792 xcf_io.device()->seek(offset);
793 int size = layer.image_tiles[j][i].width() * layer.image_tiles[j][i].height();
795 if (!loadTileRLE(xcf_io, layer.tile, size, offset2 - offset, bpp))
802 layer.assignBytes(layer, i, j);
804 xcf_io.device()->seek(saved_pos);
819 bool XCFImageFormat::loadMask(QDataStream& xcf_io, Layer& layer)
825 xcf_io >> width >> height >> name;
829 if (!loadChannelProperties(xcf_io, layer))
832 quint32 hierarchy_offset;
833 xcf_io >> hierarchy_offset;
835 xcf_io.device()->seek(hierarchy_offset);
836 layer.assignBytes = assignMaskBytes;
838 if (!loadHierarchy(xcf_io, layer))
868 bool XCFImageFormat::loadTileRLE(QDataStream& xcf_io,
uchar* tile,
int image_size,
869 int data_length, qint32 bpp)
877 if (data_length < 0 || data_length >
int(
TILE_WIDTH * TILE_HEIGHT * 4 * 1.5)) {
878 kDebug(399) <<
"XCF: invalid tile data length" << data_length;
882 xcfdata = xcfodata =
new uchar[data_length];
884 xcf_io.readRawData((
char*)xcfdata, data_length);
886 if (!xcf_io.device()->isOpen()) {
888 kDebug(399) <<
"XCF: read failure on tile";
892 xcfdatalimit = &xcfodata[data_length - 1];
894 for (
int i = 0; i < bpp; ++i) {
899 int size = image_size;
902 if (xcfdata > xcfdatalimit)
905 uchar val = *xcfdata++;
909 length = 255 - (length - 1);
911 if (xcfdata >= xcfdatalimit)
914 length = (*xcfdata << 8) + xcfdata[1];
925 if (&xcfdata[length - 1] > xcfdatalimit)
928 while (length-- > 0) {
930 data +=
sizeof(QRgb);
935 if (xcfdata >= xcfdatalimit)
938 length = (*xcfdata << 8) + xcfdata[1];
948 if (xcfdata > xcfdatalimit)
953 while (length-- > 0) {
955 data +=
sizeof(QRgb);
966 kDebug(399) <<
"The run length encoding could not be decoded properly";
979 bool XCFImageFormat::loadChannelProperties(QDataStream& xcf_io, Layer& layer)
985 if (!loadProperty(xcf_io, type, bytes)) {
986 kDebug(399) <<
"XCF: error loading channel properties";
990 QDataStream property(bytes);
997 property >> layer.mask_channel.opacity;
1001 property >> layer.mask_channel.visible;
1005 property >> layer.mask_channel.show_masked;
1009 property >> layer.mask_channel.red >> layer.mask_channel.green
1010 >> layer.mask_channel.blue;
1014 property >> layer.mask_channel.tattoo;
1018 kDebug(399) <<
"XCF: unimplemented channel property " << type
1019 <<
", size " << bytes.size() << endl;
1031 void XCFImageFormat::assignMaskBytes(Layer& layer,
uint i,
uint j)
1033 QImage &image = layer.mask_tiles[j][i];
1034 uchar* tile = layer.tile;
1035 const int width = image.width();
1036 const int height = image.height();
1037 const int bytesPerLine = image.bytesPerLine();
1038 uchar *bits = image.bits();
1040 for (
int y = 0; y < height; y++) {
1041 uchar *dataPtr = bits + y * bytesPerLine;
1042 for (
int x = 0; x < width; x++) {
1043 *dataPtr++ = tile[0];
1044 tile +=
sizeof(QRgb);
1078 bool XCFImageFormat::initializeImage(XCFImage& xcf_image)
1081 Layer& layer(xcf_image.layer);
1082 QImage& image(xcf_image.image);
1084 switch (layer.type) {
1087 image = QImage( xcf_image.width, xcf_image.height, QImage::Format_RGB32);
1090 image.fill(qRgb(255, 255, 255));
1095 image = QImage(xcf_image.width, xcf_image.height, QImage::Format_ARGB32);
1098 image.fill(
qRgba(255, 255, 255, 0));
1103 image = QImage(xcf_image.width, xcf_image.height, QImage::Format_Indexed8);
1104 image.setNumColors(256);
1107 setGrayPalette(image);
1113 image = QImage(xcf_image.width, xcf_image.height, QImage::Format_ARGB32);
1116 image.fill(
qRgba(255, 255, 255, 0));
1132 if (xcf_image.num_colors <= 2) {
1133 image = QImage(xcf_image.width, xcf_image.height, QImage::Format_MonoLSB);
1134 image.setNumColors(xcf_image.num_colors);
1138 setPalette(xcf_image, image);
1139 }
else if (xcf_image.num_colors <= 256) {
1140 image = QImage(xcf_image.width, xcf_image.height, QImage::Format_Indexed8);
1141 image.setNumColors(xcf_image.num_colors);
1145 setPalette(xcf_image, image);
1150 if (xcf_image.num_colors == 1) {
1152 xcf_image.num_colors++;
1153 xcf_image.palette.resize(xcf_image.num_colors);
1154 xcf_image.palette[1] = xcf_image.palette[0];
1155 xcf_image.palette[0] =
qRgba(255, 255, 255, 0);
1157 image = QImage(xcf_image.width, xcf_image.height, QImage::Format_MonoLSB);
1158 image.setNumColors(xcf_image.num_colors);
1162 setPalette(xcf_image, image);
1163 }
else if (xcf_image.num_colors < 256) {
1165 xcf_image.num_colors++;
1166 xcf_image.palette.resize(xcf_image.num_colors);
1167 for (
int c = xcf_image.num_colors - 1; c >= 1; c--)
1168 xcf_image.palette[c] = xcf_image.palette[c - 1];
1170 xcf_image.palette[0] =
qRgba(255, 255, 255, 0);
1171 image = QImage( xcf_image.width, xcf_image.height, QImage::Format_Indexed8);
1172 image.setNumColors(xcf_image.num_colors);
1176 setPalette(xcf_image, image);
1181 image = QImage(xcf_image.width, xcf_image.height, QImage::Format_ARGB32);
1184 image.fill(
qRgba(255, 255, 255, 0));
1189 image.setDotsPerMeterX((
int)(xcf_image.x_resolution *
INCHESPERMETER));
1190 image.setDotsPerMeterY((
int)(xcf_image.y_resolution *
INCHESPERMETER));
1200 void XCFImageFormat::copyLayerToImage(XCFImage& xcf_image)
1202 Layer& layer(xcf_image.layer);
1203 QImage& image(xcf_image.image);
1204 PixelCopyOperation copy = 0;
1206 switch (layer.type) {
1209 copy = copyRGBToRGB;
1213 copy = copyGrayToGray;
1215 copy = copyGrayToRGB;
1218 copy = copyGrayAToRGB;
1221 copy = copyIndexedToIndexed;
1224 if (xcf_image.image.depth() <= 8)
1225 copy = copyIndexedAToIndexed;
1227 copy = copyIndexedAToRGB;
1236 for (
uint j = 0; j < layer.nrows; j++) {
1239 for (
uint i = 0; i < layer.ncols; i++) {
1248 if (!random_table_initialized) {
1249 initializeRandomTable();
1250 random_table_initialized =
true;
1253 dissolveRGBPixels(layer.image_tiles[j][i], x, y);
1256 dissolveAlphaPixels(layer.alpha_tiles[j][i], x, y);
1260 if (copy == copyRGBToRGB && layer.apply_mask != 1) {
1261 QPainter painter(&image);
1262 painter.setOpacity(layer.opacity / 255.0);
1263 painter.setCompositionMode(QPainter::CompositionMode_Source);
1264 painter.drawImage(x + layer.x_offset, y + layer.y_offset, layer.image_tiles[j][i]);
1268 for (
int l = 0; l < layer.image_tiles[j][i].height(); l++) {
1269 for (
int k = 0; k < layer.image_tiles[j][i].width(); k++) {
1271 int m = x + k + layer.x_offset;
1272 int n = y + l + layer.y_offset;
1274 if (m < 0 || m >= image.width() || n < 0 || n >= image.height())
1277 (*copy)(layer, i, j, k, l, image, m, n);
1298 void XCFImageFormat::copyRGBToRGB(Layer& layer,
uint i,
uint j,
int k,
int l,
1299 QImage& image,
int m,
int n)
1301 QRgb src = layer.image_tiles[j][i].pixel(k, l);
1302 uchar src_a = layer.opacity;
1305 src_a =
INT_MULT(src_a, qAlpha(src));
1309 if (layer.apply_mask == 1 && layer.mask_tiles.size() > (int)j &&
1310 layer.mask_tiles[j].size() > (int)i)
1311 src_a =
INT_MULT(src_a, layer.mask_tiles[j][i].pixelIndex(k, l));
1313 image.setPixel(m, n,
qRgba(src, src_a));
1328 void XCFImageFormat::copyGrayToGray(Layer& layer,
uint i,
uint j,
int k,
int l,
1329 QImage& image,
int m,
int n)
1331 int src = layer.image_tiles[j][i].pixelIndex(k, l);
1332 image.setPixel(m, n, src);
1349 void XCFImageFormat::copyGrayToRGB(Layer& layer,
uint i,
uint j,
int k,
int l,
1350 QImage& image,
int m,
int n)
1352 QRgb src = layer.image_tiles[j][i].pixel(k, l);
1353 uchar src_a = layer.opacity;
1354 image.setPixel(m, n,
qRgba(src, src_a));
1371 void XCFImageFormat::copyGrayAToRGB(Layer& layer,
uint i,
uint j,
int k,
int l,
1372 QImage& image,
int m,
int n)
1374 QRgb src = layer.image_tiles[j][i].pixel(k, l);
1375 uchar src_a = layer.alpha_tiles[j][i].pixelIndex(k, l);
1376 src_a =
INT_MULT(src_a, layer.opacity);
1380 if (layer.apply_mask == 1 && layer.mask_tiles.size() > (int)j &&
1381 layer.mask_tiles[j].size() > (int)i)
1382 src_a =
INT_MULT(src_a, layer.mask_tiles[j][i].pixelIndex(k, l));
1384 image.setPixel(m, n,
qRgba(src, src_a));
1399 void XCFImageFormat::copyIndexedToIndexed(Layer& layer,
uint i,
uint j,
int k,
int l,
1400 QImage& image,
int m,
int n)
1402 int src = layer.image_tiles[j][i].pixelIndex(k, l);
1403 image.setPixel(m, n, src);
1418 void XCFImageFormat::copyIndexedAToIndexed(Layer& layer,
uint i,
uint j,
int k,
int l,
1419 QImage& image,
int m,
int n)
1421 uchar src = layer.image_tiles[j][i].pixelIndex(k, l);
1422 uchar src_a = layer.alpha_tiles[j][i].pixelIndex(k, l);
1423 src_a =
INT_MULT(src_a, layer.opacity);
1425 if (layer.apply_mask == 1 &&
1426 layer.mask_tiles.size() > (int)j &&
1427 layer.mask_tiles[j].size() > (int)i)
1428 src_a =
INT_MULT(src_a, layer.mask_tiles[j][i].pixelIndex(k, l));
1435 image.setPixel(m, n, src);
1452 void XCFImageFormat::copyIndexedAToRGB(Layer& layer,
uint i,
uint j,
int k,
int l,
1453 QImage& image,
int m,
int n)
1455 QRgb src = layer.image_tiles[j][i].pixel(k, l);
1456 uchar src_a = layer.alpha_tiles[j][i].pixelIndex(k, l);
1457 src_a =
INT_MULT(src_a, layer.opacity);
1460 if (layer.apply_mask == 1 && layer.mask_tiles.size() > (int)j &&
1461 layer.mask_tiles[j].size() > (int)i)
1462 src_a =
INT_MULT(src_a, layer.mask_tiles[j][i].pixelIndex(k, l));
1470 image.setPixel(m, n,
qRgba(src, src_a));
1478 void XCFImageFormat::mergeLayerIntoImage(XCFImage& xcf_image)
1480 Layer& layer(xcf_image.layer);
1481 QImage& image(xcf_image.image);
1483 PixelMergeOperation merge = 0;
1485 if (!layer.opacity)
return;
1487 switch (layer.type) {
1490 merge = mergeRGBToRGB;
1494 merge = mergeGrayToGray;
1496 merge = mergeGrayToRGB;
1499 if (xcf_image.image.depth() <= 8)
1500 merge = mergeGrayAToGray;
1502 merge = mergeGrayAToRGB;
1505 merge = mergeIndexedToIndexed;
1508 if (xcf_image.image.depth() <= 8)
1509 merge = mergeIndexedAToIndexed;
1511 merge = mergeIndexedAToRGB;
1518 for (
uint j = 0; j < layer.nrows; j++) {
1521 for (
uint i = 0; i < layer.ncols; i++) {
1530 if (!random_table_initialized) {
1531 initializeRandomTable();
1532 random_table_initialized =
true;
1535 dissolveRGBPixels(layer.image_tiles[j][i], x, y);
1538 dissolveAlphaPixels(layer.alpha_tiles[j][i], x, y);
1542 if (merge == mergeRGBToRGB && layer.apply_mask != 1
1544 QPainter painter(&image);
1545 painter.setOpacity(layer.opacity / 255.0);
1546 painter.setCompositionMode(QPainter::CompositionMode_SourceOver);
1547 painter.drawImage(x + layer.x_offset, y + layer.y_offset, layer.image_tiles[j][i]);
1551 for (
int l = 0; l < layer.image_tiles[j][i].height(); l++) {
1552 for (
int k = 0; k < layer.image_tiles[j][i].width(); k++) {
1554 int m = x + k + layer.x_offset;
1555 int n = y + l + layer.y_offset;
1557 if (m < 0 || m >= image.width() || n < 0 || n >= image.height())
1560 (*merge)(layer, i, j, k, l, image, m, n);
1581 void XCFImageFormat::mergeRGBToRGB(Layer& layer,
uint i,
uint j,
int k,
int l,
1582 QImage& image,
int m,
int n)
1584 QRgb src = layer.image_tiles[j][i].pixel(k, l);
1585 QRgb dst = image.pixel(m, n);
1587 uchar src_r = qRed(src);
1588 uchar src_g = qGreen(src);
1589 uchar src_b = qBlue(src);
1590 uchar src_a = qAlpha(src);
1592 uchar dst_r = qRed(dst);
1593 uchar dst_g = qGreen(dst);
1594 uchar dst_b = qBlue(dst);
1595 uchar dst_a = qAlpha(dst);
1599 switch (layer.mode) {
1604 src_a = qMin(src_a, dst_a);
1608 src_r = qMin((dst_r * 256) / (1 + src_r), 255);
1609 src_g = qMin((dst_g * 256) / (1 + src_g), 255);
1610 src_b = qMin((dst_b * 256) / (1 + src_b), 255);
1611 src_a = qMin(src_a, dst_a);
1615 src_r = 255 -
INT_MULT(255 - dst_r, 255 - src_r);
1616 src_g = 255 -
INT_MULT(255 - dst_g, 255 - src_g);
1617 src_b = 255 -
INT_MULT(255 - dst_b, 255 - src_b);
1618 src_a = qMin(src_a, dst_a);
1625 src_a = qMin(src_a, dst_a);
1629 src_r = dst_r > src_r ? dst_r - src_r : src_r - dst_r;
1630 src_g = dst_g > src_g ? dst_g - src_g : src_g - dst_g;
1631 src_b = dst_b > src_b ? dst_b - src_b : src_b - dst_b;
1632 src_a = qMin(src_a, dst_a);
1636 src_r = add_lut(dst_r,src_r);
1637 src_g = add_lut(dst_g,src_g);
1638 src_b = add_lut(dst_b,src_b);
1639 src_a = qMin(src_a, dst_a);
1643 src_r = dst_r > src_r ? dst_r - src_r : 0;
1644 src_g = dst_g > src_g ? dst_g - src_g : 0;
1645 src_b = dst_b > src_b ? dst_b - src_b : 0;
1646 src_a = qMin(src_a, dst_a);
1650 src_r = dst_r < src_r ? dst_r : src_r;
1651 src_g = dst_g < src_g ? dst_g : src_g;
1652 src_b = dst_b < src_b ? dst_b : src_b;
1653 src_a = qMin( src_a, dst_a );
1657 src_r = dst_r < src_r ? src_r : dst_r;
1658 src_g = dst_g < src_g ? src_g : dst_g;
1659 src_b = dst_b < src_b ? src_b : dst_b;
1660 src_a = qMin(src_a, dst_a);
1664 uchar new_r = dst_r;
1665 uchar new_g = dst_g;
1666 uchar new_b = dst_b;
1678 src_a = qMin( src_a, dst_a );
1682 uchar new_r = dst_r;
1683 uchar new_g = dst_g;
1684 uchar new_b = dst_b;
1696 src_a = qMin(src_a, dst_a);
1700 uchar new_r = dst_r;
1701 uchar new_g = dst_g;
1702 uchar new_b = dst_b;
1714 src_a = qMin(src_a, dst_a);
1718 uchar new_r = dst_r;
1719 uchar new_g = dst_g;
1720 uchar new_b = dst_b;
1733 src_a = qMin(src_a, dst_a);
1741 src_r = (
uchar) qMin(tmp, 255u);
1745 src_g = (
uchar) qMin(tmp, 255u);
1749 src_b = (
uchar) qMin(tmp, 255u);
1751 src_a = qMin(src_a, dst_a);
1757 tmp = (255 - dst_r) << 8;
1759 src_r = (
uchar) qMin(tmp, 255u);
1760 src_r = 255 - src_r;
1762 tmp = (255 - dst_g) << 8;
1764 src_g = (
uchar) qMin(tmp, 255u);
1765 src_g = 255 - src_g;
1767 tmp = (255 - dst_b) << 8;
1769 src_b = (
uchar) qMin(tmp, 255u);
1770 src_b = 255 - src_b;
1772 src_a = qMin(src_a, dst_a);
1778 tmp = ((int)255-dst_r) * ((int) 255 - ((src_r-128) << 1));
1779 src_r = (
uchar) qMin(255 - (tmp >> 8), 255u);
1781 tmp = (int) dst_r * ((
int) src_r << 1);
1782 src_r = (
uchar) qMin(tmp >> 8, 255u);
1786 tmp = ((int)255-dst_g) * ((int) 255 - ((src_g-128) << 1));
1787 src_g = (
uchar) qMin(255 - (tmp >> 8), 255u);
1789 tmp = (int) dst_g * ((
int) src_g << 1);
1790 src_g = (
uchar) qMin(tmp >> 8, 255u);
1794 tmp = ((int)255-dst_b) * ((int) 255 - ((src_b-128) << 1));
1795 src_b = (
uchar) qMin(255 - (tmp >> 8), 255u);
1797 tmp = (int) dst_b * ((
int) src_b << 1);
1798 src_b = (
uchar) qMin(tmp >> 8, 255u);
1800 src_a = qMin(src_a, dst_a);
1807 tmpS = 255 -
INT_MULT((255 - dst_r), (255-src_r));
1808 src_r =
INT_MULT((255 - dst_r), tmpM)
1812 tmpS = 255 -
INT_MULT((255 - dst_g), (255-src_g));
1813 src_g =
INT_MULT((255 - dst_g), tmpM)
1817 tmpS = 255 -
INT_MULT((255 - dst_b), (255-src_b));
1818 src_b =
INT_MULT((255 - dst_b), tmpM)
1821 src_a = qMin(src_a, dst_a);
1827 tmp = dst_r - src_r + 128;
1828 tmp = qMin(tmp, 255);
1830 src_r = (
uchar) tmp;
1832 tmp = dst_g - src_g + 128;
1833 tmp = qMin(tmp, 255);
1835 src_g = (
uchar) tmp;
1837 tmp = dst_b - src_b + 128;
1838 tmp = qMin(tmp, 255);
1840 src_b = (
uchar) tmp;
1842 src_a = qMin(src_a, dst_a);
1848 tmp = dst_r + src_r - 128;
1849 tmp = qMin(tmp, 255);
1851 src_r = (
uchar) tmp;
1853 tmp = dst_g + src_g - 128;
1854 tmp = qMin(tmp, 255);
1856 src_g = (
uchar) tmp;
1858 tmp = dst_b + src_b - 128;
1859 tmp = qMin(tmp, 255);
1861 src_b = (
uchar) tmp;
1863 src_a = qMin(src_a, dst_a);
1868 src_a =
INT_MULT(src_a, layer.opacity);
1872 if (layer.apply_mask == 1 && layer.mask_tiles.size() > (int)j &&
1873 layer.mask_tiles[j].size() > (int)i)
1874 src_a =
INT_MULT(src_a, layer.mask_tiles[j][i].pixelIndex(k, l));
1876 uchar new_r, new_g, new_b, new_a;
1879 float src_ratio = (float)src_a / new_a;
1880 float dst_ratio = 1.0 - src_ratio;
1882 new_r = (
uchar)(src_ratio * src_r + dst_ratio * dst_r +
EPSILON);
1883 new_g = (
uchar)(src_ratio * src_g + dst_ratio * dst_g +
EPSILON);
1884 new_b = (
uchar)(src_ratio * src_b + dst_ratio * dst_b +
EPSILON);
1886 if (!layer_modes[layer.mode].affect_alpha)
1889 image.setPixel(m, n,
qRgba(new_r, new_g, new_b, new_a));
1904 void XCFImageFormat::mergeGrayToGray(Layer& layer,
uint i,
uint j,
int k,
int l,
1905 QImage& image,
int m,
int n)
1907 int src = layer.image_tiles[j][i].pixelIndex(k, l);
1908 image.setPixel(m, n, src);
1923 void XCFImageFormat::mergeGrayAToGray(Layer& layer,
uint i,
uint j,
int k,
int l,
1924 QImage& image,
int m,
int n)
1926 int src = qGray(layer.image_tiles[j][i].pixel(k, l));
1927 int dst = image.pixelIndex(m, n);
1929 uchar src_a = layer.alpha_tiles[j][i].pixelIndex(k, l);
1933 switch (layer.mode) {
1939 src = qMin((dst * 256) / (1 + src), 255);
1943 src = 255 -
INT_MULT(255 - dst, 255 - src);
1951 src = dst > src ? dst - src : src - dst;
1955 src = add_lut(dst,src);
1959 src = dst > src ? dst - src : 0;
1963 src = dst < src ? dst : src;
1967 src = dst < src ? src : dst;
1971 uint tmp = dst << 8;
1973 src = (
uchar) qMin(tmp, 255u);
1977 uint tmp = (255-dst) << 8;
1979 src = (
uchar) qMin(tmp, 255u);
1986 tmp = ((int)255-dst) * ((int) 255 - ((src-128) << 1));
1987 src = (
uchar) qMin(255 - (tmp >> 8), 255u);
1989 tmp = (int) dst * ((
int) src << 1);
1990 src = (
uchar) qMin(tmp >> 8, 255u);
1998 tmpS = 255 -
INT_MULT((255-dst), (255-src));
2007 tmp = dst - src + 128;
2008 tmp = qMin(tmp, 255);
2017 tmp = dst + src - 128;
2018 tmp = qMin(tmp, 255);
2026 src_a =
INT_MULT(src_a, layer.opacity);
2030 if (layer.apply_mask == 1 && layer.mask_tiles.size() > (int)j &&
2031 layer.mask_tiles[j].size() > (int)i)
2032 src_a =
INT_MULT(src_a, layer.mask_tiles[j][i].pixelIndex(k, l));
2036 float src_ratio = (float)src_a / new_a;
2037 float dst_ratio = 1.0 - src_ratio;
2041 image.setPixel(m, n, new_g);
2058 void XCFImageFormat::mergeGrayToRGB(Layer& layer,
uint i,
uint j,
int k,
int l,
2059 QImage& image,
int m,
int n)
2061 QRgb src = layer.image_tiles[j][i].pixel(k, l);
2062 uchar src_a = layer.opacity;
2063 image.setPixel(m, n,
qRgba(src, src_a));
2080 void XCFImageFormat::mergeGrayAToRGB(Layer& layer,
uint i,
uint j,
int k,
int l,
2081 QImage& image,
int m,
int n)
2083 int src = qGray(layer.image_tiles[j][i].pixel(k, l));
2084 int dst = qGray(image.pixel(m, n));
2086 uchar src_a = layer.alpha_tiles[j][i].pixelIndex(k, l);
2087 uchar dst_a = qAlpha(image.pixel(m, n));
2091 switch (layer.mode) {
2094 src_a = qMin(src_a, dst_a);
2098 src = qMin((dst * 256) / (1 + src), 255);
2099 src_a = qMin(src_a, dst_a);
2103 src = 255 -
INT_MULT(255 - dst, 255 - src);
2104 src_a = qMin(src_a, dst_a);
2109 src_a = qMin(src_a, dst_a);
2113 src = dst > src ? dst - src : src - dst;
2114 src_a = qMin(src_a, dst_a);
2118 src = add_lut(dst,src);
2119 src_a = qMin(src_a, dst_a);
2123 src = dst > src ? dst - src : 0;
2124 src_a = qMin(src_a, dst_a);
2128 src = dst < src ? dst : src;
2129 src_a = qMin(src_a, dst_a);
2133 src = dst < src ? src : dst;
2134 src_a = qMin(src_a, dst_a);
2138 uint tmp = dst << 8;
2140 src = (
uchar) qMin(tmp, 255u);
2141 src_a = qMin(src_a, dst_a);
2145 uint tmp = (255-dst) << 8;
2147 src = (
uchar) qMin(tmp, 255u);
2149 src_a = qMin(src_a, dst_a);
2155 tmp = ((int)255-dst) * ((int) 255 - ((src-128) << 1));
2156 src = (
uchar) qMin(255 - (tmp >> 8), 255u);
2158 tmp = (int) dst * ((
int) src << 1);
2159 src = (
uchar) qMin(tmp >> 8, 255u);
2161 src_a = qMin(src_a, dst_a);
2168 tmpS = 255 -
INT_MULT((255 - dst), (255-src));
2172 src_a = qMin(src_a, dst_a);
2178 tmp = dst - src + 128;
2179 tmp = qMin(tmp, 255);
2183 src_a = qMin(src_a, dst_a);
2189 tmp = dst + src - 128;
2190 tmp = qMin(tmp, 255);
2194 src_a = qMin(src_a, dst_a);
2199 src_a =
INT_MULT(src_a, layer.opacity);
2202 if (layer.apply_mask == 1 && layer.mask_tiles.size() > (int)j &&
2203 layer.mask_tiles[j].size() > (int)i)
2204 src_a =
INT_MULT(src_a, layer.mask_tiles[j][i].pixelIndex(k, l));
2208 float src_ratio = (float)src_a / new_a;
2209 float dst_ratio = 1.0 - src_ratio;
2213 if (!layer_modes[layer.mode].affect_alpha)
2216 image.setPixel(m, n,
qRgba(new_g, new_g, new_g, new_a));
2231 void XCFImageFormat::mergeIndexedToIndexed(Layer& layer,
uint i,
uint j,
int k,
int l,
2232 QImage& image,
int m,
int n)
2234 int src = layer.image_tiles[j][i].pixelIndex(k, l);
2235 image.setPixel(m, n, src);
2250 void XCFImageFormat::mergeIndexedAToIndexed(Layer& layer,
uint i,
uint j,
int k,
int l,
2251 QImage& image,
int m,
int n)
2253 uchar src = layer.image_tiles[j][i].pixelIndex(k, l);
2254 uchar src_a = layer.alpha_tiles[j][i].pixelIndex(k, l);
2255 src_a =
INT_MULT( src_a, layer.opacity );
2257 if ( layer.apply_mask == 1 &&
2258 layer.mask_tiles.size() > (int)j &&
2259 layer.mask_tiles[j].size() > (int)i)
2260 src_a =
INT_MULT(src_a, layer.mask_tiles[j][i].pixelIndex(k, l));
2264 image.setPixel(m, n, src);
2282 void XCFImageFormat::mergeIndexedAToRGB(Layer& layer,
uint i,
uint j,
int k,
int l,
2283 QImage& image,
int m,
int n)
2285 QRgb src = layer.image_tiles[j][i].pixel(k, l);
2286 uchar src_a = layer.alpha_tiles[j][i].pixelIndex(k, l);
2287 src_a =
INT_MULT(src_a, layer.opacity);
2290 if (layer.apply_mask == 1 && layer.mask_tiles.size() > (int)j &&
2291 layer.mask_tiles[j].size() > (int)i)
2292 src_a =
INT_MULT(src_a, layer.mask_tiles[j][i].pixelIndex(k, l));
2300 image.setPixel(m, n,
qRgba(src, src_a));
2311 void XCFImageFormat::dissolveRGBPixels ( QImage& image,
int x,
int y )
2316 for (
int l = 0; l < image.height(); l++) {
2317 srand(random_table[( l + y ) % RANDOM_TABLE_SIZE]);
2319 for (
int k = 0; k < x; k++)
2322 for (
int k = 0; k < image.width(); k++) {
2323 int rand_val = rand() & 0xff;
2324 QRgb pixel = image.pixel(k, l);
2326 if (rand_val > qAlpha(pixel)) {
2327 image.setPixel(k, l,
qRgba(pixel, 0));
2343 void XCFImageFormat::dissolveAlphaPixels ( QImage& image,
int x,
int y )
2348 for (
int l = 0; l < image.height(); l++) {
2349 srand( random_table[(l + y) % RANDOM_TABLE_SIZE]);
2351 for (
int k = 0; k < x; k++)
2354 for (
int k = 0; k < image.width(); k++) {
2355 int rand_val = rand() & 0xff;
2356 uchar alpha = image.pixelIndex(k, l);
2358 if (rand_val > alpha) {
2359 image.setPixel(k, l, 0);
2384 return xcfif.
readXCF(device(), image);
2400 qWarning(
"DDSHandler::canRead() called with no device");
2404 qint64 oldPos = device->pos();
2407 qint64 readBytes = device->read(head,
sizeof(head));
2408 if (readBytes !=
sizeof(head)) {
2409 if (device->isSequential()) {
2410 while (readBytes > 0)
2411 device->ungetChar(head[readBytes-- - 1]);
2413 device->seek(oldPos);
2418 if (device->isSequential()) {
2419 while (readBytes > 0)
2420 device->ungetChar(head[readBytes-- - 1]);
2422 device->seek(oldPos);
2425 return qstrncmp(head,
"gimp xcf", 8) == 0;
2429 class XCFPlugin :
public QImageIOPlugin
2432 QStringList keys()
const;
2433 Capabilities capabilities(QIODevice *device,
const QByteArray &format)
const;
2434 QImageIOHandler *create(QIODevice *device,
const QByteArray &format = QByteArray())
const;
2437 QStringList XCFPlugin::keys()
const
2439 return QStringList() <<
"xcf" <<
"XCF";
2442 QImageIOPlugin::Capabilities XCFPlugin::capabilities(QIODevice *device,
const QByteArray &format)
const
2444 if (format ==
"xcf" || format ==
"XCF")
2445 return Capabilities(CanRead);
2446 if (!format.isEmpty())
2448 if (!device->isOpen())
2457 QImageIOHandler *XCFPlugin::create(QIODevice *device,
const QByteArray &format)
const
2460 handler->setDevice(device);
2461 handler->setFormat(format);
2465 Q_EXPORT_STATIC_PLUGIN(XCFPlugin)
2466 Q_EXPORT_PLUGIN2(xcf,XCFPlugin)
const float INCHESPERMETER
const int RANDOM_TABLE_SIZE
Size of dissolve random number table.
PropType
Properties which can be stored in an XCF file.
static void HLSTORGB(uchar &hue, uchar &lightness, uchar &saturation)
const double EPSILON
Roundup in alpha blending.
const uint TILE_HEIGHT
Height of a tile in the XCF file.
static void HSVTORGB(uchar &hue, uchar &saturation, uchar &value)
const uint TILE_WIDTH
Width of a tile in the XCF file.
static void RGBTOHSV(uchar &red, uchar &green, uchar &blue)
const int RANDOM_SEED
Seed for dissolve random number table.
QRgb qRgba(const QRgb &rgb, int a)
Change a QRgb value's alpha only.
bool write(const QImage &image)
const uchar OPAQUE_OPACITY
Opaque value for 8-bit alpha component.
int INT_MULT(int a, int b)
static void RGBTOHLS(uchar &red, uchar &green, uchar &blue)