Subversion Repositories Scribus

Rev

Rev 22724 | Rev 23235 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

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