File indexing completed on 2024-05-12 15:59:39
0001 /* 0002 * SPDX-FileCopyrightText: 2009 Boudewijn Rempt <boud@valdyas.org> 0003 * SPDX-FileCopyrightText: 2021 L. E. Segovia <amy@amyspark.me> 0004 * 0005 * SPDX-License-Identifier: GPL-2.0-or-later 0006 */ 0007 #include "psd_layer_section.h" 0008 0009 #include <QBuffer> 0010 #include <QIODevice> 0011 0012 #include <KoColor.h> 0013 #include <KoColorSpace.h> 0014 0015 #include <kis_debug.h> 0016 #include <kis_effect_mask.h> 0017 #include <kis_group_layer.h> 0018 #include <kis_generator_layer.h> 0019 #include <kis_image.h> 0020 #include <kis_node.h> 0021 #include <kis_paint_layer.h> 0022 #include <kis_painter.h> 0023 0024 #include "kis_dom_utils.h" 0025 0026 #include "psd.h" 0027 #include "psd_header.h" 0028 #include "psd_utils.h" 0029 0030 #include "compression.h" 0031 0032 #include <asl/kis_asl_reader_utils.h> 0033 #include <asl/kis_asl_writer_utils.h> 0034 #include <asl/kis_offset_on_exit_verifier.h> 0035 #include <kis_asl_layer_style_serializer.h> 0036 0037 PSDLayerMaskSection::PSDLayerMaskSection(const PSDHeader &header) 0038 : globalInfoSection(header) 0039 , m_header(header) 0040 { 0041 } 0042 0043 PSDLayerMaskSection::~PSDLayerMaskSection() 0044 { 0045 qDeleteAll(layers); 0046 } 0047 0048 bool PSDLayerMaskSection::read(QIODevice &io) 0049 { 0050 bool retval = true; // be optimistic! <:-) 0051 0052 try { 0053 if (m_header.tiffStyleLayerBlock) { 0054 switch (m_header.byteOrder) { 0055 case psd_byte_order::psdLittleEndian: 0056 retval = readTiffImpl<psd_byte_order::psdLittleEndian>(io); 0057 break; 0058 default: 0059 retval = readTiffImpl(io); 0060 break; 0061 } 0062 } else { 0063 retval = readPsdImpl(io); 0064 } 0065 } catch (KisAslReaderUtils::ASLParseException &e) { 0066 warnKrita << "WARNING: PSD (emb. pattern):" << e.what(); 0067 retval = false; 0068 } 0069 0070 return retval; 0071 } 0072 0073 template<psd_byte_order byteOrder> 0074 bool PSDLayerMaskSection::readLayerInfoImpl(QIODevice &io) 0075 { 0076 quint64 layerInfoSectionSize = 0; 0077 if (m_header.version == 1) { 0078 quint32 _layerInfoSectionSize = 0; 0079 SAFE_READ_EX(byteOrder, io, _layerInfoSectionSize); 0080 layerInfoSectionSize = _layerInfoSectionSize; 0081 } else if (m_header.version == 2) { 0082 SAFE_READ_EX(byteOrder, io, layerInfoSectionSize); 0083 } 0084 0085 if (layerInfoSectionSize & 0x1) { 0086 warnKrita << "WARNING: layerInfoSectionSize is NOT even! Fixing..."; 0087 layerInfoSectionSize++; 0088 } 0089 0090 { 0091 SETUP_OFFSET_VERIFIER(layerInfoSectionTag, io, layerInfoSectionSize, 0); 0092 dbgFile << "Layer info block size" << layerInfoSectionSize; 0093 0094 if (layerInfoSectionSize > 0) { 0095 if (!psdread<byteOrder>(io, nLayers) || nLayers == 0) { 0096 error = QString("Could not read read number of layers or no layers in image. %1").arg(nLayers); 0097 return false; 0098 } 0099 0100 hasTransparency = nLayers < 0; // first alpha channel is the alpha channel of the projection. 0101 nLayers = qAbs(nLayers); 0102 0103 dbgFile << "Number of layers:" << nLayers; 0104 dbgFile << "Has separate projection transparency:" << hasTransparency; 0105 0106 for (int i = 0; i < nLayers; ++i) { 0107 dbgFile << "Going to read layer" << i << "pos" << io.pos(); 0108 dbgFile << "== Enter PSDLayerRecord"; 0109 PSDHeader sanitizedHeader(m_header); 0110 sanitizedHeader.tiffStyleLayerBlock = false; // disable padding 0111 QScopedPointer<PSDLayerRecord> layerRecord(new PSDLayerRecord(sanitizedHeader)); 0112 if (!layerRecord->read(io)) { 0113 error = QString("Could not load layer %1: %2").arg(i).arg(layerRecord->error); 0114 return false; 0115 } 0116 dbgFile << "== Leave PSDLayerRecord"; 0117 dbgFile << "Finished reading layer" << i << layerRecord->layerName << "blending mode" << layerRecord->blendModeKey << io.pos() 0118 << "Number of channels:" << layerRecord->channelInfoRecords.size(); 0119 layers << layerRecord.take(); 0120 } 0121 } 0122 0123 // get the positions for the channels belonging to each layer 0124 for (int i = 0; i < nLayers; ++i) { 0125 dbgFile << "Going to seek channel positions for layer" << i << "pos" << io.pos(); 0126 if (i > layers.size()) { 0127 error = QString("Expected layer %1, but only have %2 layers").arg(i).arg(layers.size()); 0128 return false; 0129 } 0130 0131 PSDLayerRecord *layerRecord = layers.at(i); 0132 0133 for (int j = 0; j < layerRecord->nChannels; ++j) { 0134 // save the current location so we can jump beyond this block later on. 0135 quint64 channelStartPos = io.pos(); 0136 dbgFile << "\tReading channel image data for channel" << j << "from pos" << io.pos(); 0137 0138 KIS_ASSERT_RECOVER(j < layerRecord->channelInfoRecords.size()) 0139 { 0140 return false; 0141 } 0142 0143 ChannelInfo *channelInfo = layerRecord->channelInfoRecords.at(j); 0144 0145 quint16 compressionType; 0146 if (!psdread<byteOrder>(io, compressionType)) { 0147 error = "Could not read compression type for channel"; 0148 return false; 0149 } 0150 channelInfo->compressionType = static_cast<psd_compression_type>(compressionType); 0151 dbgFile << "\t\tChannel" << j << "has compression type" << compressionType; 0152 0153 QRect channelRect = layerRecord->channelRect(channelInfo); 0154 0155 // read the rle row lengths; 0156 if (channelInfo->compressionType == psd_compression_type::RLE) { 0157 for (qint64 row = 0; row < channelRect.height(); ++row) { 0158 // dbgFile << "Reading the RLE bytecount position of row" << row << "at pos" << io.pos(); 0159 0160 quint32 byteCount; 0161 if (m_header.version == 1) { 0162 quint16 _byteCount; 0163 if (!psdread<byteOrder>(io, _byteCount)) { 0164 error = QString("Could not read byteCount for rle-encoded channel"); 0165 return 0; 0166 } 0167 byteCount = _byteCount; 0168 } else { 0169 if (!psdread<byteOrder>(io, byteCount)) { 0170 error = QString("Could not read byteCount for rle-encoded channel"); 0171 return 0; 0172 } 0173 } 0174 ////dbgFile << "rle byte count" << byteCount; 0175 channelInfo->rleRowLengths << byteCount; 0176 } 0177 } 0178 0179 // we're beyond all the length bytes, rle bytes and whatever, this is the 0180 // location of the real pixel data 0181 channelInfo->channelDataStart = io.pos(); 0182 0183 dbgFile << "\t\tstart" << channelStartPos << "data start" << channelInfo->channelDataStart << "data length" << channelInfo->channelDataLength 0184 << "pos" << io.pos(); 0185 0186 // make sure we are at the start of the next channel data block 0187 io.seek(channelStartPos + channelInfo->channelDataLength); 0188 0189 // this is the length of the actual channel data bytes 0190 channelInfo->channelDataLength = channelInfo->channelDataLength - (channelInfo->channelDataStart - channelStartPos); 0191 0192 dbgFile << "\t\tchannel record" << j << "for layer" << i << "with id" << channelInfo->channelId << "starting position" 0193 << channelInfo->channelDataStart << "with length" << channelInfo->channelDataLength << "and has compression type" 0194 << channelInfo->compressionType; 0195 } 0196 } 0197 } 0198 0199 return true; 0200 } 0201 0202 bool PSDLayerMaskSection::readPsdImpl(QIODevice &io) 0203 { 0204 dbgFile << "(PSD) reading layer section. Pos:" << io.pos() << "bytes left:" << io.bytesAvailable(); 0205 0206 // https://www.adobe.com/devnet-apps/photoshop/fileformatashtml/#50577409_21849 0207 boost::optional<quint64> layerMaskBlockSize = 0; 0208 0209 if (m_header.version == 1) { 0210 quint32 _layerMaskBlockSize = 0; 0211 SAFE_READ_EX(psd_byte_order::psdBigEndian, io, _layerMaskBlockSize); 0212 layerMaskBlockSize = _layerMaskBlockSize; 0213 } else if (m_header.version == 2) { 0214 SAFE_READ_EX(psd_byte_order::psdBigEndian, io, *layerMaskBlockSize); 0215 } 0216 0217 qint64 start = io.pos(); 0218 0219 dbgFile << "layer block size" << *layerMaskBlockSize; 0220 0221 if (*layerMaskBlockSize == 0) { 0222 dbgFile << "No layer info, so no PSD layers available"; 0223 return true; 0224 } 0225 0226 /** 0227 * PSD files created in some weird web applications may 0228 * have invalid layer-mask-block-size set. Just do a simple 0229 * sanity check to catch this case 0230 */ 0231 if (static_cast<qint64>(*layerMaskBlockSize) > io.bytesAvailable()) { 0232 warnKrita << "WARNING: invalid layer block size. Got" << *layerMaskBlockSize << "Bytes left" << io.bytesAvailable() << "Triggering a workaround..."; 0233 0234 // just don't use this value for offset recovery at the end 0235 layerMaskBlockSize = boost::none; 0236 } 0237 0238 if (!readLayerInfoImpl(io)) { 0239 return false; 0240 } 0241 0242 dbgFile << "Leftover before additional blocks:" << io.pos() << io.bytesAvailable(); 0243 0244 quint32 globalMaskBlockLength; 0245 if (!psdread(io, globalMaskBlockLength)) { 0246 error = "Could not read global mask info block"; 0247 return false; 0248 } 0249 0250 dbgFile << "Global mask size:" << globalMaskBlockLength << "(" << io.pos() << io.bytesAvailable() << ")"; 0251 0252 if (globalMaskBlockLength > 0) { 0253 if (!psdread(io, globalLayerMaskInfo.overlayColorSpace)) { 0254 error = "Could not read global mask info overlay colorspace"; 0255 return false; 0256 } 0257 0258 for (int i = 0; i < 4; ++i) { 0259 if (!psdread(io, globalLayerMaskInfo.colorComponents[i])) { 0260 error = QString("Could not read mask info visualizaion color component %1").arg(i); 0261 return false; 0262 } 0263 } 0264 0265 if (!psdread(io, globalLayerMaskInfo.opacity)) { 0266 error = "Could not read global mask info visualization opacity"; 0267 return false; 0268 } 0269 0270 if (!psdread(io, globalLayerMaskInfo.kind)) { 0271 error = "Could not read global mask info visualization type"; 0272 return false; 0273 } 0274 0275 // Global mask must measure at least 13 bytes 0276 // (excluding the 1 byte compiler enforced padding) 0277 if (globalMaskBlockLength >= 13) { 0278 dbgFile << "Padding for global mask block:" 0279 << globalMaskBlockLength - 13 << "(" << io.pos() << ")"; 0280 io.skip(static_cast<size_t>(globalMaskBlockLength) - 13); 0281 } 0282 } 0283 0284 // global additional sections 0285 0286 /** 0287 * Newer versions of PSD have layers info block wrapped into 0288 * 'Lr16' or 'Lr32' additional section, while the main block is 0289 * absent. 0290 * 0291 * Here we pass the callback which should be used when such 0292 * additional section is recognized. 0293 */ 0294 globalInfoSection.setExtraLayerInfoBlockHandler( 0295 std::bind(&PSDLayerMaskSection::readLayerInfoImpl<psd_byte_order::psdBigEndian>, this, std::placeholders::_1)); 0296 0297 dbgFile << "Position before starting global info section:" << io.pos(); 0298 0299 globalInfoSection.read(io); 0300 0301 if (layerMaskBlockSize) { 0302 /* put us after this section so reading the next section will work even if we mess up */ 0303 io.seek(start + static_cast<qint64>(*layerMaskBlockSize)); 0304 } 0305 0306 return true; 0307 } 0308 0309 template<psd_byte_order byteOrder> 0310 bool PSDLayerMaskSection::readGlobalMask(QIODevice &io) 0311 { 0312 quint32 globalMaskBlockLength; 0313 if (!psdread<byteOrder>(io, globalMaskBlockLength)) { 0314 error = "Could not read global mask info block"; 0315 return false; 0316 } 0317 0318 dbgFile << "Global mask size:" << globalMaskBlockLength << "(" << io.pos() << io.bytesAvailable() << ")"; 0319 0320 if (globalMaskBlockLength > 0) { 0321 if (!psdread<byteOrder>(io, globalLayerMaskInfo.overlayColorSpace)) { 0322 error = "Could not read global mask info overlay colorspace"; 0323 return false; 0324 } 0325 0326 for (int i = 0; i < 4; ++i) { 0327 if (!psdread<byteOrder>(io, globalLayerMaskInfo.colorComponents[i])) { 0328 error = QString("Could not read mask info visualizaion color component %1").arg(i); 0329 return false; 0330 } 0331 } 0332 0333 if (!psdread<byteOrder>(io, globalLayerMaskInfo.opacity)) { 0334 error = "Could not read global mask info visualization opacity"; 0335 return false; 0336 } 0337 0338 if (!psdread<byteOrder>(io, globalLayerMaskInfo.kind)) { 0339 error = "Could not read global mask info visualization type"; 0340 return false; 0341 } 0342 0343 dbgFile << "Global mask info: "; 0344 dbgFile << "\tOverlay:" << globalLayerMaskInfo.overlayColorSpace; // 0 0345 dbgFile << "\tColor components:" << globalLayerMaskInfo.colorComponents[0] // 65535 0346 << globalLayerMaskInfo.colorComponents[1] // 0 0347 << globalLayerMaskInfo.colorComponents[2] // 0 0348 << globalLayerMaskInfo.colorComponents[3]; // 0 0349 dbgFile << "\tOpacity:" << globalLayerMaskInfo.opacity; // 50 0350 dbgFile << "\tKind:" << globalLayerMaskInfo.kind; // 128 0351 0352 if (globalMaskBlockLength >= 15) { 0353 io.skip(qMax(globalMaskBlockLength - 15, 0x0U)); 0354 } 0355 } 0356 0357 return true; 0358 } 0359 0360 template<psd_byte_order byteOrder> 0361 bool PSDLayerMaskSection::readTiffImpl(QIODevice &io) 0362 { 0363 dbgFile << "(TIFF) reading layer section. Pos:" << io.pos() << "bytes left:" << io.bytesAvailable(); 0364 0365 // TIFF additional sections 0366 0367 /** 0368 * Just like PSD, new versions of PSD have layers info block wrapped into 0369 * 'Lr16' or 'Lr32' additional section, while the main block is 0370 * absent. 0371 * Additionally, the global mask info is stored in a separate "LMsk" block. 0372 * 0373 * So, instead of having special handling, we just ship everything to the 0374 * additional layer info block handlers 0375 */ 0376 0377 globalInfoSection.setExtraLayerInfoBlockHandler(std::bind(&PSDLayerMaskSection::readLayerInfoImpl<byteOrder>, this, std::placeholders::_1)); 0378 globalInfoSection.setUserMaskInfoBlockHandler(std::bind(&PSDLayerMaskSection::readGlobalMask<byteOrder>, this, std::placeholders::_1)); 0379 0380 if (!globalInfoSection.read(io)) { 0381 dbgFile << "Failed to read TIFF Photoshop blocks!"; 0382 return false; 0383 } 0384 0385 dbgFile << "Leftover data after parsing layer/extra blocks:" << io.pos() << io.bytesAvailable() << io.peek(io.bytesAvailable()); 0386 0387 return true; 0388 } 0389 0390 struct FlattenedNode { 0391 FlattenedNode() 0392 : type(RASTER_LAYER) 0393 { 0394 } 0395 0396 KisNodeSP node; 0397 0398 enum Type { RASTER_LAYER, FOLDER_OPEN, FOLDER_CLOSED, SECTION_DIVIDER }; 0399 0400 Type type; 0401 }; 0402 0403 void addBackgroundIfNeeded(KisNodeSP root, QList<FlattenedNode> &nodes) 0404 { 0405 KisGroupLayer *group = dynamic_cast<KisGroupLayer *>(root.data()); 0406 if (!group) 0407 return; 0408 0409 KoColor projectionColor = group->defaultProjectionColor(); 0410 if (projectionColor.opacityU8() == OPACITY_TRANSPARENT_U8) 0411 return; 0412 0413 KisPaintLayerSP layer = new KisPaintLayer(group->image(), i18nc("Automatically created layer name when saving into PSD", "Background"), OPACITY_OPAQUE_U8); 0414 0415 layer->paintDevice()->setDefaultPixel(projectionColor); 0416 0417 { 0418 FlattenedNode item; 0419 item.node = layer; 0420 item.type = FlattenedNode::RASTER_LAYER; 0421 nodes << item; 0422 } 0423 } 0424 0425 void flattenNodes(KisNodeSP node, QList<FlattenedNode> &nodes) 0426 { 0427 KisNodeSP child = node->firstChild(); 0428 while (child) { 0429 const bool isLayer = child->inherits("KisLayer"); 0430 const bool isGroupLayer = child->inherits("KisGroupLayer"); 0431 0432 if (isGroupLayer) { 0433 { 0434 FlattenedNode item; 0435 item.node = child; 0436 item.type = FlattenedNode::SECTION_DIVIDER; 0437 nodes << item; 0438 } 0439 0440 flattenNodes(child, nodes); 0441 0442 { 0443 FlattenedNode item; 0444 item.node = child; 0445 item.type = FlattenedNode::FOLDER_OPEN; 0446 nodes << item; 0447 } 0448 } else if (isLayer) { 0449 FlattenedNode item; 0450 item.node = child; 0451 item.type = FlattenedNode::RASTER_LAYER; 0452 nodes << item; 0453 } 0454 0455 child = child->nextSibling(); 0456 } 0457 } 0458 0459 KisNodeSP findOnlyTransparencyMask(KisNodeSP node, FlattenedNode::Type type) 0460 { 0461 if (type != FlattenedNode::FOLDER_OPEN && type != FlattenedNode::FOLDER_CLOSED && type != FlattenedNode::RASTER_LAYER) { 0462 return 0; 0463 } 0464 0465 KisLayer *layer = qobject_cast<KisLayer *>(node.data()); 0466 QList<KisEffectMaskSP> masks = layer->effectMasks(); 0467 0468 if (masks.size() != 1) 0469 return 0; 0470 0471 KisEffectMaskSP onlyMask = masks.first(); 0472 return onlyMask->inherits("KisTransparencyMask") ? onlyMask : 0; 0473 } 0474 0475 QDomDocument fetchLayerStyleXmlData(KisNodeSP node) 0476 { 0477 const KisLayer *layer = qobject_cast<KisLayer *>(node.data()); 0478 KisPSDLayerStyleSP layerStyle = layer->layerStyle(); 0479 0480 if (!layerStyle) 0481 return QDomDocument(); 0482 0483 KisAslLayerStyleSerializer serializer; 0484 serializer.setStyles(QVector<KisPSDLayerStyleSP>() << layerStyle); 0485 return serializer.formPsdXmlDocument(); 0486 } 0487 0488 inline QDomNode findNodeByKey(const QString &key, QDomNode parent) 0489 { 0490 return KisDomUtils::findElementByAttibute(parent, "node", "key", key); 0491 } 0492 0493 void mergePatternsXMLSection(const QDomDocument &src, QDomDocument &dst) 0494 { 0495 QDomNode srcPatternsNode = findNodeByKey(ResourceType::Patterns, src.documentElement()); 0496 QDomNode dstPatternsNode = findNodeByKey(ResourceType::Patterns, dst.documentElement()); 0497 0498 if (srcPatternsNode.isNull()) 0499 return; 0500 if (dstPatternsNode.isNull()) { 0501 dst = src; 0502 return; 0503 } 0504 0505 KIS_ASSERT_RECOVER_RETURN(!srcPatternsNode.isNull()); 0506 KIS_ASSERT_RECOVER_RETURN(!dstPatternsNode.isNull()); 0507 0508 QDomNode node = srcPatternsNode.firstChild(); 0509 while (!node.isNull()) { 0510 QDomNode importedNode = dst.importNode(node, true); 0511 KIS_ASSERT_RECOVER_RETURN(!importedNode.isNull()); 0512 0513 dstPatternsNode.appendChild(importedNode); 0514 node = node.nextSibling(); 0515 } 0516 } 0517 0518 bool PSDLayerMaskSection::write(QIODevice &io, KisNodeSP rootLayer, psd_compression_type compressionType) 0519 { 0520 bool retval = true; 0521 0522 try { 0523 if (m_header.tiffStyleLayerBlock) { 0524 switch (m_header.byteOrder) { 0525 case psd_byte_order::psdLittleEndian: 0526 writeTiffImpl<psd_byte_order::psdLittleEndian>(io, rootLayer, compressionType); 0527 break; 0528 default: 0529 writeTiffImpl(io, rootLayer, compressionType); 0530 break; 0531 } 0532 } else { 0533 writePsdImpl(io, rootLayer, compressionType); 0534 } 0535 } catch (KisAslWriterUtils::ASLWriteException &e) { 0536 error = PREPEND_METHOD(e.what()); 0537 retval = false; 0538 } 0539 0540 return retval; 0541 } 0542 0543 void PSDLayerMaskSection::writePsdImpl(QIODevice &io, KisNodeSP rootLayer, psd_compression_type compressionType) 0544 { 0545 dbgFile << "Writing layer layer section"; 0546 0547 // Build the whole layer structure 0548 QList<FlattenedNode> nodes; 0549 addBackgroundIfNeeded(rootLayer, nodes); 0550 flattenNodes(rootLayer, nodes); 0551 0552 if (nodes.isEmpty()) { 0553 throw KisAslWriterUtils::ASLWriteException("Could not find paint layers to save"); 0554 } 0555 0556 { 0557 KisAslWriterUtils::OffsetStreamPusher<quint32, psd_byte_order::psdBigEndian> layerAndMaskSectionSizeTag(io, 2); 0558 QDomDocument mergedPatternsXmlDoc; 0559 0560 { 0561 KisAslWriterUtils::OffsetStreamPusher<quint32, psd_byte_order::psdBigEndian> layerInfoSizeTag(io, 2); 0562 0563 { 0564 // number of layers (negative, because krita always has alpha) 0565 const qint16 layersSize = static_cast<qint16>(-nodes.size()); 0566 SAFE_WRITE_EX(psd_byte_order::psdBigEndian, io, layersSize); 0567 0568 dbgFile << "Number of layers" << layersSize << "at" << io.pos(); 0569 } 0570 0571 // Layer records section 0572 Q_FOREACH (const FlattenedNode &item, nodes) { 0573 KisNodeSP node = item.node; 0574 0575 PSDLayerRecord *layerRecord = new PSDLayerRecord(m_header); 0576 layers.append(layerRecord); 0577 0578 KisNodeSP onlyTransparencyMask = findOnlyTransparencyMask(node, item.type); 0579 QRect maskRect = onlyTransparencyMask ? onlyTransparencyMask->paintDevice()->exactBounds() : QRect(); 0580 0581 const bool nodeVisible = node->visible(); 0582 const KoColorSpace *colorSpace = node->colorSpace(); 0583 const quint8 nodeOpacity = node->opacity(); 0584 const quint8 nodeClipping = 0; 0585 const int nodeLabelColor = node->colorLabelIndex(); 0586 const KisPaintLayer *paintLayer = qobject_cast<KisPaintLayer *>(node.data()); 0587 const bool alphaLocked = (paintLayer && paintLayer->alphaLocked()); 0588 const QString nodeCompositeOp = node->compositeOpId(); 0589 0590 const KisGroupLayer *groupLayer = qobject_cast<KisGroupLayer *>(node.data()); 0591 const bool nodeIsPassThrough = groupLayer && groupLayer->passThroughMode(); 0592 0593 const KisGeneratorLayer *fillLayer = qobject_cast<KisGeneratorLayer *>(node.data()); 0594 QDomDocument fillConfig; 0595 psd_fill_type fillType = psd_fill_solid_color; 0596 if (fillLayer) { 0597 QString generatorName = fillLayer->filter()->name(); 0598 if (generatorName == "color") { 0599 psd_layer_solid_color fill; 0600 if (fill.loadFromConfig(fillLayer->filter())) { 0601 if (node->image()) { 0602 fill.cs = node->image()->colorSpace(); 0603 } else { 0604 fill.cs = node->colorSpace(); 0605 } 0606 fillConfig = fill.getASLXML(); 0607 fillType = psd_fill_solid_color; 0608 } 0609 } else if (generatorName == "gradient") { 0610 psd_layer_gradient_fill fill; 0611 fill.imageWidth = node->image()->width(); 0612 fill.imageHeight = node->image()->height(); 0613 if (fill.loadFromConfig(fillLayer->filter())) { 0614 fillConfig = fill.getASLXML(); 0615 fillType = psd_fill_gradient; 0616 } 0617 } else if (generatorName == "pattern") { 0618 0619 psd_layer_pattern_fill fill; 0620 if (fill.loadFromConfig(fillLayer->filter())) { 0621 if (fill.pattern) { 0622 KisAslXmlWriter w; 0623 w.enterList(ResourceType::Patterns); 0624 QString uuid = w.writePattern("", fill.pattern); 0625 w.leaveList(); 0626 mergedPatternsXmlDoc = w.document(); 0627 fill.patternID = uuid; 0628 fillConfig = fill.getASLXML(); 0629 fillType = psd_fill_pattern; 0630 } 0631 } 0632 0633 } 0634 // And if anything else, it cannot be stored as a PSD fill layer. 0635 } 0636 0637 QDomDocument stylesXmlDoc = fetchLayerStyleXmlData(node); 0638 0639 if (mergedPatternsXmlDoc.isNull() && !stylesXmlDoc.isNull()) { 0640 mergedPatternsXmlDoc = stylesXmlDoc; 0641 } else if (!mergedPatternsXmlDoc.isNull() && !stylesXmlDoc.isNull()) { 0642 mergePatternsXMLSection(stylesXmlDoc, mergedPatternsXmlDoc); 0643 } 0644 0645 bool nodeIrrelevant = false; 0646 QString nodeName; 0647 KisPaintDeviceSP layerContentDevice; 0648 psd_section_type sectionType; 0649 0650 if (item.type == FlattenedNode::RASTER_LAYER) { 0651 nodeIrrelevant = false; 0652 nodeName = node->name(); 0653 layerContentDevice = onlyTransparencyMask ? node->original() : node->projection(); 0654 0655 /** 0656 * For fill layers we save their internal selection as a separate transparency mask 0657 */ 0658 if (fillLayer) { 0659 bool transparency = KisPainter::checkDeviceHasTransparency(node->paintDevice()); 0660 bool semiOpacity = node->paintDevice()->defaultPixel().opacityU8() < OPACITY_OPAQUE_U8; 0661 if (transparency || semiOpacity) { 0662 layerContentDevice = node->original(); 0663 onlyTransparencyMask = node; 0664 maskRect = onlyTransparencyMask->paintDevice()->exactBounds(); 0665 } 0666 } 0667 sectionType = psd_other; 0668 } else { 0669 nodeIrrelevant = true; 0670 nodeName = item.type == FlattenedNode::SECTION_DIVIDER ? QString("</Layer group>") : node->name(); 0671 layerContentDevice = 0; 0672 sectionType = item.type == FlattenedNode::SECTION_DIVIDER ? psd_bounding_divider 0673 : item.type == FlattenedNode::FOLDER_OPEN ? psd_open_folder 0674 : psd_closed_folder; 0675 } 0676 0677 // === no access to node anymore 0678 0679 QRect layerRect; 0680 0681 if (layerContentDevice) { 0682 QRect rc = layerContentDevice->exactBounds(); 0683 rc = rc.normalized(); 0684 0685 // keep to the max of photoshop's capabilities 0686 if (rc.width() > 30000) 0687 rc.setWidth(30000); 0688 if (rc.height() > 30000) 0689 rc.setHeight(30000); 0690 0691 layerRect = rc; 0692 } 0693 0694 layerRecord->top = layerRect.y(); 0695 layerRecord->left = layerRect.x(); 0696 layerRecord->bottom = layerRect.y() + layerRect.height(); 0697 layerRecord->right = layerRect.x() + layerRect.width(); 0698 0699 // colors + alpha channel 0700 // note: transparency mask not included 0701 layerRecord->nChannels = static_cast<quint16>(colorSpace->colorChannelCount() + 1); 0702 0703 ChannelInfo *info = new ChannelInfo; 0704 info->channelId = -1; // For the alpha channel, which we always have in Krita, and should be saved first in 0705 layerRecord->channelInfoRecords << info; 0706 0707 // the rest is in display order: rgb, cmyk, lab... 0708 for (qint16 i = 0; i < (int)colorSpace->colorChannelCount(); ++i) { 0709 info = new ChannelInfo; 0710 info->channelId = i; // 0 for red, 1 = green, etc 0711 layerRecord->channelInfoRecords << info; 0712 } 0713 0714 layerRecord->blendModeKey = composite_op_to_psd_blendmode(nodeCompositeOp); 0715 layerRecord->isPassThrough = nodeIsPassThrough; 0716 layerRecord->opacity = nodeOpacity; 0717 layerRecord->clipping = nodeClipping; 0718 0719 layerRecord->labelColor = nodeLabelColor; 0720 0721 layerRecord->transparencyProtected = alphaLocked; 0722 layerRecord->visible = nodeVisible; 0723 layerRecord->irrelevant = nodeIrrelevant; 0724 0725 layerRecord->layerName = nodeName.isEmpty() ? i18n("Unnamed Layer") : nodeName; 0726 0727 layerRecord->fillType = fillType; 0728 layerRecord->fillConfig = fillConfig; 0729 0730 layerRecord->write(io, layerContentDevice, onlyTransparencyMask, maskRect, sectionType, stylesXmlDoc, node->inherits("KisGroupLayer")); 0731 } 0732 0733 dbgFile << "start writing layer pixel data" << io.pos(); 0734 0735 // Now save the pixel data 0736 for (PSDLayerRecord *layerRecord : layers) { 0737 layerRecord->writePixelData(io, compressionType); 0738 } 0739 } 0740 0741 { 0742 // write the global layer mask info -- which is empty 0743 const quint32 globalMaskSize = 0; 0744 SAFE_WRITE_EX(psd_byte_order::psdBigEndian, io, globalMaskSize); 0745 } 0746 0747 globalInfoSection.writePattBlockEx(io, mergedPatternsXmlDoc); 0748 } 0749 } 0750 0751 template<psd_byte_order byteOrder> 0752 void PSDLayerMaskSection::writeTiffImpl(QIODevice &io, KisNodeSP rootLayer, psd_compression_type compressionType) 0753 { 0754 dbgFile << "(TIFF) Writing layer section"; 0755 0756 // Build the whole layer structure 0757 QList<FlattenedNode> nodes; 0758 addBackgroundIfNeeded(rootLayer, nodes); 0759 flattenNodes(rootLayer, nodes); 0760 0761 if (nodes.isEmpty()) { 0762 throw KisAslWriterUtils::ASLWriteException("Could not find paint layers to save"); 0763 } 0764 0765 { 0766 QDomDocument mergedPatternsXmlDoc; 0767 0768 { 0769 KisAslWriterUtils::writeFixedString<byteOrder>("8BIM", io); 0770 KisAslWriterUtils::writeFixedString<byteOrder>("Layr", io); 0771 0772 KisAslWriterUtils::OffsetStreamPusher<quint32, byteOrder> layerAndMaskSectionSizeTag(io, 4); 0773 // number of layers (negative, because krita always has alpha) 0774 const qint16 layersSize = nodes.size(); 0775 SAFE_WRITE_EX(byteOrder, io, layersSize); 0776 0777 dbgFile << "Number of layers" << layersSize << "at" << io.pos(); 0778 0779 // Layer records section 0780 for (const FlattenedNode &item : nodes) { 0781 KisNodeSP node = item.node; 0782 0783 PSDLayerRecord *layerRecord = new PSDLayerRecord(m_header); 0784 layers.append(layerRecord); 0785 0786 const bool nodeVisible = node->visible(); 0787 const KoColorSpace *colorSpace = node->colorSpace(); 0788 const quint8 nodeOpacity = node->opacity(); 0789 const quint8 nodeClipping = 0; 0790 const int nodeLabelColor = node->colorLabelIndex(); 0791 const KisPaintLayer *paintLayer = qobject_cast<KisPaintLayer *>(node.data()); 0792 const bool alphaLocked = (paintLayer && paintLayer->alphaLocked()); 0793 const QString nodeCompositeOp = node->compositeOpId(); 0794 0795 const KisGroupLayer *groupLayer = qobject_cast<KisGroupLayer *>(node.data()); 0796 const bool nodeIsPassThrough = groupLayer && groupLayer->passThroughMode(); 0797 0798 QDomDocument stylesXmlDoc = fetchLayerStyleXmlData(node); 0799 0800 if (mergedPatternsXmlDoc.isNull() && !stylesXmlDoc.isNull()) { 0801 mergedPatternsXmlDoc = stylesXmlDoc; 0802 } else if (!mergedPatternsXmlDoc.isNull() && !stylesXmlDoc.isNull()) { 0803 mergePatternsXMLSection(stylesXmlDoc, mergedPatternsXmlDoc); 0804 } 0805 0806 bool nodeIrrelevant = false; 0807 QString nodeName; 0808 KisPaintDeviceSP layerContentDevice; 0809 psd_section_type sectionType; 0810 0811 if (item.type == FlattenedNode::RASTER_LAYER) { 0812 nodeIrrelevant = false; 0813 nodeName = node->name(); 0814 layerContentDevice = node->projection(); 0815 sectionType = psd_other; 0816 } else { 0817 nodeIrrelevant = true; 0818 nodeName = item.type == FlattenedNode::SECTION_DIVIDER ? QString("</Layer group>") : node->name(); 0819 layerContentDevice = 0; 0820 sectionType = item.type == FlattenedNode::SECTION_DIVIDER ? psd_bounding_divider 0821 : item.type == FlattenedNode::FOLDER_OPEN ? psd_open_folder 0822 : psd_closed_folder; 0823 } 0824 0825 // === no access to node anymore 0826 0827 QRect layerRect; 0828 0829 if (layerContentDevice) { 0830 QRect rc = layerContentDevice->exactBounds(); 0831 rc = rc.normalized(); 0832 0833 // keep to the max of photoshop's capabilities 0834 // XXX: update this to PSB 0835 if (rc.width() > 30000) 0836 rc.setWidth(30000); 0837 if (rc.height() > 30000) 0838 rc.setHeight(30000); 0839 0840 layerRect = rc; 0841 } 0842 0843 layerRecord->top = layerRect.y(); 0844 layerRecord->left = layerRect.x(); 0845 layerRecord->bottom = layerRect.y() + layerRect.height(); 0846 layerRecord->right = layerRect.x() + layerRect.width(); 0847 0848 // colors + alpha channel 0849 // note: transparency mask not included 0850 layerRecord->nChannels = static_cast<quint16>(colorSpace->colorChannelCount() + 1); 0851 0852 ChannelInfo *info = new ChannelInfo; 0853 info->channelId = -1; // For the alpha channel, which we always have in Krita, and should be saved first in 0854 layerRecord->channelInfoRecords << info; 0855 0856 // the rest is in display order: rgb, cmyk, lab... 0857 for (quint32 i = 0; i < colorSpace->colorChannelCount(); ++i) { 0858 info = new ChannelInfo; 0859 info->channelId = static_cast<qint16>(i); // 0 for red, 1 = green, etc 0860 layerRecord->channelInfoRecords << info; 0861 } 0862 0863 layerRecord->blendModeKey = composite_op_to_psd_blendmode(nodeCompositeOp); 0864 layerRecord->isPassThrough = nodeIsPassThrough; 0865 layerRecord->opacity = nodeOpacity; 0866 layerRecord->clipping = nodeClipping; 0867 0868 layerRecord->transparencyProtected = alphaLocked; 0869 layerRecord->visible = nodeVisible; 0870 layerRecord->irrelevant = nodeIrrelevant; 0871 layerRecord->labelColor = nodeLabelColor; 0872 0873 layerRecord->layerName = nodeName.isEmpty() ? i18n("Unnamed Layer") : nodeName; 0874 0875 layerRecord->write(io, layerContentDevice, nullptr, QRect(), sectionType, stylesXmlDoc, node->inherits("KisGroupLayer")); 0876 } 0877 0878 dbgFile << "start writing layer pixel data" << io.pos(); 0879 0880 // Now save the pixel data 0881 for (PSDLayerRecord *layerRecord : layers) { 0882 layerRecord->writePixelData(io, compressionType); 0883 } 0884 } 0885 0886 // { 0887 // // write the global layer mask info -- which is NOT empty but fixed 0888 // KisAslWriterUtils::writeFixedString<byteOrder>("8BIM", io); 0889 // KisAslWriterUtils::writeFixedString<byteOrder>("LMsk", io); 0890 0891 // KisAslWriterUtils::OffsetStreamPusher<quint32, byteOrder> layerAndMaskSectionSizeTag(io, 4); 0892 // // https://www.adobe.com/devnet-apps/photoshop/fileformatashtml/#50577411_22664 0893 // psdwrite<byteOrder>(io, quint16(0)); // CS: RGB 0894 // psdwrite<byteOrder>(io, quint16(65535)); // Pure red verification 0895 // psdwrite<byteOrder>(io, quint16(0)); 0896 // psdwrite<byteOrder>(io, quint16(0)); 0897 // psdwrite<byteOrder>(io, quint16(0)); 0898 // psdwrite<byteOrder>(io, quint16(50)); // opacity 0899 // psdwrite<byteOrder>(io, quint16(128)); // kind 0900 // } 0901 0902 globalInfoSection.writePattBlockEx(io, mergedPatternsXmlDoc); 0903 } 0904 }