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

#include <psd_layer_record.h>

Classes

struct  LayerBlendingRanges
 
struct  LayerMaskData
 

Public Member Functions

void addPathShapeToPSDPath (psd_path &path, KoPathShape *shape, double shapeWidth, double shapeHeight)
 addPathShapeToPSDPath add all KoPathShape subpaths to the given psd_path struct.
 
QRect channelRect (ChannelInfo *channel) const
 
KoPathShape * constructPathShape (psd_path path, double shapeWidth, double shapeHeight)
 constructPathShape create a KoPathshape based on a psd_path struct, used in vector masks and path resources.
 
 PSDLayerRecord (const PSDHeader &header)
 
bool read (QIODevice &io)
 
bool readMask (QIODevice &io, KisPaintDeviceSP dev, ChannelInfo *channel)
 
bool readPixelData (QIODevice &io, KisPaintDeviceSP device)
 
bool valid ()
 
void write (QIODevice &io, KisPaintDeviceSP layerContentDevice, KisNodeSP onlyTransparencyMask, const QRect &maskRect, psd_section_type sectionType, const QDomDocument &stylesXmlDoc, bool useLfxsLayerStyleFormat)
 
void writePixelData (QIODevice &io, psd_compression_type compressionType)
 
 ~PSDLayerRecord ()
 

Public Attributes

LayerBlendingRanges blendingRanges
 
QString blendModeKey
 
qint32 bottom {0}
 
QVector< ChannelInfo * > channelInfoRecords
 
quint8 clipping {0}
 
QString error
 
QDomDocument fillConfig
 
psd_fill_type fillType {psd_fill_solid_color}
 
PsdAdditionalLayerInfoBlock infoBlocks
 
bool irrelevant {false}
 
bool isPassThrough {false}
 
int labelColor {0}
 
LayerMaskData layerMask
 
QString layerName {"UNINITIALIZED"}
 
qint32 left {0}
 
quint16 nChannels {0}
 
quint8 opacity {0}
 
qint32 right {0}
 
psd_layer_type_shape textShape
 
qint32 top {0}
 
bool transparencyProtected {false}
 
bool userLocked {false}
 
psd_vector_mask vectorMask
 
QDomDocument vectorOriginationData
 
QDomDocument vectorStroke
 
bool visible {true}
 

Private Member Functions

KisPaintDeviceSP convertMaskDeviceIfNeeded (KisPaintDeviceSP dev)
 
int kritaColorLabelIndex (quint16 labelColor)
 
quint16 psdLabelColor (int colorLabelIndex)
 
template<psd_byte_order byteOrder = psd_byte_order::psdBigEndian>
bool readImpl (QIODevice &io)
 
template<psd_byte_order byteOrder = psd_byte_order::psdBigEndian>
void writeImpl (QIODevice &io, KisPaintDeviceSP layerContentDevice, KisNodeSP onlyTransparencyMask, const QRect &maskRect, psd_section_type sectionType, const QDomDocument &stylesXmlDoc, bool useLfxsLayerStyleFormat)
 
template<psd_byte_order = psd_byte_order::psdBigEndian>
void writePixelDataImpl (QIODevice &io, psd_compression_type compressionType)
 
template<psd_byte_order = psd_byte_order::psdBigEndian>
void writeTransparencyMaskPixelData (QIODevice &io)
 

Private Attributes

const PSDHeader m_header
 
KisPaintDeviceSP m_layerContentDevice
 
KisNodeSP m_onlyTransparencyMask
 
QRect m_onlyTransparencyMaskRect
 
qint64 m_transparencyMaskSizeOffset {0}
 

Detailed Description

Definition at line 68 of file psd_layer_record.h.

Constructor & Destructor Documentation

◆ PSDLayerRecord()

PSDLayerRecord::PSDLayerRecord ( const PSDHeader & header)

Definition at line 162 of file psd_layer_record.cpp.

163 : infoBlocks(header)
164 , m_header(header)
165{
166}
PsdAdditionalLayerInfoBlock infoBlocks
const PSDHeader m_header

◆ ~PSDLayerRecord()

PSDLayerRecord::~PSDLayerRecord ( )
inline

Definition at line 73 of file psd_layer_record.h.

74 {
75 qDeleteAll(channelInfoRecords);
76 }
QVector< ChannelInfo * > channelInfoRecords

Member Function Documentation

◆ addPathShapeToPSDPath()

void PSDLayerRecord::addPathShapeToPSDPath ( psd_path & path,
KoPathShape * shape,
double shapeWidth,
double shapeHeight )

addPathShapeToPSDPath add all KoPathShape subpaths to the given psd_path struct.

Parameters
shapeWidththe image width in points
shapeHeightthe image height in points

Definition at line 991 of file psd_layer_record.cpp.

992{
993 QTransform tf = QTransform::fromScale(shapeWidth, shapeHeight).inverted();
994 tf = shape->absoluteTransformation()*tf;
995
996
997 for (int i = 0; i < shape->subpathCount(); i++) {
998 psd_path_sub_path subPath;
999 subPath.isClosed = shape->isClosedSubpath(i);
1000 while(subPath.nodes.size() < shape->subpathPointCount(i)) {
1001 const KoPathPoint *point = shape->pointByIndex(KoPathPointIndex(i, subPath.nodes.size()));
1002 psd_path_node node;
1003 node.node = tf.map(point->point());
1004 node.control1 = point->activeControlPoint1()? tf.map(point->controlPoint1()): node.node;
1005 node.control2 = point->activeControlPoint2()? tf.map(point->controlPoint2()): node.node;
1006
1007 node.isSmooth = (point->properties().testFlag(KoPathPoint::IsSmooth)
1008 || point->properties().testFlag(KoPathPoint::IsSymmetric));
1009 subPath.nodes.append(node);
1010 }
1011
1012 path.subPaths.append(subPath);
1013 }
1014}
QPair< int, int > KoPathPointIndex
Definition KoPathShape.h:28
A KoPathPoint represents a point in a path.
PointProperties properties
QPointF point
QPointF controlPoint1
@ IsSmooth
it is smooth, both control points on a line through the point
Definition KoPathPoint.h:41
@ IsSymmetric
it is symmetric, like smooth but control points have same distance to point
Definition KoPathPoint.h:42
bool activeControlPoint1
bool activeControlPoint2
QPointF controlPoint2
int subpathPointCount(int subpathIndex) const
Returns the number of points in a subpath.
bool isClosedSubpath(int subpathIndex) const
Checks if a subpath is closed.
int subpathCount() const
Returns the number of subpaths in the path.
KoPathPoint * pointByIndex(const KoPathPointIndex &pointIndex) const
Returns the path point specified by a path point index.
QTransform absoluteTransformation() const
Definition KoShape.cpp:330

