45 dbgFile <<
"Starting write of Photoshop layer data";
53 dbgFile <<
"This TIFF file is too big to be represented as a PSD blob!";
57 dbgFile <<
"Writing root layer projection";
60 uint16_t color_type = 0;
61 uint16_t sample_format = SAMPLEFORMAT_UINT;
65 if (!destColorSpace) {
80 warnFile <<
"TIFF does not support exporting alpha channels with "
88 TIFFSetField(
image(), TIFFTAG_BITSPERSAMPLE, depth);
94 warnFile <<
"Attempt to export JPEG with multi-byte depth, "
95 "disabling compression";
103 const std::array<uint16_t, 1> sampleinfo = {EXTRASAMPLE_UNASSALPHA};
104 TIFFSetField(
image(), TIFFTAG_EXTRASAMPLES, 1, sampleinfo.data());
107 TIFFSetField(
image(), TIFFTAG_EXTRASAMPLES, 0);
111 TIFFSetField(
image(), TIFFTAG_PHOTOMETRIC, color_type);
112 TIFFSetField(
image(), TIFFTAG_SAMPLEFORMAT, sample_format);
123 TIFFSetField(
image(),
124 TIFFTAG_PIXARLOGQUALITY,
134 TIFFSetField(
image(), TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
139 if (color_type == PHOTOMETRIC_YCBCR) {
140 TIFFSetField(
image(), TIFFTAG_YCBCRSUBSAMPLING, 1, 1);
141 TIFFSetField(
image(), TIFFTAG_YCBCRPOSITIONING, YCBCRPOSITION_CENTERED);
143 TIFFSetField(
image(), TIFFTAG_JPEGCOLORMODE, JPEGCOLORMODE_RAW);
150 if (profile && profile->
type() ==
"icc" && !profile->
rawData().isEmpty()) {
151 QByteArray ba = profile->
rawData();
152 TIFFSetField(
image(), TIFFTAG_ICCPROFILE, ba.size(), ba.constData());
155 tsize_t stripsize = TIFFStripSize(
image());
156 std::unique_ptr<std::remove_pointer_t<tdata_t>,
decltype(&_TIFFfree)> buff(
157 _TIFFmalloc(stripsize),
160 buff &&
"Unable to allocate buffer for TIFF!",
165 for (qint32 y = 0; y < height; y++) {
167 switch (color_type) {
168 case PHOTOMETRIC_MINISBLACK: {
169 const std::array<quint8, 5> poses = {0, 1};
177 case PHOTOMETRIC_RGB: {
178 const auto poses = [&]() -> std::array<quint8, 5> {
179 if (sample_format == SAMPLEFORMAT_IEEEFP) {
192 case PHOTOMETRIC_SEPARATED: {
193 const std::array<quint8, 5> poses = {0, 1, 2, 3, 4};
201 case PHOTOMETRIC_ICCLAB:
202 case PHOTOMETRIC_YCBCR: {
203 const std::array<quint8, 5> poses = {0, 1, 2, 3};
214 TIFFWriteScanline(
image(),
216 static_cast<quint32
>(y),
231 buf.open(QIODevice::WriteOnly);
237 TIFFIsBigEndian(
image()),
238 static_cast<uint32_t
>(width),
239 static_cast<uint32_t
>(height),
240 static_cast<uint16_t
>(depth),
246 dbgFile <<
"failed to write layer section. Error:" << layerSection.
record()->error << buf.pos();
251 dbgFile <<
"No layers, saving empty layers/mask block" << buf.pos();
256 buf.open(QIODevice::ReadOnly);
258 if (!TIFFSetField(
image(), TIFFTAG_IMAGESOURCEDATA,
static_cast<uint32_t
>(buf.size()), buf.data().constData())) {
259 dbgFile <<
"Failed to write the PSD image block to the TIFF field";
274 if (!annotation || annotation->type().isEmpty()) {
275 dbgFile <<
"Warning: empty annotation";
279 dbgFile <<
"Annotation:" << annotation->type() << annotation->description();
281 if (annotation->type().startsWith(QString(
"PSD Resource Block:"))) {
298 block->resource = resInfo;
308 block->resource = profileInfo;
312 dbgFile <<
"Resource section ready to write";
315 buf.open(QIODevice::WriteOnly);
317 if (!resourceSection.
write(buf)) {
318 dbgFile <<
"Failed to write resource section. Error:" << resourceSection.
error << buf.pos();
323 buf.open(QIODevice::WriteOnly);
325 if (!TIFFSetField(
image(), TIFFTAG_PHOTOSHOP,
static_cast<uint32_t
>(buf.size()), buf.data().data())) {
326 dbgFile <<
"Failed to write the PSD resource block to the TIFF field";
337 TIFFWriteDirectory(
image());