24 #include <tqiodevice.h>
25 #include <tqvaluestack.h>
26 #include <tqvaluevector.h>
35 TDE_EXPORT
void kimgio_xcf_read(TQImageIO *io)
42 TDE_EXPORT
void kimgio_xcf_write(TQImageIO *io)
44 kdDebug(399) <<
"XCF: write support not implemented" << endl;
52 int XCFImageFormat::random_table[RANDOM_TABLE_SIZE];
57 const XCFImageFormat::LayerModes XCFImageFormat::layer_modes[] = {
81 inline TQRgb tqRgba ( TQRgb rgb,
int a )
83 return ((a & 0xff) << 24 | (rgb & TQT_RGB_MASK));
91 XCFImageFormat::XCFImageFormat()
96 for (
int i = 0; i < RANDOM_TABLE_SIZE; i++)
97 random_table[i] = rand();
99 for (
int i = 0; i < RANDOM_TABLE_SIZE; i++) {
101 int swap = i + rand() % (RANDOM_TABLE_SIZE - i);
102 tmp = random_table[i];
103 random_table[i] = random_table[swap];
104 random_table[swap] = tmp;
118 int XCFImageFormat::add_lut(
int a,
int b ) {
119 return TQMIN( a + b, 255 );
122 void XCFImageFormat::readXCF(TQImageIO *io)
125 TQDataStream xcf_io(io->ioDevice());
128 xcf_io.readRawBytes(tag,
sizeof(tag));
130 if (xcf_io.device()->status() != IO_Ok) {
131 kdDebug(399) <<
"XCF: read failure on header tag" << endl;
135 xcf_io >> xcf_image.width >> xcf_image.height >> xcf_image.type;
137 if (xcf_io.device()->status() != IO_Ok) {
138 kdDebug(399) <<
"XCF: read failure on image info" << endl;
142 kdDebug() << tag <<
" " << xcf_image.width <<
" " << xcf_image.height <<
" " << xcf_image.type << endl;
143 if (!loadImageProperties(xcf_io, xcf_image))
152 TQValueStack<TQ_INT32> layer_offsets;
155 TQ_INT32 layer_offset;
157 xcf_io >> layer_offset;
159 if (xcf_io.device()->status() != IO_Ok) {
160 kdDebug(399) <<
"XCF: read failure on layer offsets" << endl;
164 if (layer_offset == 0)
167 layer_offsets.push(layer_offset);
170 xcf_image.num_layers = layer_offsets.size();
172 if (layer_offsets.size() == 0) {
173 kdDebug(399) <<
"XCF: no layers!" << endl;
178 while (!layer_offsets.isEmpty()) {
179 TQ_INT32 layer_offset = layer_offsets.pop();
181 xcf_io.device()->at(layer_offset);
183 if (!loadLayer(xcf_io, xcf_image))
187 if (!xcf_image.initialized) {
188 kdDebug(399) <<
"XCF: no visible layers!" << endl;
192 io->setImage(xcf_image.image);
204 bool XCFImageFormat::loadImageProperties(TQDataStream& xcf_io, XCFImage& xcf_image)
210 if (!loadProperty(xcf_io, type, bytes)) {
211 kdDebug(399) <<
"XCF: error loading global image properties" << endl;
215 TQDataStream property(bytes, IO_ReadOnly);
221 case PROP_COMPRESSION:
222 property >> xcf_image.compression;
225 case PROP_RESOLUTION:
226 property >> xcf_image.x_resolution >> xcf_image.y_resolution;
230 property >> xcf_image.tattoo;
234 while (!property.atEnd()) {
238 property.readBytes(tag, size);
242 property >> flags >> data;
244 if (tag && strncmp(tag,
"gimp-comment", strlen(
"gimp-comment")) == 0)
245 xcf_image.image.setText(
"Comment", 0, data);
253 property >> xcf_image.unit;
263 property >> xcf_image.num_colors;
264 if(xcf_image.num_colors < 0 || xcf_image.num_colors > 65535)
267 xcf_image.palette.reserve(xcf_image.num_colors);
269 for (
int i = 0; i < xcf_image.num_colors; i++) {
271 property >> r >> g >> b;
272 xcf_image.palette.push_back( tqRgb(r,g,b) );
277 kdDebug(399) <<
"XCF: unimplemented image property" << type
278 <<
", size " << bytes.size() << endl;
291 bool XCFImageFormat::loadProperty(TQDataStream& xcf_io, PropType& type, TQByteArray& bytes)
297 if (xcf_io.device()->status() != IO_Ok) {
298 kdDebug(399) <<
"XCF: read failure on property type" << type << endl;
309 if (type == PROP_COLORMAP) {
312 if (xcf_io.device()->status() != IO_Ok) {
313 kdDebug(399) <<
"XCF: read failure on property " << type <<
" size" << endl;
317 if(size > 65535 || size < 4)
320 size = 3 * (size - 4) + 4;
321 data =
new char[size];
323 xcf_io.readRawBytes(data, size);
324 }
else if (type == PROP_USER_UNIT) {
330 xcf_io >> size >> factor >> digits;
332 if (xcf_io.device()->status() != IO_Ok) {
333 kdDebug(399) <<
"XCF: read failure on property " << type << endl;
337 for (
int i = 0; i < 5; i++) {
338 xcf_io >> unit_strings;
340 if (xcf_io.device()->status() != IO_Ok) {
341 kdDebug(399) <<
"XCF: read failure on property " << type << endl;
345 delete[] unit_strings;
353 data =
new char[size];
354 xcf_io.readRawBytes(data, size);
357 if (xcf_io.device()->status() != IO_Ok) {
358 kdDebug(399) <<
"XCF: read failure on property " << type <<
" data, size " << size << endl;
362 if (size != 0 && data) {
363 bytes.assign(data,size);
378 bool XCFImageFormat::loadLayer(TQDataStream& xcf_io, XCFImage& xcf_image)
380 Layer& layer(xcf_image.layer);
383 xcf_io >> layer.width >> layer.height >> layer.type >> layer.name;
385 if (xcf_io.device()->status() != IO_Ok) {
386 kdDebug(399) <<
"XCF: read failure on layer" << endl;
390 if (!loadLayerProperties(xcf_io, layer))
393 cout <<
"layer: \"" << layer.name <<
"\", size: " << layer.width <<
" x "
394 << layer.height <<
", type: " << layer.type <<
", mode: " << layer.mode
395 <<
", opacity: " << layer.opacity <<
", visible: " << layer.visible
396 <<
", offset: " << layer.x_offset <<
", " << layer.y_offset << endl;
402 if (layer.visible == 0)
407 xcf_io >> layer.hierarchy_offset >> layer.mask_offset;
408 if (xcf_io.device()->status() != IO_Ok) {
409 kdDebug(399) <<
"XCF: read failure on layer image offsets" << endl;
416 if( !composeTiles(xcf_image))
418 xcf_io.device()->at(layer.hierarchy_offset);
424 layer.assignBytes = assignImageBytes;
426 if (!loadHierarchy(xcf_io, layer))
429 if (layer.mask_offset != 0) {
430 xcf_io.device()->at(layer.mask_offset);
432 if (!loadMask(xcf_io, layer))
440 if (!xcf_image.initialized) {
441 if( !initializeImage(xcf_image))
443 copyLayerToImage(xcf_image);
444 xcf_image.initialized =
true;
446 mergeLayerIntoImage(xcf_image);
459 bool XCFImageFormat::loadLayerProperties(TQDataStream& xcf_io, Layer& layer)
465 if (!loadProperty(xcf_io, type, bytes)) {
466 kdDebug(399) <<
"XCF: error loading layer properties" << endl;
470 TQDataStream property(bytes, IO_ReadOnly);
476 case PROP_ACTIVE_LAYER:
481 property >> layer.opacity;
485 property >> layer.visible;
489 property >> layer.linked;
492 case PROP_PRESERVE_TRANSPARENCY:
493 property >> layer.preserve_transparency;
496 case PROP_APPLY_MASK:
497 property >> layer.apply_mask;
501 property >> layer.edit_mask;
505 property >> layer.show_mask;
509 property >> layer.x_offset >> layer.y_offset;
513 property >> layer.mode;
517 property >> layer.tattoo;
521 kdDebug(399) <<
"XCF: unimplemented layer property " << type
522 <<
", size " << bytes.size() << endl;
533 bool XCFImageFormat::composeTiles(XCFImage& xcf_image)
535 Layer& layer(xcf_image.layer);
537 layer.nrows = (layer.height + TILE_HEIGHT - 1) / TILE_HEIGHT;
538 layer.ncols = (layer.width + TILE_WIDTH - 1) / TILE_WIDTH;
540 layer.image_tiles.resize(layer.nrows);
542 if (layer.type == GRAYA_GIMAGE || layer.type == INDEXEDA_GIMAGE)
543 layer.alpha_tiles.resize(layer.nrows);
545 if (layer.mask_offset != 0)
546 layer.mask_tiles.resize(layer.nrows);
548 for (uint j = 0; j < layer.nrows; j++) {
549 layer.image_tiles[j].resize(layer.ncols);
551 if (layer.type == GRAYA_GIMAGE || layer.type == INDEXEDA_GIMAGE)
552 layer.alpha_tiles[j].resize(layer.ncols);
554 if (layer.mask_offset != 0)
555 layer.mask_tiles[j].resize(layer.ncols);
558 for (uint j = 0; j < layer.nrows; j++) {
559 for (uint i = 0; i < layer.ncols; i++) {
561 uint tile_width = (i + 1) * TILE_WIDTH <= layer.width
562 ? TILE_WIDTH : layer.width - i * TILE_WIDTH;
564 uint tile_height = (j + 1) * TILE_HEIGHT <= layer.height
565 ? TILE_HEIGHT : layer.height - j * TILE_HEIGHT;
570 switch (layer.type) {
572 layer.image_tiles[j][i] = TQImage(tile_width, tile_height, 32, 0);
573 if( layer.image_tiles[j][i].isNull())
575 layer.image_tiles[j][i].setAlphaBuffer(
false);
579 layer.image_tiles[j][i] = TQImage(tile_width, tile_height, 32, 0);
580 if( layer.image_tiles[j][i].isNull())
582 layer.image_tiles[j][i].setAlphaBuffer(
true);
586 layer.image_tiles[j][i] = TQImage(tile_width, tile_height, 8, 256);
587 if( layer.image_tiles[j][i].isNull())
589 setGrayPalette(layer.image_tiles[j][i]);
593 layer.image_tiles[j][i] = TQImage(tile_width, tile_height, 8, 256);
594 if( layer.image_tiles[j][i].isNull())
596 setGrayPalette(layer.image_tiles[j][i]);
598 layer.alpha_tiles[j][i] = TQImage( tile_width, tile_height, 8, 256);
599 if( layer.alpha_tiles[j][i].isNull())
601 setGrayPalette(layer.alpha_tiles[j][i]);
605 layer.image_tiles[j][i] = TQImage(tile_width, tile_height, 8,
606 xcf_image.num_colors);
607 if( layer.image_tiles[j][i].isNull())
609 setPalette(xcf_image, layer.image_tiles[j][i]);
612 case INDEXEDA_GIMAGE:
613 layer.image_tiles[j][i] = TQImage(tile_width, tile_height,8,
614 xcf_image.num_colors);
615 if( layer.image_tiles[j][i].isNull())
617 setPalette(xcf_image, layer.image_tiles[j][i]);
619 layer.alpha_tiles[j][i] = TQImage(tile_width, tile_height, 8, 256);
620 if( layer.alpha_tiles[j][i].isNull())
622 setGrayPalette(layer.alpha_tiles[j][i]);
625 if (layer.mask_offset != 0) {
626 layer.mask_tiles[j][i] = TQImage(tile_width, tile_height, 8, 256);
627 if( layer.mask_tiles[j][i].isNull())
629 setGrayPalette(layer.mask_tiles[j][i]);
643 void XCFImageFormat::setGrayPalette(TQImage& image)
645 for (
int i = 0; i < 256; i++)
646 image.setColor(i, tqRgb(i, i, i));
655 void XCFImageFormat::setPalette(XCFImage& xcf_image, TQImage& image)
657 for (
int i = 0; i < xcf_image.num_colors; i++)
658 image.setColor(i, xcf_image.palette[i]);
669 void XCFImageFormat::assignImageBytes(Layer& layer, uint i, uint j)
671 uchar* tile = layer.tile;
673 switch (layer.type) {
675 for (
int l = 0; l < layer.image_tiles[j][i].height(); l++) {
676 for (
int k = 0; k < layer.image_tiles[j][i].width(); k++) {
677 layer.image_tiles[j][i].setPixel(k, l,
678 tqRgb(tile[0], tile[1], tile[2]));
679 tile +=
sizeof(TQRgb);
685 for (
int l = 0; l < layer.image_tiles[j][i].height(); l++ ) {
686 for (
int k = 0; k < layer.image_tiles[j][i].width(); k++ ) {
687 layer.image_tiles[j][i].setPixel(k, l,
688 tqRgba(tile[0], tile[1], tile[2], tile[3]));
689 tile +=
sizeof(TQRgb);
696 for (
int l = 0; l < layer.image_tiles[j][i].height(); l++) {
697 for (
int k = 0; k < layer.image_tiles[j][i].width(); k++) {
698 layer.image_tiles[j][i].setPixel(k, l, tile[0]);
699 tile +=
sizeof(TQRgb);
705 case INDEXEDA_GIMAGE:
706 for (
int l = 0; l < layer.image_tiles[j][i].height(); l++) {
707 for (
int k = 0; k < layer.image_tiles[j][i].width(); k++) {
713 if (tile[0] < layer.image_tiles[j][i].numColors())
714 layer.image_tiles[j][i].setPixel(k, l, tile[0]);
716 layer.alpha_tiles[j][i].setPixel(k, l, tile[1]);
717 tile +=
sizeof(TQRgb);
733 bool XCFImageFormat::loadHierarchy(TQDataStream& xcf_io, Layer& layer)
740 xcf_io >> width >> height >> bpp >> offset;
742 if (xcf_io.device()->status() != IO_Ok) {
743 kdDebug(399) <<
"XCF: read failure on layer " << layer.name <<
" image header" << endl;
755 if (xcf_io.device()->status() != IO_Ok) {
756 kdDebug(399) <<
"XCF: read failure on layer " << layer.name <<
" level offsets" << endl;
761 TQIODevice::Offset saved_pos = xcf_io.device()->at();
763 xcf_io.device()->at(offset);
764 if (!loadLevel(xcf_io, layer, bpp))
767 xcf_io.device()->at(saved_pos);
780 bool XCFImageFormat::loadLevel(TQDataStream& xcf_io, Layer& layer, TQ_INT32 bpp)
786 xcf_io >> width >> height >> offset;
788 if (xcf_io.device()->status() != IO_Ok) {
789 kdDebug(399) <<
"XCF: read failure on layer " << layer.name <<
" level info" << endl;
796 for (uint j = 0; j < layer.nrows; j++) {
797 for (uint i = 0; i < layer.ncols; i++) {
800 kdDebug(399) <<
"XCF: incorrect number of tiles in layer " << layer.name << endl;
804 TQIODevice::Offset saved_pos = xcf_io.device()->at();
808 if (xcf_io.device()->status() != IO_Ok) {
809 kdDebug(399) <<
"XCF: read failure on layer " << layer.name <<
" level offset look-ahead" << endl;
816 offset2 = offset + (uint)(TILE_WIDTH * TILE_HEIGHT * 4 * 1.5);
818 xcf_io.device()->at(offset);
819 int size = layer.image_tiles[j][i].width() * layer.image_tiles[j][i].height();
821 if (!loadTileRLE(xcf_io, layer.tile, size, offset2 - offset, bpp))
828 layer.assignBytes(layer, i, j);
830 xcf_io.device()->at(saved_pos);
833 if (xcf_io.device()->status() != IO_Ok) {
834 kdDebug(399) <<
"XCF: read failure on layer " << layer.name <<
" level offset" << endl;
850 bool XCFImageFormat::loadMask(TQDataStream& xcf_io, Layer& layer)
856 xcf_io >> width >> height >> name;
858 if (xcf_io.device()->status() != IO_Ok) {
859 kdDebug(399) <<
"XCF: read failure on mask info" << endl;
865 if (!loadChannelProperties(xcf_io, layer))
868 TQ_UINT32 hierarchy_offset;
869 xcf_io >> hierarchy_offset;
871 if (xcf_io.device()->status() != IO_Ok) {
872 kdDebug(399) <<
"XCF: read failure on mask image offset" << endl;
876 xcf_io.device()->at(hierarchy_offset);
877 layer.assignBytes = assignMaskBytes;
879 if (!loadHierarchy(xcf_io, layer))
909 bool XCFImageFormat::loadTileRLE(TQDataStream& xcf_io, uchar* tile,
int image_size,
910 int data_length, TQ_INT32 bpp)
918 xcfdata = xcfodata =
new uchar[data_length];
920 xcf_io.readRawBytes((
char*)xcfdata, data_length);
922 if (xcf_io.device()->status() != IO_Ok) {
924 kdDebug(399) <<
"XCF: read failure on tile" << endl;
928 xcfdatalimit = &xcfodata[data_length - 1];
930 for (
int i = 0; i < bpp; ++i) {
935 int size = image_size;
938 if (xcfdata > xcfdatalimit)
941 uchar val = *xcfdata++;
945 length = 255 - (length - 1);
947 if (xcfdata >= xcfdatalimit)
950 length = (*xcfdata << 8) + xcfdata[1];
961 if (&xcfdata[length - 1] > xcfdatalimit)
964 while (length-- > 0) {
966 data +=
sizeof(TQRgb);
971 if (xcfdata >= xcfdatalimit)
974 length = (*xcfdata << 8) + xcfdata[1];
984 if (xcfdata > xcfdatalimit)
989 while (length-- > 0) {
991 data +=
sizeof(TQRgb);
1002 kdDebug(399) <<
"The run length encoding could not be decoded properly" << endl;
1015 bool XCFImageFormat::loadChannelProperties(TQDataStream& xcf_io, Layer& layer)
1021 if (!loadProperty(xcf_io, type, bytes)) {
1022 kdDebug(399) <<
"XCF: error loading channel properties" << endl;
1026 TQDataStream property(bytes, IO_ReadOnly);
1033 property >> layer.mask_channel.opacity;
1037 property >> layer.mask_channel.visible;
1040 case PROP_SHOW_MASKED:
1041 property >> layer.mask_channel.show_masked;
1045 property >> layer.mask_channel.red >> layer.mask_channel.green
1046 >> layer.mask_channel.blue;
1050 property >> layer.mask_channel.tattoo;
1054 kdDebug(399) <<
"XCF: unimplemented channel property " << type
1055 <<
", size " << bytes.size() << endl;
1067 void XCFImageFormat::assignMaskBytes(Layer& layer, uint i, uint j)
1069 uchar* tile = layer.tile;
1071 for (
int l = 0; l < layer.image_tiles[j][i].height(); l++) {
1072 for (
int k = 0; k < layer.image_tiles[j][i].width(); k++) {
1073 layer.mask_tiles[j][i].setPixel(k, l, tile[0]);
1074 tile +=
sizeof(TQRgb);
1108 bool XCFImageFormat::initializeImage(XCFImage& xcf_image)
1111 Layer& layer(xcf_image.layer);
1112 TQImage& image(xcf_image.image);
1114 switch (layer.type) {
1116 if (layer.opacity == OPAQUE_OPACITY) {
1117 image.create( xcf_image.width, xcf_image.height, 32);
1120 image.fill(tqRgb(255, 255, 255));
1125 image.create(xcf_image.width, xcf_image.height, 32);
1128 image.fill(tqRgba(255, 255, 255, 0));
1131 image.setAlphaBuffer(
true);
1135 if (layer.opacity == OPAQUE_OPACITY) {
1136 image.create(xcf_image.width, xcf_image.height, 8, 256);
1139 setGrayPalette(image);
1145 image.create(xcf_image.width, xcf_image.height, 32);
1148 image.fill(tqRgba(255, 255, 255, 0));
1149 image.setAlphaBuffer(
true);
1152 case INDEXED_GIMAGE:
1165 if (xcf_image.num_colors <= 2) {
1166 image.create(xcf_image.width, xcf_image.height,
1167 1, xcf_image.num_colors,
1168 TQImage::LittleEndian);
1172 setPalette(xcf_image, image);
1173 }
else if (xcf_image.num_colors <= 256) {
1174 image.create(xcf_image.width, xcf_image.height,
1175 8, xcf_image.num_colors,
1176 TQImage::LittleEndian);
1180 setPalette(xcf_image, image);
1184 case INDEXEDA_GIMAGE:
1185 if (xcf_image.num_colors == 1) {
1187 xcf_image.num_colors++;
1188 xcf_image.palette.resize(xcf_image.num_colors);
1189 xcf_image.palette[1] = xcf_image.palette[0];
1190 xcf_image.palette[0] = tqRgba(255, 255, 255, 0);
1192 image.create(xcf_image.width, xcf_image.height,
1193 1, xcf_image.num_colors,
1194 TQImage::LittleEndian);
1198 setPalette(xcf_image, image);
1199 image.setAlphaBuffer(
true);
1200 }
else if (xcf_image.num_colors < 256) {
1202 xcf_image.num_colors++;
1203 xcf_image.palette.resize(xcf_image.num_colors);
1204 for (
int c = xcf_image.num_colors - 1; c >= 1; c--)
1205 xcf_image.palette[c] = xcf_image.palette[c - 1];
1207 xcf_image.palette[0] = tqRgba(255, 255, 255, 0);
1208 image.create( xcf_image.width, xcf_image.height,
1209 8, xcf_image.num_colors);
1213 setPalette(xcf_image, image);
1214 image.setAlphaBuffer(
true);
1219 image.create(xcf_image.width, xcf_image.height, 32);
1222 image.fill(tqRgba(255, 255, 255, 0));
1223 image.setAlphaBuffer(
true);
1228 image.setDotsPerMeterX((
int)(xcf_image.x_resolution * INCHESPERMETER));
1229 image.setDotsPerMeterY((
int)(xcf_image.y_resolution * INCHESPERMETER));
1239 void XCFImageFormat::copyLayerToImage(XCFImage& xcf_image)
1241 Layer& layer(xcf_image.layer);
1242 TQImage& image(xcf_image.image);
1243 PixelCopyOperation copy = 0;
1245 switch (layer.type) {
1248 copy = copyRGBToRGB;
1251 if (layer.opacity == OPAQUE_OPACITY)
1252 copy = copyGrayToGray;
1254 copy = copyGrayToRGB;
1257 copy = copyGrayAToRGB;
1259 case INDEXED_GIMAGE:
1260 copy = copyIndexedToIndexed;
1262 case INDEXEDA_GIMAGE:
1263 if (xcf_image.image.depth() <= 8)
1264 copy = copyIndexedAToIndexed;
1266 copy = copyIndexedAToRGB;
1271 for (uint j = 0; j < layer.nrows; j++) {
1272 uint y = j * TILE_HEIGHT;
1274 for (uint i = 0; i < layer.ncols; i++) {
1275 uint x = i * TILE_WIDTH;
1282 if (layer.mode == DISSOLVE_MODE) {
1283 if (layer.type == RGBA_GIMAGE)
1284 dissolveRGBPixels(layer.image_tiles[j][i], x, y);
1286 else if (layer.type == GRAYA_GIMAGE)
1287 dissolveAlphaPixels(layer.alpha_tiles[j][i], x, y);
1290 for (
int l = 0; l < layer.image_tiles[j][i].height(); l++) {
1291 for (
int k = 0; k < layer.image_tiles[j][i].width(); k++) {
1293 int m = x + k + layer.x_offset;
1294 int n = y + l + layer.y_offset;
1296 if (m < 0 || m >= image.width() || n < 0 || n >= image.height())
1299 (*copy)(layer, i, j, k, l, image, m, n);
1320 void XCFImageFormat::copyRGBToRGB(Layer& layer, uint i, uint j,
int k,
int l,
1321 TQImage& image,
int m,
int n)
1323 TQRgb src = layer.image_tiles[j][i].pixel(k, l);
1324 uchar src_a = layer.opacity;
1326 if (layer.type == RGBA_GIMAGE)
1327 src_a = INT_MULT(src_a, tqAlpha(src));
1331 if (layer.apply_mask == 1 && layer.mask_tiles.size() > j &&
1332 layer.mask_tiles[j].size() > i)
1333 src_a = INT_MULT(src_a, layer.mask_tiles[j][i].pixelIndex(k, l));
1335 image.setPixel(m, n, tqRgba(src, src_a));
1350 void XCFImageFormat::copyGrayToGray(Layer& layer, uint i, uint j,
int k,
int l,
1351 TQImage& image,
int m,
int n)
1353 int src = layer.image_tiles[j][i].pixelIndex(k, l);
1354 image.setPixel(m, n, src);
1371 void XCFImageFormat::copyGrayToRGB(Layer& layer, uint i, uint j,
int k,
int l,
1372 TQImage& image,
int m,
int n)
1374 TQRgb src = layer.image_tiles[j][i].pixel(k, l);
1375 uchar src_a = layer.opacity;
1376 image.setPixel(m, n, tqRgba(src, src_a));
1393 void XCFImageFormat::copyGrayAToRGB(Layer& layer, uint i, uint j,
int k,
int l,
1394 TQImage& image,
int m,
int n)
1396 TQRgb src = layer.image_tiles[j][i].pixel(k, l);
1397 uchar src_a = layer.alpha_tiles[j][i].pixelIndex(k, l);
1398 src_a = INT_MULT(src_a, layer.opacity);
1402 if (layer.apply_mask == 1 && layer.mask_tiles.size() > j &&
1403 layer.mask_tiles[j].size() > i)
1404 src_a = INT_MULT(src_a, layer.mask_tiles[j][i].pixelIndex(k, l));
1406 image.setPixel(m, n, tqRgba(src, src_a));
1421 void XCFImageFormat::copyIndexedToIndexed(Layer& layer, uint i, uint j,
int k,
int l,
1422 TQImage& image,
int m,
int n)
1424 int src = layer.image_tiles[j][i].pixelIndex(k, l);
1425 image.setPixel(m, n, src);
1440 void XCFImageFormat::copyIndexedAToIndexed(Layer& layer, uint i, uint j,
int k,
int l,
1441 TQImage& image,
int m,
int n)
1443 uchar src = layer.image_tiles[j][i].pixelIndex(k, l);
1444 uchar src_a = layer.alpha_tiles[j][i].pixelIndex(k, l);
1445 src_a = INT_MULT(src_a, layer.opacity);
1447 if (layer.apply_mask == 1 &&
1448 layer.mask_tiles.size() > j &&
1449 layer.mask_tiles[j].size() > i)
1450 src_a = INT_MULT(src_a, layer.mask_tiles[j][i].pixelIndex(k, l));
1457 image.setPixel(m, n, src);
1474 void XCFImageFormat::copyIndexedAToRGB(Layer& layer, uint i, uint j,
int k,
int l,
1475 TQImage& image,
int m,
int n)
1477 TQRgb src = layer.image_tiles[j][i].pixel(k, l);
1478 uchar src_a = layer.alpha_tiles[j][i].pixelIndex(k, l);
1479 src_a = INT_MULT(src_a, layer.opacity);
1482 if (layer.apply_mask == 1 && layer.mask_tiles.size() > j &&
1483 layer.mask_tiles[j].size() > i)
1484 src_a = INT_MULT(src_a, layer.mask_tiles[j][i].pixelIndex(k, l));
1490 src_a = OPAQUE_OPACITY;
1492 image.setPixel(m, n, tqRgba(src, src_a));
1500 void XCFImageFormat::mergeLayerIntoImage(XCFImage& xcf_image)
1502 Layer& layer(xcf_image.layer);
1503 TQImage& image(xcf_image.image);
1505 PixelMergeOperation merge = 0;
1507 switch (layer.type) {
1510 merge = mergeRGBToRGB;
1513 if (layer.opacity == OPAQUE_OPACITY)
1514 merge = mergeGrayToGray;
1516 merge = mergeGrayToRGB;
1519 if (xcf_image.image.depth() <= 8)
1520 merge = mergeGrayAToGray;
1522 merge = mergeGrayAToRGB;
1524 case INDEXED_GIMAGE:
1525 merge = mergeIndexedToIndexed;
1527 case INDEXEDA_GIMAGE:
1528 if (xcf_image.image.depth() <= 8)
1529 merge = mergeIndexedAToIndexed;
1531 merge = mergeIndexedAToRGB;
1534 for (uint j = 0; j < layer.nrows; j++) {
1535 uint y = j * TILE_HEIGHT;
1537 for (uint i = 0; i < layer.ncols; i++) {
1538 uint x = i * TILE_WIDTH;
1545 if (layer.mode == DISSOLVE_MODE) {
1546 if (layer.type == RGBA_GIMAGE)
1547 dissolveRGBPixels(layer.image_tiles[j][i], x, y);
1549 else if (layer.type == GRAYA_GIMAGE)
1550 dissolveAlphaPixels(layer.alpha_tiles[j][i], x, y);
1553 for (
int l = 0; l < layer.image_tiles[j][i].height(); l++) {
1554 for (
int k = 0; k < layer.image_tiles[j][i].width(); k++) {
1556 int m = x + k + layer.x_offset;
1557 int n = y + l + layer.y_offset;
1559 if (m < 0 || m >= image.width() || n < 0 || n >= image.height())
1562 (*merge)(layer, i, j, k, l, image, m, n);
1583 void XCFImageFormat::mergeRGBToRGB(Layer& layer, uint i, uint j,
int k,
int l,
1584 TQImage& image,
int m,
int n)
1586 TQRgb src = layer.image_tiles[j][i].pixel(k, l);
1587 TQRgb dst = image.pixel(m, n);
1589 uchar src_r = tqRed(src);
1590 uchar src_g = tqGreen(src);
1591 uchar src_b = tqBlue(src);
1592 uchar src_a = tqAlpha(src);
1594 uchar dst_r = tqRed(dst);
1595 uchar dst_g = tqGreen(dst);
1596 uchar dst_b = tqBlue(dst);
1597 uchar dst_a = tqAlpha(dst);
1599 switch (layer.mode) {
1600 case MULTIPLY_MODE: {
1601 src_r = INT_MULT(src_r, dst_r);
1602 src_g = INT_MULT(src_g, dst_g);
1603 src_b = INT_MULT(src_b, dst_b);
1604 src_a = KMIN(src_a, dst_a);
1608 src_r = KMIN((dst_r * 256) / (1 + src_r), 255);
1609 src_g = KMIN((dst_g * 256) / (1 + src_g), 255);
1610 src_b = KMIN((dst_b * 256) / (1 + src_b), 255);
1611 src_a = KMIN(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 = KMIN(src_a, dst_a);
1621 case OVERLAY_MODE: {
1622 src_r = INT_MULT(dst_r, dst_r + INT_MULT(2 * src_r, 255 - dst_r));
1623 src_g = INT_MULT(dst_g, dst_g + INT_MULT(2 * src_g, 255 - dst_g));
1624 src_b = INT_MULT(dst_b, dst_b + INT_MULT(2 * src_b, 255 - dst_b));
1625 src_a = KMIN(src_a, dst_a);
1628 case DIFFERENCE_MODE: {
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 = KMIN(src_a, dst_a);
1635 case ADDITION_MODE: {
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 = KMIN(src_a, dst_a);
1642 case SUBTRACT_MODE: {
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 = KMIN(src_a, dst_a);
1649 case DARKEN_ONLY_MODE: {
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 = KMIN( src_a, dst_a );
1656 case LIGHTEN_ONLY_MODE: {
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 = KMIN(src_a, dst_a);
1664 uchar new_r = dst_r;
1665 uchar new_g = dst_g;
1666 uchar new_b = dst_b;
1668 RGBTOHSV(src_r, src_g, src_b);
1669 RGBTOHSV(new_r, new_g, new_b);
1673 HSVTORGB(new_r, new_g, new_b);
1678 src_a = KMIN( src_a, dst_a );
1681 case SATURATION_MODE: {
1682 uchar new_r = dst_r;
1683 uchar new_g = dst_g;
1684 uchar new_b = dst_b;
1686 RGBTOHSV(src_r, src_g, src_b);
1687 RGBTOHSV(new_r, new_g, new_b);
1691 HSVTORGB(new_r, new_g, new_b);
1696 src_a = KMIN(src_a, dst_a);
1700 uchar new_r = dst_r;
1701 uchar new_g = dst_g;
1702 uchar new_b = dst_b;
1704 RGBTOHSV(src_r, src_g, src_b);
1705 RGBTOHSV(new_r, new_g, new_b);
1709 HSVTORGB(new_r, new_g, new_b);
1714 src_a = KMIN(src_a, dst_a);
1718 uchar new_r = dst_r;
1719 uchar new_g = dst_g;
1720 uchar new_b = dst_b;
1722 RGBTOHLS(src_r, src_g, src_b);
1723 RGBTOHLS(new_r, new_g, new_b);
1728 HLSTORGB(new_r, new_g, new_b);
1733 src_a = KMIN(src_a, dst_a);
1738 src_a = INT_MULT(src_a, layer.opacity);
1742 if (layer.apply_mask == 1 && layer.mask_tiles.size() > j &&
1743 layer.mask_tiles[j].size() > i)
1744 src_a = INT_MULT(src_a, layer.mask_tiles[j][i].pixelIndex(k, l));
1746 uchar new_r, new_g, new_b, new_a;
1747 new_a = dst_a + INT_MULT(OPAQUE_OPACITY - dst_a, src_a);
1749 float src_ratio = (float)src_a / new_a;
1750 float dst_ratio = 1.0 - src_ratio;
1752 new_r = (uchar)(src_ratio * src_r + dst_ratio * dst_r + EPSILON);
1753 new_g = (uchar)(src_ratio * src_g + dst_ratio * dst_g + EPSILON);
1754 new_b = (uchar)(src_ratio * src_b + dst_ratio * dst_b + EPSILON);
1756 if (!layer_modes[layer.mode].affect_alpha)
1759 image.setPixel(m, n, tqRgba(new_r, new_g, new_b, new_a));
1774 void XCFImageFormat::mergeGrayToGray(Layer& layer, uint i, uint j,
int k,
int l,
1775 TQImage& image,
int m,
int n)
1777 int src = layer.image_tiles[j][i].pixelIndex(k, l);
1778 image.setPixel(m, n, src);
1793 void XCFImageFormat::mergeGrayAToGray(Layer& layer, uint i, uint j,
int k,
int l,
1794 TQImage& image,
int m,
int n)
1796 int src = tqGray(layer.image_tiles[j][i].pixel(k, l));
1797 int dst = image.pixelIndex(m, n);
1799 uchar src_a = layer.alpha_tiles[j][i].pixelIndex(k, l);
1801 switch (layer.mode) {
1802 case MULTIPLY_MODE: {
1803 src = INT_MULT( src, dst );
1807 src = KMIN((dst * 256) / (1 + src), 255);
1811 src = 255 - INT_MULT(255 - dst, 255 - src);
1814 case OVERLAY_MODE: {
1815 src = INT_MULT(dst, dst + INT_MULT(2 * src, 255 - dst));
1818 case DIFFERENCE_MODE: {
1819 src = dst > src ? dst - src : src - dst;
1822 case ADDITION_MODE: {
1823 src = add_lut(dst,src);
1826 case SUBTRACT_MODE: {
1827 src = dst > src ? dst - src : 0;
1830 case DARKEN_ONLY_MODE: {
1831 src = dst < src ? dst : src;
1834 case LIGHTEN_ONLY_MODE: {
1835 src = dst < src ? src : dst;
1840 src_a = INT_MULT(src_a, layer.opacity);
1844 if (layer.apply_mask == 1 && layer.mask_tiles.size() > j &&
1845 layer.mask_tiles[j].size() > i)
1846 src_a = INT_MULT(src_a, layer.mask_tiles[j][i].pixelIndex(k, l));
1848 uchar new_a = OPAQUE_OPACITY;
1850 float src_ratio = (float)src_a / new_a;
1851 float dst_ratio = 1.0 - src_ratio;
1853 uchar new_g = (uchar)(src_ratio * src + dst_ratio * dst + EPSILON);
1855 image.setPixel(m, n, new_g);
1872 void XCFImageFormat::mergeGrayToRGB(Layer& layer, uint i, uint j,
int k,
int l,
1873 TQImage& image,
int m,
int n)
1875 TQRgb src = layer.image_tiles[j][i].pixel(k, l);
1876 uchar src_a = layer.opacity;
1877 image.setPixel(m, n, tqRgba(src, src_a));
1894 void XCFImageFormat::mergeGrayAToRGB(Layer& layer, uint i, uint j,
int k,
int l,
1895 TQImage& image,
int m,
int n)
1897 int src = tqGray(layer.image_tiles[j][i].pixel(k, l));
1898 int dst = tqGray(image.pixel(m, n));
1900 uchar src_a = layer.alpha_tiles[j][i].pixelIndex(k, l);
1901 uchar dst_a = tqAlpha(image.pixel(m, n));
1903 switch (layer.mode) {
1904 case MULTIPLY_MODE: {
1905 src = INT_MULT(src, dst);
1906 src_a = KMIN(src_a, dst_a);
1910 src = KMIN((dst * 256) / (1 + src), 255);
1911 src_a = KMIN(src_a, dst_a);
1915 src = 255 - INT_MULT(255 - dst, 255 - src);
1916 src_a = KMIN(src_a, dst_a);
1919 case OVERLAY_MODE: {
1920 src = INT_MULT( dst, dst + INT_MULT(2 * src, 255 - dst));
1921 src_a = KMIN(src_a, dst_a);
1924 case DIFFERENCE_MODE: {
1925 src = dst > src ? dst - src : src - dst;
1926 src_a = KMIN(src_a, dst_a);
1929 case ADDITION_MODE: {
1930 src = add_lut(dst,src);
1931 src_a = KMIN(src_a, dst_a);
1934 case SUBTRACT_MODE: {
1935 src = dst > src ? dst - src : 0;
1936 src_a = KMIN(src_a, dst_a);
1939 case DARKEN_ONLY_MODE: {
1940 src = dst < src ? dst : src;
1941 src_a = KMIN(src_a, dst_a);
1944 case LIGHTEN_ONLY_MODE: {
1945 src = dst < src ? src : dst;
1946 src_a = KMIN(src_a, dst_a);
1951 src_a = INT_MULT(src_a, layer.opacity);
1954 if (layer.apply_mask == 1 && layer.mask_tiles.size() > j &&
1955 layer.mask_tiles[j].size() > i)
1956 src_a = INT_MULT(src_a, layer.mask_tiles[j][i].pixelIndex(k, l));
1958 uchar new_a = dst_a + INT_MULT(OPAQUE_OPACITY - dst_a, src_a);
1960 float src_ratio = (float)src_a / new_a;
1961 float dst_ratio = 1.0 - src_ratio;
1963 uchar new_g = (uchar)(src_ratio * src + dst_ratio * dst + EPSILON);
1965 if (!layer_modes[layer.mode].affect_alpha)
1968 image.setPixel(m, n, tqRgba(new_g, new_g, new_g, new_a));
1983 void XCFImageFormat::mergeIndexedToIndexed(Layer& layer, uint i, uint j,
int k,
int l,
1984 TQImage& image,
int m,
int n)
1986 int src = layer.image_tiles[j][i].pixelIndex(k, l);
1987 image.setPixel(m, n, src);
2002 void XCFImageFormat::mergeIndexedAToIndexed(Layer& layer, uint i, uint j,
int k,
int l,
2003 TQImage& image,
int m,
int n)
2005 uchar src = layer.image_tiles[j][i].pixelIndex(k, l);
2006 uchar src_a = layer.alpha_tiles[j][i].pixelIndex(k, l);
2007 src_a = INT_MULT( src_a, layer.opacity );
2009 if ( layer.apply_mask == 1 &&
2010 layer.mask_tiles.size() > j &&
2011 layer.mask_tiles[j].size() > i)
2012 src_a = INT_MULT(src_a, layer.mask_tiles[j][i].pixelIndex(k, l));
2016 image.setPixel(m, n, src);
2034 void XCFImageFormat::mergeIndexedAToRGB(Layer& layer, uint i, uint j,
int k,
int l,
2035 TQImage& image,
int m,
int n)
2037 TQRgb src = layer.image_tiles[j][i].pixel(k, l);
2038 uchar src_a = layer.alpha_tiles[j][i].pixelIndex(k, l);
2039 src_a = INT_MULT(src_a, layer.opacity);
2042 if (layer.apply_mask == 1 && layer.mask_tiles.size() > j &&
2043 layer.mask_tiles[j].size() > i)
2044 src_a = INT_MULT(src_a, layer.mask_tiles[j][i].pixelIndex(k, l));
2050 src_a = OPAQUE_OPACITY;
2052 image.setPixel(m, n, tqRgba(src, src_a));
2063 void XCFImageFormat::dissolveRGBPixels ( TQImage& image,
int x,
int y )
2068 for (
int l = 0; l < image.height(); l++) {
2069 srand(random_table[( l + y ) % RANDOM_TABLE_SIZE]);
2071 for (
int k = 0; k < x; k++)
2074 for (
int k = 0; k < image.width(); k++) {
2075 int rand_val = rand() & 0xff;
2076 TQRgb pixel = image.pixel(k, l);
2078 if (rand_val > tqAlpha(pixel)) {
2079 image.setPixel(k, l, tqRgba(pixel, 0));
2095 void XCFImageFormat::dissolveAlphaPixels ( TQImage& image,
int x,
int y )
2100 for (
int l = 0; l < image.height(); l++) {
2101 srand( random_table[(l + y) % RANDOM_TABLE_SIZE]);
2103 for (
int k = 0; k < x; k++)
2106 for (
int k = 0; k < image.width(); k++) {
2107 int rand_val = rand() & 0xff;
2108 uchar alpha = image.pixelIndex(k, l);
2110 if (rand_val > alpha) {
2111 image.setPixel(k, l, 0);