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 "scconfig.h"
8 #include "colormgmt/sccolormgmtengine.h"
9 #include "scimgdataloader_psd.h"
10 #include "util_color.h"
11 #include "sccolorengine.h"
12 #include "scribuscore.h"
13 
14 #include <QFile>
15 #include <QFileInfo>
16 #include <QList>
17 
operator >>(QDataStream & s,PSDHeader & header)18 static QDataStream & operator>> ( QDataStream & s, PSDHeader & header )
19 {
20 	s >> header.signature;
21 	s >> header.version;
22 	for (int i = 0; i < 6; i++)
23 	{
24 		s >> header.reserved[i];
25 	}
26 	s >> header.channel_count;
27 	s >> header.height;
28 	s >> header.width;
29 	s >> header.depth;
30 	s >> header.color_mode;
31 	return s;
32 }
33 
ScImgDataLoader_PSD()34 ScImgDataLoader_PSD::ScImgDataLoader_PSD()
35 {
36 	m_maxChannels = 0;
37 	initSupportedFormatList();
38 }
39 
initSupportedFormatList()40 void ScImgDataLoader_PSD::initSupportedFormatList()
41 {
42 	m_supportedFormats.clear();
43 	m_supportedFormats.append( "psd" );
44 }
45 
loadEmbeddedProfile(const QString & fn,int)46 void ScImgDataLoader_PSD::loadEmbeddedProfile(const QString& fn, int /*page*/)
47 {
48 	m_embeddedProfile.resize(0);
49 	m_profileComponents = 0;
50 
51 	ScColorProfile prof;
52 	ScColorMgmtEngine engine(ScCore->defaultEngine);
53 	QFileInfo fi = QFileInfo(fn);
54 	if (!fi.exists())
55 		return;
56 
57 	QString ext = fi.suffix().toLower();
58 	if (ext != "psd")
59 		return;
60 
61 	QFile f(fn);
62 	if (!f.open(QIODevice::ReadOnly))
63 		return;
64 
65 	m_imageInfoRecord.xres = 72;
66 	m_imageInfoRecord.yres = 72;
67 	QDataStream s( &f );
68 	s.setByteOrder( QDataStream::BigEndian );
69 	PSDHeader header;
70 	s >> header;
71 	// Check image file format.
72 	if (s.atEnd() || !IsValid(header))
73 		return;
74 	// Check if it's a supported format.
75 	if (!IsSupported(header))
76 		return;
77 	if (!LoadPSDResources(s, header, s.device()->pos()))
78 		return;
79 	if (m_embeddedProfile.size() > 0)
80 	{
81 		prof = engine.openProfileFromMem(m_embeddedProfile.data());
82 		if (prof)
83 		{
84 			if (prof.colorSpace() == ColorSpace_Rgb)
85 				m_profileComponents = 3;
86 			if (prof.colorSpace() == ColorSpace_Cmyk)
87 				m_profileComponents = 4;
88 			if (prof.colorSpace() == ColorSpace_Gray)
89 				m_profileComponents = 1;
90 		}
91 	}
92 	f.close();
93 }
94 
preloadAlphaChannel(const QString & fn,int,int res,bool & hasAlpha)95 bool ScImgDataLoader_PSD::preloadAlphaChannel(const QString& fn, int /*page*/, int res, bool& hasAlpha)
96 {
97 	bool valid = m_imageInfoRecord.isRequest;
98 	QMap<int, ImageLoadRequest> req = m_imageInfoRecord.RequestProps;
99 	initialize();
100 	hasAlpha = false;
101 	m_imageInfoRecord.RequestProps = req;
102 	m_imageInfoRecord.isRequest = valid;
103 	QFileInfo fi = QFileInfo(fn);
104 	if (!fi.exists())
105 		return false;
106 
107 	QFile f(fn);
108 	if (f.open(QIODevice::ReadOnly))
109 	{
110 		QDataStream s( &f );
111 		s.setByteOrder( QDataStream::BigEndian );
112 		PSDHeader header;
113 		s >> header;
114 		// Check image file format.
115 		if (s.atEnd() || !IsValid(header))
116 			return false;
117 		// Check if it's a supported format.
118 		if (!IsSupported(header))
119 			return false;
120 		if (!LoadPSD(s, header))
121 			r_image.resize(0);
122 		f.close();
123 		m_imageInfoRecord.valid = true;
124 		if (header.color_mode == CM_CMYK)
125 			m_imageInfoRecord.valid = hasAlpha = (m_maxChannels > 4);
126 		else if (header.color_mode == CM_GRAYSCALE)
127 			m_imageInfoRecord.valid = hasAlpha = (m_maxChannels > 1);
128 		else
129 			m_imageInfoRecord.valid = hasAlpha = (m_maxChannels >= 4);
130 		return true;
131 	}
132 	return false;
133 }
134 
loadPicture(const QString & fn,int,int res,bool thumbnail)135 bool ScImgDataLoader_PSD::loadPicture(const QString& fn, int /*page*/, int res, bool thumbnail)
136 {
137 	ScColorMgmtEngine engine(ScCore->defaultEngine);
138 	bool isCMYK = false;
139 	if (!QFile::exists(fn))
140 		return false;
141 	bool valid = m_imageInfoRecord.isRequest;
142 	QMap<int, ImageLoadRequest> req = m_imageInfoRecord.RequestProps;
143 	initialize();
144 	m_imageInfoRecord.RequestProps = req;
145 	m_imageInfoRecord.isRequest = valid;
146 	m_imageInfoRecord.type = ImageTypePSD;
147 	m_imageInfoRecord.exifDataValid = false;
148 	m_imageInfoRecord.layerInfo.clear();
149 	m_imageInfoRecord.PDSpathData.clear();
150 	QFile f(fn);
151 	if (f.open(QIODevice::ReadOnly))
152 	{
153 		m_imageInfoRecord.xres = 72;
154 		m_imageInfoRecord.yres = 72;
155 		QDataStream s( &f );
156 		s.setByteOrder( QDataStream::BigEndian );
157 		PSDHeader header;
158 		s >> header;
159 		// Check image file format.
160 		if (s.atEnd() || !IsValid(header))
161 			return false;
162 		// Check if it's a supported format.
163 		if (!IsSupported(header))
164 			return false;
165 		if (thumbnail)
166 			header.reserved[0] = 't';
167 		if (!LoadPSD(s, header))
168 			return false;
169 		if (m_embeddedProfile.size() > 0)
170 		{
171 			ScColorProfile prof = engine.openProfileFromMem(m_embeddedProfile);
172 			m_imageInfoRecord.profileName = prof.productDescription();
173 			m_imageInfoRecord.embeddedProfileName = m_imageInfoRecord.profileName;
174 			m_imageInfoRecord.isEmbedded = true;
175 		}
176 		isCMYK = (header.color_mode == CM_CMYK);
177 		if (header.color_mode == CM_CMYK)
178 			m_imageInfoRecord.colorspace = ColorSpaceCMYK;
179 		else if (header.color_mode == CM_RGB)
180 			m_imageInfoRecord.colorspace = ColorSpaceRGB;
181 		else if (header.color_mode == CM_GRAYSCALE)
182 			m_imageInfoRecord.colorspace = ColorSpaceGray;
183 		else if (header.color_mode == CM_DUOTONE)
184 			m_imageInfoRecord.colorspace = ColorSpaceDuotone;
185 		f.close();
186 		if (thumbnail)
187 		{
188 			if (!m_imageInfoRecord.exifInfo.thumbnail.isNull())
189 			{
190 				if (isCMYK)
191 				{
192 					r_image.create(m_imageInfoRecord.exifInfo.thumbnail.width(), m_imageInfoRecord.exifInfo.thumbnail.height(), 5);
193 					m_pixelFormat = Format_CMYKA_8;
194 				}
195 				else
196 				{
197 					r_image.create(m_imageInfoRecord.exifInfo.thumbnail.width(), m_imageInfoRecord.exifInfo.thumbnail.height(), 4);
198 					m_pixelFormat = Format_RGBA_8;
199 				}
200 				QRgb *s;
201 				unsigned char cc, cm, cy, ck;
202 				uchar *d;
203 				for (int yit = 0; yit < m_imageInfoRecord.exifInfo.thumbnail.height(); ++yit)
204 				{
205 					s = (QRgb*)(m_imageInfoRecord.exifInfo.thumbnail.scanLine( yit ));
206 					d = r_image.scanLine( yit );
207 					for (int xit =0 ; xit < m_imageInfoRecord.exifInfo.thumbnail.width(); ++xit)
208 					{
209 						if (isCMYK)
210 						{
211 							cc = 255 - qRed(*s);
212 							cm = 255 - qGreen(*s);
213 							cy = 255 - qBlue(*s);
214 							ck = qMin(qMin(cc, cm), cy);
215 							d[0] = cc-ck;
216 							d[1] = cm-ck;
217 							d[2] = cy-ck;
218 							d[3] = ck;
219 							d[4] = 255;
220 						}
221 						else
222 						{
223 							d[0] = qRed(*s);
224 							d[1] = qGreen(*s);
225 							d[2] = qBlue(*s);
226 							d[3] = 255;
227 						}
228 						s++;
229 						d += r_image.channels();
230 					}
231 				}
232 				m_imageInfoRecord.exifInfo.width = header.width;
233 				m_imageInfoRecord.exifInfo.height = header.height;
234 				return true;
235 			}
236 		}
237 		m_imageInfoRecord.exifInfo.width = header.width;
238 		m_imageInfoRecord.exifInfo.height = header.height;
239 		m_imageInfoRecord.BBoxX = 0;
240 		m_imageInfoRecord.BBoxH = r_image.height();
241 		return true;
242 	}
243 	return false;
244 }
245 
LoadPSD(QDataStream & s,const PSDHeader & header)246 bool ScImgDataLoader_PSD::LoadPSD( QDataStream & s, const PSDHeader & header)
247 {
248 	// Create dst image.
249 	m_imageInfoRecord.valid = false;
250 	if (header.color_mode == CM_CMYK)
251 	{
252 		if (!r_image.create(header.width, header.height, 5))
253 			return false;
254 		m_pixelFormat = Format_CMYKA_8;
255 	}
256 	else
257 	{
258 		if (!r_image.create(header.width, header.height, 4))
259 			return false;
260 		m_pixelFormat = Format_RGBA_8;
261 	}
262 	r_image.fill(0);
263 	m_maxChannels = header.channel_count;
264 	uint tmp;
265 	uint cresStart;
266 	uint cdataStart;
267 	uint resourceDataLen;
268 	uint startResource;
269 
270 	cresStart = s.device()->pos();
271 	// Skip mode data. FIX: this is incorrect, it's the Colormap Data for indexed Images
272 	s >> tmp;
273 	cdataStart = s.device()->pos();
274 
275 	LoadPSDResources(s, header, cresStart);
276 
277 	s.device()->seek( cdataStart + tmp );
278 	s >> resourceDataLen;
279 	startResource = s.device()->pos();
280 
281 	if  ((!m_imageInfoRecord.exifInfo.thumbnail.isNull()) && (header.reserved[0] == 't'))
282 		return true;
283 	bool ret = LoadPSDImgData(s, header, startResource + resourceDataLen);
284 	return ret;
285 }
286 
LoadPSDResources(QDataStream & s,const PSDHeader & header,uint dataOffset)287 bool ScImgDataLoader_PSD::LoadPSDResources( QDataStream & s, const PSDHeader & header, uint dataOffset )
288 {
289 	// Create dst image.
290 	m_imageInfoRecord.valid = false;
291 
292 	uint tmp;
293 	uint cdataStart;
294 	uint resourceDataLen;
295 //	uint startResource;
296 
297 	s.device()->seek( dataOffset );
298 
299 	srand(314159265);
300 	for (int i = 0; i < 4096; i++)
301 		m_random_table[i] = rand();
302 	int tmpd;
303 	int swap;
304 	for (int i = 0; i < 4096; i++)
305 	{
306 		swap = i + rand() % (4096 - i);
307 		tmpd = m_random_table[i];
308 		m_random_table[i] = m_random_table[swap];
309 		m_random_table[swap] = tmpd;
310 	}
311 	// Skip mode data. FIX: this is incorrect, it's the Colormap Data for indexed Images
312 	s >> tmp;
313 	cdataStart = s.device()->pos();
314 	if (tmp != 0)
315 	{
316 		if ((header.color_mode == CM_DUOTONE))
317 		{
318 			short signature;
319 			short count;
320 			unsigned short c, m, y, k;
321 			uchar hc, sc, bc;
322 			ScColor col;
323 			s >> signature;
324 			s >> count;
325 			uint duodataStart = s.device()->pos();
326 			bool specialColour = false;
327 			for (int cda = 0; cda < count; cda++)
328 			{
329 				s >> signature;
330 				s >> c >> m >> y >> k;
331 				switch (signature)
332 				{
333 					case 0:	// RGB colour
334 						col.setRgbColor(c >> 8, m >> 8, y >> 8);
335 						m_colorTableSc.append(col);
336 						break;
337 					case 1:	// HSB colour
338 						hc = c >> 8;
339 						sc = m >> 8;
340 						bc = y >> 8;
341 						HSVTORGB(hc, sc, bc);
342 						col.setRgbColor(hc, sc, bc);
343 						m_colorTableSc.append(col);
344 						break;
345 					case 2:	// CMYK colour
346 						col.setColor(c >> 8, m >> 8, y >> 8, k >> 8);
347 						m_colorTableSc.append(col);
348 						break;
349 					case 3:	// Pantone
350 					case 4:	// Focoltone
351 					case 5:	// Truematch
352 					case 6:	// Toyo 88 colorfinder 1050
353 					case 7:	// LAB colour space
354 					case 10: // HKS colors
355 						if (m_colorTableSc.count() == 0)
356 							m_colorTableSc.append(ScColor(0, 0, 0, 255));
357 						else
358 							m_colorTableSc.append(ScColor(0, 0, 0, 0));
359 						specialColour = true;
360 						break;
361 					case 8: // Grayscale
362 						c = qRound((c / 10000.0) * 255);
363 						m_colorTableSc.append(ScColor(0, 0, 0, c));
364 						break;
365 				}
366 			}
367 			if (specialColour) // we will only load the grayscale image data and do the colorizing with the Image Effects;
368 			{
369 				s.device()->seek( duodataStart + 40 );
370 				uint duoNameStart = s.device()->pos();
371 				uint duoCurveStart = duoNameStart+256;
372 				for (int cda = 0; cda < count; cda++)
373 				{
374 					QString colName;
375 					s.device()->seek( duoNameStart + (64 * static_cast<uint>(cda)) );
376 					colName = getPascalString(s);
377 					s.device()->seek( duoCurveStart + (28 * static_cast<uint>(cda)) );
378 					FPointArray tmcu;
379 					tmcu.resize(0);
380 					for (int cu = 0; cu < 13; cu++)
381 					{
382 						short val;
383 						s >> val;
384 						if (val != -1)
385 							tmcu.addPoint(cu * 1.0 / 12.0, val / 1000.0);
386 					}
387 					PSDDuotone_Color colSpec;
388 					colSpec.Name = colName;
389 					colSpec.Color = m_colorTableSc[cda];
390 					colSpec.Curve = tmcu;
391 					m_imageInfoRecord.duotoneColors.append(colSpec);
392 				}
393 				// Initialize loading curve tables with default values
394 				m_curveTable1.resize(256);
395 				m_curveTable2.resize(256);
396 				m_curveTable3.resize(256);
397 				m_curveTable4.resize(256);
398 				for (int x = 0 ; x < 256 ; x++)
399 				{
400 					m_curveTable1[x] = x;
401 					m_curveTable2[x] = x;
402 					m_curveTable3[x] = x;
403 					m_curveTable4[x] = x;
404 				}
405 			}
406 			else
407 			{
408 				s.device()->seek( duodataStart + 40 );
409 				uint duoNameStart = s.device()->pos();
410 				uint duoCurveStart = duoNameStart+256;
411 				for (int cda = 0; cda < count; cda++)
412 				{
413 					s.device()->seek( duoCurveStart + (28 * static_cast<uint>(cda)) );
414 					FPointArray tmcu;
415 					tmcu.resize(0);
416 					for (int cu = 0; cu < 13; cu++)
417 					{
418 						short val;
419 						s >> val;
420 						if (val != -1)
421 							tmcu.addPoint(cu * 1.0 / 12.0, val / 1000.0);
422 					}
423 					if (cda == 0)
424 					{
425 						m_curveTable1.resize(256);
426 						for (int x = 0 ; x < 256 ; x++)
427 						{
428 							m_curveTable1[x] = qMin(255, qMax(0, qRound(getCurveYValue(tmcu, x / 255.0) * 255)));
429 						}
430 					}
431 					else if (cda == 1)
432 					{
433 						m_curveTable2.resize(256);
434 						for (int x = 0 ; x < 256 ; x++)
435 						{
436 							m_curveTable2[x] = qMin(255, qMax(0, qRound(getCurveYValue(tmcu, x / 255.0) * 255)));
437 						}
438 					}
439 					else if (cda == 2)
440 					{
441 						m_curveTable3.resize(256);
442 						for (int x = 0 ; x < 256 ; x++)
443 						{
444 							m_curveTable3[x] = qMin(255, qMax(0, qRound(getCurveYValue(tmcu, x / 255.0) * 255)));
445 						}
446 					}
447 					else if (cda == 3)
448 					{
449 						m_curveTable4.resize(256);
450 						for (int x = 0 ; x < 256 ; x++)
451 						{
452 							m_curveTable4[x] = qMin(255, qMax(0, qRound(getCurveYValue(tmcu, x / 255.0) * 255)));
453 						}
454 					}
455 				}
456 			}
457 		}
458 		else
459 		{
460 			QList<uchar> colorTableR;
461 			QList<uchar> colorTableG;
462 			QList<uchar> colorTableB;
463 			colorTableR.reserve(256);
464 			colorTableG.reserve(256);
465 			colorTableB.reserve(256);
466 			m_colorTable.clear();
467 			m_colorTable.reserve(256);
468 			uchar r;
469 			for (uint cc = 0; cc < 256; cc++)
470 			{
471 				s >> r;
472 				colorTableR.append(r);
473 			}
474 			for (uint cc = 0; cc < 256; cc++)
475 			{
476 				s >> r;
477 				colorTableG.append(r);
478 			}
479 			for (uint cc = 0; cc < 256; cc++)
480 			{
481 				s >> r;
482 				colorTableB.append(r);
483 			}
484 			for (uint cc = 0; cc < 256; cc++)
485 			{
486 				m_colorTable.append(qRgb(colorTableR[cc], colorTableG[cc], colorTableB[cc]));
487 			}
488 		}
489 	}
490 	s.device()->seek( cdataStart + tmp );
491 	s >> resourceDataLen;
492 //	startResource = s.device()->pos();
493 	if (resourceDataLen != 0)
494 		parseResourceData(s, header, resourceDataLen);
495 	return true;
496 }
497 
LoadPSDImgData(QDataStream & s,const PSDHeader & header,uint dataOffset)498 bool ScImgDataLoader_PSD::LoadPSDImgData( QDataStream & s, const PSDHeader & header, uint dataOffset )
499 {
500 	uint layerDataLen;
501 	uint startLayers;
502 	s.device()->seek( dataOffset );
503 	// Skip the reserved data. FIX: Also incorrect, this is the actual Layer Data for Images with Layers
504 	s >> layerDataLen;
505 	startLayers = s.device()->pos();
506 	if (layerDataLen != 0)
507 	{
508 		bool re = parseLayer(s, header);
509 		if (re)
510 		{
511 			m_imageInfoRecord.valid = true;
512 			return re;
513 		}
514 		// Try to decode simple psd file, no layers
515 		s.device()->seek(startLayers + layerDataLen);
516 		if (s.atEnd())
517 			return false;
518 		return loadLayer( s, header);
519 	}
520 	// Decoding simple psd file, no layers
521 	s.device()->seek( s.device()->pos() + layerDataLen );
522 	loadLayer( s, header);
523 	return true;
524 }
525 
parseLayer(QDataStream & s,const PSDHeader & header)526 bool ScImgDataLoader_PSD::parseLayer( QDataStream & s, const PSDHeader & header )
527 {
528 	uint addRes, layerinfo, channelLen, signature, extradata, layermasksize, layerRange, dummy;
529 	int top, left, bottom, right;
530 	short numLayers, numChannels;
531 	short channelType;
532 	uchar blendKey[4];
533 	uchar opacity, clipping, flags, filler;
534 	QString blend;
535 	struct PSDLayer lay;
536 	s >> layerinfo;
537 	s >> numLayers;
538 	if (numLayers < 0)
539 		numLayers = -numLayers;
540 	if (numLayers != 0)
541 	{
542 		for (int layer = 0; layer < numLayers; layer++)
543 		{
544 			s >> top;
545 			lay.ypos = top;
546 			s >> left;
547 			lay.xpos = left;
548 			s >> bottom;
549 			lay.height = bottom - top;
550 			s >> right;
551 			lay.width = right - left;
552 			s >> numChannels;
553 			// Qt4 check these conversions
554 			m_maxChannels = qMax(m_maxChannels, (int)numChannels);
555 			if (numChannels > 6)	// we don't support images with more than 6 channels yet
556 			{
557 				m_imageInfoRecord.layerInfo.clear();
558 				return false;
559 			}
560 			lay.channelType.clear();
561 			lay.channelLen.clear();
562 			for (int channels = 0; channels < numChannels; channels++)
563 			{
564 				s >> channelType;
565 				s >> channelLen;
566 				lay.channelType.append(channelType);
567 				lay.channelLen.append(channelLen);
568 			}
569 			s >> signature;
570 			blend = "";
571 			for (int i = 0; i < 4; i++)
572 			{
573 				s >> blendKey[i];
574 				blend += QChar(blendKey[i]);
575 			}
576 			lay.blend = blend;
577 			s >> opacity;
578 			lay.opacity = opacity;
579 			s >> clipping;
580 			lay.clipping = clipping;
581 			s >> flags;
582 			if (flags & 8)
583 			{
584 				if (flags & 16)	// Unknown combination of layer flags, probably an adjustment or effects layer
585 				{
586 					m_imageInfoRecord.layerInfo.clear();
587 					return false;
588 				}
589 			}
590 			lay.flags = flags;
591 			s >> filler;
592 			s >> extradata;
593 			s >> layermasksize;
594 			lay.maskYpos = 0;
595 			lay.maskXpos = 0;
596 			lay.maskHeight = 0;
597 			lay.maskWidth = 0;
598 			if (layermasksize != 0)
599 			{
600 				s >> lay.maskYpos;
601 				s >> lay.maskXpos;
602 				s >> dummy;
603 				lay.maskHeight = dummy - lay.maskYpos;
604 				s >> dummy;
605 				lay.maskWidth = dummy - lay.maskXpos;
606 				s >> dummy;
607 			}
608 			s >> layerRange;
609 			s.device()->seek( s.device()->pos() + layerRange );
610 			lay.layerName = getLayerString(s);
611 			m_imageInfoRecord.layerInfo.append(lay);
612 			s >> signature;
613 			if (signature == 0x3842494D)
614 			{
615 				while (signature == 0x3842494D )
616 				{
617 					s >> signature;
618 					s >> addRes;
619 					s.device()->seek( s.device()->pos() + addRes );
620 					s >> signature;
621 				}
622 				s.device()->seek( s.device()->pos() - 4 );
623 			}
624 			else
625 			{
626 				s.device()->seek( s.device()->pos() - 2 );
627 				s >> signature;
628 				if (signature == 0x3842494D)
629 				{
630 					while (signature == 0x3842494D )
631 					{
632 						s >> signature;
633 						s >> addRes;
634 						s.device()->seek( s.device()->pos() + addRes );
635 						s >> signature;
636 					}
637 					s.device()->seek( s.device()->pos() - 4 );
638 				}
639 				else
640 					s.device()->seek( s.device()->pos() - 6 );
641 			}
642 		}
643 		bool firstLayer = true;
644 		for (int layer = 0; layer < numLayers; layer++)
645 		{
646 			loadLayerChannels( s, header, m_imageInfoRecord.layerInfo, layer, &firstLayer );
647 		}
648 	}
649 	else
650 	{
651 		s >> numLayers;
652 		if (numLayers == 0)
653 			return false;
654 		loadLayer( s, header);
655 	}
656 	return true;
657 }
658 
loadChannel(QDataStream & s,const PSDHeader & header,QList<PSDLayer> & layerInfo,uint layer,int channel,int component,RawImage & tmpImg)659 bool ScImgDataLoader_PSD::loadChannel( QDataStream & s, const PSDHeader & header, QList<PSDLayer> &layerInfo, uint layer, int channel, int component, RawImage &tmpImg)
660 {
661 	uint base = s.device()->pos();
662 	uchar cbyte;
663 	ushort compression;
664 	s >> compression;
665 	if (compression > 1)
666 		return false;
667 	if (compression == 0)
668 	{
669 		int count = layerInfo[layer].channelLen[channel]-2;
670 		uchar *ptr;
671 		for (int i = 0; i < tmpImg.height(); i++)
672 		{
673 			ptr =  tmpImg.scanLine(i);
674 			for (int j = 0; j < tmpImg.width(); j++)
675 			{
676 				s >> cbyte;
677 				count--;
678 				if ((header.color_mode == CM_CMYK) && (component < 4))
679 					cbyte = 255 - cbyte;
680 				if ((header.color_mode == CM_GRAYSCALE) && (component != 3))
681 				{
682 					ptr[0] = cbyte;
683 					ptr[1] = cbyte;
684 					ptr[2] = cbyte;
685 				}
686 				else if ((header.color_mode == CM_DUOTONE) && (component != 3))
687 				{
688 					ptr -= component;
689 					putDuotone(ptr, cbyte);
690 					ptr += component;
691 				}
692 				else if ((header.color_mode == CM_INDEXED) && (component != 3))
693 				{
694 					int ccol = m_colorTable[cbyte];
695 					ptr[0] = qRed(ccol);
696 					ptr[1] = qGreen(ccol);
697 					ptr[2] = qBlue(ccol);
698 				}
699 				else
700 					ptr[component] = cbyte;
701 				if (count == 0)
702 					break;
703 				ptr += tmpImg.channels();
704 			}
705 			if (count == 0)
706 				break;
707 		}
708 	}
709 	else
710 	{
711 		s.device()->seek( s.device()->pos() + tmpImg.height() * 2 );
712 		uint pixel_count = tmpImg.width();
713 		uchar *ptr;
714 		uchar *ptr2;
715 		uint count, len;
716 		uchar c;
717 		for (int hh = 0; hh < tmpImg.height(); hh++)
718 		{
719 			count = 0;
720 			ptr = tmpImg.scanLine(hh);
721 			ptr2 = ptr+tmpImg.width() * tmpImg.channels();
722 			ptr += component;
723 			while (count < pixel_count)
724 			{
725 				if (s.atEnd())
726 					return false;
727 				s >> c;
728 				len = c;
729 				if (len < 128)
730 				{
731 					// Copy next len+1 bytes literally.
732 					len++;
733 					count += len;
734 					while (len != 0)
735 					{
736 						s >> cbyte;
737 						if (ptr < ptr2)
738 						{
739 							if ((header.color_mode == CM_CMYK) && (component < 4))
740 								cbyte = 255 - cbyte;
741 							if ((header.color_mode == CM_GRAYSCALE) && (component != 3))
742 							{
743 								ptr -= component;
744 								ptr[0] = cbyte;
745 								ptr[1] = cbyte;
746 								ptr[2] = cbyte;
747 								ptr += component;
748 							}
749 							else if ((header.color_mode == CM_DUOTONE) && (component != 3))
750 							{
751 								ptr -= component;
752 								putDuotone(ptr, cbyte);
753 								ptr += component;
754 							}
755 							else if ((header.color_mode == CM_INDEXED) && (component != 3))
756 							{
757 								ptr -= component;
758 								int ccol = m_colorTable[cbyte];
759 								ptr[0] = qRed(ccol);
760 								ptr[1] = qGreen(ccol);
761 								ptr[2] = qBlue(ccol);
762 								ptr += component;
763 							}
764 							else
765 							{
766 								*ptr = cbyte;
767 							}
768 						}
769 						ptr += tmpImg.channels();
770 						len--;
771 					}
772 				}
773 				else if (len > 128)
774 				{
775 					// Next -len+1 bytes in the dest are replicated from next source byte.
776 					// (Interpret len as a negative 8-bit int.)
777 					len ^= 0xFF;
778 					len += 2;
779 					count += len;
780 					uchar val;
781 					s >> val;
782 					if ((header.color_mode == CM_CMYK) && (component < 4))
783 						val = 255 - val;
784 					while (len != 0)
785 					{
786 						if (ptr < ptr2)
787 						{
788 							if ((header.color_mode == CM_GRAYSCALE) && (component != 3))
789 							{
790 								ptr -= component;
791 								ptr[0] = val;
792 								ptr[1] = val;
793 								ptr[2] = val;
794 								ptr += component;
795 							}
796 							else if ((header.color_mode == CM_DUOTONE) && (component != 3))
797 							{
798 								ptr -= component;
799 								putDuotone(ptr, val);
800 								ptr += component;
801 							}
802 							else if ((header.color_mode == CM_INDEXED) && (component != 3))
803 							{
804 								ptr -= component;
805 								int ccol = m_colorTable[val];
806 								ptr[0] = qRed(ccol);
807 								ptr[1] = qGreen(ccol);
808 								ptr[2] = qBlue(ccol);
809 								ptr += component;
810 							}
811 							else
812 								*ptr = val;
813 						}
814 						ptr += tmpImg.channels();
815 						len--;
816 					}
817 				}
818 				else if (len == 128)
819 				{
820 					// No-op.
821 				}
822 			}
823 		}
824 	}
825 	s.device()->seek( base+layerInfo[layer].channelLen[channel] );
826 	return true;
827 }
828 
loadLayerChannels(QDataStream & s,const PSDHeader & header,QList<PSDLayer> & layerInfo,uint layer,bool * firstLayer)829 bool ScImgDataLoader_PSD::loadLayerChannels( QDataStream & s, const PSDHeader & header, QList<PSDLayer> &layerInfo, uint layer, bool* firstLayer)
830 {
831 	// Find out if the data is compressed.
832 	// Known values:
833 	//   0: no compression
834 	//   1: RLE compressed
835 	uint base = s.device()->pos();
836 	uint base2 = base;
837 	uint channel_num = layerInfo[layer].channelLen.count();
838 	bool hasMask = false;
839 	bool hasAlpha = false;
840 	RawImage r2_image;
841 	RawImage mask;
842 	bool createOk = false;
843 	ScColorMgmtEngine engine(ScCore->defaultEngine);
844 	if (header.color_mode == CM_CMYK)
845 	{
846 		createOk = r2_image.create(layerInfo[layer].width, layerInfo[layer].height, qMax(channel_num, (uint)5));
847 		r2_image.fill(0);
848 	}
849 	else
850 	{
851 		createOk = r2_image.create(layerInfo[layer].width, layerInfo[layer].height, qMax(channel_num, (uint)4));
852 		r2_image.fill(0);
853 	}
854 	if (!createOk)
855 	{
856 		for (uint channel = 0; channel < channel_num; channel++)
857 		{
858 			base2 += layerInfo[layer].channelLen[channel];
859 		}
860 		s.device()->seek( base2 );
861 		return false;
862 	}
863 	channel_num = qMin(channel_num, (uint)39);
864 	uint components[40];
865 	for (uint channel = 0; channel < channel_num; channel++)
866 	{
867 		switch (layerInfo[layer].channelType[channel])
868 		{
869 		case 0:
870 			components[channel] = 0;
871 			break;
872 		case 1:
873 			components[channel] = 1;
874 			break;
875 		case 2:
876 			components[channel] = 2;
877 			break;
878 		case 3:
879 			components[channel] = 3;
880 			break;
881 		case -1:
882 			if (header.color_mode == CM_CMYK)
883 			{
884 				if (channel_num == 6)
885 					components[channel] = channel_num-2;
886 				else
887 					components[channel] = channel_num-1;
888 			}
889 			else
890 			{
891 				if (channel_num == 5)
892 					components[channel] = channel_num-2;
893 				else
894 				{
895 					if (header.color_mode == CM_GRAYSCALE)
896 						components[channel] = 3;
897 					else
898 						components[channel] = channel_num-1;
899 				}
900 			}
901 			hasAlpha = true;
902 			break;
903 		case -2:
904 			components[channel] = channel_num-1;
905 			break;
906 		}
907 	}
908 	if (!hasAlpha)
909 		r2_image.fill('\xff');
910 	for (uint channel = 0; channel < channel_num; channel++)
911 	{
912 		if (layerInfo[layer].channelType[channel] == -2)
913 		{
914 			if (!mask.create( layerInfo[layer].maskWidth, layerInfo[layer].maskHeight, 1 ))
915 				break;
916 			mask.fill(0);
917 			if (!loadChannel(s, header, layerInfo, layer, channel, 0, mask))
918 				break;
919 			hasMask = true;
920 		}
921 		if (!loadChannel(s, header, layerInfo, layer, channel, components[channel], r2_image))
922 			break;
923 	}
924 	for (uint channel = 0; channel < channel_num; channel++)
925 	{
926 		base2 += layerInfo[layer].channelLen[channel];
927 	}
928 	if (header.color_mode == CM_LABCOLOR)
929 	{
930 		ScColorProfile hsRGB = engine.createProfile_sRGB();
931 		ScColorProfile hLab  = engine.createProfile_Lab();
932 		ScColorTransform xform = engine.createTransform(hLab, Format_LabA_8, hsRGB, Format_RGBA_8, Intent_Perceptual, 0);
933 		for (int i = 0; i < r2_image.height(); i++)
934 		{
935 			uchar* ptr = r2_image.scanLine(i);
936 			xform.apply(ptr, ptr, r2_image.width());
937 		}
938 	}
939 	s.device()->seek( base2 );
940 	QImage tmpImg2;
941 	if (header.color_mode == CM_CMYK)
942 		tmpImg2 = r2_image.convertToQImage(true);
943 	else
944 		tmpImg2 = r2_image.convertToQImage(false);
945 	QImage imt;
946 	double sx = tmpImg2.width() / 40.0;
947 	double sy = tmpImg2.height() / 40.0;
948 	imt = sy < sx ?  tmpImg2.scaled(qRound(tmpImg2.width() / sx), qRound(tmpImg2.height() / sx), Qt::IgnoreAspectRatio, Qt::SmoothTransformation) :
949 	      tmpImg2.scaled(qRound(tmpImg2.width() / sy), qRound(tmpImg2.height() / sy), Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
950 	layerInfo[layer].thumb = imt.copy();
951 	if (hasMask)
952 	{
953 		QImage imt2;
954 		QImage tmpImg;
955 		tmpImg = mask.convertToQImage(true);
956 		double sx = tmpImg.width() / 40.0;
957 		double sy = tmpImg.height() / 40.0;
958 		imt2 = sy < sx ?  tmpImg.scaled(qRound(tmpImg.width() / sx), qRound(tmpImg.height() / sx), Qt::IgnoreAspectRatio, Qt::SmoothTransformation) :
959 	      tmpImg.scaled(qRound(tmpImg.width() / sy), qRound(tmpImg.height() / sy), Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
960 		imt2.invertPixels();
961 		layerInfo[layer].thumb_mask = imt2.copy();
962 	}
963 	else
964 		layerInfo[layer].thumb_mask = QImage();
965 	if (!m_imageInfoRecord.isRequest || !m_imageInfoRecord.RequestProps.contains(layer))
966 		m_imageInfoRecord.RequestProps[layer].useMask = true;
967 	bool visible = !(layerInfo[layer].flags & 2);
968 	if ((m_imageInfoRecord.isRequest) && (m_imageInfoRecord.RequestProps.contains(layer)))
969 		visible = m_imageInfoRecord.RequestProps[layer].visible;
970 	if (visible)
971 	{
972 		unsigned int startSrcY, startSrcX, startDstY, startDstX;
973 		if (layerInfo[layer].ypos < 0)
974 		{
975 			startSrcY = abs(layerInfo[layer].ypos);
976 			startDstY = 0;
977 		}
978 		else
979 		{
980 			startSrcY = 0;
981 			startDstY = layerInfo[layer].ypos;
982 		}
983 		if (layerInfo[layer].xpos < 0)
984 		{
985 			startSrcX = abs(layerInfo[layer].xpos);
986 			startDstX = 0;
987 		}
988 		else
989 		{
990 			startSrcX = 0;
991 			startDstX = layerInfo[layer].xpos;
992 		}
993 		unsigned int startSrcXm; //, startSrcYm, startDstYm, startDstXm;
994 	/*	if (layerInfo[layer].maskYpos < 0)
995 		{
996 			startSrcYm = abs(layerInfo[layer].maskYpos);
997 			startDstYm = 0;
998 		}
999 		else
1000 		{
1001 			startSrcYm = 0;
1002 			startDstYm = layerInfo[layer].maskYpos;
1003 		}*/
1004 		if (layerInfo[layer].maskXpos < 0)
1005 		{
1006 			startSrcXm = abs(layerInfo[layer].maskXpos);
1007 	//		startDstXm = 0;
1008 		}
1009 		else
1010 		{
1011 			startSrcXm = 0;
1012 	//		startDstXm = layerInfo[layer].maskXpos;
1013 		}
1014 		QString layBlend2 = layerInfo[layer].blend;
1015 		if ((m_imageInfoRecord.isRequest) && (m_imageInfoRecord.RequestProps.contains(layer)))
1016 			layBlend2 = m_imageInfoRecord.RequestProps[layer].blend;
1017 		if (layBlend2 == QLatin1String("diss"))
1018 		{
1019 			hasAlpha = true;
1020 			int layOpa = layerInfo[layer].opacity;
1021 			if ((m_imageInfoRecord.isRequest) && (m_imageInfoRecord.RequestProps.contains(layer)))
1022 				layOpa = m_imageInfoRecord.RequestProps[layer].opacity;
1023 			for (int l = 0; l < r2_image.height(); l++)
1024 			{
1025 				srand(m_random_table[ l  % 4096]);
1026 				for (int k = 0; k < r2_image.width(); k++)
1027 				{
1028 					int rand_val = rand() & 0xff;
1029 					if (rand_val > layOpa)
1030 						r2_image.setAlpha(k, l, 0);
1031 				}
1032 			}
1033 		}
1034 		if (*firstLayer)
1035 		{
1036 			unsigned char *s;
1037 			unsigned char *d;
1038 			for (int yi=static_cast<int>(startSrcY); yi < qMin(r2_image.height(),  r_image.height()); ++yi)
1039 			{
1040 				s = r2_image.scanLine( yi );
1041 				d = r_image.scanLine( qMin(static_cast<int>(startDstY),  r_image.height()-1) );
1042 				d += qMin(static_cast<int>(startDstX), r_image.width()-1) * r_image.channels();
1043 				s += qMin(static_cast<int>(startSrcX), r2_image.width()-1) * r2_image.channels();
1044 				for (int xi=static_cast<int>(startSrcX); xi < qMin(r2_image.width(),  r_image.width()); ++xi)
1045 				{
1046 					d[0] = s[0];
1047 					d[1] = s[1];
1048 					d[2] = s[2];
1049 					if (header.color_mode != CM_CMYK)
1050 					{
1051 						if (hasAlpha)
1052 							d[3] = s[3];
1053 						else
1054 							d[3] = 255;
1055 					}
1056 					else
1057 					{
1058 						d[3] = s[3];
1059 						if (hasAlpha)
1060 							d[4] = s[4];
1061 						else
1062 							d[4] = 255;
1063 					}
1064 					s += r2_image.channels();
1065 					d += r_image.channels();
1066 				}
1067 				startDstY++;
1068 			}
1069 		}
1070 		else
1071 		{
1072 			unsigned char *s;
1073 			unsigned char *d;
1074 			unsigned char *sm = nullptr;
1075 			unsigned char r, g, b, src_r, src_g, src_b, src_a, src_alpha, dst_alpha;
1076 			unsigned char a = 0;
1077 			uchar new_r, new_g, new_b;
1078 			unsigned int maxDestX;
1079 			for (int i = static_cast<int>(startSrcY); i < layerInfo[layer].height; i++)
1080 			{
1081 				d = r_image.scanLine(qMin(static_cast<int>(startDstY),  r_image.height()-1));
1082 				s = r2_image.scanLine(qMin(i, r2_image.height()-1));
1083 				d += qMin(static_cast<int>(startDstX),  r_image.width()-1) * r_image.channels();
1084 				s += qMin(static_cast<int>(startSrcX), r2_image.width()-1) * r2_image.channels();
1085 				sm = nullptr;
1086 				if (hasMask)
1087 				{
1088 					sm = mask.scanLine(qMin(i, mask.height()-1));
1089 					sm += qMin(static_cast<int>(startSrcXm), mask.width()-1) * mask.channels();
1090 				}
1091 				startDstY++;
1092 				maxDestX = r_image.width() - startDstX + startSrcX - 1;
1093 				for (unsigned int j = startSrcX; j < qMin(maxDestX, static_cast<unsigned int>(layerInfo[layer].width)); j++)
1094 				{
1095 					src_r = s[0];
1096 					src_g = s[1];
1097 					src_b = s[2];
1098 					src_a = s[3];
1099 					if (hasAlpha)
1100 					{
1101 						if (hasMask)
1102 						{
1103 							if (m_imageInfoRecord.RequestProps[layer].useMask)
1104 								src_alpha = sm[0];
1105 							else
1106 								src_alpha = s[channel_num - 2];
1107 						}
1108 						else
1109 						{
1110 							if (header.color_mode == CM_GRAYSCALE)
1111 								src_alpha = s[3];
1112 							else
1113 								src_alpha = s[channel_num - 1];
1114 						}
1115 					}
1116 					else
1117 						src_alpha = 255;
1118 					if ((hasMask) && (m_imageInfoRecord.RequestProps[layer].useMask))
1119 						src_alpha = sm[0];
1120 					int layOpa = layerInfo[layer].opacity;
1121 					if ((m_imageInfoRecord.isRequest) && (m_imageInfoRecord.RequestProps.contains(layer)))
1122 						layOpa = m_imageInfoRecord.RequestProps[layer].opacity;
1123 					QString layBlend = layerInfo[layer].blend;
1124 					if ((m_imageInfoRecord.isRequest) && (m_imageInfoRecord.RequestProps.contains(layer)))
1125 						layBlend = m_imageInfoRecord.RequestProps[layer].blend;
1126 					if (layBlend != QLatin1String("diss"))
1127 						src_alpha = INT_MULT(src_alpha, layOpa);
1128 					if (header.color_mode == CM_CMYK)
1129 						dst_alpha = d[4];
1130 					else
1131 						dst_alpha = d[3];
1132 					if ((dst_alpha > 0) && (src_alpha > 0))
1133 					{
1134 						if (layBlend ==  QLatin1String("mul "))
1135 						{
1136 							src_r = INT_MULT(src_r, d[0]);
1137 							src_g = INT_MULT(src_g, d[1]);
1138 							src_b = INT_MULT(src_b, d[2]);
1139 							if (header.color_mode == CM_CMYK)
1140 								src_a = INT_MULT(src_a, d[3]);
1141 						}
1142 						else if (layBlend ==  QLatin1String("scrn"))
1143 						{
1144 							src_r = 255 - ((255-src_r) * (255-d[0]) / 128);
1145 							src_g = 255 - ((255-src_g) * (255-d[1]) / 128);
1146 							src_b = 255 - ((255-src_b) * (255-d[2]) / 128);
1147 							if (header.color_mode == CM_CMYK)
1148 								src_a = 255 - ((255-src_a) * (255-d[3]) / 128);
1149 						}
1150 						else if (layBlend ==  QLatin1String("over"))
1151 						{
1152 							src_g = d[1] < 128 ? src_g * d[1] / 128 : 255 - ((255-src_g) * (255-d[1]) / 128);
1153 							src_b = d[2] < 128 ? src_b * d[2] / 128 : 255 - ((255-src_b) * (255-d[2]) / 128);
1154 							src_a = d[3] < 128 ? src_a * d[3] / 128 : 255 - ((255-src_a) * (255-d[3]) / 128);
1155 							if (header.color_mode == CM_CMYK)
1156 								src_r = d[0] < 128 ? src_r * d[0] / 128 : 255 - ((255-src_r) * (255-d[0]) / 128);
1157 						}
1158 						else if (layBlend ==  QLatin1String("diff"))
1159 						{
1160 							src_r = d[0] > src_r ? d[0] - src_r : src_r - d[0];
1161 							src_g = d[1] > src_g ? d[1] - src_g : src_g - d[1];
1162 							src_b = d[2] > src_b ? d[2] - src_b : src_b - d[2];
1163 							if (header.color_mode == CM_CMYK)
1164 								src_a = d[3] > src_a ? d[3] - src_a : src_a - d[3];
1165 						}
1166 						else if (layBlend ==  QLatin1String("dark"))
1167 						{
1168 							src_r = d[0]  < src_r ? d[0]  : src_r;
1169 							src_g = d[1] < src_g ? d[1] : src_g;
1170 							src_b = d[2] < src_b ? d[2] : src_b;
1171 							if (header.color_mode == CM_CMYK)
1172 								src_a = d[3] < src_a ? d[3] : src_a;
1173 						}
1174 						else if (layBlend ==  QLatin1String("hLit"))
1175 						{
1176 							src_r = src_r < 128 ? src_r * d[0] / 128 : 255 - ((255-src_r) * (255-d[0]) / 128);
1177 							src_g = src_g < 128 ? src_g * d[1] / 128 : 255 - ((255-src_g) * (255-d[1]) / 128);
1178 							src_b = src_b < 128 ? src_b * d[2] / 128 : 255 - ((255-src_b) * (255-d[2]) / 128);
1179 							if (header.color_mode == CM_CMYK)
1180 								src_a = src_a < 128 ? src_a * d[3] / 128 : 255 - ((255-src_a) * (255-d[3]) / 128);
1181 						}
1182 						else if (layBlend ==  QLatin1String("sLit"))
1183 						{
1184 							src_r = src_r * d[0] / 256 + src_r * (255 - ((255-src_r)*(255-d[0]) / 256) - src_r * d[0] / 256) / 256;
1185 							src_g = src_g * d[1] / 256 + src_g * (255 - ((255-src_g)*(255-d[1]) / 256) - src_g * d[1] / 256) / 256;
1186 							src_b = src_b * d[2] / 256 + src_b * (255 - ((255-src_b)*(255-d[2]) / 256) - src_b * d[2] / 256) / 256;
1187 							if (header.color_mode == CM_CMYK)
1188 								src_a = src_a * d[3] / 256 + src_a * (255 - ((255-src_a)*(255-d[3]) / 256) - src_a * d[3] / 256) / 256;
1189 						}
1190 						else if (layBlend ==  QLatin1String("lite"))
1191 						{
1192 							src_r = d[0] < src_r ? src_r : d[0];
1193 							src_g = d[1] < src_g ? src_g : d[1];
1194 							src_b = d[2] < src_b ? src_b : d[2];
1195 							if (header.color_mode == CM_CMYK)
1196 								src_a = d[3] < src_a ? src_a : d[3];
1197 						}
1198 						else if (layBlend ==  QLatin1String("smud"))
1199 						{
1200 							src_r = d[0] + src_r - src_r * d[0] / 128;
1201 							src_g = d[1] + src_g - src_g * d[1] / 128;
1202 							src_b = d[2] + src_b - src_b * d[2] / 128;
1203 							if (header.color_mode == CM_CMYK)
1204 								src_a = d[3] + src_a - src_a * d[3] / 128;
1205 						}
1206 						else if (layBlend ==  QLatin1String("div "))
1207 						{
1208 							src_r = src_r == 255 ? 255 : ((d[0] * 256) / (255-src_r)) > 255 ? 255 : (d[0] * 256) / (255-src_r);
1209 							src_g = src_g == 255 ? 255 : ((d[1] * 256) / (255-src_g)) > 255 ? 255 : (d[1] * 256) / (255-src_g);
1210 							src_b = src_b == 255 ? 255 : ((d[2] * 256) / (255-src_b)) > 255 ? 255 : (d[2] * 256) / (255-src_b);
1211 							if (header.color_mode == CM_CMYK)
1212 								src_a = src_a == 255 ? 255 : ((d[3] * 256) / (255-src_a)) > 255 ? 255 : (d[3] * 256) / (255-src_a);
1213 						}
1214 						else if (layBlend ==  QLatin1String("idiv"))
1215 						{
1216 							src_r = src_r == 0 ? 0 : (255 - (((255-d[0]) * 256) / src_r)) < 0 ? 0 : 255 - (((255-d[0]) * 256) / src_r);
1217 							src_g = src_g == 0 ? 0 : (255 - (((255-d[1]) * 256) / src_g)) < 0 ? 0 : 255 - (((255-d[1]) * 256) / src_g);
1218 							src_b = src_b == 0 ? 0 : (255 - (((255-d[2]) * 256) / src_b)) < 0 ? 0 : 255 - (((255-d[2]) * 256) / src_b);
1219 							if (header.color_mode == CM_CMYK)
1220 								src_a = src_a == 0 ? 0 : (255 - (((255-d[3]) * 256) / src_a)) < 0 ? 0 : 255 - (((255-d[3]) * 256) / src_a);
1221 						}
1222 						else if (layBlend ==  QLatin1String("hue "))
1223 						{
1224 							if (header.color_mode != CM_CMYK)
1225 							{
1226 								new_r = d[0];
1227 								new_g = d[1];
1228 								new_b = d[2];
1229 								RGBTOHSV(src_r, src_g, src_b);
1230 								RGBTOHSV(new_r, new_g, new_b);
1231 								new_r = src_r;
1232 								HSVTORGB(new_r, new_g, new_b);
1233 								src_r = new_r;
1234 								src_g = new_g;
1235 								src_b = new_b;
1236 							}
1237 						}
1238 						else if (layBlend ==  QLatin1String("sat "))
1239 						{
1240 							if (header.color_mode != CM_CMYK)
1241 							{
1242 								new_r = d[0];
1243 								new_g = d[1];
1244 								new_b = d[2];
1245 								RGBTOHSV(src_r, src_g, src_b);
1246 								RGBTOHSV(new_r, new_g, new_b);
1247 								new_g = src_g;
1248 								HSVTORGB(new_r, new_g, new_b);
1249 								src_r = new_r;
1250 								src_g = new_g;
1251 								src_b = new_b;
1252 							}
1253 						}
1254 						else if (layBlend ==  QLatin1String("lum "))
1255 						{
1256 							if (header.color_mode != CM_CMYK)
1257 							{
1258 								new_r = d[0];
1259 								new_g = d[1];
1260 								new_b = d[2];
1261 								RGBTOHSV(src_r, src_g, src_b);
1262 								RGBTOHSV(new_r, new_g, new_b);
1263 								new_b = src_b;
1264 								HSVTORGB(new_r, new_g, new_b);
1265 								src_r = new_r;
1266 								src_g = new_g;
1267 								src_b = new_b;
1268 							}
1269 						}
1270 						else if (layBlend ==  QLatin1String("colr"))
1271 						{
1272 							if (header.color_mode != CM_CMYK)
1273 							{
1274 								new_r = d[0];
1275 								new_g = d[1];
1276 								new_b = d[2];
1277 								RGBTOHLS(src_r, src_g, src_b);
1278 								RGBTOHLS(new_r, new_g, new_b);
1279 								new_r = src_r;
1280 								new_b = src_b;
1281 								HLSTORGB(new_r, new_g, new_b);
1282 								src_r = new_r;
1283 								src_g = new_g;
1284 								src_b = new_b;
1285 							}
1286 						}
1287 					}
1288 					if (dst_alpha == 0)
1289 					{
1290 						r = src_r;
1291 						g = src_g;
1292 						b = src_b;
1293 						a = src_a;
1294 					}
1295 					else
1296 					{
1297 						if (src_alpha > 0)
1298 						{
1299 							r = (d[0] * (255 - src_alpha) + src_r * src_alpha) / 255;
1300 							g = (d[1] * (255 - src_alpha) + src_g * src_alpha) / 255;
1301 							b = (d[2] * (255 - src_alpha) + src_b * src_alpha) / 255;
1302 							if (header.color_mode == CM_CMYK)
1303 								a = (d[3] * (255 - src_alpha) + src_a * src_alpha) / 255;
1304 							if (layBlend !=  QLatin1String("diss"))
1305 								src_alpha = dst_alpha + INT_MULT(255 - dst_alpha, src_alpha);
1306 						}
1307 					}
1308 					if (src_alpha > 0)
1309 					{
1310 						d[0] = r;
1311 						d[1] = g;
1312 						d[2] = b;
1313 						if (header.color_mode == CM_CMYK)
1314 						{
1315 							d[3] = a;
1316 							d[4] = src_alpha;
1317 						}
1318 						else
1319 							d[3] = src_alpha;
1320 					}
1321 					s += r2_image.channels();
1322 					d += r_image.channels();
1323 					if (hasMask)
1324 						sm += mask.channels();
1325 				}
1326 			}
1327 		}
1328 	}
1329 	*firstLayer = false;
1330 	return true;
1331 }
1332 
loadLayer(QDataStream & s,const PSDHeader & header)1333 bool ScImgDataLoader_PSD::loadLayer( QDataStream & s, const PSDHeader & header )
1334 {
1335 	ScColorMgmtEngine engine(ScCore->defaultEngine);
1336 	// Find out if the data is compressed.
1337 	// Known values:
1338 	//   0: no compression
1339 	//   1: RLE compressed
1340 	ushort compression;
1341 	uchar cbyte;
1342 	s >> compression;
1343 	if (compression > 1)
1344 	{
1345 		// Unknown compression type.
1346 		return false;
1347 	}
1348 	uint channel_num = header.channel_count;
1349 	r_image.fill('\xff');
1350 	const uint pixel_count = header.height * header.width;
1351 	static const uint components[5] = {0, 1, 2, 3, 4};
1352 	if (compression)
1353 	{
1354 		// Skip row lengths.
1355 		ushort w;
1356 		for (uint i = 0; i < header.height * header.channel_count; i++)
1357 		{
1358 			s >> w;
1359 		}
1360 		// Read RLE data.
1361 		uchar * ptr;
1362 		uint count = 0;
1363 		uchar c;
1364 		uint len;
1365 		for (uint channel = 0; channel < channel_num; channel++)
1366 		{
1367 			ptr = r_image.bits() + components[channel];
1368 			count = 0;
1369 			while (count < pixel_count)
1370 			{
1371 				if (s.atEnd())
1372 					return false;
1373 				s >> c;
1374 				len = c;
1375 				if (len < 128)
1376 				{
1377 					// Copy next len+1 bytes literally.
1378 					len++;
1379 					count += len;
1380 					if (count > pixel_count)
1381 						return false;
1382 					while (len != 0)
1383 					{
1384 						s >> cbyte;
1385 						if ((header.color_mode == CM_CMYK) && (components[channel] < 4))
1386 							cbyte = 255 - cbyte;
1387 						if ((header.color_mode == CM_GRAYSCALE) && (components[channel] != 3))
1388 						{
1389 							ptr -= components[channel];
1390 							ptr[0] = cbyte;
1391 							ptr[1] = cbyte;
1392 							ptr[2] = cbyte;
1393 							ptr += components[channel];
1394 						}
1395 						else if ((header.color_mode == CM_DUOTONE) && (components[channel] != 3))
1396 						{
1397 							ptr -= components[channel];
1398 							putDuotone(ptr, cbyte);
1399 							ptr += components[channel];
1400 						}
1401 						else if ((header.color_mode == CM_INDEXED) && (components[channel] != 3))
1402 						{
1403 							ptr -= components[channel];
1404 							int ccol = m_colorTable[cbyte];
1405 							ptr[0] = qRed(ccol);
1406 							ptr[1] = qGreen(ccol);
1407 							ptr[2] = qBlue(ccol);
1408 							ptr += components[channel];
1409 						}
1410 						else
1411 							*ptr = cbyte;
1412 						ptr += r_image.channels();
1413 						len--;
1414 					}
1415 				}
1416 				else if (len > 128)
1417 				{
1418 					// Next -len+1 bytes in the dest are replicated from next source byte.
1419 					// (Interpret len as a negative 8-bit int.)
1420 					len ^= 0xFF;
1421 					len += 2;
1422 					count += len;
1423 					if (s.atEnd() || count > pixel_count)
1424 						return false;
1425 					uchar val;
1426 					s >> val;
1427 					if ((header.color_mode == CM_CMYK) && (components[channel] < 4))
1428 						val = 255 - val;
1429 					while (len != 0)
1430 					{
1431 						if ((header.color_mode == CM_GRAYSCALE) && (components[channel] != 3))
1432 						{
1433 							ptr -= components[channel];
1434 							ptr[0] = val;
1435 							ptr[1] = val;
1436 							ptr[2] = val;
1437 							ptr += components[channel];
1438 						}
1439 						else if ((header.color_mode == CM_DUOTONE) && (components[channel] != 3))
1440 						{
1441 							ptr -= components[channel];
1442 							putDuotone(ptr, val);
1443 							ptr += components[channel];
1444 						}
1445 						else if ((header.color_mode == CM_INDEXED) && (components[channel] != 3))
1446 						{
1447 							ptr -= components[channel];
1448 							int ccol = m_colorTable[val];
1449 							ptr[0] = qRed(ccol);
1450 							ptr[1] = qGreen(ccol);
1451 							ptr[2] = qBlue(ccol);
1452 							ptr += components[channel];
1453 						}
1454 						else
1455 							*ptr = val;
1456 						ptr += r_image.channels();
1457 						len--;
1458 					}
1459 				}
1460 				else if (len == 128)
1461 				{
1462 					// No-op.
1463 				}
1464 			}
1465 		}
1466 	}
1467 	else
1468 	{
1469 		// We're at the raw image data.  It's each channel in order (Red, Green, Blue, Alpha, ...)
1470 		// where each channel consists of an 8-bit value for each pixel in the image.
1471 		// Read the data by channel.
1472 		uchar * ptr;
1473 		uint count = 0;
1474 		for (uint channel = 0; channel < channel_num; channel++)
1475 		{
1476 			ptr =  r_image.bits() + components[channel];
1477 			// Read the data.
1478 			count = pixel_count;
1479 			while (count != 0)
1480 			{
1481 				s >> cbyte;
1482 				if ((header.color_mode == CM_CMYK) && (components[channel] < 4))
1483 					cbyte = 255 - cbyte;
1484 				if ((header.color_mode == CM_GRAYSCALE) && (components[channel] != 3))
1485 				{
1486 					ptr -= components[channel];
1487 					ptr[0] = cbyte;
1488 					ptr[1] = cbyte;
1489 					ptr[2] = cbyte;
1490 					ptr += components[channel];
1491 				}
1492 				else if ((header.color_mode == CM_DUOTONE) && (components[channel] != 3))
1493 				{
1494 					ptr -= components[channel];
1495 					putDuotone(ptr, cbyte);
1496 					ptr += components[channel];
1497 				}
1498 				else if ((header.color_mode == CM_INDEXED) && (components[channel] != 3))
1499 				{
1500 					ptr -= components[channel];
1501 					int ccol = m_colorTable[cbyte];
1502 					ptr[0] = qRed(ccol);
1503 					ptr[1] = qGreen(ccol);
1504 					ptr[2] = qBlue(ccol);
1505 					ptr += components[channel];
1506 				}
1507 				else
1508 					*ptr = cbyte;
1509 				ptr += r_image.channels();
1510 				count--;
1511 			}
1512 		}
1513 	}
1514 	if (header.color_mode == CM_LABCOLOR)
1515 	{
1516 		ScColorProfile hsRGB = engine.createProfile_sRGB();
1517 		ScColorProfile hLab  = engine.createProfile_Lab();
1518 		ScColorTransform xform = engine.createTransform(hLab, Format_LabA_8, hsRGB, Format_RGBA_8, Intent_Perceptual, 0);
1519 		for (int i = 0; i < r_image.height(); i++)
1520 		{
1521 			uchar* ptr = r_image.scanLine(i);
1522 			xform.apply(ptr, ptr, r_image.width());
1523 		}
1524 	}
1525 	return true;
1526 }
1527 
getLayerString(QDataStream & s)1528 QString ScImgDataLoader_PSD::getLayerString(QDataStream & s)
1529 {
1530 	uchar len, tmp;
1531 	uint adj;
1532 	QString ret = "";
1533 	s >> len;
1534 	if (len == 0)
1535 	{
1536 		s >> tmp;
1537 		s >> tmp;
1538 		s >> tmp;
1539 		return ret;
1540 	}
1541 	for (int i = 0; i < len; i++)
1542 	{
1543 		s >> tmp;
1544 		ret += QChar(tmp);
1545 	}
1546 	adj = 0;
1547 	if (((ret.length()+1) % 4) != 0)
1548 		adj = 4 - ((ret.length()+1) % 4);
1549 	s.device()->seek( s.device()->pos() + adj );
1550 	return ret;
1551 }
1552 
IsValid(const PSDHeader & header)1553 bool ScImgDataLoader_PSD::IsValid( const PSDHeader & header )
1554 {
1555 	return header.signature == 0x38425053;
1556 }
1557 
1558 // Check that the header is supported.
IsSupported(const PSDHeader & header)1559 bool ScImgDataLoader_PSD::IsSupported( const PSDHeader & header )
1560 {
1561 	if ( header.version != 1 )
1562 		return false;
1563 	if ( header.channel_count > 16 )
1564 		return false;
1565 	if ( header.depth != 8 )
1566 		return false;
1567 	return (header.color_mode == CM_RGB) || (header.color_mode == CM_CMYK) || (header.color_mode == CM_LABCOLOR)
1568 	 || (header.color_mode == CM_GRAYSCALE) || (header.color_mode == CM_INDEXED) || (header.color_mode == CM_DUOTONE);
1569 }
1570 
putDuotone(uchar * ptr,uchar cbyte)1571 void ScImgDataLoader_PSD::putDuotone(uchar *ptr, uchar cbyte)
1572 {
1573 	CMYKColor cmyk;
1574 	int c, c1, c2, c3, m, m1, m2, m3, y, y1, y2, y3, k, k1, k2, k3;
1575 	uchar cb = 255 - cbyte;
1576 	ScColor col;
1577 	if (m_colorTableSc.count() == 1)
1578 	{
1579 		m_colorTableSc[0].getRawRGBColor(&c, &m, &y);
1580 		ptr[0] = qMin((c * m_curveTable1[(int)cbyte]) >> 8, 255);
1581 		ptr[1] = qMin((m * m_curveTable1[(int)cbyte]) >> 8, 255);
1582 		ptr[2] = qMin((y * m_curveTable1[(int)cbyte]) >> 8, 255);
1583 	}
1584 	else if (m_colorTableSc.count() == 2)
1585 	{
1586 		ScColorEngine::getCMYKValues(m_colorTableSc[0], nullptr, cmyk);
1587 		cmyk.getValues(c, m, y, k);
1588 		c = qMin((c * m_curveTable1[(int)cb]) >> 8, 255);
1589 		m = qMin((m * m_curveTable1[(int)cb]) >> 8, 255);
1590 		y = qMin((y * m_curveTable1[(int)cb]) >> 8, 255);
1591 		k = qMin((k * m_curveTable1[(int)cb]) >> 8, 255);
1592 		ScColorEngine::getCMYKValues(m_colorTableSc[1], nullptr, cmyk);
1593 		cmyk.getValues(c1, m1, y1, k1);
1594 		c1 = qMin((c1 * m_curveTable2[(int)cb]) >> 8, 255);
1595 		m1 = qMin((m1 * m_curveTable2[(int)cb]) >> 8, 255);
1596 		y1 = qMin((y1 * m_curveTable2[(int)cb]) >> 8, 255);
1597 		k1 = qMin((k1 * m_curveTable2[(int)cb]) >> 8, 255);
1598 		col = ScColor(qMin(c+c1, 255), qMin(m+m1, 255), qMin(y+y1, 255), qMin(k+k1, 255));
1599 		col.getRawRGBColor(&c, &m, &y);
1600 		ptr[0] = c;
1601 		ptr[1] = m;
1602 		ptr[2] = y;
1603 	}
1604 	else if (m_colorTableSc.count() == 3)
1605 	{
1606 		ScColorEngine::getCMYKValues(m_colorTableSc[0], nullptr, cmyk);
1607 		cmyk.getValues(c, m, y, k);
1608 		c = qMin((c * m_curveTable1[(int)cb]) >> 8, 255);
1609 		m = qMin((m * m_curveTable1[(int)cb]) >> 8, 255);
1610 		y = qMin((y * m_curveTable1[(int)cb]) >> 8, 255);
1611 		k = qMin((k * m_curveTable1[(int)cb]) >> 8, 255);
1612 		ScColorEngine::getCMYKValues(m_colorTableSc[1], nullptr, cmyk);
1613 		cmyk.getValues(c1, m1, y1, k1);
1614 		c1 = qMin((c1 * m_curveTable2[(int)cb]) >> 8, 255);
1615 		m1 = qMin((m1 * m_curveTable2[(int)cb]) >> 8, 255);
1616 		y1 = qMin((y1 * m_curveTable2[(int)cb]) >> 8, 255);
1617 		k1 = qMin((k1 * m_curveTable2[(int)cb]) >> 8, 255);
1618 		ScColorEngine::getCMYKValues(m_colorTableSc[2], nullptr, cmyk);
1619 		cmyk.getValues(c2, m2, y2, k2);
1620 		c2 = qMin((c2 * m_curveTable3[(int)cb]) >> 8, 255);
1621 		m2 = qMin((m2 * m_curveTable3[(int)cb]) >> 8, 255);
1622 		y2 = qMin((y2 * m_curveTable3[(int)cb]) >> 8, 255);
1623 		k2 = qMin((k2 * m_curveTable3[(int)cb]) >> 8, 255);
1624 		col = ScColor(qMin(c+c1+c2, 255), qMin(m+m1+m2, 255), qMin(y+y1+y2, 255), qMin(k+k1+k2, 255));
1625 		col.getRawRGBColor(&c, &m, &y);
1626 		ptr[0] = c;
1627 		ptr[1] = m;
1628 		ptr[2] = y;
1629 	}
1630 	else if (m_colorTableSc.count() == 4)
1631 	{
1632 		ScColorEngine::getCMYKValues(m_colorTableSc[0], nullptr, cmyk);
1633 		cmyk.getValues(c, m, y, k);
1634 		c = qMin((c * m_curveTable1[(int)cb]) >> 8, 255);
1635 		m = qMin((m * m_curveTable1[(int)cb]) >> 8, 255);
1636 		y = qMin((y * m_curveTable1[(int)cb]) >> 8, 255);
1637 		k = qMin((k * m_curveTable1[(int)cb]) >> 8, 255);
1638 		ScColorEngine::getCMYKValues(m_colorTableSc[1], nullptr, cmyk);
1639 		cmyk.getValues(c1, m1, y1, k1);
1640 		c1 = qMin((c1 * m_curveTable2[(int)cb]) >> 8, 255);
1641 		m1 = qMin((m1 * m_curveTable2[(int)cb]) >> 8, 255);
1642 		y1 = qMin((y1 * m_curveTable2[(int)cb]) >> 8, 255);
1643 		k1 = qMin((k1 * m_curveTable2[(int)cb]) >> 8, 255);
1644 		ScColorEngine::getCMYKValues(m_colorTableSc[2], nullptr, cmyk);
1645 		cmyk.getValues(c2, m2, y2, k2);
1646 		c2 = qMin((c2 * m_curveTable3[(int)cb]) >> 8, 255);
1647 		m2 = qMin((m2 * m_curveTable3[(int)cb]) >> 8, 255);
1648 		y2 = qMin((y2 * m_curveTable3[(int)cb]) >> 8, 255);
1649 		k2 = qMin((k2 * m_curveTable3[(int)cb]) >> 8, 255);
1650 		ScColorEngine::getCMYKValues(m_colorTableSc[3], nullptr, cmyk);
1651 		cmyk.getValues(c3, m3, y3, k3);
1652 		c3 = qMin((c3 * m_curveTable4[(int)cb]) >> 8, 255);
1653 		m3 = qMin((m3 * m_curveTable4[(int)cb]) >> 8, 255);
1654 		y3 = qMin((y3 * m_curveTable4[(int)cb]) >> 8, 255);
1655 		k3 = qMin((k3 * m_curveTable4[(int)cb]) >> 8, 255);
1656 		col = ScColor(qMin(c+c1+c2+c3, 255), qMin(m+m1+m2+m3, 255), qMin(y+y1+y2+y3, 255), qMin(k+k1+k2+k3, 255));
1657 		col.getRawRGBColor(&c, &m, &y);
1658 		ptr[0] = c;
1659 		ptr[1] = m;
1660 		ptr[2] = y;
1661 	}
1662 }
1663