References KoShape::absoluteTransformation(), KoPathPoint::activeControlPoint1, KoPathPoint::activeControlPoint2, psd_path_node::control1, psd_path_node::control2, KoPathPoint::controlPoint1, KoPathPoint::controlPoint2, psd_path_sub_path::isClosed, KoPathShape::isClosedSubpath(), KoPathPoint::IsSmooth, psd_path_node::isSmooth, KoPathPoint::IsSymmetric, psd_path_node::node, psd_path_sub_path::nodes, KoPathPoint::point, KoPathShape::pointByIndex(), KoPathPoint::properties, KoPathShape::subpathCount(), and KoPathShape::subpathPointCount().

◆ channelRect()

◆ constructPathShape()

KoPathShape * PSDLayerRecord::constructPathShape ( psd_path path,
double shapeWidth,
double shapeHeight )

constructPathShape create a KoPathshape based on a psd_path struct, used in vector masks and path resources.

Parameters
patha psd path struct.
shapeWidththe image width in points
shapeHeightthe image height in points
vogkextra vector data from the vogk layer info block.
Returns
a KoPathShape.

Definition at line 945 of file psd_layer_record.cpp.

946{
947 KoPathShape *shape = new KoPathShape();
948
949 // psd paths are stored normalized.
950 QTransform tf = QTransform::fromScale(shapeWidth, shapeHeight);
951
952 QString nodeTypes;
953 Q_FOREACH(psd_path_sub_path subPath, path.subPaths) {
954 for (int i = 0; i < subPath.nodes.size(); i++) {
955 psd_path_node node = subPath.nodes.at(i);
956 if (i == 0) {
957 shape->moveTo(tf.map(node.node));
958 } else {
959 psd_path_node previousNode = subPath.nodes.at(i-1);
960 if (previousNode.node == previousNode.control2 && node.node == node.control1) {
961 shape->lineTo(tf.map(node.node));
962 } else {
963 shape->curveTo(tf.map(previousNode.control2), tf.map(node.control1), tf.map(node.node));
964 }
965 }
966 if (node.isSmooth) {
967 nodeTypes.append("s");
968 } else {
969 nodeTypes.append("c");
970 }
971 }
972 if (subPath.isClosed) {
973 psd_path_node lastNode = subPath.nodes.last();
974 psd_path_node firstNode = subPath.nodes.first();
975 if (lastNode.node == lastNode.control2 && firstNode.node == firstNode.control1) {
976 shape->lineTo(tf.map(firstNode.node));
977 } else {
978 shape->curveTo(tf.map(lastNode.control2), tf.map(firstNode.control1), tf.map(firstNode.node));
979 }
980 shape->closeMerge();
981 }
982
983 }
984 if (shape->pointCount() > 0) {
985 shape->loadNodeTypes(nodeTypes);
986 }
987
988 return shape;
989}
The position of a path point within a path shape.
Definition KoPathShape.h:63
KoPathPoint * lineTo(const QPointF &p)
Adds a new line segment.
void closeMerge()
Closes the current subpath.
KoPathPoint * moveTo(const QPointF &p)
Starts a new Subpath.
int pointCount() const
Returns the number of points in the path.
KoPathPoint * curveTo(const QPointF &c1, const QPointF &c2, const QPointF &p)
Adds a new cubic Bezier curve segment.
void loadNodeTypes(const QString &nodeTypes)
Loads node types.

References KoPathShape::closeMerge(), psd_path_node::control1, psd_path_node::control2, KoPathShape::curveTo(), psd_path_sub_path::isClosed, psd_path_node::isSmooth, KoPathShape::lineTo(), KoPathShape::loadNodeTypes(), KoPathShape::moveTo(), psd_path_node::node, psd_path_sub_path::nodes, and KoPathShape::pointCount().

◆ convertMaskDeviceIfNeeded()

KisPaintDeviceSP PSDLayerRecord::convertMaskDeviceIfNeeded ( KisPaintDeviceSP dev)
private

Definition at line 717 of file psd_layer_record.cpp.

718{
719 KisPaintDeviceSP result = dev;
720
721 if (m_header.channelDepth == 16) {
722 result = new KisPaintDevice(*dev);
723 result->convertTo(KoColorSpaceRegistry::instance()->alpha16());
724 } else if (m_header.channelDepth == 32) {
725 result = new KisPaintDevice(*dev);
726 result->convertTo(KoColorSpaceRegistry::instance()->alpha32f());
727 }
728 return result;
729}
void convertTo(const KoColorSpace *dstColorSpace, KoColorConversionTransformation::Intent renderingIntent=KoColorConversionTransformation::internalRenderingIntent(), KoColorConversionTransformation::ConversionFlags conversionFlags=KoColorConversionTransformation::internalConversionFlags(), KUndo2Command *parentCommand=nullptr, KoUpdater *progressUpdater=nullptr)
quint16 channelDepth
Definition psd_header.h:47
static KoColorSpaceRegistry * instance()

References PSDHeader::channelDepth, KisPaintDevice::convertTo(), KoColorSpaceRegistry::instance(), and m_header.

◆ kritaColorLabelIndex()

int PSDLayerRecord::kritaColorLabelIndex ( quint16 labelColor)
private

Definition at line 768 of file psd_layer_record.cpp.

769{
770 int color = 0;
771 switch (labelColor) {
772 case 0:
773 color = 0;
774 break;
775 case 1: // red
776 color = 6;
777 break;
778 case 2: // Orange
779 color = 4;
780 break;
781 case 3: // Yellow
782 color = 3;
783 break;
784 case 4: // Green
785 color = 2;
786 break;
787 case 5: // Blue
788 color = 1;
789 break;
790 case 6: // Purple
791 color = 7;
792 break;
793 case 7: // Grey
794 color = 8;
795 break;
796 default:
797 color = 0;
798 }
799 return color;
800}

References labelColor.

◆ psdLabelColor()

quint16 PSDLayerRecord::psdLabelColor ( int colorLabelIndex)
private

Definition at line 731 of file psd_layer_record.cpp.

732{
733 quint16 color = 0;
734 switch (colorLabelIndex) {
735 case 0: // none
736 color = 0;
737 break;
738 case 1: // Blue
739 color = 5;
740 break;
741 case 2: // Green
742 color = 4;
743 break;
744 case 3: // Yellow
745 color = 3;
746 break;
747 case 4: // Orange
748 color = 2;
749 break;
750 case 5: // Brown, don't save.
751 color = 0;
752 break;
753 case 6: // Red
754 color = 1;
755 break;
756 case 7: // Purple
757 color = 6;
758 break;
759 case 8: // Grey
760 color = 7;
761 break;
762 default:
763 color = 0;
764 }
765 return color;
766}

