38{
39 dbgFile <<
"visiting on layer" << layer->
name() <<
"";
41
42 uint16_t color_type = 0;
43 uint16_t sample_format = SAMPLEFORMAT_UINT;
45
47 if (!destColorSpace) {
48 return false;
49 }
52 }
53
54 {
55
56
57
60 {
61 warnFile <<
"TIFF does not support exporting alpha channels with "
62 "YCbCr. Skipping...";
64 }
65 }
66
67
69 TIFFSetField(
image(), TIFFTAG_BITSPERSAMPLE, depth);
70
71 {
72
73
75 warnFile <<
"Attempt to export JPEG with multi-byte depth, "
76 "disabling compression";
78 }
79 }
80
81
84 const std::array<uint16_t, 1> sampleinfo = {EXTRASAMPLE_UNASSALPHA};
85 TIFFSetField(
image(), TIFFTAG_EXTRASAMPLES, 1, sampleinfo.data());
86 } else {
88 TIFFSetField(
image(), TIFFTAG_EXTRASAMPLES, 0);
89 }
90
91
92 TIFFSetField(
image(), TIFFTAG_PHOTOMETRIC, color_type);
93 TIFFSetField(
image(), TIFFTAG_SAMPLEFORMAT, sample_format);
96
97
104 TIFFSetField(
image(),
105 TIFFTAG_PIXARLOGQUALITY,
107 }
108
109
113
114
115 TIFFSetField(
image(), TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
116
117
118
119
120 if (color_type == PHOTOMETRIC_YCBCR) {
121 TIFFSetField(
image(), TIFFTAG_YCBCRSUBSAMPLING, 1, 1);
122 TIFFSetField(
image(), TIFFTAG_YCBCRPOSITIONING, YCBCRPOSITION_CENTERED);
124 TIFFSetField(
image(), TIFFTAG_JPEGCOLORMODE, JPEGCOLORMODE_RAW);
125 }
126 }
127
128
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
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
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);
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};
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 }();
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};
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};
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}
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
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)
#define KIS_SAFE_ASSERT_RECOVER(cond)
int depth(typename Forest< T >::const_child_iterator beginIt, typename Forest< T >::const_child_iterator endIt)
KisPaintDeviceSP projection() const override
KisMetaData::Store * metaData()
virtual QByteArray rawData() const
virtual QString type() const