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

#include <kis_tiff_writer_visitor.h>

+ Inheritance diagram for KisTIFFWriterVisitor:

Public Member Functions

 KisTIFFWriterVisitor (TIFF *image, KisTIFFOptions *options)
 
bool visit (KisAdjustmentLayer *layer) override
 
virtual bool visit (KisAdjustmentLayer *layer)=0
 
bool visit (KisCloneLayer *layer) override
 
virtual bool visit (KisCloneLayer *layer)=0
 
bool visit (KisColorizeMask *) override
 
virtual bool visit (KisColorizeMask *mask)=0
 
bool visit (KisExternalLayer *layer) override
 
virtual bool visit (KisExternalLayer *layer)=0
 
bool visit (KisFilterMask *) override
 
virtual bool visit (KisFilterMask *mask)=0
 
bool visit (KisGeneratorLayer *layer) override
 
virtual bool visit (KisGeneratorLayer *layer)=0
 
bool visit (KisGroupLayer *layer) override
 
virtual bool visit (KisGroupLayer *layer)=0
 
bool visit (KisNode *) override
 
virtual bool visit (KisNode *node)=0
 
bool visit (KisPaintLayer *layer) override
 
virtual bool visit (KisPaintLayer *layer)=0
 
bool visit (KisSelectionMask *) override
 
virtual bool visit (KisSelectionMask *mask)=0
 
bool visit (KisTransformMask *) override
 
virtual bool visit (KisTransformMask *mask)=0
 
bool visit (KisTransparencyMask *) override
 
virtual bool visit (KisTransparencyMask *mask)=0
 
 ~KisTIFFWriterVisitor () override
 
- Public Member Functions inherited from KisNodeVisitor
 KisNodeVisitor ()
 
virtual ~KisNodeVisitor ()
 

Private Member Functions

bool saveLayerProjection (KisLayer *)
 

Additional Inherited Members

- Protected Member Functions inherited from KisNodeVisitor
bool visitAll (KisNode *node, bool breakOnFail=false)
 
bool visitAllInverse (KisNode *node, bool breakOnFail=false)
 
- Protected Member Functions inherited from KisTIFFBaseWriter
bool copyDataToStrips (KisHLineConstIteratorSP it, tdata_t buff, uint32_t depth, uint16_t sample_format, uint8_t nbcolorssamples, const std::array< quint8, 5 > &poses)
 
TIFF * image ()
 
 KisTIFFBaseWriter (TIFF *image, KisTIFFOptions *options)
 
 ~KisTIFFBaseWriter ()=default
 
- Static Protected Member Functions inherited from KisTIFFBaseWriter
static bool isBitDepthFloat (const KoID depth)
 
static bool writeColorSpaceInformation (TIFF *image, const KoColorSpace *cs, uint16_t &color_type, uint16_t &sample_format, const KoColorSpace *&destColorSpace)
 
- Protected Attributes inherited from KisTIFFBaseWriter
TIFF * m_image
 
KisTIFFOptionsm_options
 

Detailed Description

Author
Cyrille Berger cberg.nosp@m.er@c.nosp@m.berge.nosp@m.r.ne.nosp@m.t

Definition at line 36 of file kis_tiff_writer_visitor.h.

Constructor & Destructor Documentation

◆ KisTIFFWriterVisitor()

KisTIFFWriterVisitor::KisTIFFWriterVisitor ( TIFF * image,
KisTIFFOptions * options )

Definition at line 30 of file kis_tiff_writer_visitor.cpp.

31 : KisTIFFBaseWriter(image, options)
32{
33}
KisTIFFBaseWriter(TIFF *image, KisTIFFOptions *options)

◆ ~KisTIFFWriterVisitor()

KisTIFFWriterVisitor::~KisTIFFWriterVisitor ( )
overridedefault

Member Function Documentation

◆ saveLayerProjection()

bool KisTIFFWriterVisitor::saveLayerProjection ( KisLayer * layer)
private

Definition at line 37 of file kis_tiff_writer_visitor.cpp.