◆ read()

bool PSDLayerRecord::read ( QIODevice & io)

Definition at line 168 of file psd_layer_record.cpp.

169{
170 switch (m_header.byteOrder) {
172 return readImpl<psd_byte_order::psdLittleEndian>(io);
173 default:
174 return readImpl(io);
175 }
176}
psd_byte_order byteOrder
Definition psd_header.h:49
bool readImpl(QIODevice &io)

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

◆ readImpl()

template<psd_byte_order byteOrder>
bool PSDLayerRecord::readImpl ( QIODevice & io)
private

Definition at line 179 of file psd_layer_record.cpp.

180{
181 dbgFile << "Going to read layer record. Pos:" << io.pos();
182
183 if (!psdread<byteOrder>(io, top) || !psdread<byteOrder>(io, left) || !psdread<byteOrder>(io, bottom) || !psdread<byteOrder>(io, right)
184 || !psdread<byteOrder>(io, nChannels)) {
185 error = "could not read layer record";
186 return false;
187 }
188
189 dbgFile << "\ttop" << top << "left" << left << "bottom" << bottom << "right" << right << "number of channels" << nChannels;
190
191 Q_ASSERT(top <= bottom);
192 Q_ASSERT(left <= right);
193 Q_ASSERT(nChannels > 0);
194
195 if (nChannels < 1) {
196 error = QString("Not enough channels. Got: %1").arg(nChannels);
197 return false;
198 }
199
200 if (nChannels > MAX_CHANNELS) {
201 error = QString("Too many channels. Got: %1").arg(nChannels);
202 return false;
203 }
204
205 for (int i = 0; i < nChannels; ++i) {
206 if (io.atEnd()) {
207 error = "Could not read enough data for channels";
208 return false;
209 }
210
211 ChannelInfo *info = new ChannelInfo;
212
213 if (!psdread<byteOrder>(io, info->channelId)) {
214 error = "could not read channel id";
215 delete info;
216 return false;
217 }
218 bool r;
219 if (m_header.version == 1) {
220 quint32 channelDataLength;
221 r = psdread<byteOrder>(io, channelDataLength);
222 info->channelDataLength = (quint64)channelDataLength;
223 } else {
224 r = psdread<byteOrder>(io, info->channelDataLength);
225 }
226 if (!r) {
227 error = "Could not read length for channel data";
228 delete info;
229 return false;
230 }
231
232 dbgFile << "\tchannel" << i << "id" << channelIdToChannelType(info->channelId, m_header.colormode) << "length" << info->channelDataLength << "start"
233 << info->channelDataStart << "offset" << info->channelOffset << "channelInfoPosition" << info->channelInfoPosition;
234
235 channelInfoRecords << info;
236 }
237
238 if (!psd_read_blendmode<byteOrder>(io, blendModeKey)) {
239 error = QString("Could not read blend mode key. Got: %1").arg(blendModeKey);
240 return false;
241 }
242
243 dbgFile << "\tBlend mode" << blendModeKey << "pos" << io.pos();
244
245 if (!psdread<byteOrder>(io, opacity)) {
246 error = "Could not read opacity";
247 return false;
248 }
249
250 dbgFile << "\tOpacity" << opacity << io.pos();
251
252 if (!psdread<byteOrder>(io, clipping)) {
253 error = "Could not read clipping";
254 return false;
255 }
256
257 dbgFile << "\tclipping" << clipping << io.pos();
258
259 quint8 flags;
260 if (!psdread<byteOrder>(io, flags)) {
261 error = "Could not read flags";
262 return false;
263 }
264 dbgFile << "\tflags" << flags << io.pos();
265
266 transparencyProtected = flags & 1 ? true : false;
267
268 dbgFile << "\ttransparency protected" << transparencyProtected;
269
270 visible = flags & 2 ? false : true;
271
272 dbgFile << "\tvisible" << visible;
273
274 if (flags & 8) {
275 irrelevant = flags & 16 ? true : false;
276 } else {
277 irrelevant = false;
278 }
279
280 dbgFile << "\tirrelevant" << irrelevant;
281
282 dbgFile << "\tfiller at " << io.pos();
283
284 quint8 filler;
285 if (!psdread<byteOrder>(io, filler) || filler != 0) {
286 error = "Could not read padding";
287 return false;
288 }
289
290 dbgFile << "\tGoing to read extra data length" << io.pos();
291
292 quint32 extraDataLength;
293 if (!psdread<byteOrder>(io, extraDataLength) || io.bytesAvailable() < extraDataLength) {
294 error = QString("Could not read extra layer data: %1 at pos %2").arg(extraDataLength).arg(io.pos());
295 return false;
296 }
297
298 dbgFile << "\tExtra data length" << extraDataLength;
299
300 if (extraDataLength > 0) {
301 dbgFile << "Going to read extra data field. Bytes available: " << io.bytesAvailable() << "pos" << io.pos();
302
303 // See https://www.adobe.com/devnet-apps/photoshop/fileformatashtml/#50577409_22582
304 quint32 layerMaskLength = 1; // invalid...
305 if (!psdread<byteOrder>(io, layerMaskLength) || io.bytesAvailable() < layerMaskLength) {
306 error = QString("Could not read layer mask length: %1").arg(layerMaskLength);
307 return false;
308 }
309
310 layerMask = {};
311
312 if (layerMaskLength == 0) {
313 dbgFile << "\tNo layer mask/adjustment layer data. pos" << io.pos();
314 } else {
315 dbgFile << "\tReading layer mask/adjustment layer data. Length of block:" << layerMaskLength << "pos"
316 << io.pos();
317
318 if (!psdread<byteOrder>(io, layerMask.top) || !psdread<byteOrder>(io, layerMask.left)
319 || !psdread<byteOrder>(io, layerMask.bottom) || !psdread<byteOrder>(io, layerMask.right)
320 || !psdread<byteOrder>(io, layerMask.defaultColor) || !psdread<byteOrder>(io, flags)) {
321 error = "could not read common records of layer mask";
322 return false;
323 }
324
325 layerMask.positionedRelativeToLayer = (flags & 1) != 0;
326 layerMask.disabled = (flags & 2) != 0;
327 layerMask.invertLayerMaskWhenBlending = (flags & 4) != 0;
328 const bool hasMaskParameters = (flags & 8) != 0;
329
330 dbgFile << "\tLayer mask info (original): position relative" << layerMask.positionedRelativeToLayer
331 << ", disabled" << layerMask.disabled << ", invert" << layerMask.invertLayerMaskWhenBlending
332 << ", needs to read mask parameters" << hasMaskParameters;
333
334 if (layerMaskLength == 20) {
335 quint16 padding = 0;
336 if (!psdread<byteOrder>(io, padding)) {
337 error = "Could not read layer mask padding";
338 return false;
339 }
340 } else {
341 quint32 remainingBlockLength = layerMaskLength - 18;
342
343 dbgFile << "\tReading selective records from layer mask info. Remaining block length"
344 << remainingBlockLength;
345
346 if (hasMaskParameters) {
347 if (!psdread<byteOrder>(io, flags)) {
348 error = "could not read mask parameters";
349 return false;
350 }
351
352 remainingBlockLength -= 1;
353
354 dbgFile << "\t\tMask parameters" << QString::number(flags, 2) << ". Remaining block length"
355 << remainingBlockLength;
356
357 if (flags & 1) {
358 quint8 dummy = 0;
359 if (!psdread<byteOrder>(io, dummy)) {
360 error = "could not read user mask density";
361 return false;
362 }
363 remainingBlockLength -= sizeof(dummy);
364 }
365
366 if (flags & 2) {
367 double dummy = 0;
368 if (!psdread<byteOrder>(io, dummy)) {
369 error = "could not read user mask feather";
370 return false;
371 }
372 remainingBlockLength -= sizeof(dummy);
373 }
374
375 if (flags & 4) {
376 quint8 dummy = 0;
377 if (!psdread<byteOrder>(io, dummy)) {
378 error = "could not read vector mask density";
379 return false;
380 }
381 remainingBlockLength -= sizeof(dummy);
382 }
383
384 if (flags & 8) {
385 double dummy = 0;
386 if (!psdread<byteOrder>(io, dummy)) {
387 error = "could not read vector mask feather";
388 return false;
389 }
390 remainingBlockLength -= sizeof(dummy);
391 }
392 }
393
394 if (remainingBlockLength >= 1) {
395 if (!psdread<byteOrder>(io, flags)) {
396 error = "could not read 'real' mask record";
397 return false;
398 }
399
400 layerMask.positionedRelativeToLayer = (flags & 1) != 0;
401 layerMask.disabled = (flags & 2) != 0;
402 layerMask.invertLayerMaskWhenBlending = (flags & 4) != 0;
403 const bool hasMaskParameters = (flags & 8) != 0;
404
405 dbgFile << "\t\tLayer mask info (real): position relative" << layerMask.positionedRelativeToLayer
406 << ", disabled" << layerMask.disabled << ", invert" << layerMask.invertLayerMaskWhenBlending
407 << ", needs to read mask parameters" << hasMaskParameters;
408
409 remainingBlockLength -= 1;
410
411 dbgFile << "\t\tRemaining block length" << remainingBlockLength;
412 }
413
414 if (remainingBlockLength >= 1) {
415 if (!psdread<byteOrder>(io, layerMask.defaultColor)) {
416 error = "could not read 'real' default color";
417 return false;
418 }
419 remainingBlockLength -= 1;
420 dbgFile << "\t\tRead 'real' default color. Remaining block length" << remainingBlockLength;
421 }
422
423 if (remainingBlockLength >= 16) {
424 if (!psdread<byteOrder>(io, layerMask.top) || !psdread<byteOrder>(io, layerMask.left)
425 || !psdread<byteOrder>(io, layerMask.bottom) || !psdread<byteOrder>(io, layerMask.right)) {
426 error = "could not read 'real' mask rectangle";
427 return false;
428 }
429 remainingBlockLength -= 16;
430 dbgFile << "\t\tRead 'real' mask rectangle. Remaining block length" << remainingBlockLength;
431 }
432 }
433 }
434
435 // layer blending thingies
436 quint32 blendingDataLength = 0;
437 if (!psdread<byteOrder>(io, blendingDataLength) || io.bytesAvailable() < blendingDataLength) {
438 error = "Could not read extra blending data.";
439 return false;
440 }
441
442 quint32 blendingNchannels = blendingDataLength > 0 ? (blendingDataLength - 8) / 4 / 2 : 0;
443
444 dbgFile << "\tNumber of blending channels:" << blendingNchannels;
445
446 if (blendingDataLength > 0) {
447 if (blendingDataLength > 0) {
448 if (!psdread<byteOrder>(io, blendingRanges.compositeGrayRange.first.blackValues[0])
449 || !psdread<byteOrder>(io, blendingRanges.compositeGrayRange.first.blackValues[1])
450 || !psdread<byteOrder>(io, blendingRanges.compositeGrayRange.first.whiteValues[0])
451 || !psdread<byteOrder>(io, blendingRanges.compositeGrayRange.first.whiteValues[1])) {
452 error = "Could not read blending black/white values";
453 return false;
454 }
455 }
456 blendingDataLength -= 4;
457
458 if (blendingDataLength > 0) {
459 if (!psdread<byteOrder>(io, blendingRanges.compositeGrayRange.second.blackValues[0])
460 || !psdread<byteOrder>(io, blendingRanges.compositeGrayRange.second.blackValues[1])
461 || !psdread<byteOrder>(io, blendingRanges.compositeGrayRange.second.whiteValues[0])
462 || !psdread<byteOrder>(io, blendingRanges.compositeGrayRange.second.whiteValues[1])) {
463 error = "Could not read blending black/white values";
464 return false;
465 }
466 }
467 blendingDataLength -= 4;
468
469 dbgFile << "\tBlending ranges:";
470 dbgFile << "\t\tcomposite gray (source) :" << blendingRanges.compositeGrayRange.first;
471 dbgFile << "\t\tcomposite gray (dest):" << blendingRanges.compositeGrayRange.second;
472
473 for (quint32 i = 0; i < blendingNchannels; ++i) {
474 LayerBlendingRanges::LayerBlendingRange src{};
475 LayerBlendingRanges::LayerBlendingRange dst{};
476 if (!psdread<byteOrder>(io, src.blackValues[0]) || !psdread<byteOrder>(io, src.blackValues[1]) || !psdread<byteOrder>(io, src.whiteValues[0])
477 || !psdread<byteOrder>(io, src.whiteValues[1]) || !psdread<byteOrder>(io, dst.blackValues[0]) || !psdread<byteOrder>(io, dst.blackValues[1])
478 || !psdread<byteOrder>(io, dst.whiteValues[0]) || !psdread<byteOrder>(io, dst.whiteValues[1])) {
479 error = QString("could not read src/dst range for channel %1").arg(i);
480 return false;
481 }
482 dbgFile << "\t\tread range " << src << "to" << dst << "for channel" << i;
483 blendingRanges.sourceDestinationRanges << qMakePair(src, dst);
484 }
485 }
486
487 dbgFile << "\tGoing to read layer name at" << io.pos();
488 quint8 layerNameLength;
489 if (!psdread<byteOrder>(io, layerNameLength)) {
490 error = "Could not read layer name length";
491 return false;
492 }
493
494 dbgFile << "\tlayer name length unpadded" << layerNameLength << "pos" << io.pos();
495 layerNameLength = ((layerNameLength + 1 + 3) & ~0x03) - 1;
496
497 dbgFile << "\tlayer name length padded" << layerNameLength << "pos" << io.pos();
498 // XXX: This should use psdread_pascalstring
499 layerName = io.read(layerNameLength);
500 dbgFile << "\tlayer name" << layerName << io.pos();
501
502 dbgFile << "\tAbout to read additional info blocks at" << io.pos();
503
504 if (!infoBlocks.read(io)) {
506 return false;
507 }
508
509 if (infoBlocks.keys.contains("luni") && !infoBlocks.unicodeLayerName.isEmpty()) {
511 }
512
513 if (infoBlocks.keys.contains("lspf")) {
515 }
517 }
518
519 return valid();
520}
psd_color_mode colormode
Definition psd_header.h:48
quint16 version
Definition psd_header.h:43
LayerBlendingRanges blendingRanges
int kritaColorLabelIndex(quint16 labelColor)
#define dbgFile
Definition kis_debug.h:57
const int MAX_CHANNELS
Definition psd.h:27
QString channelIdToChannelType(int channelId, psd_color_mode colormode)
quint64 channelDataLength
quint64 channelDataStart
QVector< QPair< LayerBlendingRange, LayerBlendingRange > > sourceDestinationRanges
QPair< LayerBlendingRange, LayerBlendingRange > compositeGrayRange

