Krita Source Code Documentation
Loading...
Searching...
No Matches
PsdAdditionalLayerInfoBlock Class Reference

The PsdAdditionalLayerInfoBlock class implements the Additional Layer Information block. More...

#include <psd_additional_layer_info_block.h>

Public Types

using ExtraLayerInfoBlockHandler = std::function<bool(QIODevice &)>
 
using UserMaskInfoBlockHandler = std::function<bool(QIODevice &)>
 

Public Member Functions

 PsdAdditionalLayerInfoBlock (const PSDHeader &header)
 
bool read (QIODevice &io)
 
void setExtraLayerInfoBlockHandler (ExtraLayerInfoBlockHandler handler)
 
void setUserMaskInfoBlockHandler (UserMaskInfoBlockHandler handler)
 
bool valid ()
 
bool write (QIODevice &io, KisNodeSP node)
 
void writeFillLayerBlockEx (QIODevice &io, const QDomDocument &fillConfig, psd_fill_type type)
 
void writeLclrBlockEx (QIODevice &io, const quint16 &labelColor)
 
void writeLfx2BlockEx (QIODevice &io, const QDomDocument &stylesXmlDoc, bool useLfxsLayerStyleFormat)
 
void writeLsctBlockEx (QIODevice &io, psd_section_type sectionType, bool isPassThrough, const QString &blendModeKey)
 
void writeLspfBlockEx (QIODevice &io, const bool lock)
 
void writeLuniBlockEx (QIODevice &io, const QString &layerName)
 
void writePattBlockEx (QIODevice &io, const QDomDocument &patternsXmlDoc)
 
void writeTxt2BlockEx (QIODevice &io, const QVariantHash txt2Hash)
 
void writeTypeToolBlockEx (QIODevice &io, psd_layer_type_shape typeTool)
 
void writeVectorOriginationDataEx (QIODevice &io, const QDomDocument &vectorOrigination)
 
void writeVectorStrokeDataEx (QIODevice &io, const QDomDocument &vectorStroke)
 
void writeVmskBlockEx (QIODevice &io, psd_vector_mask mask)
 

Public Attributes

QVector< QDomDocument > embeddedPatterns
 
QString error
 
QDomDocument fillConfig
 
psd_fill_type fillType {psd_fill_solid_color}
 
QStringList keys
 
quint16 labelColor {0}
 
QDomDocument layerStyleXml
 
const PSDHeader & m_header
 
QString sectionDividerBlendMode
 
psd_section_type sectionDividerType
 
QDomDocument textData
 
QTransform textTransform
 
QVariantHash txt2Data
 
QString unicodeLayerName
 
bool userLock {false}
 
psd_vector_mask vectorMask
 
QDomDocument vectorOriginationData
 
QDomDocument vectorStroke
 

Private Member Functions

template<psd_byte_order byteOrder = psd_byte_order::psdBigEndian>
void readImpl (QIODevice &io)
 
template<psd_byte_order byteOrder = psd_byte_order::psdBigEndian>
void writeFillLayerBlockExImpl (QIODevice &io, const QDomDocument &fillConfig, psd_fill_type type)
 
template<psd_byte_order byteOrder = psd_byte_order::psdBigEndian>
void writeLclrBlockExImpl (QIODevice &io, const quint16 &lclr)
 
template<psd_byte_order byteOrder = psd_byte_order::psdBigEndian>
void writeLfx2BlockExImpl (QIODevice &io, const QDomDocument &stylesXmlDoc, bool useLfxsLayerStyleFormat)
 
template<psd_byte_order byteOrder = psd_byte_order::psdBigEndian>
void writeLsctBlockExImpl (QIODevice &io, psd_section_type sectionType, bool isPassThrough, const QString &blendModeKey)
 
template<psd_byte_order byteOrder = psd_byte_order::psdBigEndian>
void writeLspfBlockExImpl (QIODevice &io, const bool &lock)
 
template<psd_byte_order byteOrder = psd_byte_order::psdBigEndian>
void writeLuniBlockExImpl (QIODevice &io, const QString &layerName)
 
template<psd_byte_order byteOrder = psd_byte_order::psdBigEndian>
void writePattBlockExImpl (QIODevice &io, const QDomDocument &patternsXmlDoc)
 
template<psd_byte_order byteOrder = psd_byte_order::psdBigEndian>
void writeTxt2BlockExImpl (QIODevice &io, const QVariantHash txt2Hash)
 
template<psd_byte_order byteOrder = psd_byte_order::psdBigEndian>
void writeTypeToolImpl (QIODevice &io, psd_layer_type_shape tool)
 
template<psd_byte_order byteOrder = psd_byte_order::psdBigEndian>
void writeVectorMaskImpl (QIODevice &io, psd_vector_mask mask)
 
template<psd_byte_order byteOrder = psd_byte_order::psdBigEndian>
void writeVectorOriginationDataImpl (QIODevice &io, const QDomDocument &vectorOrigination)
 
template<psd_byte_order byteOrder = psd_byte_order::psdBigEndian>
void writeVectorStrokeDataImpl (QIODevice &io, const QDomDocument &vectorStroke)
 

Private Attributes

ExtraLayerInfoBlockHandler m_layerInfoBlockHandler
 
UserMaskInfoBlockHandler m_userMaskBlockHandler
 

Detailed Description

Member Typedef Documentation

◆ ExtraLayerInfoBlockHandler

using PsdAdditionalLayerInfoBlock::ExtraLayerInfoBlockHandler = std::function<bool(QIODevice &)>

Definition at line 1354 of file psd_additional_layer_info_block.h.

◆ UserMaskInfoBlockHandler

using PsdAdditionalLayerInfoBlock::UserMaskInfoBlockHandler = std::function<bool(QIODevice &)>

Definition at line 1355 of file psd_additional_layer_info_block.h.

Constructor & Destructor Documentation

◆ PsdAdditionalLayerInfoBlock()

PsdAdditionalLayerInfoBlock::PsdAdditionalLayerInfoBlock ( const PSDHeader & header)

Definition at line 23 of file psd_additional_layer_info_block.cpp.

Member Function Documentation

◆ read()

bool PsdAdditionalLayerInfoBlock::read ( QIODevice & io)

Definition at line 39 of file psd_additional_layer_info_block.cpp.

