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 #ifndef PSD_LAYER_RECORD_H 0008 #define PSD_LAYER_RECORD_H 0009 0010 #include "kritapsd_export.h" 0011 0012 #include <QBitArray> 0013 #include <QByteArray> 0014 #include <QString> 0015 #include <QVector> 0016 0017 #include <kis_node.h> 0018 #include <kis_paint_device.h> 0019 #include <kis_types.h> 0020 #include <psd.h> 0021 0022 #include "psd_additional_layer_info_block.h" 0023 #include "psd_header.h" 0024 0025 class QIODevice; 0026 0027 enum psd_layer_type { 0028 psd_layer_type_normal, 0029 psd_layer_type_hidden, 0030 psd_layer_type_folder, 0031 psd_layer_type_solid_color, 0032 psd_layer_type_gradient_fill, 0033 psd_layer_type_pattern_fill, 0034 psd_layer_type_levels, 0035 psd_layer_type_curves, 0036 psd_layer_type_brightness_contrast, 0037 psd_layer_type_color_balance, 0038 psd_layer_type_hue_saturation, 0039 psd_layer_type_selective_color, 0040 psd_layer_type_threshold, 0041 psd_layer_type_invert, 0042 psd_layer_type_posterize, 0043 psd_layer_type_channel_mixer, 0044 psd_layer_type_gradient_map, 0045 psd_layer_type_photo_filter, 0046 }; 0047 0048 struct KRITAPSD_EXPORT ChannelInfo { 0049 ChannelInfo() 0050 : channelId(0) 0051 , compressionType(psd_compression_type::Unknown) 0052 , channelDataStart(0) 0053 , channelDataLength(0) 0054 , channelOffset(0) 0055 , channelInfoPosition(0) 0056 { 0057 } 0058 0059 qint16 channelId; // 0 red, 1 green, 2 blue, -1 transparency, -2 user-supplied layer mask 0060 psd_compression_type compressionType; 0061 quint64 channelDataStart; 0062 quint64 channelDataLength; 0063 QVector<quint32> rleRowLengths; 0064 int channelOffset; // where the channel data starts 0065 int channelInfoPosition; // where the channelinfo record is saved in the file 0066 }; 0067 0068 class KRITAPSD_EXPORT PSDLayerRecord 0069 { 0070 public: 0071 PSDLayerRecord(const PSDHeader &header); 0072 0073 ~PSDLayerRecord() 0074 { 0075 qDeleteAll(channelInfoRecords); 0076 } 0077 0078 QRect channelRect(ChannelInfo *channel) const; 0079 0080 bool read(QIODevice &io); 0081 bool readPixelData(QIODevice &io, KisPaintDeviceSP device); 0082 bool readMask(QIODevice &io, KisPaintDeviceSP dev, ChannelInfo *channel); 0083 0084 void write(QIODevice &io, 0085 KisPaintDeviceSP layerContentDevice, 0086 KisNodeSP onlyTransparencyMask, 0087 const QRect &maskRect, 0088 psd_section_type sectionType, 0089 const QDomDocument &stylesXmlDoc, 0090 bool useLfxsLayerStyleFormat); 0091 void writePixelData(QIODevice &io, psd_compression_type compressionType); 0092 0093 bool valid(); 0094 0095 QString error; 0096 0097 qint32 top; 0098 qint32 left; 0099 qint32 bottom; 0100 qint32 right; 0101 0102 quint16 nChannels; 0103 0104 QVector<ChannelInfo *> channelInfoRecords; 0105 0106 QString blendModeKey; 0107 bool isPassThrough; 0108 0109 quint8 opacity; 0110 quint8 clipping; 0111 bool transparencyProtected; 0112 bool visible; 0113 bool irrelevant; 0114 0115 int labelColor; 0116 0117 psd_fill_type fillType {psd_fill_solid_color}; 0118 QDomDocument fillConfig; 0119 0120 struct LayerMaskData { 0121 qint32 top {0}; 0122 qint32 left {0}; 0123 qint32 bottom {0}; 0124 qint32 right {0}; 0125 quint8 defaultColor {255}; // 0 or 255 0126 bool positionedRelativeToLayer {false}; 0127 bool disabled {false}; 0128 bool invertLayerMaskWhenBlending {false}; 0129 quint8 userMaskDensity {0}; 0130 double userMaskFeather {0.0}; 0131 quint8 vectorMaskDensity {0}; 0132 double vectorMaskFeather {0.0}; 0133 }; 0134 0135 LayerMaskData layerMask; 0136 0137 struct LayerBlendingRanges { 0138 struct LayerBlendingRange { 0139 std::array<quint8, 2> blackValues; 0140 std::array<quint8, 2> whiteValues; 0141 }; 0142 0143 QByteArray data; 0144 0145 QPair<LayerBlendingRange, LayerBlendingRange> compositeGrayRange; 0146 QVector<QPair<LayerBlendingRange, LayerBlendingRange>> sourceDestinationRanges; 0147 }; 0148 0149 LayerBlendingRanges blendingRanges; 0150 0151 QString layerName; // pascal, not unicode! 0152 0153 PsdAdditionalLayerInfoBlock infoBlocks; 0154 0155 private: 0156 template<psd_byte_order byteOrder = psd_byte_order::psdBigEndian> 0157 bool readImpl(QIODevice &io); 0158 0159 template<psd_byte_order byteOrder = psd_byte_order::psdBigEndian> 0160 void writeImpl(QIODevice &io, 0161 KisPaintDeviceSP layerContentDevice, 0162 KisNodeSP onlyTransparencyMask, 0163 const QRect &maskRect, 0164 psd_section_type sectionType, 0165 const QDomDocument &stylesXmlDoc, 0166 bool useLfxsLayerStyleFormat); 0167 0168 template<psd_byte_order = psd_byte_order::psdBigEndian> 0169 void writeTransparencyMaskPixelData(QIODevice &io); 0170 0171 template<psd_byte_order = psd_byte_order::psdBigEndian> 0172 void writePixelDataImpl(QIODevice &io, psd_compression_type compressionType); 0173 0174 KisPaintDeviceSP convertMaskDeviceIfNeeded(KisPaintDeviceSP dev); 0175 0176 quint16 psdLabelColor(int colorLabelIndex); 0177 int kritaColorLabelIndex(quint16 labelColor); 0178 0179 private: 0180 KisPaintDeviceSP m_layerContentDevice; 0181 KisNodeSP m_onlyTransparencyMask; 0182 QRect m_onlyTransparencyMaskRect; 0183 qint64 m_transparencyMaskSizeOffset; 0184 0185 const PSDHeader m_header; 0186 }; 0187 0188 KRITAPSD_EXPORT QDebug operator<<(QDebug dbg, const PSDLayerRecord &layer); 0189 KRITAPSD_EXPORT QDebug operator<<(QDebug dbg, const ChannelInfo &layer); 0190 0191 inline QDebug operator<<(QDebug dbg, const PSDLayerRecord::LayerBlendingRanges::LayerBlendingRange &data) 0192 { 0193 return dbg << data.blackValues[0] << data.blackValues[1] << data.whiteValues[0] << data.whiteValues[1]; 0194 } 0195 0196 #endif // PSD_LAYER_RECORD_H