References blendingRanges, blendModeKey, bottom, PSDLayerRecord::LayerMaskData::bottom, ChannelInfo::channelDataLength, ChannelInfo::channelDataStart, ChannelInfo::channelId, channelIdToChannelType(), ChannelInfo::channelInfoPosition, channelInfoRecords, ChannelInfo::channelOffset, clipping, PSDHeader::colormode, PSDLayerRecord::LayerBlendingRanges::compositeGrayRange, dbgFile, PSDLayerRecord::LayerMaskData::defaultColor, PSDLayerRecord::LayerMaskData::disabled, PsdAdditionalLayerInfoBlock::error, error, infoBlocks, PSDLayerRecord::LayerMaskData::invertLayerMaskWhenBlending, irrelevant, PsdAdditionalLayerInfoBlock::keys, kritaColorLabelIndex(), PsdAdditionalLayerInfoBlock::labelColor, labelColor, layerMask, layerName, left, PSDLayerRecord::LayerMaskData::left, m_header, MAX_CHANNELS, nChannels, opacity, PSDLayerRecord::LayerMaskData::positionedRelativeToLayer, PsdAdditionalLayerInfoBlock::read(), right, PSDLayerRecord::LayerMaskData::right, PSDLayerRecord::LayerBlendingRanges::sourceDestinationRanges, top, PSDLayerRecord::LayerMaskData::top, transparencyProtected, PsdAdditionalLayerInfoBlock::unicodeLayerName, PsdAdditionalLayerInfoBlock::userLock, userLocked, valid(), PSDHeader::version, and visible.

◆ readMask()

bool PSDLayerRecord::readMask ( QIODevice & io,
KisPaintDeviceSP dev,
ChannelInfo * channel )

Definition at line 913 of file psd_layer_record.cpp.

914{
915 KIS_ASSERT_RECOVER(channelInfo->channelId < -1)
916 {
917 return false;
918 }
919
920 dbgFile << "Going to read" << channelIdToChannelType(channelInfo->channelId, m_header.colormode) << "mask";
921
922 QRect maskRect = channelRect(channelInfo);
923 if (maskRect.isEmpty()) {
924 dbgFile << "Empty Channel";
925 return true;
926 }
927
928 // the device must be a pixel selection
929 KIS_ASSERT_RECOVER(dev->pixelSize() == 1)
930 {
931 return false;
932 }
933
935
936 const int pixelSize = m_header.channelDepth == 16 ? 2 : m_header.channelDepth == 32 ? 4 : 1;
937
938 QVector<ChannelInfo *> infoRecords;
939 infoRecords << channelInfo;
940 PsdPixelUtils::readAlphaMaskChannels(io, dev, pixelSize, maskRect, infoRecords);
941
942 return true;
943}
quint32 pixelSize() const
void setDefaultPixel(const KoColor &defPixel)
const KoColorSpace * colorSpace() const
QRect channelRect(ChannelInfo *channel) const
#define KIS_ASSERT_RECOVER(cond)
Definition kis_assert.h:55
void readAlphaMaskChannels(QIODevice &io, KisPaintDeviceSP device, int channelSize, const QRect &layerRect, QVector< ChannelInfo * > infoRecords, psd_byte_order byteOrder)

References PSDHeader::channelDepth, ChannelInfo::channelId, channelIdToChannelType(), channelRect(), PSDHeader::colormode, KisPaintDevice::colorSpace(), dbgFile, PSDLayerRecord::LayerMaskData::defaultColor, KIS_ASSERT_RECOVER, layerMask, m_header, KisPaintDevice::pixelSize(), PsdPixelUtils::readAlphaMaskChannels(), and KisPaintDevice::setDefaultPixel().

◆ readPixelData()

bool PSDLayerRecord::readPixelData ( QIODevice & io,
KisPaintDeviceSP device )

Definition at line 881 of file psd_layer_record.cpp.

882{
883 dbgFile << "Reading pixel data for layer" << layerName << "pos" << io.pos();
884
885 const int channelSize = m_header.channelDepth / 8;
886 const QRect layerRect = QRect(left, top, right - left, bottom - top);
887
888 try {
889 // WARNING: Pixel data is ALWAYS in big endian!!!
892 device->clear();
893 error = e.what();
894 return false;
895 }
896
897 return true;
898}
virtual void clear()
void readChannels(QIODevice &io, KisPaintDeviceSP device, psd_color_mode colorMode, int channelSize, const QRect &layerRect, QVector< ChannelInfo * > infoRecords, psd_byte_order byteOrder)

References bottom, PSDHeader::channelDepth, channelInfoRecords, KisPaintDevice::clear(), PSDHeader::colormode, dbgFile, error, layerName, left, m_header, psdBigEndian, PsdPixelUtils::readChannels(), right, and top.

◆ valid()

bool PSDLayerRecord::valid ( )

Definition at line 875 of file psd_layer_record.cpp.

876{
877 // XXX: check validity!
878 return true;
879}

◆ write()

void PSDLayerRecord::write ( QIODevice & io,
KisPaintDeviceSP layerContentDevice,
KisNodeSP onlyTransparencyMask,
const QRect & maskRect,
psd_section_type sectionType,
const QDomDocument & stylesXmlDoc,
bool useLfxsLayerStyleFormat )

Definition at line 522 of file psd_layer_record.cpp.

529{
530 switch (m_header.byteOrder) {
532 return writeImpl<psd_byte_order::psdLittleEndian>(io,
533 layerContentDevice,
534 onlyTransparencyMask,
535 maskRect,
536 sectionType,
537 stylesXmlDoc,
538 useLfxsLayerStyleFormat);
539 default:
540 return writeImpl(io, layerContentDevice, onlyTransparencyMask, maskRect, sectionType, stylesXmlDoc, useLfxsLayerStyleFormat);
541 }
542}
void writeImpl(QIODevice &io, KisPaintDeviceSP layerContentDevice, KisNodeSP onlyTransparencyMask, const QRect &maskRect, psd_section_type sectionType, const QDomDocument &stylesXmlDoc, bool useLfxsLayerStyleFormat)

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

◆ writeImpl()

template<psd_byte_order byteOrder>
void PSDLayerRecord::writeImpl ( QIODevice & io,
KisPaintDeviceSP layerContentDevice,
KisNodeSP onlyTransparencyMask,
const QRect & maskRect,
psd_section_type sectionType,
const QDomDocument & stylesXmlDoc,
bool useLfxsLayerStyleFormat )
private

Definition at line 545 of file psd_layer_record.cpp.

552{
553 dbgFile << "writing layer info record"
554 << "at" << io.pos();
555
556 m_layerContentDevice = layerContentDevice;
557 m_onlyTransparencyMask = onlyTransparencyMask;
559
560 dbgFile << "saving layer record for " << layerName << "at pos" << io.pos();
561 dbgFile << "\ttop" << top << "left" << left << "bottom" << bottom << "right" << right << "number of channels" << nChannels;
562 Q_ASSERT(left <= right);
563 Q_ASSERT(top <= bottom);
564 Q_ASSERT(nChannels > 0);
565
566 try {
567 {
568 const QRect layerRect(left, top, right - left, bottom - top);
569 KisAslWriterUtils::writeRect<byteOrder>(layerRect, io);
570 }
571
572 {
573 quint16 realNumberOfChannels = nChannels + bool(m_onlyTransparencyMask);
574 SAFE_WRITE_EX(byteOrder, io, realNumberOfChannels);
575 }
576
577 Q_FOREACH (ChannelInfo *channel, channelInfoRecords) {
578 SAFE_WRITE_EX(byteOrder, io, (quint16)channel->channelId);
579
580 channel->channelInfoPosition = static_cast<int>(io.pos());
581
582 // to be filled in when we know how big channel block is
583 const quint32 fakeChannelSize = 0;
584 SAFE_WRITE_EX(byteOrder, io, fakeChannelSize);
585 }
586
588 const quint16 userSuppliedMaskChannelId = -2;
589 SAFE_WRITE_EX(byteOrder, io, userSuppliedMaskChannelId);
590
592
593 const quint32 fakeTransparencyMaskSize = 0;
594 SAFE_WRITE_EX(byteOrder, io, fakeTransparencyMaskSize);
595 }
596
597 // blend mode
598 dbgFile << ppVar(blendModeKey) << ppVar(io.pos());
599
600 KisAslWriterUtils::writeFixedString<byteOrder>("8BIM", io);
601 KisAslWriterUtils::writeFixedString<byteOrder>(blendModeKey, io);
602
603 SAFE_WRITE_EX(byteOrder, io, opacity);
604 SAFE_WRITE_EX(byteOrder, io, clipping); // unused
605
606 // visibility and protection
607 quint8 flags = 0;
609 flags |= 1;
610 if (!visible)
611 flags |= 2;
612 flags |= (1 << 3);
613 if (irrelevant) {
614 flags |= (1 << 4);
615 }
616
617 SAFE_WRITE_EX(byteOrder, io, flags);
618
619 {
620 quint8 padding = 0;
621 SAFE_WRITE_EX(byteOrder, io, padding);
622 }
623
624 {
625 // extra fields with their own length tag
627
629 {
630 const quint32 layerMaskDataSize = 20; // support simple case only
631 SAFE_WRITE_EX(byteOrder, io, layerMaskDataSize);
632 }
633
634 KisAslWriterUtils::writeRect<byteOrder>(m_onlyTransparencyMaskRect, io);
635
636 {
637 // NOTE: in PSD the default color of the mask is stored in 1 byte value!
638 // Even when the mask is actually 16/32 bit! I have no idea how it is
639 // actually treated in this case.
641 const quint8 defaultPixel = *m_onlyTransparencyMask->paintDevice()->defaultPixel().data();
642 SAFE_WRITE_EX(byteOrder, io, defaultPixel);
643 }
644
645 {
646 quint8 maskFlags = 0; // nothing serious
647 if (!vectorMask.path.subPaths.isEmpty()) {
648 maskFlags |= 8; // bit 3 = indicates that the user mask actually came from rendering other data
649 }
650 SAFE_WRITE_EX(byteOrder, io, maskFlags);
651
652 const quint16 padding = 0; // 2-byte padding
653 SAFE_WRITE_EX(byteOrder, io, padding);
654 }
655 } else {
656 const quint32 nullLayerMaskDataSize = 0;
657 SAFE_WRITE_EX(byteOrder, io, nullLayerMaskDataSize);
658 }
659
660 {
661 // blending ranges are not implemented yet
662 const quint32 nullBlendingRangesSize = 0;
663 SAFE_WRITE_EX(byteOrder, io, nullBlendingRangesSize);
664 }
665
666 // layer name: Pascal string, padded to a multiple of 4 bytes.
667 psdwrite_pascalstring<byteOrder>(io, layerName, 4);
668
669 PsdAdditionalLayerInfoBlock additionalInfoBlock(m_header);
670
671 // write 'luni' data block
672 additionalInfoBlock.writeLuniBlockEx(io, layerName);
673
674 additionalInfoBlock.writeLspfBlockEx(io, userLocked);
675 additionalInfoBlock.writeLclrBlockEx(io, psdLabelColor(labelColor));
676
677 // write 'lsct' data block
678 if (sectionType != psd_other) {
679 additionalInfoBlock.writeLsctBlockEx(io, sectionType, isPassThrough, blendModeKey);
680 }
681
682 // write 'lfx2' data block
683 if (!stylesXmlDoc.isNull()) {
684 additionalInfoBlock.writeLfx2BlockEx(io, stylesXmlDoc, useLfxsLayerStyleFormat);
685 }
686
687 // write SoCo, GdFl, PtFl data blocks.
688 if (!fillConfig.isNull()) {
689 additionalInfoBlock.writeFillLayerBlockEx(io, fillConfig, fillType);
690 }
691
692 // write 'vmsk' data block
693 if (!vectorMask.path.subPaths.isEmpty()) {
694 additionalInfoBlock.writeVmskBlockEx(io, vectorMask);
695 }
696
697 // write 'tysh' data block
698 if (!textShape.engineData.isEmpty()) {
699 additionalInfoBlock.writeTypeToolBlockEx(io, textShape);
700 }
701
702 // write 'vstk' data block
703 if (!vectorStroke.isNull()) {
704 additionalInfoBlock.writeVectorStrokeDataEx(io, vectorStroke);
705 }
706
707 if (!vectorOriginationData.isNull()) {
708 additionalInfoBlock.writeVectorOriginationDataEx(io, vectorOriginationData);
709 }
710
711 }
714 }
715}
KoColor defaultPixel() const
quint8 * data()
Definition KoColor.h:144
qint64 m_transparencyMaskSizeOffset
QRect m_onlyTransparencyMaskRect
psd_fill_type fillType
psd_vector_mask vectorMask
psd_layer_type_shape textShape
QDomDocument vectorOriginationData
KisPaintDeviceSP m_layerContentDevice
quint16 psdLabelColor(int colorLabelIndex)
QDomDocument vectorStroke
QDomDocument fillConfig
KisNodeSP m_onlyTransparencyMask
The PsdAdditionalLayerInfoBlock class implements the Additional Layer Information block.
#define SAFE_WRITE_EX(byteOrder, device, varname)
#define KIS_ASSERT_RECOVER_NOOP(cond)
Definition kis_assert.h:97
#define PREPEND_METHOD(msg)
Definition kis_debug.h:180
#define ppVar(var)
Definition kis_debug.h:163
@ psd_other
Definition psd.h:144
virtual KisPaintDeviceSP paintDevice() const =0
QList< psd_path_sub_path > subPaths