40{
41 bool result = true;
42
43 try {
44 switch (m_header.byteOrder) {
46 readImpl<psd_byte_order::psdLittleEndian>(io);
47 break;
48 default:
49 readImpl(io);
50 break;
51 }
53 error = e.what();
54 result = false;
55 }
56
57 return result;
58}
psd_byte_order byteOrder
Definition psd_header.h:49

References PSDHeader::byteOrder, error, m_header, psdLittleEndian, and readImpl().

◆ readImpl()

template<psd_byte_order byteOrder>
void PsdAdditionalLayerInfoBlock::readImpl ( QIODevice & io)
private

"I don't care I don't care, no... !" (c)

Definition at line 61 of file psd_additional_layer_info_block.cpp.

62{
63 using namespace KisAslReaderUtils;
64
65 QStringList longBlocks;
66 if (m_header.version > 1) {
67 longBlocks << "LMsk"
68 << "Lr16"
69 << "Lr32"
70 << "Layr"
71 << "Mt16"
72 << "Mt32"
73 << "Mtrn"
74 << "Alph"
75 << "FMsk"
76 << "lnk2"
77 << "FEid"
78 << "FXid"
79 << "PxSD";
80 }
81
82 while (!io.atEnd()) {
83 {
84 const std::array<quint8, 4> refSignature1 = {'8', 'B', 'I', 'M'}; // '8BIM' in big-endian
85 const std::array<quint8, 4> refSignature2 = {'8', 'B', '6', '4'}; // '8B64' in big-endian
86
87 if (!TRY_READ_SIGNATURE_2OPS_EX<byteOrder>(io, refSignature1, refSignature2)) {
88 break;
89 }
90 }
91
92 QString key = readFixedString<byteOrder>(io);
93 dbgFile << "found info block with key" << key << "(" << io.pos() << ")";
94
95 quint64 blockSize = GARBAGE_VALUE_MARK;
96 if (longBlocks.contains(key)) {
97 SAFE_READ_EX(byteOrder, io, blockSize);
98 } else {
99 quint32 size32;
100 SAFE_READ_EX(byteOrder, io, size32);
101 blockSize = size32;
102 }
103
104 // Since TIFF headers are padded to multiples of 4,
105 // staving them off here is way easier.
107 if (blockSize % 4U) {
108 dbgFile << "(TIFF) WARNING: current block size is NOT a multiple of 4! Fixing...";
109 blockSize += (4U - blockSize % 4U);
110 }
111 }
112
113 dbgFile << "info block size" << blockSize << "(" << io.pos() << ")";
114
115 if (blockSize == 0)
116 continue;
117
118 // offset verifier will correct the position on the exit from
119 // current namespace, including 'continue', 'return' and
120 // exceptions.
121 SETUP_OFFSET_VERIFIER(infoBlockEndVerifier, io, blockSize, 0);
122
123 if (keys.contains(key)) {
124 error = "Found duplicate entry for key ";
125 continue;
126 }
127 keys << key;
128
129 // TODO: Loading of 32 bit files is not supported yet
130 if (key == "Lr16" /* || key == "Lr32"*/) {
132 int offset = m_header.version > 1 ? 8 : 4;
133 dbgFile << "Offset for block handler: " << io.pos() << offset;
134 io.seek(io.pos() - offset);
136 }
137 } else if (key == "Layr") {
139 int offset = m_header.version > 1 ? 8 : 4;
140 dbgFile << "(TIFF) Offset for block handler: " << io.pos() << offset;
141 io.seek(io.pos() - offset);
143 }
144 } else if (key == "SoCo") {
145 // Solid Color
148 } else if (key == "GdFl") {
149 // Gradient Fill
152 } else if (key == "PtFl") {
153 // Pattern Fill
156 } else if (key == "brit") {
157 } else if (key == "levl") {
158 } else if (key == "curv") {
159 } else if (key == "expA") {
160 } else if (key == "vibA") {
161 } else if (key == "hue") {
162 } else if (key == "hue2") {
163 } else if (key == "blnc") {
164 } else if (key == "blwh") {
165 } else if (key == "phfl") {
166 } else if (key == "mixr") {
167 } else if (key == "clrL") {
168 } else if (key == "nvrt") {
169 } else if (key == "post") {
170 } else if (key == "thrs") {
171 } else if (key == "selc") {
172 } else if (key == "lrFX") {
173 // deprecated! use lfx2 instead!
174 } else if (key == "tySh") {
175 } else if (key == "luni") {
176 // get the unicode layer name
177 unicodeLayerName = readUnicodeString<byteOrder>(io);
178 dbgFile << "\t" << "unicodeLayerName" << unicodeLayerName;
179 } else if (key == "lyid") {
180 quint32 id;
181 psdread<byteOrder>(io, id);
182 dbgFile << "\t" << "layer ID:" << id;
183 } else if (key == "lfx2" || key == "lfxs") {
184 // lfxs is a special variant of layer styles for group layers
186 } else if (key == "Patt" || key == "Pat2" || key == "Pat3") {
187 QDomDocument pattern = KisAslReader::readPsdSectionPattern(io, blockSize, byteOrder);
188 embeddedPatterns << pattern;
189 } else if (key == "Anno") {
190 } else if (key == "clbl") {
191 } else if (key == "infx") {
192 } else if (key == "knko") {
193 } else if (key == "lspf") {
194 // Protected setting. Only the (undocumented) complete
195 // lock flag is supported. Other flags include
196 // transparency, composite and position (bits 0-2).
197 quint32 protection;
198 psdread<byteOrder>(io, protection);
199 userLock = protection & (1 << 31)? true: false;
200 } else if (key == "lclr") {
201 // layer label color.
202 quint16 col1 = 0;
203 quint16 col2 = 0;
204 quint16 col3 = 0;
205 quint16 col4 = 0;
206 psdread<byteOrder>(io, col1);
207 psdread<byteOrder>(io, col2);
208 psdread<byteOrder>(io, col3);
209 psdread<byteOrder>(io, col4);
210 dbgFile << "\t" << "layer color:" << col1 << col2 << col3 << col4;
211 labelColor = col1;
212 } else if (key == "fxrp") {
213 } else if (key == "grdm") {
214 } else if (key == "lsct") {
215 quint32 dividerType = GARBAGE_VALUE_MARK;
216 SAFE_READ_EX(byteOrder, io, dividerType);
217 this->sectionDividerType = (psd_section_type)dividerType;
218
219 dbgFile << "Reading \"lsct\" block:";
220 dbgFile << ppVar(blockSize);
221 dbgFile << ppVar(dividerType);
222
223 if (blockSize >= 12) {
224 quint32 lsctSignature = GARBAGE_VALUE_MARK;
225 const quint32 refSignature1 = 0x3842494D; // '8BIM' in little-endian
226 SAFE_READ_SIGNATURE_EX(byteOrder, io, lsctSignature, refSignature1);
227
228 this->sectionDividerBlendMode = readFixedString<byteOrder>(io);
229
231 }
232
233 // Animation
234 if (blockSize >= 14) {
239 }
240
241 } else if (key == "brst") {
242 } else if (key == "vmsk" || key == "vsms") { // If key is "vsms" then we are writing for (Photoshop CS6) and the document will have a "vscg" key
243 quint32 version; // ( = 3 for Photoshop 6.0)
244 psdread<byteOrder>(io, version);
245
246 quint32 flags;
247 psdread<byteOrder>(io, flags);
248 // read the flags.
249 vectorMask.invert = flags & 1? true: false;
250 vectorMask.notLink = flags & 2? true: false;
251 vectorMask.disable = flags & 4? true: false;
252
253 quint64 currentPos = 8;
254 psd_path_sub_path currentPath;
255 bool firstPath = true;
256
257 while (currentPos < blockSize) {
258 quint16 recordType;
259 psdread<byteOrder>(io, recordType);
260
261 if (recordType == 6) {
262 io.skip(24);
263 dbgFile << "\trecord" << recordType;
264 } else if (recordType == 7) {
265 QRectF bounds;
266 // unsure if there can be multiple clipboard records...
267 bounds.setTop(psdreadFixedPoint<byteOrder>(io));
268 bounds.setLeft(psdreadFixedPoint<byteOrder>(io));
269 bounds.setBottom(psdreadFixedPoint<byteOrder>(io));
270 bounds.setRight(psdreadFixedPoint<byteOrder>(io));
272 vectorMask.path.clipBoardResolution = psdreadFixedPoint<byteOrder>(io);
273 dbgFile << "\trecord" << recordType << "top" << bounds << "res" << vectorMask.path.clipBoardResolution;
274 io.skip(4);
275 } else if (recordType == 0 || recordType == 3) {
276 quint16 length;
277 psdread<byteOrder>(io, length);
278 dbgFile << "\trecord" << recordType << "length" << length;
279 if (firstPath) {
280 currentPath.isClosed = (recordType == 0);
281 } else {
282 vectorMask.path.subPaths.append(currentPath);
283 currentPath = psd_path_sub_path();
284 currentPath.isClosed = (recordType == 0);
285 }
286 firstPath = false;
287 io.skip(22);
288 } else if (recordType == 8) {
289 quint16 length;
290 psdread<byteOrder>(io, length);
291 dbgFile << "\trecord" << recordType << "length" << length;
293 io.skip(22);
294 } else {
295 psd_path_node node;
296 node.control1.setY(psdreadFixedPoint<byteOrder>(io));
297 node.control1.setX(psdreadFixedPoint<byteOrder>(io));
298 node.node.setY(psdreadFixedPoint<byteOrder>(io));
299 node.node.setX(psdreadFixedPoint<byteOrder>(io));
300 node.control2.setY(psdreadFixedPoint<byteOrder>(io));
301 node.control2.setX(psdreadFixedPoint<byteOrder>(io));
302 node.isSmooth = (recordType == 1 || recordType == 4);
303 dbgFile << "\trecord" << recordType << "c1" << node.control1
304 << "node" << node.node << "c2" << node.control2;
305 currentPath.nodes.append(node);
306 }
307
308 currentPos += 26;
309 }
310 if (!currentPath.nodes.isEmpty()) {
311 vectorMask.path.subPaths.append(currentPath);
312 }
313
314 } else if (key == "TySh") {
316 } else if (key == "ffxi") {
317 } else if (key == "lnsr") {
318 } else if (key == "shpa") {
319 } else if (key == "shmd") {
320 } else if (key == "lyvr") {
321 } else if (key == "tsly") {
322 } else if (key == "lmgm") {
323 } else if (key == "vmgm") {
324 } else if (key == "plLd") { // Replaced by SoLd in CS3
325
326 } else if (key == "linkD" || key == "lnk2" || key == "lnk3") {
327 } else if (key == "CgEd") {
328 } else if (key == "Txt2") { // global text data, basically the same as an Illustrator text object.
329 // Docs say "first 4 are length", this is not true for this particular block, only when in ASL is first 4 length.
330 QByteArray ba = io.read(blockSize);
332 txt2Data = KisTxt2Utils::uncompressKeys(p.parseCosToJson(&ba));
333 } else if (key == "pths") {
334 } else if (key == "anFX") {
335 } else if (key == "FMsk") {
336 } else if (key == "SoLd") {
337 } else if (key == "vstk") { // vector stroke info
339 } else if (key == "vscg") {
340 if (blockSize > 4) {
341 QString vscgKey = readFixedString<byteOrder>(io);
343 if (vscgKey == "SoCo") {
345 } else if (vscgKey == "GdFl") {
346 // Gradient Fill
348 } else if (vscgKey == "PtFl") {
349 // Pattern Fill
351 }
352 }
353 } else if (key == "sn2P") {
354 } else if (key == "vogk") { // Live path shapes, these are similar to parametric shapes.
356 } else if (key == "Mtrn" || key == "Mt16" || key == "Mt32") { // There is no data associated with these keys.
357
358 } else if (key == "LMsk") {
359 // TIFFs store the global mask here.
361 int offset = m_header.version > 1 ? 8 : 4;
362 dbgFile << "(TIFF) Offset for block handler: " << io.pos() << offset;
363 io.seek(io.pos() - offset);
365 }
366 } else if (key == "FXid") {
367 } else if (key == "FEid") {
368 }
369 }
370}
qreal length(const QPointF &vec)
Definition Ellipse.cc:82
const Params2D p
static QDomDocument readLfx2PsdSection(QIODevice &device, psd_byte_order byteOrder=psd_byte_order::psdBigEndian)
static QDomDocument readPsdSectionPattern(QIODevice &device, qint64 bytesLeft, psd_byte_order byteOrder=psd_byte_order::psdBigEndian)
static QDomDocument readTypeToolObjectSettings(QIODevice &device, QTransform &transform, psd_byte_order byteOrder=psd_byte_order::psdBigEndian)
static QDomDocument readVectorOriginationData(QIODevice &device, psd_byte_order byteOrder=psd_byte_order::psdBigEndian)
static QDomDocument readVectorStroke(QIODevice &device, psd_byte_order byteOrder=psd_byte_order::psdBigEndian)
static QDomDocument readFillLayer(QIODevice &device, psd_byte_order byteOrder=psd_byte_order::psdBigEndian)
The KisCosParser class.
static QVariantHash uncompressKeys(QVariantHash doc)
uncompressKeys One of the problems with the Txt2 block is that older versions of photoshop (cs2-cs3 e...
quint16 version
Definition psd_header.h:43
bool tiffStyleLayerBlock
Definition psd_header.h:50
ExtraLayerInfoBlockHandler m_layerInfoBlockHandler
#define GARBAGE_VALUE_MARK
#define SAFE_READ_EX(byteOrder, device, varname)
#define SAFE_READ_SIGNATURE_EX(byteOrder, device, varname, expected)
#define bounds(x, a, b)
#define ppVar(var)
Definition kis_debug.h:163
#define dbgFile
Definition kis_debug.h:57
#define SETUP_OFFSET_VERIFIER(name, device, expectedOffset, maxPadding)
psd_section_type
Definition psd.h:144
@ psd_fill_solid_color
Definition psd.h:124
@ psd_fill_gradient
Definition psd.h:125
@ psd_fill_pattern
Definition psd.h:126
QList< psd_path_sub_path > subPaths

References bounds, psd_path::clipBoardBounds, psd_path::clipBoardResolution, psd_path_node::control1, psd_path_node::control2, dbgFile, psd_vector_mask::disable, embeddedPatterns, error, fillConfig, fillType, GARBAGE_VALUE_MARK, psd_path::initialFillRecord, psd_vector_mask::invert, psd_path_sub_path::isClosed, psd_path_node::isSmooth, keys, labelColor, layerStyleXml, length(), m_header, m_layerInfoBlockHandler, m_userMaskBlockHandler, psd_path_node::node, psd_path_sub_path::nodes, psd_vector_mask::notLink, p, psd_vector_mask::path, ppVar, psd_fill_gradient, psd_fill_pattern, psd_fill_solid_color, KisAslReader::readFillLayer(), KisAslReader::readLfx2PsdSection(), KisAslReader::readPsdSectionPattern(), KisAslReader::readTypeToolObjectSettings(), KisAslReader::readVectorOriginationData(), KisAslReader::readVectorStroke(), SAFE_READ_EX, SAFE_READ_SIGNATURE_EX, sectionDividerBlendMode, sectionDividerType, SETUP_OFFSET_VERIFIER, psd_path::subPaths, textData, textTransform, PSDHeader::tiffStyleLayerBlock, txt2Data, KisTxt2Utils::uncompressKeys(), unicodeLayerName, userLock, vectorMask, vectorOriginationData, vectorStroke, and PSDHeader::version.

◆ setExtraLayerInfoBlockHandler()

void PsdAdditionalLayerInfoBlock::setExtraLayerInfoBlockHandler ( ExtraLayerInfoBlockHandler handler)

Definition at line 29 of file psd_additional_layer_info_block.cpp.

30{
32}

References m_layerInfoBlockHandler.

◆ setUserMaskInfoBlockHandler()

void PsdAdditionalLayerInfoBlock::setUserMaskInfoBlockHandler ( UserMaskInfoBlockHandler handler)

Definition at line 34 of file psd_additional_layer_info_block.cpp.

35{
36 m_userMaskBlockHandler = handler;
37}

References m_userMaskBlockHandler.

◆ valid()

bool PsdAdditionalLayerInfoBlock::valid ( )

Definition at line 377 of file psd_additional_layer_info_block.cpp.

378{
379 return true;
380}

◆ write()

bool PsdAdditionalLayerInfoBlock::write ( QIODevice & io,
KisNodeSP node )

Definition at line 372 of file psd_additional_layer_info_block.cpp.

373{
374 return true;
375}

◆ writeFillLayerBlockEx()

void PsdAdditionalLayerInfoBlock::writeFillLayerBlockEx ( QIODevice & io,
const QDomDocument & fillConfig,
psd_fill_type type )

Definition at line 497 of file psd_additional_layer_info_block.cpp.

498{
499 switch (m_header.byteOrder) {
501 writeFillLayerBlockExImpl<psd_byte_order::psdLittleEndian>(io, fillConfig, type);
502 break;
503 default:
505 break;
506 }
507}
void writeFillLayerBlockExImpl(QIODevice &io, const QDomDocument &fillConfig, psd_fill_type type)

References PSDHeader::byteOrder, fillConfig, m_header, psdLittleEndian, and writeFillLayerBlockExImpl().

◆ writeFillLayerBlockExImpl()

template<psd_byte_order byteOrder>
void PsdAdditionalLayerInfoBlock::writeFillLayerBlockExImpl ( QIODevice & io,
const QDomDocument & fillConfig,
psd_fill_type type )
private

Definition at line 610 of file psd_additional_layer_info_block.cpp.

611{
612 KisAslWriterUtils::writeFixedString<byteOrder>("8BIM", io);
613 if (type == psd_fill_solid_color) {
614 KisAslWriterUtils::writeFixedString<byteOrder>("SoCo", io);
615 } else if (type == psd_fill_gradient) {
616 KisAslWriterUtils::writeFixedString<byteOrder>("GdFl", io);
617 } else {
618 KisAslWriterUtils::writeFixedString<byteOrder>("PtFl", io);
619 }
621
622 try {
623 KisAslWriter writer(byteOrder);
624
625 writer.writeFillLayerSectionEx(io, fillConfig);
626
628 warnKrita << "WARNING: Couldn't save fill layer block:" << PREPEND_METHOD(e.what());
629
630 // TODO: make this error recoverable!
631 throw e;
632 }
633}
#define PREPEND_METHOD(msg)
Definition kis_debug.h:180
#define warnKrita
Definition kis_debug.h:94

References fillConfig, PREPEND_METHOD, psd_fill_gradient, psd_fill_solid_color, warnKrita, and KisAslWriter::writeFillLayerSectionEx().

◆ writeLclrBlockEx()

void PsdAdditionalLayerInfoBlock::writeLclrBlockEx ( QIODevice & io,
const quint16 & labelColor )

Definition at line 485 of file psd_additional_layer_info_block.cpp.

486{
487 switch (m_header.byteOrder) {
489 writeLclrBlockExImpl<psd_byte_order::psdLittleEndian>(io, labelColor);
490 break;
491 default:
493 break;
494 }
495}
void writeLclrBlockExImpl(QIODevice &io, const quint16 &lclr)

References PSDHeader::byteOrder, labelColor, m_header, psdLittleEndian, and writeLclrBlockExImpl().

◆ writeLclrBlockExImpl()

template<psd_byte_order byteOrder>
void PsdAdditionalLayerInfoBlock::writeLclrBlockExImpl ( QIODevice & io,
const quint16 & lclr )
private

Definition at line 593 of file psd_additional_layer_info_block.cpp.

594{
595 KisAslWriterUtils::writeFixedString<byteOrder>("8BIM", io);
596 KisAslWriterUtils::writeFixedString<byteOrder>("lclr", io);
597 // 4x2 quint16
598 const quint32 len = 8;
599 SAFE_WRITE_EX(byteOrder, io, len);
600 quint16 zero = 0;
601 SAFE_WRITE_EX(byteOrder, io, lclr);
602 SAFE_WRITE_EX(byteOrder, io, zero);
603 SAFE_WRITE_EX(byteOrder, io, zero);
604 SAFE_WRITE_EX(byteOrder, io, zero);
605
606
607}
#define SAFE_WRITE_EX(byteOrder, device, varname)

References SAFE_WRITE_EX.

◆ writeLfx2BlockEx()

void PsdAdditionalLayerInfoBlock::writeLfx2BlockEx ( QIODevice & io,
const QDomDocument & stylesXmlDoc,
bool useLfxsLayerStyleFormat )

Definition at line 429 of file psd_additional_layer_info_block.cpp.

430{
431 switch (m_header.byteOrder) {
433 writeLfx2BlockExImpl<psd_byte_order::psdLittleEndian>(io, stylesXmlDoc, useLfxsLayerStyleFormat);
434 break;
435 default:
436 writeLfx2BlockExImpl(io, stylesXmlDoc, useLfxsLayerStyleFormat);
437 break;
438 }
439}
void writeLfx2BlockExImpl(QIODevice &io, const QDomDocument &stylesXmlDoc, bool useLfxsLayerStyleFormat)

References PSDHeader::byteOrder, m_header, psdLittleEndian, and writeLfx2BlockExImpl().

◆ writeLfx2BlockExImpl()

template<psd_byte_order byteOrder>
void PsdAdditionalLayerInfoBlock::writeLfx2BlockExImpl ( QIODevice & io,
const QDomDocument & stylesXmlDoc,
bool useLfxsLayerStyleFormat )
private

Definition at line 442 of file psd_additional_layer_info_block.cpp.

443{
444 KisAslWriterUtils::writeFixedString<byteOrder>("8BIM", io);
445 // 'lfxs' format is used for Group layers in PS
446 KisAslWriterUtils::writeFixedString<byteOrder>(!useLfxsLayerStyleFormat ? "lfx2" : "lfxs", io);
448
449 try {
450 KisAslWriter writer(byteOrder);
451 writer.writePsdLfx2SectionEx(io, stylesXmlDoc);
452
454 warnKrita << "WARNING: Couldn't save layer style lfx2 block:" << PREPEND_METHOD(e.what());
455
456 // TODO: make this error recoverable!
457 throw e;
458 }
459}

References PREPEND_METHOD, warnKrita, and KisAslWriter::writePsdLfx2SectionEx().

◆ writeLsctBlockEx()

void PsdAdditionalLayerInfoBlock::writeLsctBlockEx ( QIODevice & io,
psd_section_type sectionType,
bool isPassThrough,
const QString & blendModeKey )

Definition at line 403 of file psd_additional_layer_info_block.cpp.

404{
405 switch (m_header.byteOrder) {
407 writeLsctBlockExImpl<psd_byte_order::psdLittleEndian>(io, sectionType, isPassThrough, blendModeKey);
408 break;
409 default:
410 writeLsctBlockExImpl(io, sectionType, isPassThrough, blendModeKey);
411 break;
412 }
413}
void writeLsctBlockExImpl(QIODevice &io, psd_section_type sectionType, bool isPassThrough, const QString &blendModeKey)

References PSDHeader::byteOrder, m_header, psdLittleEndian, and writeLsctBlockExImpl().

◆ writeLsctBlockExImpl()

template<psd_byte_order byteOrder>
void PsdAdditionalLayerInfoBlock::writeLsctBlockExImpl ( QIODevice & io,
psd_section_type sectionType,
bool isPassThrough,
const QString & blendModeKey )
private

Definition at line 416 of file psd_additional_layer_info_block.cpp.

417{
418 KisAslWriterUtils::writeFixedString<byteOrder>("8BIM", io);
419 KisAslWriterUtils::writeFixedString<byteOrder>("lsct", io);
421 SAFE_WRITE_EX(byteOrder, io, (quint32)sectionType);
422
423 QString realBlendModeKey = isPassThrough ? QString("pass") : blendModeKey;
424
425 KisAslWriterUtils::writeFixedString<byteOrder>("8BIM", io);
426 KisAslWriterUtils::writeFixedString<byteOrder>(realBlendModeKey, io);
427}

References SAFE_WRITE_EX.

◆ writeLspfBlockEx()

void PsdAdditionalLayerInfoBlock::writeLspfBlockEx ( QIODevice & io,
const bool lock )

Definition at line 473 of file psd_additional_layer_info_block.cpp.

474{
475 switch (m_header.byteOrder) {
477 writeLspfBlockExImpl<psd_byte_order::psdLittleEndian>(io, lock);
478 break;
479 default:
480 writeLspfBlockExImpl(io, lock);
481 break;
482 }
483}
void writeLspfBlockExImpl(QIODevice &io, const bool &lock)

References PSDHeader::byteOrder, m_header, psdLittleEndian, and writeLspfBlockExImpl().

◆ writeLspfBlockExImpl()

template<psd_byte_order byteOrder>
void PsdAdditionalLayerInfoBlock::writeLspfBlockExImpl ( QIODevice & io,
const bool & lock )
private

Definition at line 578 of file psd_additional_layer_info_block.cpp.

579{
580 KisAslWriterUtils::writeFixedString<byteOrder>("8BIM", io);
581 KisAslWriterUtils::writeFixedString<byteOrder>("lspf", io);
582 const quint32 len = 4;
583 SAFE_WRITE_EX(byteOrder, io, len);
584
585 quint32 flags = 0;
586 if (lock) {
587 flags |= (1 << 31);
588 }
589 SAFE_WRITE_EX(byteOrder, io, flags);
590}

References SAFE_WRITE_EX.

◆ writeLuniBlockEx()

void PsdAdditionalLayerInfoBlock::writeLuniBlockEx ( QIODevice & io,
const QString & layerName )

Definition at line 382 of file psd_additional_layer_info_block.cpp.

383{
384 switch (m_header.byteOrder) {
386 writeLuniBlockExImpl<psd_byte_order::psdLittleEndian>(io, layerName);
387 break;
388 default:
389 writeLuniBlockExImpl(io, layerName);
390 break;
391 }
392}
void writeLuniBlockExImpl(QIODevice &io, const QString &layerName)

References PSDHeader::byteOrder, m_header, psdLittleEndian, and writeLuniBlockExImpl().

◆ writeLuniBlockExImpl()

template<psd_byte_order byteOrder>
void PsdAdditionalLayerInfoBlock::writeLuniBlockExImpl ( QIODevice & io,
const QString & layerName )
private

Definition at line 395 of file psd_additional_layer_info_block.cpp.

396{
397 KisAslWriterUtils::writeFixedString<byteOrder>("8BIM", io);
398 KisAslWriterUtils::writeFixedString<byteOrder>("luni", io);
400 KisAslWriterUtils::writeUnicodeString<byteOrder>(layerName, io);
401}

◆ writePattBlockEx()

void PsdAdditionalLayerInfoBlock::writePattBlockEx ( QIODevice & io,
const QDomDocument & patternsXmlDoc )

Definition at line 461 of file psd_additional_layer_info_block.cpp.

462{
463 switch (m_header.byteOrder) {
465 writePattBlockExImpl<psd_byte_order::psdLittleEndian>(io, patternsXmlDoc);
466 break;
467 default:
468 writePattBlockExImpl(io, patternsXmlDoc);
469 break;
470 }
471}
void writePattBlockExImpl(QIODevice &io, const QDomDocument &patternsXmlDoc)

References PSDHeader::byteOrder, m_header, psdLittleEndian, and writePattBlockExImpl().

◆ writePattBlockExImpl()

template<psd_byte_order byteOrder>
void PsdAdditionalLayerInfoBlock::writePattBlockExImpl ( QIODevice & io,
const QDomDocument & patternsXmlDoc )
private

Definition at line 558 of file psd_additional_layer_info_block.cpp.

559{
560 KisAslWriterUtils::writeFixedString<byteOrder>("8BIM", io);
561 KisAslWriterUtils::writeFixedString<byteOrder>("Patt", io);
562 const quint32 padding = m_header.tiffStyleLayerBlock ? 4 : 2;
564
565 try {
566 KisAslPatternsWriter writer(patternsXmlDoc, io, byteOrder);
567 writer.writePatterns();
568
570 warnKrita << "WARNING: Couldn't save layer style patterns block:" << PREPEND_METHOD(e.what());
571
572 // TODO: make this error recoverable!
573 throw e;
574 }
575}

References m_header, PREPEND_METHOD, PSDHeader::tiffStyleLayerBlock, warnKrita, and KisAslPatternsWriter::writePatterns().

◆ writeTxt2BlockEx()

void PsdAdditionalLayerInfoBlock::writeTxt2BlockEx ( QIODevice & io,
const QVariantHash txt2Hash )

Definition at line 760 of file psd_additional_layer_info_block.cpp.

761{
762 switch (m_header.byteOrder) {
764 writeTxt2BlockExImpl<psd_byte_order::psdLittleEndian>(io, txt2Hash);
765 break;
766 default:
767 writeTxt2BlockExImpl(io, txt2Hash);
768 break;
769 }
770}
void writeTxt2BlockExImpl(QIODevice &io, const QVariantHash txt2Hash)

References PSDHeader::byteOrder, m_header, psdLittleEndian, and writeTxt2BlockExImpl().

◆ writeTxt2BlockExImpl()

template<psd_byte_order byteOrder>
void PsdAdditionalLayerInfoBlock::writeTxt2BlockExImpl ( QIODevice & io,
const QVariantHash txt2Hash )
private

Definition at line 773 of file psd_additional_layer_info_block.cpp.

774{
775 KisAslWriterUtils::writeFixedString<byteOrder>("8BIM", io);
776 KisAslWriterUtils::writeFixedString<byteOrder>("Txt2", io);
777
778 QByteArray ba = KisCosWriter::writeTxt2FromVariantHash(txt2Hash);
779 quint32 length = ba.size();
780 SAFE_WRITE_EX(byteOrder, io, length);
781 io.write(ba);
782}
static QByteArray writeTxt2FromVariantHash(const QVariantHash doc)

References length(), SAFE_WRITE_EX, and KisCosWriter::writeTxt2FromVariantHash().

◆ writeTypeToolBlockEx()

void PsdAdditionalLayerInfoBlock::writeTypeToolBlockEx ( QIODevice & io,
psd_layer_type_shape typeTool )

Definition at line 521 of file psd_additional_layer_info_block.cpp.

522{
523 switch (m_header.byteOrder) {
525 writeTypeToolImpl<psd_byte_order::psdLittleEndian>(io, typeTool);
526 break;
527 default:
528 writeTypeToolImpl(io, typeTool);
529 break;
530 }
531}
void writeTypeToolImpl(QIODevice &io, psd_layer_type_shape tool)

References PSDHeader::byteOrder, m_header, psdLittleEndian, and writeTypeToolImpl().

◆ writeTypeToolImpl()

template<psd_byte_order byteOrder>
void PsdAdditionalLayerInfoBlock::writeTypeToolImpl ( QIODevice & io,
psd_layer_type_shape tool )
private

Definition at line 721 of file psd_additional_layer_info_block.cpp.

722{
723 KisAslWriterUtils::writeFixedString<byteOrder>("8BIM", io);
724 KisAslWriterUtils::writeFixedString<byteOrder>("TySh", io);
725
727
728 try {
729 KisAslWriter writer(byteOrder);
730
731 writer.writeTypeToolObjectSettings(io, tool.textDataASLXML(), tool.textWarpXML(), tool.transform, tool.boundingBox);
732
734 warnKrita << "WARNING: Couldn't save text layer block:" << PREPEND_METHOD(e.what());
735
736 // TODO: make this error recoverable!
737 throw e;
738 }
739}

References psd_layer_type_shape::boundingBox, PREPEND_METHOD, psd_layer_type_shape::textDataASLXML(), psd_layer_type_shape::textWarpXML(), psd_layer_type_shape::transform, warnKrita, and KisAslWriter::writeTypeToolObjectSettings().

◆ writeVectorMaskImpl()

template<psd_byte_order byteOrder>
void PsdAdditionalLayerInfoBlock::writeVectorMaskImpl ( QIODevice & io,
psd_vector_mask mask )
private

Definition at line 636 of file psd_additional_layer_info_block.cpp.

637{
638 KisAslWriterUtils::writeFixedString<byteOrder>("8BIM", io);
639 KisAslWriterUtils::writeFixedString<byteOrder>("vmsk", io);
640
641 quint32 len = 8; //, 4 version, 4 flags
642 len += 52; // 26 path record, 26 initial fill rule.
643 Q_FOREACH(psd_path_sub_path subPath, mask.path.subPaths) {
644 len += 26; // subpath record;
645 len += subPath.nodes.size() * 26; //and one for each node.
646 }
647
648 SAFE_WRITE_EX(byteOrder, io, len);
649
650 quint32 version = 3;
651 SAFE_WRITE_EX(byteOrder, io, version);
652 quint32 flags = 0;
653 if (mask.invert) {
654 flags |= 1;
655 }
656 if (mask.notLink) {
657 flags |= 2;
658 }
659 if (mask.disable) {
660 flags |= 4;
661 }
662 SAFE_WRITE_EX(byteOrder, io, flags);
663
664 // start path records
665 quint16 recordType = 6;
666 quint32 zero = 0;
667 SAFE_WRITE_EX(byteOrder, io, recordType);
668 // 24 empty bits
669 SAFE_WRITE_EX(byteOrder, io, zero);
670 SAFE_WRITE_EX(byteOrder, io, zero);
671 SAFE_WRITE_EX(byteOrder, io, zero);
672 SAFE_WRITE_EX(byteOrder, io, zero);
673 SAFE_WRITE_EX(byteOrder, io, zero);
674 SAFE_WRITE_EX(byteOrder, io, zero);
675 // initial fill rule record
676 recordType = 8;
677 SAFE_WRITE_EX(byteOrder, io, recordType);
678 quint16 fillType = mask.path.initialFillRecord? 1: 0;
679 SAFE_WRITE_EX(byteOrder, io, fillType);
680 // 22 empty bits
681 const quint16 halfZero = 0;
682 SAFE_WRITE_EX(byteOrder, io, halfZero);
683 SAFE_WRITE_EX(byteOrder, io, zero);
684 SAFE_WRITE_EX(byteOrder, io, zero);
685 SAFE_WRITE_EX(byteOrder, io, zero);
686 SAFE_WRITE_EX(byteOrder, io, zero);
687 SAFE_WRITE_EX(byteOrder, io, zero);
688 // write the subpaths.
689 Q_FOREACH(psd_path_sub_path subPath, mask.path.subPaths) {
690 recordType = subPath.isClosed? 0: 3;
691 quint16 length = subPath.nodes.size();
692 dbgFile << "writing subpath" << subPath.nodes.size();
693 SAFE_WRITE_EX(byteOrder, io, recordType);
694 SAFE_WRITE_EX(byteOrder, io, length);
695 // 22 empty bits
696 SAFE_WRITE_EX(byteOrder, io, halfZero);
697 SAFE_WRITE_EX(byteOrder, io, zero);
698 SAFE_WRITE_EX(byteOrder, io, zero);
699 SAFE_WRITE_EX(byteOrder, io, zero);
700 SAFE_WRITE_EX(byteOrder, io, zero);
701 SAFE_WRITE_EX(byteOrder, io, zero);
702
703 Q_FOREACH(psd_path_node node, subPath.nodes) {
704 if (subPath.isClosed) {
705 recordType = node.isSmooth? 1: 2;
706 } else {
707 recordType = node.isSmooth? 4: 5;
708 }
709 SAFE_WRITE_EX(byteOrder, io, recordType);
710 psdwriteFixedPoint<byteOrder>(io, node.control1.y());
711 psdwriteFixedPoint<byteOrder>(io, node.control1.x());
712 psdwriteFixedPoint<byteOrder>(io, node.node.y());
713 psdwriteFixedPoint<byteOrder>(io, node.node.x());
714 psdwriteFixedPoint<byteOrder>(io, node.control2.y());
715 psdwriteFixedPoint<byteOrder>(io, node.control2.x());
716 }
717 }
718}

References psd_path_node::control1, psd_path_node::control2, dbgFile, psd_vector_mask::disable, fillType, psd_path::initialFillRecord, psd_vector_mask::invert, psd_path_sub_path::isClosed, psd_path_node::isSmooth, length(), psd_path_node::node, psd_path_sub_path::nodes, psd_vector_mask::notLink, psd_vector_mask::path, SAFE_WRITE_EX, and psd_path::subPaths.

◆ writeVectorOriginationDataEx()

void PsdAdditionalLayerInfoBlock::writeVectorOriginationDataEx ( QIODevice & io,
const QDomDocument & vectorOrigination )

Definition at line 545 of file psd_additional_layer_info_block.cpp.

546{
547 switch (m_header.byteOrder) {
549 writeVectorOriginationDataImpl<psd_byte_order::psdLittleEndian>(io, vectorOrigination);
550 break;
551 default:
552 writeVectorOriginationDataImpl(io, vectorOrigination);
553 break;
554 }
555}
void writeVectorOriginationDataImpl(QIODevice &io, const QDomDocument &vectorOrigination)

References PSDHeader::byteOrder, m_header, psdLittleEndian, and writeVectorOriginationDataImpl().

◆ writeVectorOriginationDataImpl()

template<psd_byte_order byteOrder>
void PsdAdditionalLayerInfoBlock::writeVectorOriginationDataImpl ( QIODevice & io,
const QDomDocument & vectorOrigination )
private

Definition at line 785 of file psd_additional_layer_info_block.cpp.

786{
787 KisAslWriterUtils::writeFixedString<byteOrder>("8BIM", io);
788 KisAslWriterUtils::writeFixedString<byteOrder>("vogk", io);
790 try {
791 KisAslWriter writer(byteOrder);
792
793 writer.writeVectorOriginationDataEx(io, vectorOrigination);
794
796 warnKrita << "WARNING: Couldn't save vector stroke layer block:" << PREPEND_METHOD(e.what());
797
798 // TODO: make this error recoverable!
799 throw e;
800 }
801}

References PREPEND_METHOD, warnKrita, and KisAslWriter::writeVectorOriginationDataEx().

◆ writeVectorStrokeDataEx()

void PsdAdditionalLayerInfoBlock::writeVectorStrokeDataEx ( QIODevice & io,
const QDomDocument & vectorStroke )

Definition at line 533 of file psd_additional_layer_info_block.cpp.

534{
535 switch (m_header.byteOrder) {
537 writeVectorStrokeDataImpl<psd_byte_order::psdLittleEndian>(io, vectorStroke);
538 break;
539 default:
541 break;
542 }
543}
void writeVectorStrokeDataImpl(QIODevice &io, const QDomDocument &vectorStroke)

References PSDHeader::byteOrder, m_header, psdLittleEndian, vectorStroke, and writeVectorStrokeDataImpl().

◆ writeVectorStrokeDataImpl()

template<psd_byte_order byteOrder>
void PsdAdditionalLayerInfoBlock::writeVectorStrokeDataImpl ( QIODevice & io,
const QDomDocument & vectorStroke )
private

Definition at line 742 of file psd_additional_layer_info_block.cpp.

743{
744 KisAslWriterUtils::writeFixedString<byteOrder>("8BIM", io);
745 KisAslWriterUtils::writeFixedString<byteOrder>("vstk", io);
747 try {
748 KisAslWriter writer(byteOrder);
749
750 writer.writeVectorStrokeDataEx(io, vectorStroke);
751
753 warnKrita << "WARNING: Couldn't save vector stroke layer block:" << PREPEND_METHOD(e.what());
754
755 // TODO: make this error recoverable!
756 throw e;
757 }
758}

References PREPEND_METHOD, vectorStroke, warnKrita, and KisAslWriter::writeVectorStrokeDataEx().

◆ writeVmskBlockEx()

void PsdAdditionalLayerInfoBlock::writeVmskBlockEx ( QIODevice & io,
psd_vector_mask mask )

Definition at line 509 of file psd_additional_layer_info_block.cpp.

510{
511 switch (m_header.byteOrder) {
513 writeVectorMaskImpl<psd_byte_order::psdLittleEndian>(io, mask);
514 break;
515 default:
516 writeVectorMaskImpl(io, mask);
517 break;
518 }
519}
void writeVectorMaskImpl(QIODevice &io, psd_vector_mask mask)

References PSDHeader::byteOrder, m_header, psdLittleEndian, and writeVectorMaskImpl().

Member Data Documentation

◆ embeddedPatterns

QVector<QDomDocument> PsdAdditionalLayerInfoBlock::embeddedPatterns

Definition at line 1386 of file psd_additional_layer_info_block.h.

◆ error

QString PsdAdditionalLayerInfoBlock::error

Definition at line 1380 of file psd_additional_layer_info_block.h.

◆ fillConfig

QDomDocument PsdAdditionalLayerInfoBlock::fillConfig

Definition at line 1392 of file psd_additional_layer_info_block.h.

◆ fillType

psd_fill_type PsdAdditionalLayerInfoBlock::fillType {psd_fill_solid_color}

Definition at line 1393 of file psd_additional_layer_info_block.h.

◆ keys

QStringList PsdAdditionalLayerInfoBlock::keys

Definition at line 1381 of file psd_additional_layer_info_block.h.

◆ labelColor

quint16 PsdAdditionalLayerInfoBlock::labelColor {0}

Definition at line 1390 of file psd_additional_layer_info_block.h.

1390{0}; // layer color.

◆ layerStyleXml

QDomDocument PsdAdditionalLayerInfoBlock::layerStyleXml

Definition at line 1384 of file psd_additional_layer_info_block.h.

◆ m_header

const PSDHeader& PsdAdditionalLayerInfoBlock::m_header

Definition at line 1379 of file psd_additional_layer_info_block.h.

◆ m_layerInfoBlockHandler

ExtraLayerInfoBlockHandler PsdAdditionalLayerInfoBlock::m_layerInfoBlockHandler
private

Definition at line 1446 of file psd_additional_layer_info_block.h.

◆ m_userMaskBlockHandler

UserMaskInfoBlockHandler PsdAdditionalLayerInfoBlock::m_userMaskBlockHandler
private

Definition at line 1447 of file psd_additional_layer_info_block.h.

◆ sectionDividerBlendMode

QString PsdAdditionalLayerInfoBlock::sectionDividerBlendMode

Definition at line 1403 of file psd_additional_layer_info_block.h.

◆ sectionDividerType

psd_section_type PsdAdditionalLayerInfoBlock::sectionDividerType

Definition at line 1402 of file psd_additional_layer_info_block.h.

◆ textData

QDomDocument PsdAdditionalLayerInfoBlock::textData

Definition at line 1396 of file psd_additional_layer_info_block.h.

◆ textTransform

QTransform PsdAdditionalLayerInfoBlock::textTransform

Definition at line 1395 of file psd_additional_layer_info_block.h.

◆ txt2Data

QVariantHash PsdAdditionalLayerInfoBlock::txt2Data

Definition at line 1387 of file psd_additional_layer_info_block.h.

◆ unicodeLayerName

QString PsdAdditionalLayerInfoBlock::unicodeLayerName

Definition at line 1383 of file psd_additional_layer_info_block.h.

◆ userLock

bool PsdAdditionalLayerInfoBlock::userLock {false}

Definition at line 1389 of file psd_additional_layer_info_block.h.

1389{false};

◆ vectorMask

psd_vector_mask PsdAdditionalLayerInfoBlock::vectorMask

Definition at line 1398 of file psd_additional_layer_info_block.h.

◆ vectorOriginationData

QDomDocument PsdAdditionalLayerInfoBlock::vectorOriginationData

Definition at line 1400 of file psd_additional_layer_info_block.h.

◆ vectorStroke

QDomDocument PsdAdditionalLayerInfoBlock::vectorStroke

Definition at line 1399 of file psd_additional_layer_info_block.h.


The documentation for this class was generated from the following files: