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