References blendModeKey, bottom, ChannelInfo::channelId, ChannelInfo::channelInfoPosition, channelInfoRecords, clipping, KoColor::data(), dbgFile, KisPaintDevice::defaultPixel(), psd_layer_type_shape::engineData, fillConfig, fillType, irrelevant, isPassThrough, KIS_ASSERT_RECOVER_NOOP, labelColor, layerName, left, m_header, m_layerContentDevice, m_onlyTransparencyMask, m_onlyTransparencyMaskRect, m_transparencyMaskSizeOffset, nChannels, opacity, KisBaseNode::paintDevice(), psd_vector_mask::path, KisPaintDevice::pixelSize(), ppVar, PREPEND_METHOD, psd_other, psdLabelColor(), right, SAFE_WRITE_EX, psd_path::subPaths, textShape, top, transparencyProtected, userLocked, vectorMask, vectorOriginationData, vectorStroke, visible, PsdAdditionalLayerInfoBlock::writeFillLayerBlockEx(), PsdAdditionalLayerInfoBlock::writeLclrBlockEx(), PsdAdditionalLayerInfoBlock::writeLfx2BlockEx(), PsdAdditionalLayerInfoBlock::writeLsctBlockEx(), PsdAdditionalLayerInfoBlock::writeLspfBlockEx(), PsdAdditionalLayerInfoBlock::writeLuniBlockEx(), PsdAdditionalLayerInfoBlock::writeTypeToolBlockEx(), PsdAdditionalLayerInfoBlock::writeVectorOriginationDataEx(), PsdAdditionalLayerInfoBlock::writeVectorStrokeDataEx(), and PsdAdditionalLayerInfoBlock::writeVmskBlockEx().

◆ writePixelData()

void PSDLayerRecord::writePixelData ( QIODevice & io,
psd_compression_type compressionType )

Definition at line 822 of file psd_layer_record.cpp.

823{
824 try {
825 switch (m_header.byteOrder) {
827 writePixelDataImpl<psd_byte_order::psdLittleEndian>(io, compressionType);
828 break;
829 default:
830 writePixelDataImpl(io, compressionType);
831 break;
832 }
835 }
836}
void writePixelDataImpl(QIODevice &io, psd_compression_type compressionType)

References PSDHeader::byteOrder, m_header, PREPEND_METHOD, psdLittleEndian, and writePixelDataImpl().

◆ writePixelDataImpl()

template<psd_byte_order byteOrder>
void PSDLayerRecord::writePixelDataImpl ( QIODevice & io,
psd_compression_type compressionType )
private

Definition at line 839 of file psd_layer_record.cpp.

840{
841 dbgFile << "writing pixel data for layer" << layerName << "at" << io.pos();
842
844 const QRect rc(left, top, right - left, bottom - top);
845
846 if (rc.isEmpty()) {
847 dbgFile << "Layer is empty! Writing placeholder information.";
848
849 for (int i = 0; i < nChannels; i++) {
850 const ChannelInfo *channelInfo = channelInfoRecords[i];
851 KisAslWriterUtils::OffsetStreamPusher<quint32, byteOrder> channelBlockSizeExternalTag(io, 0, channelInfo->channelInfoPosition);
852 SAFE_WRITE_EX(byteOrder, io, static_cast<quint16>(psd_compression_type::Uncompressed));
853 }
854
855 writeTransparencyMaskPixelData<byteOrder>(io);
856
857 return;
858 }
859
860 // now write all the channels in display order
861 dbgFile << "layer" << layerName;
862
863 const int channelSize = m_header.channelDepth / 8;
864 const psd_color_mode colorMode = m_header.colormode;
865
867 Q_FOREACH (const ChannelInfo *channelInfo, channelInfoRecords) {
868 writingInfoList << PsdPixelUtils::ChannelWritingInfo(channelInfo->channelId, channelInfo->channelInfoPosition);
869 }
870
871 PsdPixelUtils::writePixelDataCommon(io, dev, rc, colorMode, channelSize, true, true, writingInfoList, compressionType, byteOrder);
872 writeTransparencyMaskPixelData<byteOrder>(io);
873}
void writePixelDataCommon(QIODevice &io, KisPaintDeviceSP dev, const QRect &rc, psd_color_mode colorMode, int channelSize, bool alphaFirst, const bool writeCompressionType, QVector< ChannelWritingInfo > &writingInfoList, psd_compression_type compressionType, psd_byte_order byteOrder)
@ Uncompressed
Definition psd.h:40
psd_color_mode
Definition psd.h:50