38{
39 dbgFile << "visiting on layer" << layer->name() << "";
40 KisPaintDeviceSP pd = layer->projection();
41
42 uint16_t color_type = 0;
43 uint16_t sample_format = SAMPLEFORMAT_UINT;
44 const KoColorSpace *destColorSpace = nullptr;
45 // Check colorspace
46 if (!writeColorSpaceInformation(image(), pd->colorSpace(), color_type, sample_format, destColorSpace)) { // unsupported colorspace
47 if (!destColorSpace) {
48 return false;
49 }
50 pd.attach(new KisPaintDevice(*pd));
51 pd->convertTo(destColorSpace);
52 }
53
54 {
55 // WORKAROUND: block any attempts to use YCbCr with alpha channels.
56 // This should not happen because alpha is disabled by default
57 // and the checkbox is blocked for YCbCr and CMYK.
58 KIS_SAFE_ASSERT_RECOVER(color_type != PHOTOMETRIC_YCBCR
59 || !m_options->alpha)
60 {
61 warnFile << "TIFF does not support exporting alpha channels with "
62 "YCbCr. Skipping...";
63 m_options->alpha = false;
64 }
65 }
66
67 // Save depth
68 uint32_t depth = 8 * pd->pixelSize() / pd->channelCount();
69 TIFFSetField(image(), TIFFTAG_BITSPERSAMPLE, depth);
70
71 {
72 // WORKAROUND: block any attempts to use JPEG with >= 8 bits
73
74 if (m_options->compressionType == COMPRESSION_JPEG && depth != 8) {
75 warnFile << "Attempt to export JPEG with multi-byte depth, "
76 "disabling compression";
77 m_options->compressionType = COMPRESSION_NONE;
78 }
79 }
80
81 // Save number of samples
82 if (m_options->alpha) {
83 TIFFSetField(image(), TIFFTAG_SAMPLESPERPIXEL, pd->channelCount());
84 const std::array<uint16_t, 1> sampleinfo = {EXTRASAMPLE_UNASSALPHA};
85 TIFFSetField(image(), TIFFTAG_EXTRASAMPLES, 1, sampleinfo.data());
86 } else {
87 TIFFSetField(image(), TIFFTAG_SAMPLESPERPIXEL, pd->channelCount() - 1);
88 TIFFSetField(image(), TIFFTAG_EXTRASAMPLES, 0);
89 }
90
91 // Save colorspace information
92 TIFFSetField(image(), TIFFTAG_PHOTOMETRIC, color_type);
93 TIFFSetField(image(), TIFFTAG_SAMPLEFORMAT, sample_format);
94 TIFFSetField(image(), TIFFTAG_IMAGEWIDTH, layer->image()->width());
95 TIFFSetField(image(), TIFFTAG_IMAGELENGTH, layer->image()->height());
96
97 // Set the compression options
98 TIFFSetField(image(), TIFFTAG_COMPRESSION, m_options->compressionType);
99 if (m_options->compressionType == COMPRESSION_JPEG) {
100 TIFFSetField(image(), TIFFTAG_JPEGQUALITY, m_options->jpegQuality);
101 } else if (m_options->compressionType == COMPRESSION_ADOBE_DEFLATE) {
102 TIFFSetField(image(), TIFFTAG_ZIPQUALITY, m_options->deflateCompress);
103 } else if (m_options->compressionType == COMPRESSION_PIXARLOG) {
104 TIFFSetField(image(),
105 TIFFTAG_PIXARLOGQUALITY,
107 }
108
109 // Set the predictor
110 if (m_options->compressionType == COMPRESSION_LZW
111 || m_options->compressionType == COMPRESSION_ADOBE_DEFLATE)
112 TIFFSetField(image(), TIFFTAG_PREDICTOR, m_options->predictor);
113
114 // Use contiguous configuration
115 TIFFSetField(image(), TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
116
117 // Do not set the rowsperstrip, as it's incompatible with JPEG
118
119 // But do set YCbCr 4:4:4 if applicable
120 if (color_type == PHOTOMETRIC_YCBCR) {
121 TIFFSetField(image(), TIFFTAG_YCBCRSUBSAMPLING, 1, 1);
122 TIFFSetField(image(), TIFFTAG_YCBCRPOSITIONING, YCBCRPOSITION_CENTERED);
123 if (m_options->compressionType == COMPRESSION_JPEG) {
124 TIFFSetField(image(), TIFFTAG_JPEGCOLORMODE, JPEGCOLORMODE_RAW);
125 }
126 }
127
128 // Save profile
129 if (m_options->saveProfile) {
130 const KoColorProfile* profile = pd->colorSpace()->profile();
131 if (profile && profile->type() == "icc" && !profile->rawData().isEmpty()) {
132 QByteArray ba = profile->rawData();
133 TIFFSetField(image(), TIFFTAG_ICCPROFILE, ba.size(), ba.constData());
134 }
135 }
136
137 {
138 // IPTC
141 QBuffer buf;
143
144 if (buf.size()
145 && !TIFFSetField(image(),
146 TIFFTAG_RICHTIFFIPTC,
147 static_cast<uint32_t>(buf.size()),
148 buf.data().data())) {
149 dbgFile << "Failed to write the IPTC metadata to the TIFF field";
150 }
151 }
152
153 {
154 // XMP
157 QBuffer buf;
159
160 if (buf.size()
161 && !TIFFSetField(image(),
162 TIFFTAG_XMLPACKET,
163 static_cast<uint32_t>(buf.size()),
164 buf.data().data())) {
165 dbgFile << "Failed to write the XMP metadata to the TIFF field";
166 }
167 }
168
169 tsize_t stripsize = TIFFStripSize(image());
170 std::unique_ptr<std::remove_pointer_t<tdata_t>, decltype(&_TIFFfree)> buff(
171 _TIFFmalloc(stripsize),
172 &_TIFFfree);
174 buff && "Unable to allocate buffer for TIFF!",
175 false);
176 qint32 height = layer->image()->height();
177 qint32 width = layer->image()->width();
178 bool r = true;
179 for (int y = 0; y < height; y++) {
181 switch (color_type) {
182 case PHOTOMETRIC_MINISBLACK: {
183 const std::array<quint8, 5> poses = {0, 1};
184 r = copyDataToStrips(it,
185 buff.get(),
186 depth,
187 sample_format,
188 1,
189 poses);
190 }
191 break;
192 case PHOTOMETRIC_RGB: {
193 const auto poses = [&]() -> std::array<quint8, 5> {
194 if (sample_format == SAMPLEFORMAT_IEEEFP) {
195 return {0, 1, 2, 3};
196 } else {
197 return {2, 1, 0, 3};
198 }
199 }();
200 r = copyDataToStrips(it,
201 buff.get(),
202 depth,
203 sample_format,
204 3,
205 poses);
206 }
207 break;
208 case PHOTOMETRIC_SEPARATED: {
209 const std::array<quint8, 5> poses = {0, 1, 2, 3, 4};
210 r = copyDataToStrips(it,
211 buff.get(),
212 depth,
213 sample_format,
214 4,
215 poses);
216 }
217 break;
218 case PHOTOMETRIC_ICCLAB:
219 case PHOTOMETRIC_YCBCR: {
220 const std::array<quint8, 5> poses = {0, 1, 2, 3};
221 r = copyDataToStrips(it,
222 buff.get(),
223 depth,
224 sample_format,
225 3,
226 poses);
227 } break;
228 }
229 if (!r) return false;
230 TIFFWriteScanline(image(),
231 buff.get(),
232 static_cast<uint32_t>(y),
233 (tsample_t)-1);
234 }
235 buff.reset();
236
237 return TIFFWriteDirectory(image());
238}
qint32 width() const
qint32 height() const
@ NoHeader
Don't append any header.
virtual bool saveTo(const Store *store, QIODevice *ioDevice, HeaderType headerType=NoHeader) const =0
static KisMetadataBackendRegistry * instance()
quint32 pixelSize() const
quint32 channelCount() const
const KoColorSpace * colorSpace() const
void convertTo(const KoColorSpace *dstColorSpace, KoColorConversionTransformation::Intent renderingIntent=KoColorConversionTransformation::internalRenderingIntent(), KoColorConversionTransformation::ConversionFlags conversionFlags=KoColorConversionTransformation::internalConversionFlags(), KUndo2Command *parentCommand=nullptr, KoUpdater *progressUpdater=nullptr)
KisHLineConstIteratorSP createHLineConstIteratorNG(qint32 x, qint32 y, qint32 w) const
void attach(T *p)
bool copyDataToStrips(KisHLineConstIteratorSP it, tdata_t buff, uint32_t depth, uint16_t sample_format, uint8_t nbcolorssamples, const std::array< quint8, 5 > &poses)
KisTIFFOptions * m_options
static bool writeColorSpaceInformation(TIFF *image, const KoColorSpace *cs, uint16_t &color_type, uint16_t &sample_format, const KoColorSpace *&destColorSpace)
virtual const KoColorProfile * profile() const =0
const T value(const QString &id) const
#define KIS_ASSERT_RECOVER_RETURN_VALUE(cond, val)
Definition kis_assert.h:85
#define KIS_SAFE_ASSERT_RECOVER(cond)
Definition kis_assert.h:126
#define warnFile
Definition kis_debug.h:95
#define dbgFile
Definition kis_debug.h:53
int depth(typename Forest< T >::const_child_iterator beginIt, typename Forest< T >::const_child_iterator endIt)
Definition KisForest.h:1213
KisImageWSP image
QString name() const
KisPaintDeviceSP projection() const override
Definition kis_layer.cc:820
KisMetaData::Store * metaData()
virtual QByteArray rawData() const
virtual QString type() const

References KisTIFFOptions::alpha, KisSharedPtr< T >::attach(), KisPaintDevice::channelCount(), KisPaintDevice::colorSpace(), KisTIFFOptions::compressionType, KisPaintDevice::convertTo(), KisTIFFBaseWriter::copyDataToStrips(), KisPaintDevice::createHLineConstIteratorNG(), dbgFile, KisTIFFOptions::deflateCompress, KisImage::height(), KisBaseNode::image, KisTIFFBaseWriter::image(), KisMetadataBackendRegistry::instance(), KisTIFFOptions::jpegQuality, KIS_ASSERT_RECOVER_RETURN_VALUE, KIS_SAFE_ASSERT_RECOVER, KisTIFFBaseWriter::m_options, KisLayer::metaData(), KisBaseNode::name(), KisMetaData::IOBackend::NoHeader, KisTIFFOptions::pixarLogCompress, KisPaintDevice::pixelSize(), KisTIFFOptions::predictor, KoColorSpace::profile(), KisLayer::projection(), KoColorProfile::rawData(), KisTIFFOptions::saveProfile, KisMetaData::IOBackend::saveTo(), KoColorProfile::type(), KoGenericRegistry< T >::value(), warnFile, KisImage::width(), and KisTIFFBaseWriter::writeColorSpaceInformation().

◆ visit() [1/24]

bool KisTIFFWriterVisitor::visit ( KisAdjustmentLayer * layer)
inlineoverridevirtual

Implements KisNodeVisitor.

Definition at line 72 of file kis_tiff_writer_visitor.h.

72 {
73 return saveLayerProjection(layer);
74 }

References saveLayerProjection().

◆ visit() [2/24]

virtual bool KisNodeVisitor::visit ( KisAdjustmentLayer * layer)
virtual

Implements KisNodeVisitor.

◆ visit() [3/24]

bool KisTIFFWriterVisitor::visit ( KisCloneLayer * layer)
inlineoverridevirtual

Implements KisNodeVisitor.

Definition at line 64 of file kis_tiff_writer_visitor.h.

64 {
65 return saveLayerProjection(layer);
66 }

References saveLayerProjection().

◆ visit() [4/24]

virtual bool KisNodeVisitor::visit ( KisCloneLayer * layer)
virtual

Implements KisNodeVisitor.

◆ visit() [5/24]

bool KisTIFFWriterVisitor::visit ( KisColorizeMask * )
inlineoverridevirtual

Implements KisNodeVisitor.

Definition at line 92 of file kis_tiff_writer_visitor.h.

92 {
93 return true;
94 }

◆ visit() [6/24]

virtual bool KisNodeVisitor::visit ( KisColorizeMask * mask)
virtual

Implements KisNodeVisitor.

◆ visit() [7/24]

bool KisTIFFWriterVisitor::visit ( KisExternalLayer * layer)
inlineoverridevirtual

Implements KisNodeVisitor.

Definition at line 68 of file kis_tiff_writer_visitor.h.

68 {
69 return saveLayerProjection(layer);
70 }

References saveLayerProjection().

◆ visit() [8/24]

virtual bool KisNodeVisitor::visit ( KisExternalLayer * layer)
virtual

Implements KisNodeVisitor.

◆ visit() [9/24]

bool KisTIFFWriterVisitor::visit ( KisFilterMask * )
inlineoverridevirtual

Implements KisNodeVisitor.

Definition at line 76 of file kis_tiff_writer_visitor.h.

76 {
77 return true;
78 }

◆ visit() [10/24]

virtual bool KisNodeVisitor::visit ( KisFilterMask * mask)
virtual

Implements KisNodeVisitor.

◆ visit() [11/24]

bool KisTIFFWriterVisitor::visit ( KisGeneratorLayer * layer)
inlineoverridevirtual

Implements KisNodeVisitor.

Definition at line 60 of file kis_tiff_writer_visitor.h.

60 {
61 return saveLayerProjection(layer);
62 }

References saveLayerProjection().

◆ visit() [12/24]

virtual bool KisNodeVisitor::visit ( KisGeneratorLayer * layer)
virtual

Implements KisNodeVisitor.

◆ visit() [13/24]

bool KisTIFFWriterVisitor::visit ( KisGroupLayer * layer)
inlineoverridevirtual

Implements KisNodeVisitor.

Definition at line 55 of file kis_tiff_writer_visitor.h.

55 {
56 dbgFile << "Visiting on grouplayer" << layer->name() << "";
57 return visitAll(layer, true);
58 }
bool visitAll(KisNode *node, bool breakOnFail=false)

References dbgFile, KisBaseNode::name(), and KisNodeVisitor::visitAll().

◆ visit() [14/24]

virtual bool KisNodeVisitor::visit ( KisGroupLayer * layer)
virtual

Implements KisNodeVisitor.

◆ visit() [15/24]

bool KisTIFFWriterVisitor::visit ( KisNode * )
inlineoverridevirtual

Implements KisNodeVisitor.

Definition at line 47 of file kis_tiff_writer_visitor.h.

47 {
48 return true;
49 }

◆ visit() [16/24]

virtual bool KisNodeVisitor::visit ( KisNode * node)
virtual

Implements KisNodeVisitor.

◆ visit() [17/24]

bool KisTIFFWriterVisitor::visit ( KisPaintLayer * layer)
inlineoverridevirtual

Implements KisNodeVisitor.

Definition at line 51 of file kis_tiff_writer_visitor.h.

51 {
52 return saveLayerProjection(layer);
53 }

References saveLayerProjection().

◆ visit() [18/24]

virtual bool KisNodeVisitor::visit ( KisPaintLayer * layer)
virtual

Implements KisNodeVisitor.

◆ visit() [19/24]

bool KisTIFFWriterVisitor::visit ( KisSelectionMask * )
inlineoverridevirtual

Implements KisNodeVisitor.

Definition at line 88 of file kis_tiff_writer_visitor.h.

88 {
89 return true;
90 }

◆ visit() [20/24]

virtual bool KisNodeVisitor::visit ( KisSelectionMask * mask)
virtual

Implements KisNodeVisitor.

◆ visit() [21/24]

bool KisTIFFWriterVisitor::visit ( KisTransformMask * )
inlineoverridevirtual

Implements KisNodeVisitor.

Definition at line 80 of file kis_tiff_writer_visitor.h.

80 {
81 return true;
82 }

◆ visit() [22/24]

virtual bool KisNodeVisitor::visit ( KisTransformMask * mask)
virtual

Implements KisNodeVisitor.

◆ visit() [23/24]

bool KisTIFFWriterVisitor::visit ( KisTransparencyMask * )
inlineoverridevirtual

Implements KisNodeVisitor.

Definition at line 84 of file kis_tiff_writer_visitor.h.

84 {
85 return true;
86 }

◆ visit() [24/24]

virtual bool KisNodeVisitor::visit ( KisTransparencyMask * mask)
virtual

Implements KisNodeVisitor.


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