1 /*
2 For general Scribus (>=1.3.2) copyright and licensing information please refer
3 to the COPYING file provided with the program. Following this notice may exist
4 a copyright and/or license notice that predates the release of Scribus 1.3.2
5 for which a new license (GPL+exception) is in place.
6 */
7 #include <QFile>
8 #include <QFileInfo>
9 #include <QObject>
10 #include <QList>
11
12 #include "scconfig.h"
13 #include "colormgmt/sccolormgmtengine.h"
14 #include "scimgdataloader_tiff.h"
15 #include "scribuscore.h"
16 #include "util_color.h"
17
TagExtender(TIFF * tiff)18 static void TagExtender(TIFF *tiff)
19 {
20 static const TIFFFieldInfo xtiffFieldInfo[] =
21 {
22 { 37724, -3, -3, TIFF_UNDEFINED, FIELD_CUSTOM, true, true, const_cast<char*>("PhotoshopLayerData") }
23 };
24 TIFFMergeFieldInfo(tiff, xtiffFieldInfo, sizeof (xtiffFieldInfo) / sizeof (xtiffFieldInfo[0]));
25 }
26
ScImgDataLoader_TIFF()27 ScImgDataLoader_TIFF::ScImgDataLoader_TIFF()
28 {
29 m_photometric = PHOTOMETRIC_MINISBLACK;
30 m_samplesperpixel = 72;
31
32 initSupportedFormatList();
33 }
34
initSupportedFormatList()35 void ScImgDataLoader_TIFF::initSupportedFormatList()
36 {
37 m_supportedFormats.clear();
38 m_supportedFormats.append( "tif" );
39 m_supportedFormats.append( "tiff" );
40 }
41
loadEmbeddedProfile(const QString & fn,int)42 void ScImgDataLoader_TIFF::loadEmbeddedProfile(const QString& fn, int /*page*/)
43 {
44 ScColorMgmtEngine engine(ScCore->defaultEngine);
45 m_embeddedProfile.resize(0);
46 m_profileComponents = 0;
47 if (!QFile::exists(fn))
48 return;
49 TIFFSetTagExtender(TagExtender);
50 TIFF* tif = TIFFOpen(fn.toLocal8Bit(), "r");
51 if (!tif)
52 return;
53
54 uint32 EmbedLen = 0;
55 void* EmbedBuffer;
56 if (TIFFGetField(tif, TIFFTAG_ICCPROFILE, &EmbedLen, &EmbedBuffer))
57 {
58 QByteArray profArray((const char*) EmbedBuffer, EmbedLen);
59 ScColorProfile tiffProf = engine.openProfileFromMem(profArray);
60 if (tiffProf)
61 {
62 if (tiffProf.colorSpace() == ColorSpace_Rgb)
63 m_profileComponents = 3;
64 if (tiffProf.colorSpace() == ColorSpace_Cmyk)
65 m_profileComponents = 4;
66 if (tiffProf.colorSpace() == ColorSpace_Gray)
67 m_profileComponents = 1;
68 m_embeddedProfile = profArray;
69 }
70 }
71 TIFFClose(tif);
72 }
73
preloadAlphaChannel(const QString & fn,int page,int res,bool & hasAlpha)74 bool ScImgDataLoader_TIFF::preloadAlphaChannel(const QString& fn, int page, int res, bool& hasAlpha)
75 {
76 bool success = true;
77 bool valid = m_imageInfoRecord.isRequest;
78 QMap<int, ImageLoadRequest> req = m_imageInfoRecord.RequestProps;
79 initialize();
80 m_imageInfoRecord.RequestProps = req;
81 m_imageInfoRecord.isRequest = valid;
82 if (!QFile::exists(fn))
83 return false;
84 hasAlpha = false;
85 if (testAlphaChannelAvailability(fn, page, hasAlpha))
86 {
87 if (!hasAlpha)
88 success = true;
89 else if (loadPicture(fn, page, res, false))
90 {
91 m_imageInfoRecord.valid = true;
92 hasAlpha = success = true;
93 /*if (photometric == PHOTOMETRIC_SEPARATED)
94 {
95 if (samplesperpixel == 4)
96 m_imageInfoRecord.valid = hasAlpha = false;
97 }
98 else
99 {
100 if (samplesperpixel == 3)
101 m_imageInfoRecord.valid = hasAlpha = false;
102 }
103 if (!hasAlpha) r_image.resize(0);*/
104 }
105 }
106 return success;
107 }
108
getLayers(const QString & fn,int)109 int ScImgDataLoader_TIFF::getLayers(const QString& fn, int /*page*/)
110 {
111 int layerNum = 1;
112 int test;
113 struct PSDLayer lay;
114 TIFFSetTagExtender(TagExtender);
115 TIFF* tif = TIFFOpen(fn.toLocal8Bit(), "r");
116 if (!tif)
117 return layerNum;
118
119 do
120 {
121 char *layerName = nullptr;
122 TIFFGetField(tif, TIFFTAG_PAGENAME, &layerName);
123 QString name = QString(layerName);
124 if (name.isEmpty())
125 lay.layerName = QString("Layer #%1").arg(layerNum);
126 else
127 lay.layerName = name;
128 lay.blend = "norm";
129 lay.opacity = 255;
130 lay.flags = 0;
131 m_imageInfoRecord.layerInfo.append(lay);
132 m_imageInfoRecord.valid = true;
133 layerNum++;
134 test = TIFFReadDirectory(tif);
135 }
136 while (test == 1);
137 TIFFClose(tif);
138
139 return layerNum;
140 }
141
testAlphaChannelAvailability(const QString & fn,int,bool & hasAlpha)142 bool ScImgDataLoader_TIFF::testAlphaChannelAvailability(const QString& fn, int /*page*/, bool& hasAlpha)
143 {
144 int test;
145
146 QByteArray byteOrder(2, ' ');
147 QFile fo(fn);
148 if (fo.open(QIODevice::ReadOnly))
149 {
150 fo.read(byteOrder.data(), 1);
151 fo.close();
152 }
153
154 TIFFSetTagExtender(TagExtender);
155 TIFF* tif = TIFFOpen(fn.toLocal8Bit(), "r");
156 if (!tif)
157 return false;
158
159 uint16 extrasamples, *extratypes;
160 hasAlpha = false;
161 do
162 {
163 if (TIFFGetField (tif, TIFFTAG_EXTRASAMPLES, &extrasamples, &extratypes) == 1)
164 {
165 for (int i = 0; i < extrasamples; ++i)
166 {
167 if (extratypes[i] != EXTRASAMPLE_UNSPECIFIED)
168 {
169 hasAlpha = true;
170 break;
171 }
172 }
173 }
174 test = TIFFReadDirectory(tif);
175 }
176 while (test == 1);
177
178 if (hasAlpha)
179 {
180 TIFFClose(tif);
181 return true;
182 }
183
184 unsigned int PhotoshopLen2 = 0;
185 unsigned char* PhotoshopBuffer2;
186 int gotField = TIFFGetField(tif, 37724, &PhotoshopLen2, &PhotoshopBuffer2);
187 if (gotField && (PhotoshopLen2 > 40))
188 {
189 m_imageInfoRecord.layerInfo.clear();
190 QByteArray arrayPhot = QByteArray::fromRawData((const char*)PhotoshopBuffer2, PhotoshopLen2);
191 QDataStream s(&arrayPhot, QIODevice::ReadOnly);
192 if (byteOrder[0] == 'M')
193 s.setByteOrder(QDataStream::BigEndian);
194 else
195 s.setByteOrder(QDataStream::LittleEndian);
196
197 QList<PSDLayer> layerInfo;
198 if (loadLayerInfo(s, layerInfo))
199 {
200 for (int layer = 0; layer < layerInfo.count(); ++layer)
201 {
202 const PSDLayer& psdLayer = layerInfo.at(layer);
203 uint channel_num = psdLayer.channelLen.count();
204 for (uint channel = 0; channel < channel_num; ++channel)
205 {
206 if (psdLayer.channelType[channel] == -1)
207 {
208 hasAlpha = true;
209 break;
210 }
211 }
212 if (hasAlpha) break;
213 }
214 }
215 }
216
217 TIFFClose(tif);
218 return true;
219 }
220
unmultiplyRGBA(RawImage * image)221 void ScImgDataLoader_TIFF::unmultiplyRGBA(RawImage *image)
222 {
223 double r1, g1, b1, coeff;
224 unsigned char r, g, b, a;
225 for (int i = 0; i < image->height(); ++i)
226 {
227 unsigned int *ptr = (QRgb *) image->scanLine(i);
228 for (int j = 0; j < image->width(); ++j)
229 {
230 r = qRed(*ptr);
231 g = qGreen(*ptr);
232 b = qBlue(*ptr);
233 a = qAlpha(*ptr);
234 if (a > 0 && a < 255)
235 {
236 coeff = 255.0 / a;
237 r1 = coeff * r;
238 g1 = coeff * g;
239 b1 = coeff * b;
240 r = (r1 <= 255.0) ? (unsigned char) r1 : 255;
241 g = (g1 <= 255.0) ? (unsigned char) g1 : 255;
242 b = (b1 <= 255.0) ? (unsigned char) b1 : 255;
243 *ptr++ = qRgba(r,g,b,a);
244 }
245 else
246 ++ptr;
247 }
248 }
249 }
250
getImageData(TIFF * tif,RawImage * image,uint widtht,uint heightt,uint size,uint16 photometric,uint16 bitspersample,uint16 samplesperpixel,bool & bilevel,bool & isCMYK)251 bool ScImgDataLoader_TIFF::getImageData(TIFF* tif, RawImage *image, uint widtht, uint heightt, uint size, uint16 photometric, uint16 bitspersample, uint16 samplesperpixel, bool &bilevel, bool &isCMYK)
252 {
253 uint32 *bits = nullptr;
254 if (photometric == PHOTOMETRIC_SEPARATED)
255 {
256 if (samplesperpixel > 5)
257 {
258 if (!getImageData_RGBA(tif, image, widtht, heightt, size, bitspersample, samplesperpixel))
259 return false;
260 if (bitspersample == 1)
261 bilevel = true;
262 isCMYK = false;
263 m_pixelFormat = Format_RGBA_8;
264 }
265 else
266 {
267 if (TIFFIsTiled(tif))
268 {
269 uint32 columns, rows;
270 uint32 *tile_buf;
271 uint32 xt, yt;
272 TIFFGetField(tif, TIFFTAG_TILEWIDTH, &columns);
273 TIFFGetField(tif, TIFFTAG_TILELENGTH, &rows);
274 tile_buf = (uint32*) _TIFFmalloc(columns*rows*sizeof(uint32));
275 if (tile_buf == nullptr)
276 {
277 TIFFClose(tif);
278 return false;
279 }
280 uint32 tileW = columns, tileH = rows;
281 for (yt = 0; yt < (uint32) image->height(); yt += rows)
282 {
283 if (yt > (uint) image->height())
284 break;
285 if (image->height()-yt < rows)
286 tileH = image->height()-yt;
287 tileW = columns;
288 uint32 yi;
289 int chans = image->channels();
290 for (xt = 0; xt < (uint) image->width(); xt += columns)
291 {
292 TIFFReadTile(tif, tile_buf, xt, yt, 0, 0);
293 for (yi = 0; yi < tileH; yi++)
294 {
295 _TIFFmemcpy(image->scanLine(yt+(tileH-1-yi))+xt, tile_buf+tileW*yi, tileW*chans);
296 }
297 }
298 }
299 _TIFFfree(tile_buf);
300 }
301 else
302 {
303 tsize_t bytesperrow = TIFFScanlineSize(tif);
304 bits = (uint32 *) _TIFFmalloc(bytesperrow);
305 int chans = image->channels();
306 if (bits)
307 {
308 for (unsigned int y = 0; y < heightt; y++)
309 {
310 if (TIFFReadScanline(tif, bits, y, 0))
311 {
312 /* The code below allows loading of CMYK TIFFs generated by ImageMagick,
313 currently commented out because its an ugly hack atm
314 When converting 8-bit PNGs with an alpha channel to CMYK Tiff, ImageMagick
315 creates a 16-bit CMYK Tiff !?!??
316 if (bitspersample > 8)
317 {
318 uchar *ptrT = image->scanLine(y);
319 uchar *ptrS = (uchar*)bits;
320 for (unsigned int x = 0; x < widtht; x++)
321 {
322 ptrT[0] = ptrS[1];
323 ptrT[1] = ptrS[3];
324 ptrT[2] = ptrS[5];
325 ptrT[3] = ptrS[7];
326 if (samplesperpixel > 4)
327 ptrT[4] = ptrS[9];
328 ptrT += chans;
329 ptrS += chans * 2;
330 }
331 }
332 else */
333 memcpy(image->scanLine(y), bits, chans * widtht);
334 }
335 }
336 _TIFFfree(bits);
337 }
338 }
339 isCMYK = true;
340 m_pixelFormat = (image->channels() == 5) ? Format_CMYKA_8 : Format_CMYK_8;
341 }
342 }
343 else
344 {
345 if (!getImageData_RGBA(tif, image, widtht, heightt, size, bitspersample, samplesperpixel))
346 return false;
347 if (bitspersample == 1)
348 bilevel = true;
349 m_pixelFormat = Format_RGBA_8;
350 }
351 return true;
352 }
353
getImageData_RGBA(TIFF * tif,RawImage * image,uint widtht,uint heightt,uint size,uint16 bitspersample,uint16 samplesperpixel)354 bool ScImgDataLoader_TIFF::getImageData_RGBA(TIFF* tif, RawImage *image, uint widtht, uint heightt, uint size, uint16 bitspersample, uint16 samplesperpixel)
355 {
356 uint32* bits = (uint32 *) _TIFFmalloc(size * sizeof(uint32));
357 if (!bits)
358 return false;
359
360 uint16 extrasamples(0), *extratypes(nullptr);
361 if (!TIFFGetField (tif, TIFFTAG_EXTRASAMPLES, &extrasamples, &extratypes))
362 extrasamples = 0;
363
364 bool gotData = false;
365 if (TIFFReadRGBAImage(tif, widtht, heightt, bits, 0))
366 {
367 for (unsigned int y = 0; y < heightt; y++)
368 {
369 memcpy(image->scanLine(heightt - 1 - y), bits + y * widtht, widtht * image->channels());
370 if (QSysInfo::ByteOrder == QSysInfo::BigEndian)
371 {
372 unsigned char *s = image->scanLine( heightt - 1 - y );
373 unsigned char r, g, b, a;
374 for (uint xi=0; xi < widtht; ++xi)
375 {
376 r = s[0];
377 g = s[1];
378 b = s[2];
379 a = s[3];
380 s[0] = a;
381 s[1] = b;
382 s[2] = g;
383 s[3] = r;
384 s += image->channels();
385 }
386 }
387 }
388 if (extrasamples > 0 && extratypes[0] == EXTRASAMPLE_ASSOCALPHA)
389 unmultiplyRGBA(image);
390 gotData = true;
391 }
392 _TIFFfree(bits);
393
394 return gotData;
395 }
396
blendOntoTarget(RawImage * tmp,int layOpa,const QString & layBlend,bool cmyk,bool useMask)397 void ScImgDataLoader_TIFF::blendOntoTarget(RawImage *tmp, int layOpa, const QString& layBlend, bool cmyk, bool useMask)
398 {
399 if (layBlend == "diss")
400 {
401 for (int l = 0; l < tmp->height(); l++)
402 {
403 srand(m_random_table[ l % 4096]);
404 for (int k = 0; k < tmp->width(); k++)
405 {
406 int rand_val = rand() & 0xff;
407 if (rand_val > layOpa)
408 tmp->setAlpha(k, l, 0);
409 }
410 }
411 }
412 int w = r_image.width();
413 int h = r_image.height();
414 for (int yi=0; yi < h; ++yi)
415 {
416 unsigned char *s = tmp->scanLine( yi );
417 unsigned char *d = r_image.scanLine( yi );
418 unsigned char r, g, b, src_r, src_g, src_b, src_a, src_alpha, dst_alpha;
419 unsigned char a = 0;
420 for (int xi=0; xi < w; ++xi)
421 {
422 src_r = s[0];
423 src_g = s[1];
424 src_b = s[2];
425 src_a = s[3];
426 if (r_image.channels() == 5)
427 {
428 dst_alpha = d[4];
429 if (useMask)
430 src_alpha = s[4];
431 else
432 src_alpha = 255;
433 }
434 else
435 {
436 if (cmyk)
437 {
438 dst_alpha = 255;
439 src_alpha = 255;
440 }
441 else
442 {
443 dst_alpha = d[3];
444 src_alpha = s[3];
445 }
446 }
447 if (layBlend != "diss")
448 src_alpha = INT_MULT(src_alpha, layOpa);
449 if ((dst_alpha > 0) && (src_alpha > 0))
450 {
451 if (layBlend == "mul ")
452 {
453 src_r = INT_MULT(src_r, d[0]);
454 src_g = INT_MULT(src_g, d[1]);
455 src_b = INT_MULT(src_b, d[2]);
456 if (cmyk)
457 src_a = INT_MULT(src_a, d[3]);
458 }
459 else if (layBlend == "scrn")
460 {
461 src_r = 255 - ((255-src_r) * (255-d[0]) / 128);
462 src_g = 255 - ((255-src_g) * (255-d[1]) / 128);
463 src_b = 255 - ((255-src_b) * (255-d[2]) / 128);
464 if (cmyk)
465 src_a = 255 - ((255-src_a) * (255-d[3]) / 128);
466 }
467 else if (layBlend == "over")
468 {
469 src_r = d[0] < 128 ? src_r * d[0] / 128 : 255 - ((255-src_r) * (255-d[0]) / 128);
470 src_g = d[1] < 128 ? src_g * d[1] / 128 : 255 - ((255-src_g) * (255-d[1]) / 128);
471 src_b = d[2] < 128 ? src_b * d[2] / 128 : 255 - ((255-src_b) * (255-d[2]) / 128);
472 if (cmyk)
473 src_a = d[3] < 128 ? src_a * d[3] / 128 : 255 - ((255-src_a) * (255-d[3]) / 128);
474 }
475 else if (layBlend == "diff")
476 {
477 src_r = d[0] > src_r ? d[0] - src_r : src_r - d[0];
478 src_g = d[1] > src_g ? d[1] - src_g : src_g - d[1];
479 src_b = d[2] > src_b ? d[2] - src_b : src_b - d[2];
480 if (cmyk)
481 src_a = d[3] > src_a ? d[3] - src_a : src_a - d[3];
482 }
483 else if (layBlend == "dark")
484 {
485 src_r = d[0] < src_r ? d[0] : src_r;
486 src_g = d[1] < src_g ? d[1] : src_g;
487 src_b = d[2] < src_b ? d[2] : src_b;
488 if (cmyk)
489 src_a = d[3] < src_a ? d[3] : src_a;
490 }
491 else if (layBlend == "hLit")
492 {
493 src_r = src_r < 128 ? src_r * d[0] / 128 : 255 - ((255-src_r) * (255-d[0]) / 128);
494 src_g = src_g < 128 ? src_g * d[1] / 128 : 255 - ((255-src_g) * (255-d[1]) / 128);
495 src_b = src_b < 128 ? src_b * d[2] / 128 : 255 - ((255-src_b) * (255-d[2]) / 128);
496 if (cmyk)
497 src_a = src_a < 128 ? src_a * d[3] / 128 : 255 - ((255-src_a) * (255-d[3]) / 128);
498 }
499 else if (layBlend == "sLit")
500 {
501 src_r = src_r * d[0] / 256 + src_r * (255 - ((255-src_r)*(255-d[0]) / 256) - src_r * d[0] / 256) / 256;
502 src_g = src_g * d[1] / 256 + src_g * (255 - ((255-src_g)*(255-d[1]) / 256) - src_g * d[1] / 256) / 256;
503 src_b = src_b * d[2] / 256 + src_b * (255 - ((255-src_b)*(255-d[2]) / 256) - src_b * d[2] / 256) / 256;
504 if (cmyk)
505 src_a = src_a * d[3] / 256 + src_a * (255 - ((255-src_a)*(255-d[3]) / 256) - src_a * d[3] / 256) / 256;
506 }
507 else if (layBlend == "lite")
508 {
509 src_r = d[0] < src_r ? src_r : d[0];
510 src_g = d[1] < src_g ? src_g : d[1];
511 src_b = d[2] < src_b ? src_b : d[2];
512 if (cmyk)
513 src_a = d[3] < src_a ? src_a : d[3];
514 }
515 else if (layBlend == "smud")
516 {
517 src_r = d[0] + src_r - src_r * d[0] / 128;
518 src_g = d[1] + src_g - src_g * d[1] / 128;
519 src_b = d[2] + src_b - src_b * d[2] / 128;
520 if (cmyk)
521 src_a = d[3] + src_a - src_a * d[3] / 128;
522 }
523 else if (layBlend == "div ")
524 {
525 src_r = src_r == 255 ? 255 : ((d[0] * 256) / (255-src_r)) > 255 ? 255 : (d[0] * 256) / (255-src_r);
526 src_g = src_g == 255 ? 255 : ((d[1] * 256) / (255-src_g)) > 255 ? 255 : (d[1] * 256) / (255-src_g);
527 src_b = src_b == 255 ? 255 : ((d[2] * 256) / (255-src_b)) > 255 ? 255 : (d[2] * 256) / (255-src_b);
528 if (cmyk)
529 src_a = src_a == 255 ? 255 : ((d[3] * 256) / (255-src_a)) > 255 ? 255 : (d[3] * 256) / (255-src_a);
530 }
531 else if (layBlend == "idiv")
532 {
533 src_r = src_r == 0 ? 0 : (255 - (((255-d[0]) * 256) / src_r)) < 0 ? 0 : 255 - (((255-d[0]) * 256) / src_r);
534 src_g = src_g == 0 ? 0 : (255 - (((255-d[1]) * 256) / src_g)) < 0 ? 0 : 255 - (((255-d[1]) * 256) / src_g);
535 src_b = src_b == 0 ? 0 : (255 - (((255-d[2]) * 256) / src_b)) < 0 ? 0 : 255 - (((255-d[2]) * 256) / src_b);
536 if (cmyk)
537 src_a = src_a == 0 ? 0 : (255 - (((255-d[3]) * 256) / src_a)) < 0 ? 0 : 255 - (((255-d[3]) * 256) / src_a);
538 }
539 else if (layBlend == "hue ")
540 {
541 if (!cmyk)
542 {
543 uchar new_r = d[0];
544 uchar new_g = d[1];
545 uchar new_b = d[2];
546 RGBTOHSV(src_r, src_g, src_b);
547 RGBTOHSV(new_r, new_g, new_b);
548 new_r = src_r;
549 HSVTORGB(new_r, new_g, new_b);
550 src_r = new_r;
551 src_g = new_g;
552 src_b = new_b;
553 }
554 }
555 else if (layBlend == "sat ")
556 {
557 if (!cmyk)
558 {
559 uchar new_r = d[0];
560 uchar new_g = d[1];
561 uchar new_b = d[2];
562 RGBTOHSV(src_r, src_g, src_b);
563 RGBTOHSV(new_r, new_g, new_b);
564 new_g = src_g;
565 HSVTORGB(new_r, new_g, new_b);
566 src_r = new_r;
567 src_g = new_g;
568 src_b = new_b;
569 }
570 }
571 else if (layBlend == "lum ")
572 {
573 if (!cmyk)
574 {
575 uchar new_r = d[0];
576 uchar new_g = d[1];
577 uchar new_b = d[2];
578 RGBTOHSV(src_r, src_g, src_b);
579 RGBTOHSV(new_r, new_g, new_b);
580 new_b = src_b;
581 HSVTORGB(new_r, new_g, new_b);
582 src_r = new_r;
583 src_g = new_g;
584 src_b = new_b;
585 }
586 }
587 else if (layBlend == "colr")
588 {
589 if (!cmyk)
590 {
591 uchar new_r = d[0];
592 uchar new_g = d[1];
593 uchar new_b = d[2];
594 RGBTOHLS(src_r, src_g, src_b);
595 RGBTOHLS(new_r, new_g, new_b);
596 new_r = src_r;
597 new_b = src_b;
598 HLSTORGB(new_r, new_g, new_b);
599 src_r = new_r;
600 src_g = new_g;
601 src_b = new_b;
602 }
603 }
604 }
605 if (dst_alpha == 0)
606 {
607 r = src_r;
608 g = src_g;
609 b = src_b;
610 a = src_a;
611 }
612 else
613 {
614 if (src_alpha > 0)
615 {
616 r = (d[0] * (255 - src_alpha) + src_r * src_alpha) / 255;
617 g = (d[1] * (255 - src_alpha) + src_g * src_alpha) / 255;
618 b = (d[2] * (255 - src_alpha) + src_b * src_alpha) / 255;
619 if (cmyk)
620 a = (d[3] * (255 - src_alpha) + src_a * src_alpha) / 255;
621 if (layBlend != "diss")
622 src_alpha = dst_alpha + INT_MULT(255 - dst_alpha, src_alpha);
623 }
624 }
625 if (src_alpha > 0)
626 {
627 d[0] = r;
628 d[1] = g;
629 d[2] = b;
630 if (r_image.channels() == 5)
631 {
632 d[3] = a;
633 d[4] = src_alpha;
634 }
635 else
636 {
637 if (cmyk)
638 d[3] = a;
639 else
640 d[3] = src_alpha;
641 }
642 }
643 d += r_image.channels();
644 s += tmp->channels();
645 }
646 }
647 }
648
loadPicture(const QString & fn,int page,int res,bool thumbnail)649 bool ScImgDataLoader_TIFF::loadPicture(const QString& fn, int page, int res, bool thumbnail)
650 {
651 ScColorMgmtEngine engine(ScCore->defaultEngine);
652 bool bilevel = false;
653 bool failedPS = false;
654 bool foundPS = false;
655 short resolutionunit = RESUNIT_INCH; // Default unit is inch
656 float xres = 72.0, yres = 72.0;
657 if (!QFile::exists(fn))
658 return false;
659 QByteArray byteOrder(2, ' ');
660 QFile fo(fn);
661 if (fo.open(QIODevice::ReadOnly))
662 {
663 fo.read(byteOrder.data(), 1);
664 fo.close();
665 }
666 srand(314159265);
667 for (int i = 0; i < 4096; i++)
668 m_random_table[i] = rand();
669 for (int i = 0; i < 4096; i++)
670 {
671 int tmp;
672 int swap = i + rand() % (4096 - i);
673 tmp = m_random_table[i];
674 m_random_table[i] = m_random_table[swap];
675 m_random_table[swap] = tmp;
676 }
677
678 initialize();
679
680 int test;
681 bool valid = m_imageInfoRecord.isRequest;
682 QMap<int, ImageLoadRequest> req = m_imageInfoRecord.RequestProps;
683 m_imageInfoRecord.RequestProps = req;
684 m_imageInfoRecord.isRequest = valid;
685 m_imageInfoRecord.type = ImageTypeTIF;
686 getLayers(fn, page);
687
688 TIFFSetTagExtender(TagExtender);
689 TIFF* tif = TIFFOpen(fn.toLocal8Bit(), "r");
690 if (!tif)
691 return false;
692
693 bool isCMYK = false;
694 unsigned int widtht, heightt, size;
695 char *description=nullptr, *copyright=nullptr, *datetime=nullptr, *artist=nullptr, *scannerMake=nullptr, *scannerModel=nullptr;
696 uint16 bitspersample, fillorder, planar;
697
698 TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &widtht);
699 TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &heightt);
700 TIFFGetField(tif, TIFFTAG_XRESOLUTION, &xres);
701 TIFFGetField(tif, TIFFTAG_YRESOLUTION, &yres);
702 TIFFGetField(tif, TIFFTAG_RESOLUTIONUNIT , &resolutionunit);
703 size = widtht * heightt;
704 TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &m_photometric);
705 TIFFGetField(tif, TIFFTAG_PLANARCONFIG, &planar);
706 TIFFGetField(tif, TIFFTAG_BITSPERSAMPLE, &bitspersample);
707 TIFFGetField(tif, TIFFTAG_SAMPLESPERPIXEL, &m_samplesperpixel);
708 TIFFGetField(tif, TIFFTAG_FILLORDER, &fillorder);
709
710 TIFFGetField(tif, TIFFTAG_MAKE, &scannerMake);
711 TIFFGetField(tif, TIFFTAG_MODEL, &scannerModel);
712 TIFFGetField(tif, TIFFTAG_IMAGEDESCRIPTION, &description);
713 TIFFGetField(tif, TIFFTAG_COPYRIGHT, ©right);
714 TIFFGetField(tif, TIFFTAG_DATETIME, &datetime);
715 TIFFGetField(tif, TIFFTAG_ARTIST, &artist);
716 m_imageInfoRecord.exifInfo.cameraName = QString(scannerModel);
717 m_imageInfoRecord.exifInfo.cameraVendor = QString(scannerMake);
718 m_imageInfoRecord.exifInfo.comment = QString(description);
719 m_imageInfoRecord.exifInfo.userComment = QString(copyright);
720 m_imageInfoRecord.exifInfo.width = widtht;
721 m_imageInfoRecord.exifInfo.height = heightt;
722 m_imageInfoRecord.exifInfo.dateTime = QString(datetime);
723 m_imageInfoRecord.exifInfo.artist = QString(artist);
724 m_imageInfoRecord.exifInfo.thumbnail = QImage();
725 m_imageInfoRecord.exifDataValid = true;
726 uint32 EmbedLen = 0;
727 void* EmbedBuffer;
728 if (TIFFGetField(tif, TIFFTAG_ICCPROFILE, &EmbedLen, &EmbedBuffer))
729 {
730 QByteArray profArray((const char*) EmbedBuffer, EmbedLen);
731 ScColorProfile tiffProf = engine.openProfileFromMem(profArray);
732 m_embeddedProfile = profArray;
733 m_imageInfoRecord.profileName = tiffProf.productDescription();
734 m_imageInfoRecord.embeddedProfileName = m_imageInfoRecord.profileName;
735 m_imageInfoRecord.isEmbedded = true;
736 }
737 else
738 {
739 m_imageInfoRecord.isEmbedded = false;
740 m_imageInfoRecord.profileName.clear();
741 m_imageInfoRecord.embeddedProfileName.clear();
742 }
743 unsigned int PhotoshopLen = 0;
744 unsigned char* PhotoshopBuffer;
745 if (TIFFGetField(tif, TIFFTAG_PHOTOSHOP, &PhotoshopLen, &PhotoshopBuffer) )
746 {
747 if (PhotoshopLen != 0)
748 {
749 QByteArray arrayPhot = QByteArray((const char*)PhotoshopBuffer,PhotoshopLen);
750 QDataStream strPhot(&arrayPhot,QIODevice::ReadOnly);
751 strPhot.setByteOrder( QDataStream::BigEndian );
752 PSDHeader fakeHeader;
753 fakeHeader.width = widtht;
754 fakeHeader.height = heightt;
755 parseResourceData(strPhot, fakeHeader, PhotoshopLen);
756 m_imageInfoRecord.exifInfo.width = widtht;
757 m_imageInfoRecord.exifInfo.height = heightt;
758 if (!m_imageInfoRecord.valid)
759 m_imageInfoRecord.valid = (m_imageInfoRecord.PDSpathData.size())>0;
760 if (thumbnail)
761 {
762 if (m_photometric == PHOTOMETRIC_SEPARATED)
763 {
764 isCMYK = true;
765 m_imageInfoRecord.colorspace = ColorSpaceCMYK;
766 }
767 else if (m_samplesperpixel == 1)
768 {
769 m_imageInfoRecord.colorspace = ColorSpaceGray;
770 isCMYK = false;
771 }
772 else
773 m_imageInfoRecord.colorspace = ColorSpaceRGB;
774 if (bitspersample == 1)
775 bilevel = true;
776 if (!m_imageInfoRecord.exifInfo.thumbnail.isNull())
777 {
778 if (isCMYK)
779 {
780 r_image.create(m_imageInfoRecord.exifInfo.thumbnail.width(), m_imageInfoRecord.exifInfo.thumbnail.height(), 5);
781 m_pixelFormat = Format_CMYKA_8;;
782 }
783 else
784 {
785 r_image.create(m_imageInfoRecord.exifInfo.thumbnail.width(), m_imageInfoRecord.exifInfo.thumbnail.height(), 4);
786 m_pixelFormat = (m_imageInfoRecord.colorspace == ColorSpaceCMYK) ? Format_CMYK_8 : Format_RGBA_8;
787 }
788 r_image.fill(0);
789 QRgb *s;
790 uchar *d;
791 unsigned char cc, cm, cy, ck;
792 for (int yit = 0; yit < m_imageInfoRecord.exifInfo.thumbnail.height(); ++yit)
793 {
794 s = (QRgb*)(m_imageInfoRecord.exifInfo.thumbnail.scanLine(yit));
795 d = r_image.scanLine(yit);
796 for (int xit = 0; xit < m_imageInfoRecord.exifInfo.thumbnail.width(); ++xit)
797 {
798 if (isCMYK)
799 {
800 cc = 255 - qRed(*s);
801 cm = 255 - qGreen(*s);
802 cy = 255 - qBlue(*s);
803 ck = qMin(qMin(cc, cm), cy);
804 d[0] = cc-ck;
805 d[1] = cm-ck;
806 d[2] = cy-ck;
807 d[3] = ck;
808 d[4] = 255;
809 }
810 else
811 {
812 d[0] = qRed(*s);
813 d[1] = qGreen(*s);
814 d[2] = qBlue(*s);
815 d[3] = 255;
816 }
817 s++;
818 d += r_image.channels();
819 }
820 }
821 TIFFClose(tif);
822 return true;
823 }
824 }
825 }
826 }
827
828 unsigned int PhotoshopLen2 = 0;
829 unsigned char* PhotoshopBuffer2;
830 int gotField = TIFFGetField(tif, 37724, &PhotoshopLen2, &PhotoshopBuffer2);
831 if (gotField && (PhotoshopLen2 > 40))
832 {
833 m_imageInfoRecord.layerInfo.clear();
834 QByteArray arrayPhot = QByteArray::fromRawData((const char*)PhotoshopBuffer2, PhotoshopLen2);
835 QDataStream s(&arrayPhot,QIODevice::ReadOnly);
836 if (byteOrder[0] == 'M')
837 s.setByteOrder( QDataStream::BigEndian );
838 else
839 s.setByteOrder( QDataStream::LittleEndian );
840
841 failedPS = !loadLayerInfo(s, m_imageInfoRecord.layerInfo);
842 if (!failedPS)
843 {
844 int chans = 4;
845 int numChannels = m_imageInfoRecord.layerInfo.last().channelType.count();
846 int numLayers = m_imageInfoRecord.layerInfo.count();
847 PSDHeader fakeHeader;
848 fakeHeader.width = widtht;
849 fakeHeader.height = heightt;
850 fakeHeader.channel_count = numChannels;
851 fakeHeader.depth = 8;
852 if (m_photometric == PHOTOMETRIC_SEPARATED)
853 {
854 isCMYK = true;
855 fakeHeader.color_mode = CM_CMYK;
856 chans = 5;
857 }
858 else if (m_samplesperpixel == 1)
859 {
860 fakeHeader.color_mode = CM_GRAYSCALE;
861 isCMYK = false;
862 chans = 4;
863 }
864 else
865 {
866 fakeHeader.color_mode = CM_RGB;
867 isCMYK = false;
868 chans = 4;
869 }
870 if (!r_image.create(widtht, heightt, chans))
871 return false;
872 r_image.fill(0);
873 bool firstLayer = true;
874 for (int layer = 0; layer < numLayers; layer++)
875 {
876 loadLayerChannels( s, fakeHeader, m_imageInfoRecord.layerInfo, layer, &firstLayer );
877 }
878 arrayPhot.clear();
879 TIFFClose(tif);
880 foundPS = true;
881 if (m_imageInfoRecord.layerInfo.count() == 1)
882 m_imageInfoRecord.layerInfo.clear();
883 }
884 else
885 {
886 arrayPhot.clear();
887 getLayers(fn, page);
888 }
889 }
890
891 if (xres <= 1.0 || yres <= 1.0)
892 {
893 xres = yres = 72.0;
894 QFileInfo qfi(fn);
895 m_message = QObject::tr("%1 may be corrupted : missing resolution tags").arg(qfi.fileName());
896 m_msgType = warningMsg;
897 }
898 if ((!foundPS) || (failedPS))
899 {
900 int chans = 4;
901 if (m_photometric == PHOTOMETRIC_SEPARATED)
902 {
903 if (m_samplesperpixel > 5)
904 chans = 4;
905 else
906 chans = m_samplesperpixel;
907 }
908 else
909 chans = 4;
910 if (!r_image.create(widtht, heightt, chans))
911 {
912 TIFFClose(tif);
913 return false;
914 }
915 r_image.fill(0);
916 int layerNum = 0;
917 do
918 {
919 RawImage tmpImg;
920 if (!tmpImg.create(widtht, heightt, chans))
921 {
922 TIFFClose(tif);
923 return false;
924 }
925
926 tmpImg.fill(0);
927 if (!getImageData(tif, &tmpImg, widtht, heightt, size, m_photometric, bitspersample, m_samplesperpixel, bilevel, isCMYK))
928 {
929 TIFFClose(tif);
930 return false;
931 }
932 bool visible = true;
933 bool useMask = true;
934 if ((m_imageInfoRecord.isRequest) && (m_imageInfoRecord.RequestProps.contains(layerNum)))
935 visible = m_imageInfoRecord.RequestProps[layerNum].visible;
936 QString layBlend("norm");
937 if ((m_imageInfoRecord.isRequest) && (m_imageInfoRecord.RequestProps.contains(layerNum)))
938 layBlend = m_imageInfoRecord.RequestProps[layerNum].blend;
939 if ((m_imageInfoRecord.isRequest) && (m_imageInfoRecord.RequestProps.contains(layerNum)))
940 useMask = m_imageInfoRecord.RequestProps[layerNum].useMask;
941 int layOpa = 255;
942 if ((m_imageInfoRecord.isRequest) && (m_imageInfoRecord.RequestProps.contains(layerNum)))
943 layOpa = m_imageInfoRecord.RequestProps[layerNum].opacity;
944 if (visible)
945 {
946 if ((layerNum == 0) && (layBlend != "diss"))
947 r_image = tmpImg;
948 else
949 blendOntoTarget(&tmpImg, layOpa, layBlend, isCMYK, useMask);
950 }
951 //JG Copy should not be necessary as QImage is implicitly shared in Qt4
952 QImage imt; //QImage imt = tmpImg.copy();
953 double sx = tmpImg.width() / 40.0;
954 double sy = tmpImg.height() / 40.0;
955 imt = tmpImg.convertToQImage(chans > 4);
956 imt = sy < sx ? imt.scaled(qRound(imt.width() / sx), qRound(imt.height() / sx), Qt::IgnoreAspectRatio, Qt::SmoothTransformation) :
957 imt.scaled(qRound(imt.width() / sy), qRound(imt.height() / sy), Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
958 m_imageInfoRecord.layerInfo[layerNum].thumb = imt.copy();
959 if (chans > 4)
960 {
961 QImage imt2 = imt.createAlphaMask();
962 imt2.invertPixels();
963 m_imageInfoRecord.layerInfo[layerNum].thumb_mask = imt2.copy();
964 }
965 else
966 m_imageInfoRecord.layerInfo[layerNum].thumb_mask = QImage();
967 layerNum++;
968
969 if ((m_imageInfoRecord.layerInfo.count() == 1) && (chans < 5))
970 m_imageInfoRecord.layerInfo.clear();
971 test = TIFFReadDirectory(tif);
972
973 // #10415 : check that image size for the current directory is the same as the main one
974 // Some progs use tiff directory to store previews, we do not handle such case
975 // and may perform reads in non allocated blocks if we continue
976 while (test == 1)
977 {
978 unsigned int dirWidth(0), dirHeight(0);
979 TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &dirWidth);
980 TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &dirHeight);
981 if (dirWidth == widtht && dirHeight == heightt)
982 break;
983 test = TIFFReadDirectory(tif);
984 layerNum++;
985 }
986 }
987 while (test == 1);
988 TIFFClose(tif);
989 }
990 if (resolutionunit == RESUNIT_INCH)
991 {
992 m_image.setDotsPerMeterX ((int) (xres / 0.0254));
993 m_image.setDotsPerMeterY ((int) (yres / 0.0254));
994 m_imageInfoRecord.xres = qRound(xres);
995 m_imageInfoRecord.yres = qRound(yres);
996 }
997 else if (resolutionunit == RESUNIT_CENTIMETER)
998 {
999 m_image.setDotsPerMeterX ((int) (xres * 100.0));
1000 m_image.setDotsPerMeterY ((int) (yres * 100.0));
1001 m_imageInfoRecord.xres = qRound(xres*2.54);
1002 m_imageInfoRecord.yres = qRound(yres*2.54);
1003 }
1004 if (isCMYK)
1005 {
1006 m_imageInfoRecord.colorspace = ColorSpaceCMYK;
1007 m_pixelFormat = (r_image.channels() == 5) ? Format_CMYKA_8 : Format_CMYK_8;
1008 }
1009 else if (m_samplesperpixel == 1)
1010 {
1011 // Do not set m_pixelFormat here as the real pixel format is most probably different than gray
1012 if (bitspersample == 1)
1013 m_imageInfoRecord.colorspace = ColorSpaceMonochrome;
1014 else
1015 m_imageInfoRecord.colorspace = ColorSpaceGray;
1016 }
1017 else
1018 {
1019 m_imageInfoRecord.colorspace = ColorSpaceRGB;
1020 m_pixelFormat = Format_RGBA_8;
1021 }
1022 m_imageInfoRecord.BBoxX = 0;
1023 m_imageInfoRecord.BBoxH = r_image.height();
1024 m_imageInfoRecord.valid = !(m_imageInfoRecord.layerInfo.isEmpty() && m_imageInfoRecord.PDSpathData.isEmpty());
1025 return true;
1026 }
1027
getLayerString(QDataStream & s)1028 QString ScImgDataLoader_TIFF::getLayerString(QDataStream & s)
1029 {
1030 uchar len, tmp;
1031 uint adj;
1032 QString ret = "";
1033 s >> len;
1034 if (len == 0)
1035 {
1036 s >> tmp;
1037 s >> tmp;
1038 s >> tmp;
1039 return ret;
1040 }
1041 for (int i = 0; i < len; i++)
1042 {
1043 s >> tmp;
1044 ret += QChar(tmp);
1045 }
1046 adj = 0;
1047 if (((ret.length()+1) % 4) != 0)
1048 adj = 4 - ((ret.length()+1) % 4);
1049 s.device()->seek( s.device()->pos() + adj );
1050 return ret;
1051 }
1052
loadChannel(QDataStream & s,const PSDHeader & header,QList<PSDLayer> & layerInfo,uint layer,int channel,int component,RawImage & tmpImg)1053 bool ScImgDataLoader_TIFF::loadChannel( QDataStream & s, const PSDHeader & header, QList<PSDLayer> &layerInfo, uint layer, int channel, int component, RawImage &tmpImg)
1054 {
1055 uint base = s.device()->pos();
1056 uchar cbyte;
1057 ushort compression;
1058 s >> compression;
1059 if (compression > 1)
1060 return false;
1061 if (compression == 0)
1062 {
1063 int count = layerInfo[layer].channelLen[channel]-2;
1064 for (int i = 0; i < tmpImg.height(); i++)
1065 {
1066 uchar *ptr = tmpImg.scanLine(i);
1067 for (int j = 0; j < tmpImg.width(); j++)
1068 {
1069 s >> cbyte;
1070 count--;
1071 if ((header.color_mode == CM_CMYK) && (component < 4))
1072 cbyte = 255 - cbyte;
1073 if ((header.color_mode == CM_GRAYSCALE) && (component != 3))
1074 {
1075 ptr[0] = cbyte;
1076 ptr[1] = cbyte;
1077 ptr[2] = cbyte;
1078 }
1079 else
1080 ptr[component] = cbyte;
1081 if (count == 0)
1082 break;
1083 ptr += tmpImg.channels();
1084 }
1085 if (count == 0)
1086 break;
1087 }
1088 }
1089 else
1090 {
1091 s.device()->seek( s.device()->pos() + tmpImg.height() * 2 );
1092 uint pixel_count = tmpImg.width();
1093 for (int hh = 0; hh < tmpImg.height(); hh++)
1094 {
1095 uint count = 0;
1096 uchar *ptr = tmpImg.scanLine(hh);
1097 uchar *ptr2 = ptr+tmpImg.width() * tmpImg.channels();
1098 ptr += component;
1099 while (count < pixel_count)
1100 {
1101 uchar c;
1102 if (s.atEnd())
1103 return false;
1104 s >> c;
1105 uint len = c;
1106 if (len < 128)
1107 {
1108 // Copy next len+1 bytes literally.
1109 len++;
1110 count += len;
1111 while (len != 0)
1112 {
1113 s >> cbyte;
1114 if (ptr < ptr2)
1115 {
1116 if ((header.color_mode == CM_CMYK) && (component < 4))
1117 cbyte = 255 - cbyte;
1118 if ((header.color_mode == CM_GRAYSCALE) && (component != 3))
1119 {
1120 ptr -= component;
1121 ptr[0] = cbyte;
1122 ptr[1] = cbyte;
1123 ptr[2] = cbyte;
1124 ptr += component;
1125 }
1126 else
1127 *ptr = cbyte;
1128 }
1129 ptr += tmpImg.channels();
1130 len--;
1131 }
1132 }
1133 else if (len > 128)
1134 {
1135 // Next -len+1 bytes in the dest are replicated from next source byte.
1136 // (Interpret len as a negative 8-bit int.)
1137 len ^= 0xFF;
1138 len += 2;
1139 count += len;
1140 uchar val;
1141 s >> val;
1142 if ((header.color_mode == CM_CMYK) && (component < 4))
1143 val = 255 - val;
1144 while (len != 0)
1145 {
1146 if (ptr < ptr2)
1147 {
1148 if ((header.color_mode == CM_GRAYSCALE) && (component != 3))
1149 {
1150 ptr -= component;
1151 ptr[0] = val;
1152 ptr[1] = val;
1153 ptr[2] = val;
1154 ptr += component;
1155 }
1156 else
1157 *ptr = val;
1158 }
1159 ptr += tmpImg.channels();
1160 len--;
1161 }
1162 }
1163 else if (len == 128)
1164 {
1165 // No-op.
1166 }
1167 }
1168 }
1169 }
1170 s.device()->seek( base+layerInfo[layer].channelLen[channel] );
1171 return true;
1172 }
1173
loadLayerInfo(QDataStream & s,QList<PSDLayer> & layerInfo)1174 bool ScImgDataLoader_TIFF::loadLayerInfo(QDataStream & s, QList<PSDLayer> &layerInfo)
1175 {
1176 bool failedPS = false;
1177 uint addRes, layerinfo, channelLen, signature, extradata, layermasksize, layerRange, dummy;
1178 int top, left, bottom, right;
1179 short numLayers, numChannels;
1180 short channelType;
1181 uchar blendKey[4];
1182 uchar opacity, clipping, flags, filler;
1183 QString blend;
1184
1185 layerInfo.clear();
1186
1187 struct PSDLayer lay;
1188 do
1189 {
1190 if (s.atEnd())
1191 {
1192 layerInfo.clear();
1193 failedPS = true;
1194 break;
1195 }
1196 s >> signature;
1197 }
1198 while (signature != 0x4c617972);
1199
1200 if (failedPS)
1201 return false;
1202
1203 s >> layerinfo;
1204 s >> numLayers;
1205 if (numLayers < 0)
1206 numLayers = -numLayers;
1207 if (numLayers == 0)
1208 return true;
1209
1210 QDataStream::ByteOrder byteOrder = s.byteOrder();
1211
1212 for (int layer = 0; layer < numLayers; layer++)
1213 {
1214 s >> top;
1215 lay.ypos = top;
1216 s >> left;
1217 lay.xpos = left;
1218 s >> bottom;
1219 lay.height = bottom - top;
1220 s >> right;
1221 lay.width = right - left;
1222 s >> numChannels;
1223 if (numChannels > 6) // we don't support images with more than 6 channels yet
1224 {
1225 m_imageInfoRecord.layerInfo.clear();
1226 failedPS = true;
1227 break;
1228 }
1229 lay.channelType.clear();
1230 lay.channelLen.clear();
1231 for (int channels = 0; channels < numChannels; channels++)
1232 {
1233 s >> channelType;
1234 s >> channelLen;
1235 lay.channelType.append(channelType);
1236 lay.channelLen.append(channelLen);
1237 }
1238 s >> signature;
1239 blend = "";
1240 for (int i = 0; i < 4; i++)
1241 {
1242 s >> blendKey[i];
1243 if (byteOrder == QDataStream::BigEndian)
1244 blend.append(QChar(blendKey[i]));
1245 else
1246 blend.prepend(QChar(blendKey[i]));
1247 }
1248 lay.blend = blend;
1249 s >> opacity;
1250 lay.opacity = opacity;
1251 s >> clipping;
1252 lay.clipping = clipping;
1253 s >> flags;
1254 if (flags & 8)
1255 {
1256 if (flags & 16) // Unknown combination of layer flags, probably an adjustment or effects layer
1257 {
1258 layerInfo.clear();
1259 failedPS = true;
1260 break;
1261 }
1262 }
1263 lay.flags = flags;
1264 s >> filler;
1265 s >> extradata;
1266 s >> layermasksize;
1267 lay.maskYpos = 0;
1268 lay.maskXpos = 0;
1269 lay.maskHeight = 0;
1270 lay.maskWidth = 0;
1271 if (layermasksize != 0)
1272 {
1273 s >> lay.maskYpos;
1274 s >> lay.maskXpos;
1275 s >> dummy;
1276 lay.maskHeight = dummy - lay.maskYpos;
1277 s >> dummy;
1278 lay.maskWidth = dummy - lay.maskXpos;
1279 s >> dummy;
1280 }
1281 s >> layerRange;
1282 s.device()->seek( s.device()->pos() + layerRange );
1283 lay.layerName = getLayerString(s);
1284 layerInfo.append(lay);
1285 s >> signature;
1286 if (signature == 0x3842494D)
1287 {
1288 while (signature == 0x3842494D)
1289 {
1290 s >> signature;
1291 s >> addRes;
1292 s.device()->seek( s.device()->pos() + addRes );
1293 s >> signature;
1294 }
1295 s.device()->seek( s.device()->pos() - 4 );
1296 }
1297 else
1298 {
1299 s.device()->seek( s.device()->pos() - 2 );
1300 s >> signature;
1301 if (signature == 0x3842494D)
1302 {
1303 while (signature == 0x3842494D)
1304 {
1305 s >> signature;
1306 s >> addRes;
1307 s.device()->seek( s.device()->pos() + addRes );
1308 s >> signature;
1309 }
1310 s.device()->seek( s.device()->pos() - 4 );
1311 }
1312 else
1313 s.device()->seek( s.device()->pos() - 6 );
1314 }
1315 }
1316
1317 return (!failedPS && (layerInfo.count() >= 0));
1318 }
1319
loadLayerChannels(QDataStream & s,const PSDHeader & header,QList<PSDLayer> & layerInfo,uint layer,bool * firstLayer)1320 bool ScImgDataLoader_TIFF::loadLayerChannels( QDataStream & s, const PSDHeader & header, QList<PSDLayer> &layerInfo, uint layer, bool* firstLayer)
1321 {
1322 // Find out if the data is compressed.
1323 // Known values:
1324 // 0: no compression
1325 // 1: RLE compressed
1326 uint base = s.device()->pos();
1327 uint base2 = base;
1328 uint channel_num = layerInfo[layer].channelLen.count();
1329 bool hasMask = false;
1330 bool hasAlpha = false;
1331 RawImage r2_image;
1332 RawImage mask;
1333 bool createOk = false;
1334 if (header.color_mode == CM_CMYK)
1335 {
1336 createOk = r2_image.create(layerInfo[layer].width, layerInfo[layer].height, qMax(channel_num, (uint) 5));
1337 r2_image.fill(0);
1338 }
1339 else
1340 {
1341 createOk = r2_image.create(layerInfo[layer].width, layerInfo[layer].height, qMax(channel_num, (uint) 4));
1342 r2_image.fill(0);
1343 }
1344 if (!createOk)
1345 {
1346 for (uint channel = 0; channel < channel_num; channel++)
1347 {
1348 base2 += layerInfo[layer].channelLen[channel];
1349 }
1350 s.device()->seek( base2 );
1351 return false;
1352 }
1353 channel_num = qMin(channel_num, (uint) 39);
1354 uint components[40] = {0};
1355 for (uint channel = 0; channel < channel_num; channel++)
1356 {
1357 switch (layerInfo[layer].channelType[channel])
1358 {
1359 case 0:
1360 components[channel] = 0;
1361 break;
1362 case 1:
1363 components[channel] = 1;
1364 break;
1365 case 2:
1366 components[channel] = 2;
1367 break;
1368 case 3:
1369 components[channel] = 3;
1370 break;
1371 case -1:
1372 if (header.color_mode == CM_CMYK)
1373 {
1374 if (channel_num == 6)
1375 components[channel] = channel_num - 2;
1376 else
1377 components[channel] = channel_num - 1;
1378 }
1379 else
1380 {
1381 if (channel_num == 5)
1382 components[channel] = channel_num - 2;
1383 else
1384 {
1385 if (header.color_mode == CM_GRAYSCALE)
1386 components[channel] = 3;
1387 else
1388 components[channel] = channel_num - 1;
1389 }
1390 }
1391 hasAlpha = true;
1392 break;
1393 case -2:
1394 components[channel] = channel_num-1;
1395 break;
1396 }
1397 }
1398 if (!hasAlpha)
1399 r2_image.fill((char) 255);
1400 for (uint channel = 0; channel < channel_num; channel++)
1401 {
1402 if (layerInfo[layer].channelType[channel] == -2)
1403 {
1404 if (!mask.create( layerInfo[layer].maskWidth, layerInfo[layer].maskHeight, 1))
1405 break;
1406 mask.fill(0);
1407 if (!loadChannel(s, header, layerInfo, layer, channel, 0, mask))
1408 break;
1409 hasMask = true;
1410 }
1411 if (!loadChannel(s, header, layerInfo, layer, channel, components[channel], r2_image))
1412 break;
1413 }
1414 for (uint channel = 0; channel < channel_num; channel++)
1415 {
1416 base2 += layerInfo[layer].channelLen[channel];
1417 }
1418 s.device()->seek( base2 );
1419 QImage tmpImg2;
1420 if (header.color_mode == CM_CMYK)
1421 tmpImg2 = r2_image.convertToQImage(true);
1422 else
1423 tmpImg2 = r2_image.convertToQImage(false);
1424 QImage imt;
1425 double sx = tmpImg2.width() / 40.0;
1426 double sy = tmpImg2.height() / 40.0;
1427 imt = sy < sx ? tmpImg2.scaled(qRound(tmpImg2.width() / sx), qRound(tmpImg2.height() / sx), Qt::IgnoreAspectRatio, Qt::SmoothTransformation) :
1428 tmpImg2.scaled(qRound(tmpImg2.width() / sy), qRound(tmpImg2.height() / sy), Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
1429 layerInfo[layer].thumb = imt.copy();
1430 if (hasMask)
1431 {
1432 QImage imt2;
1433 QImage tmpImg;
1434 tmpImg = mask.convertToQImage(true);
1435 double sx = tmpImg.width() / 40.0;
1436 double sy = tmpImg.height() / 40.0;
1437 imt2 = sy < sx ? tmpImg.scaled(qRound(tmpImg.width() / sx), qRound(tmpImg.height() / sx), Qt::IgnoreAspectRatio, Qt::SmoothTransformation) :
1438 tmpImg.scaled(qRound(tmpImg.width() / sy), qRound(tmpImg.height() / sy), Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
1439 imt2.invertPixels();
1440 layerInfo[layer].thumb_mask = imt2.copy();
1441 }
1442 else
1443 layerInfo[layer].thumb_mask = QImage();
1444 if (!m_imageInfoRecord.isRequest || !m_imageInfoRecord.RequestProps.contains(layer))
1445 m_imageInfoRecord.RequestProps[layer].useMask = true;
1446 bool visible = !(layerInfo[layer].flags & 2);
1447 if ((m_imageInfoRecord.isRequest) && (m_imageInfoRecord.RequestProps.contains(layer)))
1448 visible = m_imageInfoRecord.RequestProps[layer].visible;
1449 if (visible)
1450 {
1451 unsigned int startSrcY, startSrcX, startDstY, startDstX;
1452 if (layerInfo[layer].ypos < 0)
1453 {
1454 startSrcY = abs(layerInfo[layer].ypos);
1455 startDstY = 0;
1456 }
1457 else
1458 {
1459 startSrcY = 0;
1460 startDstY = layerInfo[layer].ypos;
1461 }
1462 if (layerInfo[layer].xpos < 0)
1463 {
1464 startSrcX = abs(layerInfo[layer].xpos);
1465 startDstX = 0;
1466 }
1467 else
1468 {
1469 startSrcX = 0;
1470 startDstX = layerInfo[layer].xpos;
1471 }
1472 unsigned int startSrcXm; //, startSrcYm, startDstYm, startDstXm;
1473 /* if (layerInfo[layer].maskYpos < 0)
1474 {
1475 startSrcYm = abs(layerInfo[layer].maskYpos);
1476 startDstYm = 0;
1477 }
1478 else
1479 {
1480 startSrcYm = 0;
1481 startDstYm = layerInfo[layer].maskYpos;
1482 }*/
1483 if (layerInfo[layer].maskXpos < 0)
1484 {
1485 startSrcXm = abs(layerInfo[layer].maskXpos);
1486 // startDstXm = 0;
1487 }
1488 else
1489 {
1490 startSrcXm = 0;
1491 // startDstXm = layerInfo[layer].maskXpos;
1492 }
1493 QString layBlend2 = layerInfo[layer].blend;
1494 if ((m_imageInfoRecord.isRequest) && (m_imageInfoRecord.RequestProps.contains(layer)))
1495 layBlend2 = m_imageInfoRecord.RequestProps[layer].blend;
1496 if (layBlend2 == "diss")
1497 {
1498 hasAlpha = true;
1499 int layOpa = layerInfo[layer].opacity;
1500 if ((m_imageInfoRecord.isRequest) && (m_imageInfoRecord.RequestProps.contains(layer)))
1501 layOpa = m_imageInfoRecord.RequestProps[layer].opacity;
1502 for (int l = 0; l < r2_image.height(); l++)
1503 {
1504 srand(m_random_table[ l % 4096]);
1505 for (int k = 0; k < r2_image.width(); k++)
1506 {
1507 int rand_val = rand() & 0xff;
1508 if (rand_val > layOpa)
1509 r2_image.setAlpha(k, l, 0);
1510 }
1511 }
1512 }
1513 if (*firstLayer)
1514 {
1515 for (int yi=static_cast<int>(startSrcY); yi < qMin(r2_image.height(), r_image.height()); ++yi)
1516 {
1517 unsigned char *s = r2_image.scanLine( yi );
1518 unsigned char *d = r_image.scanLine( qMin(static_cast<int>(startDstY), r_image.height()-1) );
1519 d += qMin(static_cast<int>(startDstX), r_image.width()-1) * r_image.channels();
1520 s += qMin(static_cast<int>(startSrcX), r2_image.width()-1) * r2_image.channels();
1521 for (int xi=static_cast<int>(startSrcX); xi < qMin(r2_image.width(), r_image.width()); ++xi )
1522 {
1523 d[0] = s[0];
1524 d[1] = s[1];
1525 d[2] = s[2];
1526 if (header.color_mode == CM_RGB)
1527 {
1528 if (hasAlpha)
1529 d[3] = s[3];
1530 else
1531 d[3] = 255;
1532 }
1533 else
1534 {
1535 d[3] = s[3];
1536 if (hasAlpha)
1537 d[4] = s[4];
1538 else
1539 d[4] = 255;
1540 }
1541 s += r2_image.channels();
1542 d += r_image.channels();
1543 }
1544 startDstY++;
1545 }
1546 }
1547 else
1548 {
1549 for (int i = static_cast<int>(startSrcY); i < layerInfo[layer].height; i++)
1550 {
1551 unsigned char *d = r_image.scanLine(qMin(static_cast<int>(startDstY), r_image.height()-1));
1552 unsigned char *s = r2_image.scanLine(qMin(i, r2_image.height()-1));
1553 d += qMin(static_cast<int>(startDstX), r_image.width()-1) * r_image.channels();
1554 s += qMin(static_cast<int>(startSrcX), r2_image.width()-1) * r2_image.channels();
1555 unsigned char *sm = nullptr;
1556 if (hasMask)
1557 {
1558 sm = mask.scanLine(qMin(i, mask.height()-1));
1559 sm += qMin(static_cast<int>(startSrcXm), mask.width()-1) * mask.channels();
1560 }
1561 startDstY++;
1562 unsigned char r, g, b, src_r, src_g, src_b, src_a, src_alpha, dst_alpha;
1563 unsigned char a = 0;
1564 unsigned int maxDestX = r_image.width() - startDstX + startSrcX - 1;
1565 for (unsigned int j = startSrcX; j < qMin(maxDestX, static_cast<unsigned int>(layerInfo[layer].width)); j++)
1566 {
1567 src_r = s[0];
1568 src_g = s[1];
1569 src_b = s[2];
1570 src_a = s[3];
1571 if (hasAlpha)
1572 {
1573 if (hasMask)
1574 {
1575 if (m_imageInfoRecord.RequestProps[layer].useMask)
1576 src_alpha = sm[0];
1577 else
1578 src_alpha = s[channel_num - 2];
1579 }
1580 else
1581 src_alpha = s[channel_num - 1];
1582 }
1583 else
1584 src_alpha = 255;
1585 if ((hasMask) && (m_imageInfoRecord.RequestProps[layer].useMask))
1586 src_alpha = sm[0];
1587 int layOpa = layerInfo[layer].opacity;
1588 if ((m_imageInfoRecord.isRequest) && (m_imageInfoRecord.RequestProps.contains(layer)))
1589 layOpa = m_imageInfoRecord.RequestProps[layer].opacity;
1590 QString layBlend = layerInfo[layer].blend;
1591 if ((m_imageInfoRecord.isRequest) && (m_imageInfoRecord.RequestProps.contains(layer)))
1592 layBlend = m_imageInfoRecord.RequestProps[layer].blend;
1593 if (layBlend != "diss")
1594 src_alpha = INT_MULT(src_alpha, layOpa);
1595 if (header.color_mode == CM_CMYK)
1596 dst_alpha = d[4];
1597 else
1598 dst_alpha = d[3];
1599 if ((dst_alpha > 0) && (src_alpha > 0))
1600 {
1601 if (layBlend == "mul ")
1602 {
1603 src_r = INT_MULT(src_r, d[0]);
1604 src_g = INT_MULT(src_g, d[1]);
1605 src_b = INT_MULT(src_b, d[2]);
1606 if (header.color_mode == CM_CMYK)
1607 src_a = INT_MULT(src_a, d[3]);
1608 }
1609 else if (layBlend == "scrn")
1610 {
1611 src_r = 255 - ((255-src_r) * (255-d[0]) / 128);
1612 src_g = 255 - ((255-src_g) * (255-d[1]) / 128);
1613 src_b = 255 - ((255-src_b) * (255-d[2]) / 128);
1614 if (header.color_mode == CM_CMYK)
1615 src_a = 255 - ((255-src_a) * (255-d[3]) / 128);
1616 }
1617 else if (layBlend == "over")
1618 {
1619 src_g = d[1] < 128 ? src_g * d[1] / 128 : 255 - ((255-src_g) * (255-d[1]) / 128);
1620 src_b = d[2] < 128 ? src_b * d[2] / 128 : 255 - ((255-src_b) * (255-d[2]) / 128);
1621 src_a = d[3] < 128 ? src_a * d[3] / 128 : 255 - ((255-src_a) * (255-d[3]) / 128);
1622 if (header.color_mode == CM_CMYK)
1623 src_r = d[0] < 128 ? src_r * d[0] / 128 : 255 - ((255-src_r) * (255-d[0]) / 128);
1624 }
1625 else if (layBlend == "diff")
1626 {
1627 src_r = d[0] > src_r ? d[0] - src_r : src_r - d[0];
1628 src_g = d[1] > src_g ? d[1] - src_g : src_g - d[1];
1629 src_b = d[2] > src_b ? d[2] - src_b : src_b - d[2];
1630 if (header.color_mode == CM_CMYK)
1631 src_a = d[3] > src_a ? d[3] - src_a : src_a - d[3];
1632 }
1633 else if (layBlend == "dark")
1634 {
1635 src_r = d[0] < src_r ? d[0] : src_r;
1636 src_g = d[1] < src_g ? d[1] : src_g;
1637 src_b = d[2] < src_b ? d[2] : src_b;
1638 if (header.color_mode == CM_CMYK)
1639 src_a = d[3] < src_a ? d[3] : src_a;
1640 }
1641 else if (layBlend == "hLit")
1642 {
1643 src_r = src_r < 128 ? src_r * d[0] / 128 : 255 - ((255-src_r) * (255-d[0]) / 128);
1644 src_g = src_g < 128 ? src_g * d[1] / 128 : 255 - ((255-src_g) * (255-d[1]) / 128);
1645 src_b = src_b < 128 ? src_b * d[2] / 128 : 255 - ((255-src_b) * (255-d[2]) / 128);
1646 if (header.color_mode == CM_CMYK)
1647 src_a = src_a < 128 ? src_a * d[3] / 128 : 255 - ((255-src_a) * (255-d[3]) / 128);
1648 }
1649 else if (layBlend == "sLit")
1650 {
1651 src_r = src_r * d[0] / 256 + src_r * (255 - ((255-src_r)*(255-d[0]) / 256) - src_r * d[0] / 256) / 256;
1652 src_g = src_g * d[1] / 256 + src_g * (255 - ((255-src_g)*(255-d[1]) / 256) - src_g * d[1] / 256) / 256;
1653 src_b = src_b * d[2] / 256 + src_b * (255 - ((255-src_b)*(255-d[2]) / 256) - src_b * d[2] / 256) / 256;
1654 if (header.color_mode == CM_CMYK)
1655 src_a = src_a * d[3] / 256 + src_a * (255 - ((255-src_a)*(255-d[3]) / 256) - src_a * d[3] / 256) / 256;
1656 }
1657 else if (layBlend == "lite")
1658 {
1659 src_r = d[0] < src_r ? src_r : d[0];
1660 src_g = d[1] < src_g ? src_g : d[1];
1661 src_b = d[2] < src_b ? src_b : d[2];
1662 if (header.color_mode == CM_CMYK)
1663 src_a = d[3] < src_a ? src_a : d[3];
1664 }
1665 else if (layBlend == "smud")
1666 {
1667 src_r = d[0] + src_r - src_r * d[0] / 128;
1668 src_g = d[1] + src_g - src_g * d[1] / 128;
1669 src_b = d[2] + src_b - src_b * d[2] / 128;
1670 if (header.color_mode == CM_CMYK)
1671 src_a = d[3] + src_a - src_a * d[3] / 128;
1672 }
1673 else if (layBlend == "div ")
1674 {
1675 src_r = src_r == 255 ? 255 : ((d[0] * 256) / (255-src_r)) > 255 ? 255 : (d[0] * 256) / (255-src_r);
1676 src_g = src_g == 255 ? 255 : ((d[1] * 256) / (255-src_g)) > 255 ? 255 : (d[1] * 256) / (255-src_g);
1677 src_b = src_b == 255 ? 255 : ((d[2] * 256) / (255-src_b)) > 255 ? 255 : (d[2] * 256) / (255-src_b);
1678 if (header.color_mode == CM_CMYK)
1679 src_a = src_a == 255 ? 255 : ((d[3] * 256) / (255-src_a)) > 255 ? 255 : (d[3] * 256) / (255-src_a);
1680 }
1681 else if (layBlend == "idiv")
1682 {
1683 src_r = src_r == 0 ? 0 : (255 - (((255-d[0]) * 256) / src_r)) < 0 ? 0 : 255 - (((255-d[0]) * 256) / src_r);
1684 src_g = src_g == 0 ? 0 : (255 - (((255-d[1]) * 256) / src_g)) < 0 ? 0 : 255 - (((255-d[1]) * 256) / src_g);
1685 src_b = src_b == 0 ? 0 : (255 - (((255-d[2]) * 256) / src_b)) < 0 ? 0 : 255 - (((255-d[2]) * 256) / src_b);
1686 if (header.color_mode == CM_CMYK)
1687 src_a = src_a == 0 ? 0 : (255 - (((255-d[3]) * 256) / src_a)) < 0 ? 0 : 255 - (((255-d[3]) * 256) / src_a);
1688 }
1689 else if (layBlend == "hue ")
1690 {
1691 if (header.color_mode != CM_CMYK)
1692 {
1693 uchar new_r = d[0];
1694 uchar new_g = d[1];
1695 uchar new_b = d[2];
1696 RGBTOHSV(src_r, src_g, src_b);
1697 RGBTOHSV(new_r, new_g, new_b);
1698 new_r = src_r;
1699 HSVTORGB(new_r, new_g, new_b);
1700 src_r = new_r;
1701 src_g = new_g;
1702 src_b = new_b;
1703 }
1704 }
1705 else if (layBlend == "sat ")
1706 {
1707 if (header.color_mode != CM_CMYK)
1708 {
1709 uchar new_r = d[0];
1710 uchar new_g = d[1];
1711 uchar new_b = d[2];
1712 RGBTOHSV(src_r, src_g, src_b);
1713 RGBTOHSV(new_r, new_g, new_b);
1714 new_g = src_g;
1715 HSVTORGB(new_r, new_g, new_b);
1716 src_r = new_r;
1717 src_g = new_g;
1718 src_b = new_b;
1719 }
1720 }
1721 else if (layBlend == "lum ")
1722 {
1723 if (header.color_mode != CM_CMYK)
1724 {
1725 uchar new_r = d[0];
1726 uchar new_g = d[1];
1727 uchar new_b = d[2];
1728 RGBTOHSV(src_r, src_g, src_b);
1729 RGBTOHSV(new_r, new_g, new_b);
1730 new_b = src_b;
1731 HSVTORGB(new_r, new_g, new_b);
1732 src_r = new_r;
1733 src_g = new_g;
1734 src_b = new_b;
1735 }
1736 }
1737 else if (layBlend == "colr")
1738 {
1739 if (header.color_mode != CM_CMYK)
1740 {
1741 uchar new_r = d[0];
1742 uchar new_g = d[1];
1743 uchar new_b = d[2];
1744 RGBTOHLS(src_r, src_g, src_b);
1745 RGBTOHLS(new_r, new_g, new_b);
1746 new_r = src_r;
1747 new_b = src_b;
1748 HLSTORGB(new_r, new_g, new_b);
1749 src_r = new_r;
1750 src_g = new_g;
1751 src_b = new_b;
1752 }
1753 }
1754 }
1755 if (dst_alpha == 0)
1756 {
1757 r = src_r;
1758 g = src_g;
1759 b = src_b;
1760 a = src_a;
1761 }
1762 else
1763 {
1764 if (src_alpha > 0)
1765 {
1766 r = (d[0] * (255 - src_alpha) + src_r * src_alpha) / 255;
1767 g = (d[1] * (255 - src_alpha) + src_g * src_alpha) / 255;
1768 b = (d[2] * (255 - src_alpha) + src_b * src_alpha) / 255;
1769 if (header.color_mode == CM_CMYK)
1770 a = (d[3] * (255 - src_alpha) + src_a * src_alpha) / 255;
1771 if (layBlend != "diss")
1772 src_alpha = dst_alpha + INT_MULT(255 - dst_alpha, src_alpha);
1773 }
1774 }
1775 if (src_alpha > 0)
1776 {
1777 d[0] = r;
1778 d[1] = g;
1779 d[2] = b;
1780 if (header.color_mode == CM_CMYK)
1781 {
1782 d[3] = a;
1783 d[4] = src_alpha;
1784 }
1785 else
1786 d[3] = src_alpha;
1787 }
1788 s += r2_image.channels();
1789 d += r_image.channels();
1790 if (hasMask)
1791 sm += mask.channels();
1792 }
1793 }
1794 }
1795 }
1796 *firstLayer = false;
1797 return true;
1798 }
1799