References bottom, PSDHeader::channelDepth, ChannelInfo::channelId, ChannelInfo::channelInfoPosition, channelInfoRecords, PSDHeader::colormode, dbgFile, layerName, left, m_header, m_layerContentDevice, nChannels, right, SAFE_WRITE_EX, top, Uncompressed, and PsdPixelUtils::writePixelDataCommon().

◆ writeTransparencyMaskPixelData()

template<psd_byte_order byteOrder>
void PSDLayerRecord::writeTransparencyMaskPixelData ( QIODevice & io)
private

Definition at line 803 of file psd_layer_record.cpp.

804{
807
808 QByteArray buffer(static_cast<int>(device->pixelSize()) * m_onlyTransparencyMaskRect.width() * m_onlyTransparencyMaskRect.height(), 0);
809 device->readBytes((quint8 *)buffer.data(), m_onlyTransparencyMaskRect);
810
812 (quint8 *)buffer.data(),
813 static_cast<int>(device->pixelSize()),
816 -1,
817 true,
818 byteOrder);
819 }
820}
void readBytes(quint8 *data, qint32 x, qint32 y, qint32 w, qint32 h) const
KisPaintDeviceSP convertMaskDeviceIfNeeded(KisPaintDeviceSP dev)
void writeChannelDataRLE(QIODevice &io, const quint8 *plane, const int channelSize, const QRect &rc, const qint64 sizeFieldOffset, const qint64 rleBlockOffset, const bool writeCompressionType, psd_byte_order byteOrder)

References convertMaskDeviceIfNeeded(), m_onlyTransparencyMask, m_onlyTransparencyMaskRect, m_transparencyMaskSizeOffset, KisBaseNode::paintDevice(), KisPaintDevice::pixelSize(), KisPaintDevice::readBytes(), and PsdPixelUtils::writeChannelDataRLE().

Member Data Documentation

◆ blendingRanges

LayerBlendingRanges PSDLayerRecord::blendingRanges

Definition at line 174 of file psd_layer_record.h.

◆ blendModeKey

QString PSDLayerRecord::blendModeKey

Definition at line 125 of file psd_layer_record.h.

◆ bottom

qint32 PSDLayerRecord::bottom {0}

Definition at line 118 of file psd_layer_record.h.

118{0};

◆ channelInfoRecords

QVector<ChannelInfo *> PSDLayerRecord::channelInfoRecords

Definition at line 123 of file psd_layer_record.h.

◆ clipping

quint8 PSDLayerRecord::clipping {0}

Definition at line 129 of file psd_layer_record.h.

129{0};

◆ error

QString PSDLayerRecord::error

Definition at line 114 of file psd_layer_record.h.

◆ fillConfig

QDomDocument PSDLayerRecord::fillConfig

Definition at line 138 of file psd_layer_record.h.

◆ fillType

psd_fill_type PSDLayerRecord::fillType {psd_fill_solid_color}

Definition at line 137 of file psd_layer_record.h.

@ psd_fill_solid_color
Definition psd.h:124

◆ infoBlocks

PsdAdditionalLayerInfoBlock PSDLayerRecord::infoBlocks

Definition at line 178 of file psd_layer_record.h.

◆ irrelevant

bool PSDLayerRecord::irrelevant {false}

Definition at line 132 of file psd_layer_record.h.

132{false};

◆ isPassThrough

bool PSDLayerRecord::isPassThrough {false}

Definition at line 126 of file psd_layer_record.h.

126{false};

◆ labelColor

int PSDLayerRecord::labelColor {0}

Definition at line 135 of file psd_layer_record.h.

135{0};

◆ layerMask

LayerMaskData PSDLayerRecord::layerMask

Definition at line 160 of file psd_layer_record.h.

◆ layerName

QString PSDLayerRecord::layerName {"UNINITIALIZED"}

Definition at line 176 of file psd_layer_record.h.

176{"UNINITIALIZED"}; // pascal, not unicode!

◆ left

qint32 PSDLayerRecord::left {0}

Definition at line 117 of file psd_layer_record.h.

117{0};

◆ m_header

const PSDHeader PSDLayerRecord::m_header
private

Definition at line 210 of file psd_layer_record.h.

◆ m_layerContentDevice

KisPaintDeviceSP PSDLayerRecord::m_layerContentDevice
private

Definition at line 205 of file psd_layer_record.h.

◆ m_onlyTransparencyMask

KisNodeSP PSDLayerRecord::m_onlyTransparencyMask
private

Definition at line 206 of file psd_layer_record.h.

◆ m_onlyTransparencyMaskRect

QRect PSDLayerRecord::m_onlyTransparencyMaskRect
private

Definition at line 207 of file psd_layer_record.h.

◆ m_transparencyMaskSizeOffset

qint64 PSDLayerRecord::m_transparencyMaskSizeOffset {0}
private

Definition at line 208 of file psd_layer_record.h.

208{0};

◆ nChannels

quint16 PSDLayerRecord::nChannels {0}

Definition at line 121 of file psd_layer_record.h.

121{0};

◆ opacity

quint8 PSDLayerRecord::opacity {0}

Definition at line 128 of file psd_layer_record.h.

128{0};

◆ right

qint32 PSDLayerRecord::right {0}

Definition at line 119 of file psd_layer_record.h.

119{0};

◆ textShape

psd_layer_type_shape PSDLayerRecord::textShape

Definition at line 141 of file psd_layer_record.h.

◆ top

qint32 PSDLayerRecord::top {0}

Definition at line 116 of file psd_layer_record.h.

116{0};

◆ transparencyProtected

bool PSDLayerRecord::transparencyProtected {false}

Definition at line 130 of file psd_layer_record.h.

130{false};

◆ userLocked

bool PSDLayerRecord::userLocked {false}

Definition at line 133 of file psd_layer_record.h.

133{false};

◆ vectorMask

psd_vector_mask PSDLayerRecord::vectorMask

Definition at line 140 of file psd_layer_record.h.

◆ vectorOriginationData

QDomDocument PSDLayerRecord::vectorOriginationData

Definition at line 143 of file psd_layer_record.h.

◆ vectorStroke

QDomDocument PSDLayerRecord::vectorStroke

Definition at line 142 of file psd_layer_record.h.

◆ visible

bool PSDLayerRecord::visible {true}

Definition at line 131 of file psd_layer_record.h.

131{true};

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