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_record.h" 0008 0009 #include <QtEndian> 0010 0011 #include <KoColor.h> 0012 #include <QBuffer> 0013 #include <QDataStream> 0014 #include <QIODevice> 0015 #include <QStringList> 0016 0017 #include "kis_iterator_ng.h" 0018 #include <algorithm> 0019 #include <kis_debug.h> 0020 #include <kis_node.h> 0021 #include <kis_paint_layer.h> 0022 0023 #include "compression.h" 0024 #include "psd.h" 0025 #include "psd_header.h" 0026 #include "psd_utils.h" 0027 0028 #include <KoColorSpace.h> 0029 #include <KoColorSpaceMaths.h> 0030 #include <KoColorSpaceRegistry.h> 0031 #include <KoColorSpaceTraits.h> 0032 0033 #include <asl/kis_asl_reader_utils.h> 0034 #include <asl/kis_asl_writer_utils.h> 0035 #include <asl/kis_offset_keeper.h> 0036 0037 #include "psd_pixel_utils.h" 0038 #include <kundo2command.h> 0039 0040 // Just for pretty debug messages 0041 QString channelIdToChannelType(int channelId, psd_color_mode colormode) 0042 { 0043 switch (channelId) { 0044 case -3: 0045 return "Real User Supplied Layer Mask (when both a user mask and a vector mask are present"; 0046 case -2: 0047 return "User Supplied Layer Mask"; 0048 case -1: 0049 return "Transparency mask"; 0050 case 0: 0051 switch (colormode) { 0052 case Bitmap: 0053 case Indexed: 0054 return QString("bitmap or indexed: %1").arg(channelId); 0055 case Grayscale: 0056 case Gray16: 0057 return "gray"; 0058 case RGB: 0059 case RGB48: 0060 return "red"; 0061 case Lab: 0062 case Lab48: 0063 return "L"; 0064 case CMYK: 0065 case CMYK64: 0066 return "cyan"; 0067 case MultiChannel: 0068 case DeepMultichannel: 0069 return QString("multichannel channel %1").arg(channelId); 0070 case DuoTone: 0071 case Duotone16: 0072 return QString("duotone channel %1").arg(channelId); 0073 default: 0074 return QString("unknown: %1").arg(channelId); 0075 }; 0076 case 1: 0077 switch (colormode) { 0078 case Bitmap: 0079 case Indexed: 0080 return QString("WARNING bitmap or indexed: %1").arg(channelId); 0081 case Grayscale: 0082 case Gray16: 0083 return QString("WARNING: %1").arg(channelId); 0084 case RGB: 0085 case RGB48: 0086 return "green"; 0087 case Lab: 0088 case Lab48: 0089 return "a"; 0090 case CMYK: 0091 case CMYK64: 0092 return "Magenta"; 0093 case MultiChannel: 0094 case DeepMultichannel: 0095 return QString("multichannel channel %1").arg(channelId); 0096 case DuoTone: 0097 case Duotone16: 0098 return QString("duotone channel %1").arg(channelId); 0099 default: 0100 return QString("unknown: %1").arg(channelId); 0101 }; 0102 case 2: 0103 switch (colormode) { 0104 case Bitmap: 0105 case Indexed: 0106 return QString("WARNING bitmap or indexed: %1").arg(channelId); 0107 case Grayscale: 0108 case Gray16: 0109 return QString("WARNING: %1").arg(channelId); 0110 case RGB: 0111 case RGB48: 0112 return "blue"; 0113 case Lab: 0114 case Lab48: 0115 return "b"; 0116 case CMYK: 0117 case CMYK64: 0118 return "yellow"; 0119 case MultiChannel: 0120 case DeepMultichannel: 0121 return QString("multichannel channel %1").arg(channelId); 0122 case DuoTone: 0123 case Duotone16: 0124 return QString("duotone channel %1").arg(channelId); 0125 default: 0126 return QString("unknown: %1").arg(channelId); 0127 }; 0128 case 3: 0129 switch (colormode) { 0130 case Bitmap: 0131 case Indexed: 0132 return QString("WARNING bitmap or indexed: %1").arg(channelId); 0133 case Grayscale: 0134 case Gray16: 0135 return QString("WARNING: %1").arg(channelId); 0136 case RGB: 0137 case RGB48: 0138 return QString("alpha: %1").arg(channelId); 0139 case Lab: 0140 case Lab48: 0141 return QString("alpha: %1").arg(channelId); 0142 case CMYK: 0143 case CMYK64: 0144 return "Key"; 0145 case MultiChannel: 0146 case DeepMultichannel: 0147 return QString("multichannel channel %1").arg(channelId); 0148 case DuoTone: 0149 case Duotone16: 0150 return QString("duotone channel %1").arg(channelId); 0151 default: 0152 return QString("unknown: %1").arg(channelId); 0153 }; 0154 default: 0155 return QString("unknown: %1").arg(channelId); 0156 }; 0157 } 0158 0159 PSDLayerRecord::PSDLayerRecord(const PSDHeader &header) 0160 : top(0) 0161 , left(0) 0162 , bottom(0) 0163 , right(0) 0164 , nChannels(0) 0165 , opacity(0) 0166 , clipping(0) 0167 , transparencyProtected(false) 0168 , visible(true) 0169 , irrelevant(false) 0170 , layerName("UNINITIALIZED") 0171 , infoBlocks(header) 0172 , m_transparencyMaskSizeOffset(0) 0173 , m_header(header) 0174 { 0175 } 0176 0177 bool PSDLayerRecord::read(QIODevice &io) 0178 { 0179 switch (m_header.byteOrder) { 0180 case psd_byte_order::psdLittleEndian: 0181 return readImpl<psd_byte_order::psdLittleEndian>(io); 0182 default: 0183 return readImpl(io); 0184 } 0185 } 0186 0187 template<psd_byte_order byteOrder> 0188 bool PSDLayerRecord::readImpl(QIODevice &io) 0189 { 0190 dbgFile << "Going to read layer record. Pos:" << io.pos(); 0191 0192 if (!psdread<byteOrder>(io, top) || !psdread<byteOrder>(io, left) || !psdread<byteOrder>(io, bottom) || !psdread<byteOrder>(io, right) 0193 || !psdread<byteOrder>(io, nChannels)) { 0194 error = "could not read layer record"; 0195 return false; 0196 } 0197 0198 dbgFile << "\ttop" << top << "left" << left << "bottom" << bottom << "right" << right << "number of channels" << nChannels; 0199 0200 Q_ASSERT(top <= bottom); 0201 Q_ASSERT(left <= right); 0202 Q_ASSERT(nChannels > 0); 0203 0204 if (nChannels < 1) { 0205 error = QString("Not enough channels. Got: %1").arg(nChannels); 0206 return false; 0207 } 0208 0209 if (nChannels > MAX_CHANNELS) { 0210 error = QString("Too many channels. Got: %1").arg(nChannels); 0211 return false; 0212 } 0213 0214 for (int i = 0; i < nChannels; ++i) { 0215 if (io.atEnd()) { 0216 error = "Could not read enough data for channels"; 0217 return false; 0218 } 0219 0220 ChannelInfo *info = new ChannelInfo; 0221 0222 if (!psdread<byteOrder>(io, info->channelId)) { 0223 error = "could not read channel id"; 0224 delete info; 0225 return false; 0226 } 0227 bool r; 0228 if (m_header.version == 1) { 0229 quint32 channelDataLength; 0230 r = psdread<byteOrder>(io, channelDataLength); 0231 info->channelDataLength = (quint64)channelDataLength; 0232 } else { 0233 r = psdread<byteOrder>(io, info->channelDataLength); 0234 } 0235 if (!r) { 0236 error = "Could not read length for channel data"; 0237 delete info; 0238 return false; 0239 } 0240 0241 dbgFile << "\tchannel" << i << "id" << channelIdToChannelType(info->channelId, m_header.colormode) << "length" << info->channelDataLength << "start" 0242 << info->channelDataStart << "offset" << info->channelOffset << "channelInfoPosition" << info->channelInfoPosition; 0243 0244 channelInfoRecords << info; 0245 } 0246 0247 if (!psd_read_blendmode<byteOrder>(io, blendModeKey)) { 0248 error = QString("Could not read blend mode key. Got: %1").arg(blendModeKey); 0249 return false; 0250 } 0251 0252 dbgFile << "\tBlend mode" << blendModeKey << "pos" << io.pos(); 0253 0254 if (!psdread<byteOrder>(io, opacity)) { 0255 error = "Could not read opacity"; 0256 return false; 0257 } 0258 0259 dbgFile << "\tOpacity" << opacity << io.pos(); 0260 0261 if (!psdread<byteOrder>(io, clipping)) { 0262 error = "Could not read clipping"; 0263 return false; 0264 } 0265 0266 dbgFile << "\tclipping" << clipping << io.pos(); 0267 0268 quint8 flags; 0269 if (!psdread<byteOrder>(io, flags)) { 0270 error = "Could not read flags"; 0271 return false; 0272 } 0273 dbgFile << "\tflags" << flags << io.pos(); 0274 0275 transparencyProtected = flags & 1 ? true : false; 0276 0277 dbgFile << "\ttransparency protected" << transparencyProtected; 0278 0279 visible = flags & 2 ? false : true; 0280 0281 dbgFile << "\tvisible" << visible; 0282 0283 if (flags & 8) { 0284 irrelevant = flags & 16 ? true : false; 0285 } else { 0286 irrelevant = false; 0287 } 0288 0289 dbgFile << "\tirrelevant" << irrelevant; 0290 0291 dbgFile << "\tfiller at " << io.pos(); 0292 0293 quint8 filler; 0294 if (!psdread<byteOrder>(io, filler) || filler != 0) { 0295 error = "Could not read padding"; 0296 return false; 0297 } 0298 0299 dbgFile << "\tGoing to read extra data length" << io.pos(); 0300 0301 quint32 extraDataLength; 0302 if (!psdread<byteOrder>(io, extraDataLength) || io.bytesAvailable() < extraDataLength) { 0303 error = QString("Could not read extra layer data: %1 at pos %2").arg(extraDataLength).arg(io.pos()); 0304 return false; 0305 } 0306 0307 dbgFile << "\tExtra data length" << extraDataLength; 0308 0309 if (extraDataLength > 0) { 0310 dbgFile << "Going to read extra data field. Bytes available: " << io.bytesAvailable() << "pos" << io.pos(); 0311 0312 // See https://www.adobe.com/devnet-apps/photoshop/fileformatashtml/#50577409_22582 0313 quint32 layerMaskLength = 1; // invalid... 0314 if (!psdread<byteOrder>(io, layerMaskLength) || io.bytesAvailable() < layerMaskLength) { 0315 error = QString("Could not read layer mask length: %1").arg(layerMaskLength); 0316 return false; 0317 } 0318 0319 layerMask = {}; 0320 0321 if (layerMaskLength == 0) { 0322 dbgFile << "\tNo layer mask/adjustment layer data. pos" << io.pos(); 0323 } else { 0324 dbgFile << "\tReading layer mask/adjustment layer data. Length of block:" << layerMaskLength << "pos" 0325 << io.pos(); 0326 0327 if (!psdread<byteOrder>(io, layerMask.top) || !psdread<byteOrder>(io, layerMask.left) 0328 || !psdread<byteOrder>(io, layerMask.bottom) || !psdread<byteOrder>(io, layerMask.right) 0329 || !psdread<byteOrder>(io, layerMask.defaultColor) || !psdread<byteOrder>(io, flags)) { 0330 error = "could not read common records of layer mask"; 0331 return false; 0332 } 0333 0334 layerMask.positionedRelativeToLayer = (flags & 1) != 0; 0335 layerMask.disabled = (flags & 2) != 0; 0336 layerMask.invertLayerMaskWhenBlending = (flags & 4) != 0; 0337 const bool hasMaskParameters = (flags & 8) != 0; 0338 0339 dbgFile << "\tLayer mask info (original): position relative" << layerMask.positionedRelativeToLayer 0340 << ", disabled" << layerMask.disabled << ", invert" << layerMask.invertLayerMaskWhenBlending 0341 << ", needs to read mask parameters" << hasMaskParameters; 0342 0343 if (layerMaskLength == 20) { 0344 quint16 padding = 0; 0345 if (!psdread<byteOrder>(io, padding)) { 0346 error = "Could not read layer mask padding"; 0347 return false; 0348 } 0349 } else { 0350 quint32 remainingBlockLength = layerMaskLength - 18; 0351 0352 dbgFile << "\tReading selective records from layer mask info. Remaining block length" 0353 << remainingBlockLength; 0354 0355 if (hasMaskParameters) { 0356 if (!psdread<byteOrder>(io, flags)) { 0357 error = "could not read mask parameters"; 0358 return false; 0359 } 0360 0361 remainingBlockLength -= 1; 0362 0363 dbgFile << "\t\tMask parameters" << QString::number(flags, 2) << ". Remaining block length" 0364 << remainingBlockLength; 0365 0366 if (flags & 1) { 0367 quint8 dummy = 0; 0368 if (!psdread<byteOrder>(io, dummy)) { 0369 error = "could not read user mask density"; 0370 return false; 0371 } 0372 remainingBlockLength -= sizeof(dummy); 0373 } 0374 0375 if (flags & 2) { 0376 double dummy = 0; 0377 if (!psdread<byteOrder>(io, dummy)) { 0378 error = "could not read user mask feather"; 0379 return false; 0380 } 0381 remainingBlockLength -= sizeof(dummy); 0382 } 0383 0384 if (flags & 4) { 0385 quint8 dummy = 0; 0386 if (!psdread<byteOrder>(io, dummy)) { 0387 error = "could not read vector mask density"; 0388 return false; 0389 } 0390 remainingBlockLength -= sizeof(dummy); 0391 } 0392 0393 if (flags & 8) { 0394 double dummy = 0; 0395 if (!psdread<byteOrder>(io, dummy)) { 0396 error = "could not read vector mask feather"; 0397 return false; 0398 } 0399 remainingBlockLength -= sizeof(dummy); 0400 } 0401 } 0402 0403 if (remainingBlockLength >= 1) { 0404 if (!psdread<byteOrder>(io, flags)) { 0405 error = "could not read 'real' mask record"; 0406 return false; 0407 } 0408 0409 layerMask.positionedRelativeToLayer = (flags & 1) != 0; 0410 layerMask.disabled = (flags & 2) != 0; 0411 layerMask.invertLayerMaskWhenBlending = (flags & 4) != 0; 0412 const bool hasMaskParameters = (flags & 8) != 0; 0413 0414 dbgFile << "\t\tLayer mask info (real): position relative" << layerMask.positionedRelativeToLayer 0415 << ", disabled" << layerMask.disabled << ", invert" << layerMask.invertLayerMaskWhenBlending 0416 << ", needs to read mask parameters" << hasMaskParameters; 0417 0418 remainingBlockLength -= 1; 0419 0420 dbgFile << "\t\tRemaining block length" << remainingBlockLength; 0421 } 0422 0423 if (remainingBlockLength >= 1) { 0424 if (!psdread<byteOrder>(io, layerMask.defaultColor)) { 0425 error = "could not read 'real' default color"; 0426 return false; 0427 } 0428 remainingBlockLength -= 1; 0429 dbgFile << "\t\tRead 'real' default color. Remaining block length" << remainingBlockLength; 0430 } 0431 0432 if (remainingBlockLength >= 16) { 0433 if (!psdread<byteOrder>(io, layerMask.top) || !psdread<byteOrder>(io, layerMask.left) 0434 || !psdread<byteOrder>(io, layerMask.bottom) || !psdread<byteOrder>(io, layerMask.right)) { 0435 error = "could not read 'real' mask rectangle"; 0436 return false; 0437 } 0438 remainingBlockLength -= 16; 0439 dbgFile << "\t\tRead 'real' mask rectangle. Remaining block length" << remainingBlockLength; 0440 } 0441 } 0442 } 0443 0444 // layer blending thingies 0445 quint32 blendingDataLength = 0; 0446 if (!psdread<byteOrder>(io, blendingDataLength) || io.bytesAvailable() < blendingDataLength) { 0447 error = "Could not read extra blending data."; 0448 return false; 0449 } 0450 0451 quint32 blendingNchannels = blendingDataLength > 0 ? (blendingDataLength - 8) / 4 / 2 : 0; 0452 0453 dbgFile << "\tNumber of blending channels:" << blendingNchannels; 0454 0455 if (blendingDataLength > 0) { 0456 if (blendingDataLength > 0) { 0457 if (!psdread<byteOrder>(io, blendingRanges.compositeGrayRange.first.blackValues[0]) 0458 || !psdread<byteOrder>(io, blendingRanges.compositeGrayRange.first.blackValues[1]) 0459 || !psdread<byteOrder>(io, blendingRanges.compositeGrayRange.first.whiteValues[0]) 0460 || !psdread<byteOrder>(io, blendingRanges.compositeGrayRange.first.whiteValues[1])) { 0461 error = "Could not read blending black/white values"; 0462 return false; 0463 } 0464 } 0465 blendingDataLength -= 4; 0466 0467 if (blendingDataLength > 0) { 0468 if (!psdread<byteOrder>(io, blendingRanges.compositeGrayRange.second.blackValues[0]) 0469 || !psdread<byteOrder>(io, blendingRanges.compositeGrayRange.second.blackValues[1]) 0470 || !psdread<byteOrder>(io, blendingRanges.compositeGrayRange.second.whiteValues[0]) 0471 || !psdread<byteOrder>(io, blendingRanges.compositeGrayRange.second.whiteValues[1])) { 0472 error = "Could not read blending black/white values"; 0473 return false; 0474 } 0475 } 0476 blendingDataLength -= 4; 0477 0478 dbgFile << "\tBlending ranges:"; 0479 dbgFile << "\t\tcomposite gray (source) :" << blendingRanges.compositeGrayRange.first; 0480 dbgFile << "\t\tcomposite gray (dest):" << blendingRanges.compositeGrayRange.second; 0481 0482 for (quint32 i = 0; i < blendingNchannels; ++i) { 0483 LayerBlendingRanges::LayerBlendingRange src{}; 0484 LayerBlendingRanges::LayerBlendingRange dst{}; 0485 if (!psdread<byteOrder>(io, src.blackValues[0]) || !psdread<byteOrder>(io, src.blackValues[1]) || !psdread<byteOrder>(io, src.whiteValues[0]) 0486 || !psdread<byteOrder>(io, src.whiteValues[1]) || !psdread<byteOrder>(io, dst.blackValues[0]) || !psdread<byteOrder>(io, dst.blackValues[1]) 0487 || !psdread<byteOrder>(io, dst.whiteValues[0]) || !psdread<byteOrder>(io, dst.whiteValues[1])) { 0488 error = QString("could not read src/dst range for channel %1").arg(i); 0489 return false; 0490 } 0491 dbgFile << "\t\tread range " << src << "to" << dst << "for channel" << i; 0492 blendingRanges.sourceDestinationRanges << qMakePair(src, dst); 0493 } 0494 } 0495 0496 dbgFile << "\tGoing to read layer name at" << io.pos(); 0497 quint8 layerNameLength; 0498 if (!psdread<byteOrder>(io, layerNameLength)) { 0499 error = "Could not read layer name length"; 0500 return false; 0501 } 0502 0503 dbgFile << "\tlayer name length unpadded" << layerNameLength << "pos" << io.pos(); 0504 layerNameLength = ((layerNameLength + 1 + 3) & ~0x03) - 1; 0505 0506 dbgFile << "\tlayer name length padded" << layerNameLength << "pos" << io.pos(); 0507 // XXX: This should use psdread_pascalstring 0508 layerName = io.read(layerNameLength); 0509 dbgFile << "\tlayer name" << layerName << io.pos(); 0510 0511 dbgFile << "\tAbout to read additional info blocks at" << io.pos(); 0512 0513 if (!infoBlocks.read(io)) { 0514 error = infoBlocks.error; 0515 return false; 0516 } 0517 0518 if (infoBlocks.keys.contains("luni") && !infoBlocks.unicodeLayerName.isEmpty()) { 0519 layerName = infoBlocks.unicodeLayerName; 0520 } 0521 0522 labelColor = kritaColorLabelIndex(infoBlocks.labelColor); 0523 } 0524 0525 return valid(); 0526 } 0527 0528 void PSDLayerRecord::write(QIODevice &io, 0529 KisPaintDeviceSP layerContentDevice, 0530 KisNodeSP onlyTransparencyMask, 0531 const QRect &maskRect, 0532 psd_section_type sectionType, 0533 const QDomDocument &stylesXmlDoc, 0534 bool useLfxsLayerStyleFormat) 0535 { 0536 switch (m_header.byteOrder) { 0537 case psd_byte_order::psdLittleEndian: 0538 return writeImpl<psd_byte_order::psdLittleEndian>(io, 0539 layerContentDevice, 0540 onlyTransparencyMask, 0541 maskRect, 0542 sectionType, 0543 stylesXmlDoc, 0544 useLfxsLayerStyleFormat); 0545 default: 0546 return writeImpl(io, layerContentDevice, onlyTransparencyMask, maskRect, sectionType, stylesXmlDoc, useLfxsLayerStyleFormat); 0547 } 0548 } 0549 0550 template<psd_byte_order byteOrder> 0551 void PSDLayerRecord::writeImpl(QIODevice &io, 0552 KisPaintDeviceSP layerContentDevice, 0553 KisNodeSP onlyTransparencyMask, 0554 const QRect &maskRect, 0555 psd_section_type sectionType, 0556 const QDomDocument &stylesXmlDoc, 0557 bool useLfxsLayerStyleFormat) 0558 { 0559 dbgFile << "writing layer info record" 0560 << "at" << io.pos(); 0561 0562 m_layerContentDevice = layerContentDevice; 0563 m_onlyTransparencyMask = onlyTransparencyMask; 0564 m_onlyTransparencyMaskRect = maskRect; 0565 0566 dbgFile << "saving layer record for " << layerName << "at pos" << io.pos(); 0567 dbgFile << "\ttop" << top << "left" << left << "bottom" << bottom << "right" << right << "number of channels" << nChannels; 0568 Q_ASSERT(left <= right); 0569 Q_ASSERT(top <= bottom); 0570 Q_ASSERT(nChannels > 0); 0571 0572 try { 0573 { 0574 const QRect layerRect(left, top, right - left, bottom - top); 0575 KisAslWriterUtils::writeRect<byteOrder>(layerRect, io); 0576 } 0577 0578 { 0579 quint16 realNumberOfChannels = nChannels + bool(m_onlyTransparencyMask); 0580 SAFE_WRITE_EX(byteOrder, io, realNumberOfChannels); 0581 } 0582 0583 Q_FOREACH (ChannelInfo *channel, channelInfoRecords) { 0584 SAFE_WRITE_EX(byteOrder, io, (quint16)channel->channelId); 0585 0586 channel->channelInfoPosition = static_cast<int>(io.pos()); 0587 0588 // to be filled in when we know how big channel block is 0589 const quint32 fakeChannelSize = 0; 0590 SAFE_WRITE_EX(byteOrder, io, fakeChannelSize); 0591 } 0592 0593 if (m_onlyTransparencyMask) { 0594 const quint16 userSuppliedMaskChannelId = -2; 0595 SAFE_WRITE_EX(byteOrder, io, userSuppliedMaskChannelId); 0596 0597 m_transparencyMaskSizeOffset = io.pos(); 0598 0599 const quint32 fakeTransparencyMaskSize = 0; 0600 SAFE_WRITE_EX(byteOrder, io, fakeTransparencyMaskSize); 0601 } 0602 0603 // blend mode 0604 dbgFile << ppVar(blendModeKey) << ppVar(io.pos()); 0605 0606 KisAslWriterUtils::writeFixedString<byteOrder>("8BIM", io); 0607 KisAslWriterUtils::writeFixedString<byteOrder>(blendModeKey, io); 0608 0609 SAFE_WRITE_EX(byteOrder, io, opacity); 0610 SAFE_WRITE_EX(byteOrder, io, clipping); // unused 0611 0612 // visibility and protection 0613 quint8 flags = 0; 0614 if (transparencyProtected) 0615 flags |= 1; 0616 if (!visible) 0617 flags |= 2; 0618 flags |= (1 << 3); 0619 if (irrelevant) { 0620 flags |= (1 << 4); 0621 } 0622 0623 SAFE_WRITE_EX(byteOrder, io, flags); 0624 0625 { 0626 quint8 padding = 0; 0627 SAFE_WRITE_EX(byteOrder, io, padding); 0628 } 0629 0630 { 0631 // extra fields with their own length tag 0632 KisAslWriterUtils::OffsetStreamPusher<quint32, byteOrder> extraDataSizeTag(io); 0633 0634 if (m_onlyTransparencyMask) { 0635 { 0636 const quint32 layerMaskDataSize = 20; // support simple case only 0637 SAFE_WRITE_EX(byteOrder, io, layerMaskDataSize); 0638 } 0639 0640 KisAslWriterUtils::writeRect<byteOrder>(m_onlyTransparencyMaskRect, io); 0641 0642 { 0643 // NOTE: in PSD the default color of the mask is stored in 1 byte value! 0644 // Even when the mask is actually 16/32 bit! I have no idea how it is 0645 // actually treated in this case. 0646 KIS_ASSERT_RECOVER_NOOP(m_onlyTransparencyMask->paintDevice()->pixelSize() == 1); 0647 const quint8 defaultPixel = *m_onlyTransparencyMask->paintDevice()->defaultPixel().data(); 0648 SAFE_WRITE_EX(byteOrder, io, defaultPixel); 0649 } 0650 0651 { 0652 const quint8 maskFlags = 0; // nothing serious 0653 SAFE_WRITE_EX(byteOrder, io, maskFlags); 0654 0655 const quint16 padding = 0; // 2-byte padding 0656 SAFE_WRITE_EX(byteOrder, io, padding); 0657 } 0658 } else { 0659 const quint32 nullLayerMaskDataSize = 0; 0660 SAFE_WRITE_EX(byteOrder, io, nullLayerMaskDataSize); 0661 } 0662 0663 { 0664 // blending ranges are not implemented yet 0665 const quint32 nullBlendingRangesSize = 0; 0666 SAFE_WRITE_EX(byteOrder, io, nullBlendingRangesSize); 0667 } 0668 0669 // layer name: Pascal string, padded to a multiple of 4 bytes. 0670 psdwrite_pascalstring<byteOrder>(io, layerName, 4); 0671 0672 PsdAdditionalLayerInfoBlock additionalInfoBlock(m_header); 0673 0674 // write 'luni' data block 0675 additionalInfoBlock.writeLuniBlockEx(io, layerName); 0676 0677 additionalInfoBlock.writeLclrBlockEx(io, psdLabelColor(labelColor)); 0678 0679 // write 'lsct' data block 0680 if (sectionType != psd_other) { 0681 additionalInfoBlock.writeLsctBlockEx(io, sectionType, isPassThrough, blendModeKey); 0682 } 0683 0684 // write 'lfx2' data block 0685 if (!stylesXmlDoc.isNull()) { 0686 additionalInfoBlock.writeLfx2BlockEx(io, stylesXmlDoc, useLfxsLayerStyleFormat); 0687 } 0688 0689 // write SoCo, GdFl, PtFl data blocks. 0690 if (!fillConfig.isNull()) { 0691 additionalInfoBlock.writeFillLayerBlockEx(io, fillConfig, fillType); 0692 } 0693 0694 } 0695 } catch (KisAslWriterUtils::ASLWriteException &e) { 0696 throw KisAslWriterUtils::ASLWriteException(PREPEND_METHOD(e.what())); 0697 } 0698 } 0699 0700 KisPaintDeviceSP PSDLayerRecord::convertMaskDeviceIfNeeded(KisPaintDeviceSP dev) 0701 { 0702 KisPaintDeviceSP result = dev; 0703 0704 if (m_header.channelDepth == 16) { 0705 result = new KisPaintDevice(*dev); 0706 result->convertTo(KoColorSpaceRegistry::instance()->alpha16()); 0707 } else if (m_header.channelDepth == 32) { 0708 result = new KisPaintDevice(*dev); 0709 result->convertTo(KoColorSpaceRegistry::instance()->alpha32f()); 0710 } 0711 return result; 0712 } 0713 0714 quint16 PSDLayerRecord::psdLabelColor(int colorLabelIndex) 0715 { 0716 quint16 color = 0; 0717 switch (colorLabelIndex) { 0718 case 0: // none 0719 color = 0; 0720 break; 0721 case 1: // Blue 0722 color = 5; 0723 break; 0724 case 2: // Green 0725 color = 4; 0726 break; 0727 case 3: // Yellow 0728 color = 3; 0729 break; 0730 case 4: // Orange 0731 color = 2; 0732 break; 0733 case 5: // Brown, don't save. 0734 color = 0; 0735 break; 0736 case 6: // Red 0737 color = 1; 0738 break; 0739 case 7: // Purple 0740 color = 6; 0741 break; 0742 case 8: // Grey 0743 color = 7; 0744 break; 0745 default: 0746 color = 0; 0747 } 0748 return color; 0749 } 0750 0751 int PSDLayerRecord::kritaColorLabelIndex(quint16 labelColor) 0752 { 0753 int color = 0; 0754 switch (labelColor) { 0755 case 0: 0756 color = 0; 0757 break; 0758 case 1: // red 0759 color = 6; 0760 break; 0761 case 2: // Orange 0762 color = 4; 0763 break; 0764 case 3: // Yellow 0765 color = 3; 0766 break; 0767 case 4: // Green 0768 color = 2; 0769 break; 0770 case 5: // Blue 0771 color = 1; 0772 break; 0773 case 6: // Purple 0774 color = 7; 0775 break; 0776 case 7: // Grey 0777 color = 8; 0778 break; 0779 default: 0780 color = 0; 0781 } 0782 return color; 0783 } 0784 0785 template<psd_byte_order byteOrder> 0786 void PSDLayerRecord::writeTransparencyMaskPixelData(QIODevice &io) 0787 { 0788 if (m_onlyTransparencyMask) { 0789 KisPaintDeviceSP device = convertMaskDeviceIfNeeded(m_onlyTransparencyMask->paintDevice()); 0790 0791 QByteArray buffer(static_cast<int>(device->pixelSize()) * m_onlyTransparencyMaskRect.width() * m_onlyTransparencyMaskRect.height(), 0); 0792 device->readBytes((quint8 *)buffer.data(), m_onlyTransparencyMaskRect); 0793 0794 PsdPixelUtils::writeChannelDataRLE(io, 0795 (quint8 *)buffer.data(), 0796 static_cast<int>(device->pixelSize()), 0797 m_onlyTransparencyMaskRect, 0798 m_transparencyMaskSizeOffset, 0799 -1, 0800 true, 0801 byteOrder); 0802 } 0803 } 0804 0805 void PSDLayerRecord::writePixelData(QIODevice &io, psd_compression_type compressionType) 0806 { 0807 try { 0808 switch (m_header.byteOrder) { 0809 case psd_byte_order::psdLittleEndian: 0810 writePixelDataImpl<psd_byte_order::psdLittleEndian>(io, compressionType); 0811 break; 0812 default: 0813 writePixelDataImpl(io, compressionType); 0814 break; 0815 } 0816 } catch (KisAslWriterUtils::ASLWriteException &e) { 0817 throw KisAslWriterUtils::ASLWriteException(PREPEND_METHOD(e.what())); 0818 } 0819 } 0820 0821 template<psd_byte_order byteOrder> 0822 void PSDLayerRecord::writePixelDataImpl(QIODevice &io, psd_compression_type compressionType) 0823 { 0824 dbgFile << "writing pixel data for layer" << layerName << "at" << io.pos(); 0825 0826 KisPaintDeviceSP dev = m_layerContentDevice; 0827 const QRect rc(left, top, right - left, bottom - top); 0828 0829 if (rc.isEmpty()) { 0830 dbgFile << "Layer is empty! Writing placeholder information."; 0831 0832 for (int i = 0; i < nChannels; i++) { 0833 const ChannelInfo *channelInfo = channelInfoRecords[i]; 0834 KisAslWriterUtils::OffsetStreamPusher<quint32, byteOrder> channelBlockSizeExternalTag(io, 0, channelInfo->channelInfoPosition); 0835 SAFE_WRITE_EX(byteOrder, io, static_cast<quint16>(psd_compression_type::Uncompressed)); 0836 } 0837 0838 writeTransparencyMaskPixelData<byteOrder>(io); 0839 0840 return; 0841 } 0842 0843 // now write all the channels in display order 0844 dbgFile << "layer" << layerName; 0845 0846 const int channelSize = m_header.channelDepth / 8; 0847 const psd_color_mode colorMode = m_header.colormode; 0848 0849 QVector<PsdPixelUtils::ChannelWritingInfo> writingInfoList; 0850 Q_FOREACH (const ChannelInfo *channelInfo, channelInfoRecords) { 0851 writingInfoList << PsdPixelUtils::ChannelWritingInfo(channelInfo->channelId, channelInfo->channelInfoPosition); 0852 } 0853 0854 PsdPixelUtils::writePixelDataCommon(io, dev, rc, colorMode, channelSize, true, true, writingInfoList, compressionType, byteOrder); 0855 writeTransparencyMaskPixelData<byteOrder>(io); 0856 } 0857 0858 bool PSDLayerRecord::valid() 0859 { 0860 // XXX: check validity! 0861 return true; 0862 } 0863 0864 bool PSDLayerRecord::readPixelData(QIODevice &io, KisPaintDeviceSP device) 0865 { 0866 dbgFile << "Reading pixel data for layer" << layerName << "pos" << io.pos(); 0867 0868 const int channelSize = m_header.channelDepth / 8; 0869 const QRect layerRect = QRect(left, top, right - left, bottom - top); 0870 0871 try { 0872 // WARNING: Pixel data is ALWAYS in big endian!!! 0873 PsdPixelUtils::readChannels(io, device, m_header.colormode, channelSize, layerRect, channelInfoRecords, psd_byte_order::psdBigEndian); 0874 } catch (KisAslReaderUtils::ASLParseException &e) { 0875 device->clear(); 0876 error = e.what(); 0877 return false; 0878 } 0879 0880 return true; 0881 } 0882 0883 QRect PSDLayerRecord::channelRect(ChannelInfo *channel) const 0884 { 0885 QRect result; 0886 0887 if (channel->channelId < -1) { 0888 result = QRect(layerMask.left, layerMask.top, layerMask.right - layerMask.left, layerMask.bottom - layerMask.top); 0889 } else { 0890 result = QRect(left, top, right - left, bottom - top); 0891 } 0892 0893 return result; 0894 } 0895 0896 bool PSDLayerRecord::readMask(QIODevice &io, KisPaintDeviceSP dev, ChannelInfo *channelInfo) 0897 { 0898 KIS_ASSERT_RECOVER(channelInfo->channelId < -1) 0899 { 0900 return false; 0901 } 0902 0903 dbgFile << "Going to read" << channelIdToChannelType(channelInfo->channelId, m_header.colormode) << "mask"; 0904 0905 QRect maskRect = channelRect(channelInfo); 0906 if (maskRect.isEmpty()) { 0907 dbgFile << "Empty Channel"; 0908 return true; 0909 } 0910 0911 // the device must be a pixel selection 0912 KIS_ASSERT_RECOVER(dev->pixelSize() == 1) 0913 { 0914 return false; 0915 } 0916 0917 dev->setDefaultPixel(KoColor(&layerMask.defaultColor, dev->colorSpace())); 0918 0919 const int pixelSize = m_header.channelDepth == 16 ? 2 : m_header.channelDepth == 32 ? 4 : 1; 0920 0921 QVector<ChannelInfo *> infoRecords; 0922 infoRecords << channelInfo; 0923 PsdPixelUtils::readAlphaMaskChannels(io, dev, pixelSize, maskRect, infoRecords); 0924 0925 return true; 0926 } 0927 0928 QDebug operator<<(QDebug dbg, const PSDLayerRecord &layer) 0929 { 0930 #ifndef NODEBUG 0931 dbg.nospace() << "valid: " << const_cast<PSDLayerRecord *>(&layer)->valid(); 0932 dbg.nospace() << ", name: " << layer.layerName; 0933 dbg.nospace() << ", top: " << layer.top; 0934 dbg.nospace() << ", left:" << layer.left; 0935 dbg.nospace() << ", bottom: " << layer.bottom; 0936 dbg.nospace() << ", right: " << layer.right; 0937 dbg.nospace() << ", number of channels: " << layer.nChannels; 0938 dbg.nospace() << ", blendModeKey: " << layer.blendModeKey; 0939 dbg.nospace() << ", opacity: " << layer.opacity; 0940 dbg.nospace() << ", clipping: " << layer.clipping; 0941 dbg.nospace() << ", transparency protected: " << layer.transparencyProtected; 0942 dbg.nospace() << ", visible: " << layer.visible; 0943 dbg.nospace() << ", irrelevant: " << layer.irrelevant << "\n"; 0944 Q_FOREACH (const ChannelInfo *channel, layer.channelInfoRecords) { 0945 dbg.space() << channel; 0946 } 0947 #endif 0948 return dbg.nospace(); 0949 } 0950 0951 QDebug operator<<(QDebug dbg, const ChannelInfo &channel) 0952 { 0953 #ifndef NODEBUG 0954 dbg.nospace() << "\tChannel type" << channel.channelId << "size: " << channel.channelDataLength << "compression type" << channel.compressionType << "\n"; 0955 #endif 0956 return dbg.nospace(); 0957 }