Subversion Repositories Scribus

Rev

Rev 24643 | Rev 24646 | 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
 
24643 jghali 54
        uint32_t EmbedLen = 0;
22536 jghali 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
 
24643 jghali 159
        uint16_t extrasamples, *extratypes;
18925 jghali 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
 
24643 jghali 251
bool ScImgDataLoader_TIFF::getImageData(TIFF* tif, RawImage *image, uint widtht, uint heightt, uint size, uint16_t photometric, uint16_t bitspersample, uint16_t samplesperpixel, bool &bilevel, bool &isCMYK)
11540 fschmid 252
{
24643 jghali 253
        uint32_t *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
                        {
24643 jghali 269
                                uint32_t columns, rows;
270
                                uint32_t *tile_buf;
271
                                uint32_t xt, yt;
6589 fschmid 272
                                TIFFGetField(tif, TIFFTAG_TILEWIDTH,  &columns);
273
                                TIFFGetField(tif, TIFFTAG_TILELENGTH, &rows);
24643 jghali 274
                                tile_buf = (uint32_t*) _TIFFmalloc(columns * rows * sizeof(uint32_t));
22518 craig 275
                                if (tile_buf == nullptr)
6589 fschmid 276
                                {
277
                                        TIFFClose(tif);
278
                                        return false;
279
                                }
24643 jghali 280
                                uint32_t tileW = columns, tileH = rows;
281
                                for (yt = 0; yt < (uint32_t) image->height(); yt += rows)
6589 fschmid 282
                                {
283
                                        if (yt > (uint) image->height())
284
                                                break;
285
                                        if (image->height()-yt < rows)
24645 jghali 286
                                                tileH = image->height() - yt;
6589 fschmid 287
                                        tileW = columns;
24643 jghali 288
                                        uint32_t 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
                                                {
24645 jghali 295
                                                        _TIFFmemcpy(image->scanLine(yt + (tileH - 1 - yi)) + xt, tile_buf + tileW * yi, tileW * chans);
6854 fschmid 296
                                                }
6589 fschmid 297
                                        }
298
                                }
299
                                _TIFFfree(tile_buf);
300
                        }
301
                        else
302
                        {
303
                                tsize_t bytesperrow = TIFFScanlineSize(tif);
24643 jghali 304
                                bits = (uint32_t *) _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
 
24643 jghali 354
bool ScImgDataLoader_TIFF::getImageData_RGBA(TIFF* tif, RawImage *image, uint widtht, uint heightt, uint size, uint16_t bitspersample, uint16_t samplesperpixel)
11537 jghali 355
{
24643 jghali 356
        uint32_t* bits = (uint32_t *) _TIFFmalloc(size * sizeof(uint32_t));
23202 jghali 357
        if (!bits)
358
                return false;
359
 
24643 jghali 360
        uint16_t  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;
24643 jghali 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;
23235 jghali 655
        short resolutionunit = RESUNIT_INCH; // Default unit is inch
5937 jghali 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;
24643 jghali 696
        uint16_t 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;
24643 jghali 726
        uint32_t EmbedLen = 0;
22536 jghali 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();
23537 jghali 734
                m_imageInfoRecord.embeddedProfileName = m_imageInfoRecord.profileName;
22536 jghali 735
                m_imageInfoRecord.isEmbedded = true;
736
        }
737
        else
738
        {
739
                m_imageInfoRecord.isEmbedded = false;
23537 jghali 740
                m_imageInfoRecord.profileName.clear();
741
                m_imageInfoRecord.embeddedProfileName.clear();
22536 jghali 742
        }
743
        unsigned int PhotoshopLen = 0;
744
        unsigned char* PhotoshopBuffer;
745
        if (TIFFGetField(tif, TIFFTAG_PHOTOSHOP, &PhotoshopLen, &PhotoshopBuffer) )
746
        {
747
                if (PhotoshopLen != 0)
5937 jghali 748
                {
22536 jghali 749
                        QByteArray arrayPhot = QByteArray((const char*)PhotoshopBuffer,PhotoshopLen);
750
                        QDataStream strPhot(&arrayPhot,QIODevice::ReadOnly);
751
                        strPhot.setByteOrder( QDataStream::BigEndian );
752
                        PSDHeader fakeHeader;
753
                        fakeHeader.width = widtht;
754
                        fakeHeader.height = heightt;
24186 craig 755
                        parseResourceData(strPhot, fakeHeader, PhotoshopLen);
22536 jghali 756
                        m_imageInfoRecord.exifInfo.width = widtht;
757
                        m_imageInfoRecord.exifInfo.height = heightt;
758
                        if (!m_imageInfoRecord.valid)
22605 craig 759
                                m_imageInfoRecord.valid = (m_imageInfoRecord.PDSpathData.size())>0;
22536 jghali 760
                        if (thumbnail)
5937 jghali 761
                        {
22536 jghali 762
                                if (m_photometric == PHOTOMETRIC_SEPARATED)
6766 fschmid 763
                                {
22536 jghali 764
                                        isCMYK = true;
765
                                        m_imageInfoRecord.colorspace = ColorSpaceCMYK;
766
                                }
767
                                else if (m_samplesperpixel == 1)
768
                                {
769
                                        m_imageInfoRecord.colorspace = ColorSpaceGray;
770
                                        isCMYK = false;
771
                                }
772
                                else
773
                                        m_imageInfoRecord.colorspace = ColorSpaceRGB;
774
                                if (bitspersample == 1)
775
                                        bilevel = true;
776
                                if (!m_imageInfoRecord.exifInfo.thumbnail.isNull())
777
                                {
778
                                        if (isCMYK)
6766 fschmid 779
                                        {
22536 jghali 780
                                                r_image.create(m_imageInfoRecord.exifInfo.thumbnail.width(), m_imageInfoRecord.exifInfo.thumbnail.height(), 5);
781
                                                m_pixelFormat = Format_CMYKA_8;;
6766 fschmid 782
                                        }
22536 jghali 783
                                        else
12732 fschmid 784
                                        {
22536 jghali 785
                                                r_image.create(m_imageInfoRecord.exifInfo.thumbnail.width(), m_imageInfoRecord.exifInfo.thumbnail.height(), 4);
786
                                                m_pixelFormat = (m_imageInfoRecord.colorspace == ColorSpaceCMYK) ? Format_CMYK_8 : Format_RGBA_8;
12732 fschmid 787
                                        }
22536 jghali 788
                                        r_image.fill(0);
789
                                        QRgb *s;
790
                                        uchar *d;
791
                                        unsigned char cc, cm, cy, ck;
24416 jghali 792
                                        for (int yit = 0; yit < m_imageInfoRecord.exifInfo.thumbnail.height(); ++yit)
6766 fschmid 793
                                        {
24416 jghali 794
                                                s = (QRgb*)(m_imageInfoRecord.exifInfo.thumbnail.scanLine(yit));
795
                                                d = r_image.scanLine(yit);
796
                                                for (int xit = 0; xit < m_imageInfoRecord.exifInfo.thumbnail.width(); ++xit)
15128 jghali 797
                                                {
22536 jghali 798
                                                        if (isCMYK)
6766 fschmid 799
                                                        {
22536 jghali 800
                                                                cc = 255 - qRed(*s);
801
                                                                cm = 255 - qGreen(*s);
802
                                                                cy = 255 - qBlue(*s);
803
                                                                ck = qMin(qMin(cc, cm), cy);
804
                                                                d[0] = cc-ck;
805
                                                                d[1] = cm-ck;
806
                                                                d[2] = cy-ck;
807
                                                                d[3] = ck;
808
                                                                d[4] = 255;
6766 fschmid 809
                                                        }
22536 jghali 810
                                                        else
811
                                                        {
812
                                                                d[0] = qRed(*s);
813
                                                                d[1] = qGreen(*s);
814
                                                                d[2] = qBlue(*s);
815
                                                                d[3] = 255;
816
                                                        }
817
                                                        s++;
818
                                                        d += r_image.channels();
6766 fschmid 819
                                                }
820
                                        }
22536 jghali 821
                                        TIFFClose(tif);
822
                                        return true;
6766 fschmid 823
                                }
5937 jghali 824
                        }
825
                }
22536 jghali 826
        }
18925 jghali 827
 
22536 jghali 828
        unsigned int PhotoshopLen2 = 0;
829
        unsigned char* PhotoshopBuffer2;
830
        int gotField = TIFFGetField(tif, 37724, &PhotoshopLen2, &PhotoshopBuffer2);
831
        if (gotField && (PhotoshopLen2 > 40))
832
        {
833
                m_imageInfoRecord.layerInfo.clear();
834
                QByteArray arrayPhot = QByteArray::fromRawData((const char*)PhotoshopBuffer2, PhotoshopLen2);
835
                QDataStream s(&arrayPhot,QIODevice::ReadOnly);
836
                if (byteOrder[0] == 'M')
837
                        s.setByteOrder( QDataStream::BigEndian );
838
                else
839
                        s.setByteOrder( QDataStream::LittleEndian );
18925 jghali 840
 
22536 jghali 841
                failedPS = !loadLayerInfo(s, m_imageInfoRecord.layerInfo);
842
                if (!failedPS)
6589 fschmid 843
                {
6850 fschmid 844
                        int chans = 4;
22536 jghali 845
                        int numChannels = m_imageInfoRecord.layerInfo.last().channelType.count();
846
                        int numLayers = m_imageInfoRecord.layerInfo.count();
847
                        PSDHeader fakeHeader;
848
                        fakeHeader.width = widtht;
849
                        fakeHeader.height = heightt;
850
                        fakeHeader.channel_count = numChannels;
851
                        fakeHeader.depth = 8;
20691 craig 852
                        if (m_photometric == PHOTOMETRIC_SEPARATED)
6589 fschmid 853
                        {
22536 jghali 854
                                isCMYK = true;
855
                                fakeHeader.color_mode = CM_CMYK;
856
                                chans = 5;
6850 fschmid 857
                        }
22536 jghali 858
                        else if (m_samplesperpixel == 1)
859
                        {
860
                                fakeHeader.color_mode = CM_GRAYSCALE;
861
                                isCMYK = false;
862
                                chans = 4;
863
                        }
6850 fschmid 864
                        else
22536 jghali 865
                        {
866
                                fakeHeader.color_mode = CM_RGB;
867
                                isCMYK = false;
6850 fschmid 868
                                chans = 4;
22536 jghali 869
                        }
6850 fschmid 870
                        if (!r_image.create(widtht, heightt, chans))
6589 fschmid 871
                                return false;
8767 fschmid 872
                        r_image.fill(0);
22536 jghali 873
                        bool firstLayer = true;
874
                        for (int layer = 0; layer < numLayers; layer++)
6589 fschmid 875
                        {
22536 jghali 876
                                loadLayerChannels( s, fakeHeader, m_imageInfoRecord.layerInfo, layer, &firstLayer );
6589 fschmid 877
                        }
22536 jghali 878
                        arrayPhot.clear();
6766 fschmid 879
                        TIFFClose(tif);
22536 jghali 880
                        foundPS = true;
881
                        if (m_imageInfoRecord.layerInfo.count() == 1)
882
                                m_imageInfoRecord.layerInfo.clear();
6589 fschmid 883
                }
22536 jghali 884
                else
5937 jghali 885
                {
22536 jghali 886
                        arrayPhot.clear();
887
                        getLayers(fn, page);
5937 jghali 888
                }
22536 jghali 889
        }
890
 
891
        if (xres <= 1.0 || yres <= 1.0)
892
        {
893
                xres = yres = 72.0;
894
                QFileInfo qfi(fn);
895
                m_message = QObject::tr("%1 may be corrupted : missing resolution tags").arg(qfi.fileName());
896
                m_msgType = warningMsg;
897
        }
898
        if ((!foundPS) || (failedPS))
899
        {
900
                int chans = 4;
901
                if (m_photometric == PHOTOMETRIC_SEPARATED)
5937 jghali 902
                {
22536 jghali 903
                        if (m_samplesperpixel > 5)
904
                                chans = 4;
905
                        else
906
                                chans = m_samplesperpixel;
5937 jghali 907
                }
22536 jghali 908
                else
909
                        chans = 4;
910
                if (!r_image.create(widtht, heightt, chans))
15182 jghali 911
                {
22536 jghali 912
                        TIFFClose(tif);
913
                        return false;
15182 jghali 914
                }
22536 jghali 915
                r_image.fill(0);
916
                int layerNum = 0;
917
                do
15182 jghali 918
                {
22536 jghali 919
                        RawImage tmpImg;
920
                        if (!tmpImg.create(widtht, heightt, chans))
17758 jghali 921
                        {
22536 jghali 922
                                TIFFClose(tif);
923
                                return false;
17758 jghali 924
                        }
22536 jghali 925
 
926
                        tmpImg.fill(0);
927
                        if (!getImageData(tif, &tmpImg, widtht, heightt, size, m_photometric, bitspersample, m_samplesperpixel, bilevel, isCMYK))
928
                        {
929
                                TIFFClose(tif);
930
                                return false;
931
                        }
932
                        bool visible = true;
933
                        bool useMask = true;
934
                        if ((m_imageInfoRecord.isRequest) && (m_imageInfoRecord.RequestProps.contains(layerNum)))
935
                                visible = m_imageInfoRecord.RequestProps[layerNum].visible;
22700 craig 936
                        QString layBlend("norm");
22536 jghali 937
                        if ((m_imageInfoRecord.isRequest) && (m_imageInfoRecord.RequestProps.contains(layerNum)))
938
                                layBlend = m_imageInfoRecord.RequestProps[layerNum].blend;
939
                        if ((m_imageInfoRecord.isRequest) && (m_imageInfoRecord.RequestProps.contains(layerNum)))
940
                                useMask = m_imageInfoRecord.RequestProps[layerNum].useMask;
941
                        int layOpa = 255;
942
                        if ((m_imageInfoRecord.isRequest) && (m_imageInfoRecord.RequestProps.contains(layerNum)))
943
                                layOpa = m_imageInfoRecord.RequestProps[layerNum].opacity;
944
                        if (visible)
945
                        {
946
                                if ((layerNum == 0) && (layBlend != "diss"))
947
                                        r_image = tmpImg;
948
                                else
949
                                        blendOntoTarget(&tmpImg, layOpa, layBlend, isCMYK, useMask);
950
                        }
951
                        //JG Copy should not be necessary as QImage is implicitly shared in Qt4
952
                        QImage imt; //QImage imt = tmpImg.copy();
953
                        double sx = tmpImg.width() / 40.0;
954
                        double sy = tmpImg.height() / 40.0;
22605 craig 955
                        imt = tmpImg.convertToQImage(chans > 4);
22536 jghali 956
                        imt = sy < sx ? imt.scaled(qRound(imt.width() / sx), qRound(imt.height() / sx), Qt::IgnoreAspectRatio, Qt::SmoothTransformation) :
957
                                                                                imt.scaled(qRound(imt.width() / sy), qRound(imt.height() / sy), Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
958
                        m_imageInfoRecord.layerInfo[layerNum].thumb = imt.copy();
959
                        if (chans > 4)
960
                        {
961
                                QImage imt2 = imt.createAlphaMask();
962
                                imt2.invertPixels();
963
                                m_imageInfoRecord.layerInfo[layerNum].thumb_mask = imt2.copy();
964
                        }
17758 jghali 965
                        else
22536 jghali 966
                                m_imageInfoRecord.layerInfo[layerNum].thumb_mask = QImage();
967
                        layerNum++;
968
 
969
                        if ((m_imageInfoRecord.layerInfo.count() == 1) && (chans < 5))
970
                                m_imageInfoRecord.layerInfo.clear();
971
                        test = TIFFReadDirectory(tif);
972
 
973
                        // #10415 : check that image size for the current directory is the same as the main one
974
                        // Some progs use tiff directory to store previews, we do not handle such case
975
                        // and may perform reads in non allocated blocks if we continue
976
                        while (test == 1)
17758 jghali 977
                        {
22536 jghali 978
                                unsigned int dirWidth(0), dirHeight(0);
979
                                TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &dirWidth);
980
                                TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &dirHeight);
981
                                if (dirWidth == widtht && dirHeight == heightt)
982
                                        break;
983
                                test = TIFFReadDirectory(tif);
984
                                layerNum++;
17758 jghali 985
                        }
15182 jghali 986
                }
22536 jghali 987
                while (test == 1);
988
                TIFFClose(tif);
989
        }
990
        if (resolutionunit == RESUNIT_INCH)
991
        {
992
                m_image.setDotsPerMeterX ((int) (xres / 0.0254));
993
                m_image.setDotsPerMeterY ((int) (yres / 0.0254));
994
                m_imageInfoRecord.xres = qRound(xres);
995
                m_imageInfoRecord.yres = qRound(yres);
996
        }
997
        else if (resolutionunit == RESUNIT_CENTIMETER)
998
        {
999
                m_image.setDotsPerMeterX ((int) (xres * 100.0));
1000
                m_image.setDotsPerMeterY ((int) (yres * 100.0));
1001
                m_imageInfoRecord.xres = qRound(xres*2.54);
1002
                m_imageInfoRecord.yres = qRound(yres*2.54);
1003
        }
1004
        if (isCMYK)
1005
        {
1006
                m_imageInfoRecord.colorspace = ColorSpaceCMYK;
1007
                m_pixelFormat = (r_image.channels() == 5) ? Format_CMYKA_8 : Format_CMYK_8;
1008
        }
1009
        else if (m_samplesperpixel == 1)
1010
        {
1011
                // Do not set m_pixelFormat here as the real pixel format is most probably different than gray
1012
                if (bitspersample == 1)
1013
                        m_imageInfoRecord.colorspace = ColorSpaceMonochrome;
5937 jghali 1014
                else
22536 jghali 1015
                        m_imageInfoRecord.colorspace = ColorSpaceGray;
5937 jghali 1016
        }
22536 jghali 1017
        else
1018
        {
1019
                m_imageInfoRecord.colorspace = ColorSpaceRGB;
1020
                m_pixelFormat = Format_RGBA_8;
1021
        }
1022
        m_imageInfoRecord.BBoxX = 0;
1023
        m_imageInfoRecord.BBoxH = r_image.height();
24256 craig 1024
        m_imageInfoRecord.valid = !(m_imageInfoRecord.layerInfo.isEmpty() && m_imageInfoRecord.PDSpathData.isEmpty());
22536 jghali 1025
        return true;
5937 jghali 1026
}
6736 fschmid 1027
 
1028
QString ScImgDataLoader_TIFF::getLayerString(QDataStream & s)
1029
{
1030
        uchar len, tmp;
1031
        uint adj;
1032
        QString ret = "";
1033
        s >> len;
1034
        if (len == 0)
1035
        {
1036
                s >> tmp;
1037
                s >> tmp;
1038
                s >> tmp;
1039
                return ret;
1040
        }
22536 jghali 1041
        for (int i = 0; i < len; i++)
6736 fschmid 1042
        {
1043
                s >> tmp;
1044
                ret += QChar(tmp);
1045
        }
1046
        adj = 0;
1047
        if (((ret.length()+1) % 4) != 0)
1048
                adj = 4 - ((ret.length()+1) % 4);
10562 fschmid 1049
        s.device()->seek( s.device()->pos() + adj );
6736 fschmid 1050
        return ret;
1051
}
6766 fschmid 1052
 
9803 fschmid 1053
bool ScImgDataLoader_TIFF::loadChannel( QDataStream & s, const PSDHeader & header, QList<PSDLayer> &layerInfo, uint layer, int channel, int component, RawImage &tmpImg)
6766 fschmid 1054
{
24643 jghali 1055
        qint64 base = s.device()->pos();
6766 fschmid 1056
        uchar cbyte;
1057
        ushort compression;
1058
        s >> compression;
22536 jghali 1059
        if (compression > 1)
6766 fschmid 1060
                return false;
1061
        if (compression == 0)
1062
        {
24643 jghali 1063
                int count = layerInfo[layer].channelLen[channel] - 2;
6766 fschmid 1064
                for (int i = 0; i < tmpImg.height(); i++)
1065
                {
1066
                        uchar *ptr =  tmpImg.scanLine(i);
1067
                        for (int j = 0; j < tmpImg.width(); j++)
1068
                        {
1069
                                s >> cbyte;
1070
                                count--;
6850 fschmid 1071
                                if ((header.color_mode == CM_CMYK) && (component < 4))
6766 fschmid 1072
                                        cbyte = 255 - cbyte;
12732 fschmid 1073
                                if ((header.color_mode == CM_GRAYSCALE) && (component != 3))
1074
                                {
1075
                                        ptr[0] = cbyte;
1076
                                        ptr[1] = cbyte;
1077
                                        ptr[2] = cbyte;
1078
                                }
1079
                                else
1080
                                        ptr[component] = cbyte;
6766 fschmid 1081
                                if (count == 0)
1082
                                        break;
6850 fschmid 1083
                                ptr += tmpImg.channels();
6766 fschmid 1084
                        }
1085
                        if (count == 0)
1086
                                break;
1087
                }
1088
        }
1089
        else
1090
        {
10562 fschmid 1091
                s.device()->seek( s.device()->pos() + tmpImg.height() * 2 );
6766 fschmid 1092
                uint pixel_count = tmpImg.width();
1093
                for (int hh = 0; hh < tmpImg.height(); hh++)
1094
                {
1095
                        uint count = 0;
1096
                        uchar *ptr = tmpImg.scanLine(hh);
6850 fschmid 1097
                        uchar *ptr2 = ptr+tmpImg.width() * tmpImg.channels();
6766 fschmid 1098
                        ptr += component;
22724 jghali 1099
                        while (count < pixel_count)
6766 fschmid 1100
                        {
1101
                                uchar c;
22536 jghali 1102
                                if (s.atEnd())
6766 fschmid 1103
                                        return false;
1104
                                s >> c;
1105
                                uint len = c;
22536 jghali 1106
                                if (len < 128)
6766 fschmid 1107
                                {
1108
                                        // Copy next len+1 bytes literally.
1109
                                        len++;
1110
                                        count += len;
22724 jghali 1111
                                        while (len != 0)
6766 fschmid 1112
                                        {
1113
                                                s >> cbyte;
1114
                                                if (ptr < ptr2)
1115
                                                {
6850 fschmid 1116
                                                        if ((header.color_mode == CM_CMYK) && (component < 4))
6766 fschmid 1117
                                                                cbyte = 255 - cbyte;
12732 fschmid 1118
                                                        if ((header.color_mode == CM_GRAYSCALE) && (component != 3))
1119
                                                        {
1120
                                                                ptr -= component;
1121
                                                                ptr[0] = cbyte;
1122
                                                                ptr[1] = cbyte;
1123
                                                                ptr[2] = cbyte;
1124
                                                                ptr += component;
1125
                                                        }
1126
                                                        else
1127
                                                                *ptr = cbyte;
6766 fschmid 1128
                                                }
6850 fschmid 1129
                                                ptr += tmpImg.channels();
6766 fschmid 1130
                                                len--;
1131
                                        }
1132
                                }
22536 jghali 1133
                                else if (len > 128)
6766 fschmid 1134
                                {
1135
                                        // Next -len+1 bytes in the dest are replicated from next source byte.
1136
                                        // (Interpret len as a negative 8-bit int.)
1137
                                        len ^= 0xFF;
1138
                                        len += 2;
1139
                                        count += len;
1140
                                        uchar val;
1141
                                        s >> val;
6850 fschmid 1142
                                        if ((header.color_mode == CM_CMYK) && (component < 4))
6766 fschmid 1143
                                                val = 255 - val;
22724 jghali 1144
                                        while (len != 0)
6766 fschmid 1145
                                        {
1146
                                                if (ptr < ptr2)
12732 fschmid 1147
                                                {
1148
                                                        if ((header.color_mode == CM_GRAYSCALE) && (component != 3))
1149
                                                        {
1150
                                                                ptr -= component;
1151
                                                                ptr[0] = val;
1152
                                                                ptr[1] = val;
1153
                                                                ptr[2] = val;
1154
                                                                ptr += component;
1155
                                                        }
1156
                                                        else
1157
                                                                *ptr = val;
1158
                                                }
6850 fschmid 1159
                                                ptr += tmpImg.channels();
6766 fschmid 1160
                                                len--;
1161
                                        }
1162
                                }
22536 jghali 1163
                                else if (len == 128)
6766 fschmid 1164
                                {
1165
                                        // No-op.
1166
                                }
1167
                        }
1168
                }
1169
        }
24643 jghali 1170
        s.device()->seek( base + layerInfo[layer].channelLen[channel] );
6766 fschmid 1171
        return true;
1172
}
1173
 
18925 jghali 1174
bool ScImgDataLoader_TIFF::loadLayerInfo(QDataStream & s, QList<PSDLayer> &layerInfo)
1175
{
1176
        bool failedPS = false;
1177
        uint addRes, layerinfo, channelLen, signature, extradata, layermasksize, layerRange, dummy;
1178
        int top, left, bottom, right;
1179
        short numLayers, numChannels;
1180
        short channelType;
1181
        uchar blendKey[4];
1182
        uchar opacity, clipping, flags, filler;
21939 craig 1183
        QString blend;
18925 jghali 1184
 
1185
        layerInfo.clear();
1186
 
1187
        struct PSDLayer lay;
1188
        do
1189
        {
22536 jghali 1190
                if (s.atEnd())
18925 jghali 1191
                {
1192
                        layerInfo.clear();
1193
                        failedPS = true;
1194
                        break;
1195
                }
1196
                s >> signature;
1197
        }
1198
        while (signature != 0x4c617972);
1199
 
1200
        if (failedPS)
1201
                return false;
1202
 
1203
        s >> layerinfo;
1204
        s >> numLayers;
1205
        if (numLayers < 0)
1206
                numLayers = -numLayers;
1207
        if (numLayers == 0)
1208
                return true;
1209
 
1210
        QDataStream::ByteOrder byteOrder = s.byteOrder();
1211
 
1212
        for (int layer = 0; layer < numLayers; layer++)
1213
        {
1214
                s >> top;
1215
                lay.ypos = top;
1216
                s >> left;
1217
                lay.xpos = left;
1218
                s >> bottom;
1219
                lay.height = bottom - top;
1220
                s >> right;
1221
                lay.width = right - left;
1222
                s >> numChannels;
1223
                if (numChannels > 6)    // we don't support images with more than 6 channels yet
1224
                {
1225
                        m_imageInfoRecord.layerInfo.clear();
1226
                        failedPS = true;
1227
                        break;
1228
                }
1229
                lay.channelType.clear();
1230
                lay.channelLen.clear();
1231
                for (int channels = 0; channels < numChannels; channels++)
1232
                {
1233
                        s >> channelType;
1234
                        s >> channelLen;
1235
                        lay.channelType.append(channelType);
1236
                        lay.channelLen.append(channelLen);
1237
                }
1238
                s >> signature;
1239
                blend = "";
22536 jghali 1240
                for (int i = 0; i < 4; i++)
18925 jghali 1241
                {
1242
                        s >> blendKey[i];
1243
                        if (byteOrder == QDataStream::BigEndian)
1244
                                blend.append(QChar(blendKey[i]));
1245
                        else
1246
                                blend.prepend(QChar(blendKey[i]));
1247
                }
1248
                lay.blend = blend;
1249
                s >> opacity;
1250
                lay.opacity = opacity;
1251
                s >> clipping;
1252
                lay.clipping = clipping;
1253
                s >> flags;
1254
                if (flags & 8)
1255
                {
1256
                        if (flags & 16) // Unknown combination of layer flags, probably an adjustment or effects layer
1257
                        {
1258
                                layerInfo.clear();
1259
                                failedPS = true;
1260
                                break;
1261
                        }
1262
                }
1263
                lay.flags = flags;
1264
                s >> filler;
1265
                s >> extradata;
1266
                s >> layermasksize;
1267
                lay.maskYpos = 0;
1268
                lay.maskXpos = 0;
1269
                lay.maskHeight = 0;
1270
                lay.maskWidth = 0;
1271
                if (layermasksize != 0)
1272
                {
1273
                        s >> lay.maskYpos;
1274
                        s >> lay.maskXpos;
1275
                        s >> dummy;
1276
                        lay.maskHeight = dummy - lay.maskYpos;
1277
                        s >> dummy;
1278
                        lay.maskWidth = dummy - lay.maskXpos;
1279
                        s >> dummy;
1280
                }
1281
                s >> layerRange;
1282
                s.device()->seek( s.device()->pos() + layerRange );
1283
                lay.layerName = getLayerString(s);
1284
                layerInfo.append(lay);
1285
                s >> signature;
22536 jghali 1286
                if (signature == 0x3842494D)
18925 jghali 1287
                {
22536 jghali 1288
                        while (signature == 0x3842494D)
18925 jghali 1289
                        {
1290
                                s >> signature;
1291
                                s >> addRes;
1292
                                s.device()->seek( s.device()->pos() + addRes );
1293
                                s >> signature;
1294
                        }
1295
                        s.device()->seek( s.device()->pos() - 4 );
1296
                }
1297
                else
1298
                {
1299
                        s.device()->seek( s.device()->pos() - 2 );
1300
                        s >> signature;
22536 jghali 1301
                        if (signature == 0x3842494D)
18925 jghali 1302
                        {
22536 jghali 1303
                                while (signature == 0x3842494D)
18925 jghali 1304
                                {
1305
                                        s >> signature;
1306
                                        s >> addRes;
1307
                                        s.device()->seek( s.device()->pos() + addRes );
1308
                                        s >> signature;
1309
                                }
1310
                                s.device()->seek( s.device()->pos() - 4 );
1311
                        }
1312
                        else
1313
                                s.device()->seek( s.device()->pos() - 6 );
1314
                }
1315
        }
1316
 
1317
        return (!failedPS && (layerInfo.count() >= 0));
1318
}
1319
 
9803 fschmid 1320
bool ScImgDataLoader_TIFF::loadLayerChannels( QDataStream & s, const PSDHeader & header, QList<PSDLayer> &layerInfo, uint layer, bool* firstLayer)
6766 fschmid 1321
{
1322
        // Find out if the data is compressed.
1323
        // Known values:
1324
        //   0: no compression
1325
        //   1: RLE compressed
24643 jghali 1326
        qint64 base = s.device()->pos();
1327
        qint64 base2 = base;
6766 fschmid 1328
        uint channel_num = layerInfo[layer].channelLen.count();
6850 fschmid 1329
        bool hasMask = false;
1330
        bool hasAlpha = false;
1331
        RawImage r2_image;
1332
        RawImage mask;
1333
        bool createOk = false;
1334
        if (header.color_mode == CM_CMYK)
6766 fschmid 1335
        {
8574 jghali 1336
                createOk = r2_image.create(layerInfo[layer].width, layerInfo[layer].height, qMax(channel_num, (uint) 5));
6850 fschmid 1337
                r2_image.fill(0);
1338
        }
1339
        else
1340
        {
8574 jghali 1341
                createOk = r2_image.create(layerInfo[layer].width, layerInfo[layer].height, qMax(channel_num, (uint) 4));
6850 fschmid 1342
                r2_image.fill(0);
1343
        }
22536 jghali 1344
        if (!createOk)
6850 fschmid 1345
        {
22536 jghali 1346
                for (uint channel = 0; channel < channel_num; channel++)
6766 fschmid 1347
                {
1348
                        base2 += layerInfo[layer].channelLen[channel];
1349
                }
10562 fschmid 1350
                s.device()->seek( base2 );
6766 fschmid 1351
                return false;
1352
        }
8574 jghali 1353
        channel_num = qMin(channel_num, (uint) 39);
23880 craig 1354
        uint components[40] = {0};
22536 jghali 1355
        for (uint channel = 0; channel < channel_num; channel++)
6766 fschmid 1356
        {
22724 jghali 1357
                switch (layerInfo[layer].channelType[channel])
6766 fschmid 1358
                {
1359
                case 0:
6850 fschmid 1360
                        components[channel] = 0;
6766 fschmid 1361
                        break;
1362
                case 1:
1363
                        components[channel] = 1;
1364
                        break;
1365
                case 2:
6850 fschmid 1366
                        components[channel] = 2;
6766 fschmid 1367
                        break;
1368
                case 3:
1369
                        components[channel] = 3;
1370
                        break;
1371
                case -1:
6850 fschmid 1372
                        if (header.color_mode == CM_CMYK)
1373
                        {
1374
                                if (channel_num == 6)
24416 jghali 1375
                                        components[channel] = channel_num - 2;
6850 fschmid 1376
                                else
24416 jghali 1377
                                        components[channel] = channel_num - 1;
6850 fschmid 1378
                        }
1379
                        else
1380
                        {
1381
                                if (channel_num == 5)
24416 jghali 1382
                                        components[channel] = channel_num - 2;
6850 fschmid 1383
                                else
12732 fschmid 1384
                                {
1385
                                        if (header.color_mode == CM_GRAYSCALE)
1386
                                                components[channel] = 3;
1387
                                        else
24416 jghali 1388
                                                components[channel] = channel_num - 1;
12732 fschmid 1389
                                }
6850 fschmid 1390
                        }
1391
                        hasAlpha = true;
1392
                        break;
6766 fschmid 1393
                case -2:
6850 fschmid 1394
                        components[channel] = channel_num-1;
6766 fschmid 1395
                        break;
1396
                }
1397
        }
6850 fschmid 1398
        if (!hasAlpha)
11543 jghali 1399
                r2_image.fill((char) 255);
22536 jghali 1400
        for (uint channel = 0; channel < channel_num; channel++)
6766 fschmid 1401
        {
1402
                if (layerInfo[layer].channelType[channel] == -2)
1403
                {
24416 jghali 1404
                        if (!mask.create( layerInfo[layer].maskWidth, layerInfo[layer].maskHeight, 1))
6766 fschmid 1405
                                break;
6850 fschmid 1406
                        mask.fill(0);
1407
                        if (!loadChannel(s, header, layerInfo, layer, channel, 0, mask))
6766 fschmid 1408
                                break;
6850 fschmid 1409
                        hasMask = true;
6766 fschmid 1410
                }
6850 fschmid 1411
                if (!loadChannel(s, header, layerInfo, layer, channel, components[channel], r2_image))
1412
                        break;
6766 fschmid 1413
        }
22536 jghali 1414
        for (uint channel = 0; channel < channel_num; channel++)
6766 fschmid 1415
        {
1416
                base2 += layerInfo[layer].channelLen[channel];
1417
        }
10562 fschmid 1418
        s.device()->seek( base2 );
6850 fschmid 1419
        QImage tmpImg2;
6766 fschmid 1420
        if (header.color_mode == CM_CMYK)
6850 fschmid 1421
                tmpImg2 = r2_image.convertToQImage(true);
1422
        else
1423
                tmpImg2 = r2_image.convertToQImage(false);
6766 fschmid 1424
        QImage imt;
6850 fschmid 1425
        double sx = tmpImg2.width() / 40.0;
1426
        double sy = tmpImg2.height() / 40.0;
10562 fschmid 1427
        imt = sy < sx ?  tmpImg2.scaled(qRound(tmpImg2.width() / sx), qRound(tmpImg2.height() / sx), Qt::IgnoreAspectRatio, Qt::SmoothTransformation) :
1428
              tmpImg2.scaled(qRound(tmpImg2.width() / sy), qRound(tmpImg2.height() / sy), Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
6766 fschmid 1429
        layerInfo[layer].thumb = imt.copy();
6850 fschmid 1430
        if (hasMask)
6766 fschmid 1431
        {
6850 fschmid 1432
                QImage imt2;
1433
                QImage tmpImg;
1434
                tmpImg = mask.convertToQImage(true);
1435
                double sx = tmpImg.width() / 40.0;
1436
                double sy = tmpImg.height() / 40.0;
10562 fschmid 1437
                imt2 = sy < sx ?  tmpImg.scaled(qRound(tmpImg.width() / sx), qRound(tmpImg.height() / sx), Qt::IgnoreAspectRatio, Qt::SmoothTransformation) :
1438
              tmpImg.scaled(qRound(tmpImg.width() / sy), qRound(tmpImg.height() / sy), Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
6766 fschmid 1439
                imt2.invertPixels();
1440
                layerInfo[layer].thumb_mask = imt2.copy();
1441
        }
1442
        else
1443
                layerInfo[layer].thumb_mask = QImage();
22533 jghali 1444
        if (!m_imageInfoRecord.isRequest || !m_imageInfoRecord.RequestProps.contains(layer))
6766 fschmid 1445
                m_imageInfoRecord.RequestProps[layer].useMask = true;
1446
        bool visible = !(layerInfo[layer].flags & 2);
1447
        if ((m_imageInfoRecord.isRequest) && (m_imageInfoRecord.RequestProps.contains(layer)))
1448
                visible = m_imageInfoRecord.RequestProps[layer].visible;
1449
        if (visible)
1450
        {
1451
                unsigned int startSrcY, startSrcX, startDstY, startDstX;
1452
                if (layerInfo[layer].ypos < 0)
1453
                {
1454
                        startSrcY = abs(layerInfo[layer].ypos);
1455
                        startDstY = 0;
1456
                }
1457
                else
1458
                {
1459
                        startSrcY = 0;
1460
                        startDstY = layerInfo[layer].ypos;
1461
                }
1462
                if (layerInfo[layer].xpos < 0)
1463
                {
1464
                        startSrcX = abs(layerInfo[layer].xpos);
1465
                        startDstX = 0;
1466
                }
1467
                else
1468
                {
1469
                        startSrcX = 0;
1470
                        startDstX = layerInfo[layer].xpos;
1471
                }
19730 fschmid 1472
                unsigned int startSrcXm; //, startSrcYm, startDstYm, startDstXm;
1473
        /*      if (layerInfo[layer].maskYpos < 0)
6766 fschmid 1474
                {
1475
                        startSrcYm = abs(layerInfo[layer].maskYpos);
1476
                        startDstYm = 0;
1477
                }
1478
                else
1479
                {
1480
                        startSrcYm = 0;
1481
                        startDstYm = layerInfo[layer].maskYpos;
19730 fschmid 1482
                }*/
6766 fschmid 1483
                if (layerInfo[layer].maskXpos < 0)
1484
                {
1485
                        startSrcXm = abs(layerInfo[layer].maskXpos);
19730 fschmid 1486
                //      startDstXm = 0;
6766 fschmid 1487
                }
1488
                else
1489
                {
1490
                        startSrcXm = 0;
19730 fschmid 1491
                //      startDstXm = layerInfo[layer].maskXpos;
6766 fschmid 1492
                }
1493
                QString layBlend2 = layerInfo[layer].blend;
1494
                if ((m_imageInfoRecord.isRequest) && (m_imageInfoRecord.RequestProps.contains(layer)))
1495
                        layBlend2 = m_imageInfoRecord.RequestProps[layer].blend;
6850 fschmid 1496
                if (layBlend2 == "diss")
6766 fschmid 1497
                {
6850 fschmid 1498
                        hasAlpha = true;
6766 fschmid 1499
                        int layOpa = layerInfo[layer].opacity;
1500
                        if ((m_imageInfoRecord.isRequest) && (m_imageInfoRecord.RequestProps.contains(layer)))
1501
                                layOpa = m_imageInfoRecord.RequestProps[layer].opacity;
6850 fschmid 1502
                        for (int l = 0; l < r2_image.height(); l++)
6766 fschmid 1503
                        {
20691 craig 1504
                                srand(m_random_table[ l  % 4096]);
6850 fschmid 1505
                                for (int k = 0; k < r2_image.width(); k++)
6766 fschmid 1506
                                {
1507
                                        int rand_val = rand() & 0xff;
1508
                                        if (rand_val > layOpa)
6850 fschmid 1509
                                                r2_image.setAlpha(k, l, 0);
6766 fschmid 1510
                                }
1511
                        }
1512
                }
1513
                if (*firstLayer)
1514
                {
22536 jghali 1515
                        for (int yi=static_cast<int>(startSrcY); yi < qMin(r2_image.height(),  r_image.height()); ++yi)
6766 fschmid 1516
                        {
6850 fschmid 1517
                                unsigned char *s = r2_image.scanLine( yi );
8562 jghali 1518
                                unsigned char *d = r_image.scanLine( qMin(static_cast<int>(startDstY),  r_image.height()-1) );
1519
                                d += qMin(static_cast<int>(startDstX), r_image.width()-1) * r_image.channels();
1520
                                s += qMin(static_cast<int>(startSrcX), r2_image.width()-1) * r2_image.channels();
22536 jghali 1521
                                for (int xi=static_cast<int>(startSrcX); xi < qMin(r2_image.width(),  r_image.width()); ++xi )
6766 fschmid 1522
                                {
6850 fschmid 1523
                                        d[0] = s[0];
1524
                                        d[1] = s[1];
1525
                                        d[2] = s[2];
1526
                                        if (header.color_mode == CM_RGB)
1527
                                        {
1528
                                                if (hasAlpha)
1529
                                                        d[3] = s[3];
1530
                                                else
1531
                                                        d[3] = 255;
1532
                                        }
1533
                                        else
1534
                                        {
1535
                                                d[3] = s[3];
1536
                                                if (hasAlpha)
1537
                                                        d[4] = s[4];
1538
                                                else
1539
                                                        d[4] = 255;
1540
                                        }
1541
                                        s += r2_image.channels();
1542
                                        d += r_image.channels();
6766 fschmid 1543
                                }
1544
                                startDstY++;
1545
                        }
1546
                }
1547
                else
1548
                {
1549
                        for (int i = static_cast<int>(startSrcY); i < layerInfo[layer].height; i++)
1550
                        {
8562 jghali 1551
                                unsigned char *d = r_image.scanLine(qMin(static_cast<int>(startDstY),  r_image.height()-1));
1552
                                unsigned char *s = r2_image.scanLine(qMin(i, r2_image.height()-1));
1553
                                d += qMin(static_cast<int>(startDstX),  r_image.width()-1) * r_image.channels();
1554
                                s += qMin(static_cast<int>(startSrcX), r2_image.width()-1) * r2_image.channels();
22605 craig 1555
                                unsigned char *sm = nullptr;
6850 fschmid 1556
                                if (hasMask)
6766 fschmid 1557
                                {
8562 jghali 1558
                                        sm = mask.scanLine(qMin(i, mask.height()-1));
1559
                                        sm += qMin(static_cast<int>(startSrcXm), mask.width()-1) * mask.channels();
6766 fschmid 1560
                                }
1561
                                startDstY++;
7980 fschmid 1562
                                unsigned char r, g, b, src_r, src_g, src_b, src_a, src_alpha, dst_alpha;
1563
                                unsigned char a = 0;
6850 fschmid 1564
                                unsigned int maxDestX = r_image.width() - startDstX + startSrcX - 1;
8562 jghali 1565
                                for (unsigned int j = startSrcX; j < qMin(maxDestX, static_cast<unsigned int>(layerInfo[layer].width)); j++)
6766 fschmid 1566
                                {
1567
                                        src_r = s[0];
1568
                                        src_g = s[1];
1569
                                        src_b = s[2];
1570
                                        src_a = s[3];
6850 fschmid 1571
                                        if (hasAlpha)
1572
                                        {
6854 fschmid 1573
                                                if (hasMask)
1574
                                                {
1575
                                                        if (m_imageInfoRecord.RequestProps[layer].useMask)
1576
                                                                src_alpha = sm[0];
1577
                                                        else
1578
                                                                src_alpha = s[channel_num - 2];
1579
                                                }
6850 fschmid 1580
                                                else
1581
                                                        src_alpha = s[channel_num - 1];
1582
                                        }
6854 fschmid 1583
                                        else
1584
                                                src_alpha = 255;
6850 fschmid 1585
                                        if ((hasMask) && (m_imageInfoRecord.RequestProps[layer].useMask))
1586
                                                src_alpha = sm[0];
1587
                                        int layOpa = layerInfo[layer].opacity;
1588
                                        if ((m_imageInfoRecord.isRequest) && (m_imageInfoRecord.RequestProps.contains(layer)))
1589
                                                layOpa = m_imageInfoRecord.RequestProps[layer].opacity;
6766 fschmid 1590
                                        QString layBlend = layerInfo[layer].blend;
1591
                                        if ((m_imageInfoRecord.isRequest) && (m_imageInfoRecord.RequestProps.contains(layer)))
1592
                                                layBlend = m_imageInfoRecord.RequestProps[layer].blend;
6850 fschmid 1593
                                        if (layBlend != "diss")
1594
                                                src_alpha = INT_MULT(src_alpha, layOpa);
1595
                                        if (header.color_mode == CM_CMYK)
1596
                                                dst_alpha = d[4];
1597
                                        else
1598
                                                dst_alpha = d[3];
1599
                                        if ((dst_alpha > 0) && (src_alpha > 0))
6766 fschmid 1600
                                        {
6850 fschmid 1601
                                                if (layBlend == "mul ")
6766 fschmid 1602
                                                {
1603
                                                        src_r = INT_MULT(src_r, d[0]);
1604
                                                        src_g = INT_MULT(src_g, d[1]);
1605
                                                        src_b = INT_MULT(src_b, d[2]);
6850 fschmid 1606
                                                        if (header.color_mode == CM_CMYK)
1607
                                                                src_a = INT_MULT(src_a, d[3]);
6766 fschmid 1608
                                                }
6850 fschmid 1609
                                                else if (layBlend == "scrn")
6766 fschmid 1610
                                                {
1611
                                                        src_r = 255 - ((255-src_r) * (255-d[0]) / 128);
1612
                                                        src_g = 255 - ((255-src_g) * (255-d[1]) / 128);
1613
                                                        src_b = 255 - ((255-src_b) * (255-d[2]) / 128);
6850 fschmid 1614
                                                        if (header.color_mode == CM_CMYK)
1615
                                                                src_a = 255 - ((255-src_a) * (255-d[3]) / 128);
6766 fschmid 1616
                                                }
6850 fschmid 1617
                                                else if (layBlend == "over")
6766 fschmid 1618
                                                {
1619
                                                        src_g = d[1] < 128 ? src_g * d[1] / 128 : 255 - ((255-src_g) * (255-d[1]) / 128);
1620
                                                        src_b = d[2] < 128 ? src_b * d[2] / 128 : 255 - ((255-src_b) * (255-d[2]) / 128);
1621
                                                        src_a = d[3] < 128 ? src_a * d[3] / 128 : 255 - ((255-src_a) * (255-d[3]) / 128);
6850 fschmid 1622
                                                        if (header.color_mode == CM_CMYK)
6766 fschmid 1623
                                                                src_r = d[0] < 128 ? src_r * d[0] / 128 : 255 - ((255-src_r) * (255-d[0]) / 128);
1624
                                                }
6850 fschmid 1625
                                                else if (layBlend == "diff")
6766 fschmid 1626
                                                {
1627
                                                        src_r = d[0] > src_r ? d[0] - src_r : src_r - d[0];
1628
                                                        src_g = d[1] > src_g ? d[1] - src_g : src_g - d[1];
1629
                                                        src_b = d[2] > src_b ? d[2] - src_b : src_b - d[2];
6850 fschmid 1630
                                                        if (header.color_mode == CM_CMYK)
1631
                                                                src_a = d[3] > src_a ? d[3] - src_a : src_a - d[3];
6766 fschmid 1632
                                                }
6850 fschmid 1633
                                                else if (layBlend == "dark")
6766 fschmid 1634
                                                {
1635
                                                        src_r = d[0]  < src_r ? d[0]  : src_r;
1636
                                                        src_g = d[1] < src_g ? d[1] : src_g;
1637
                                                        src_b = d[2] < src_b ? d[2] : src_b;
6850 fschmid 1638
                                                        if (header.color_mode == CM_CMYK)
1639
                                                                src_a = d[3] < src_a ? d[3] : src_a;
6766 fschmid 1640
                                                }
6850 fschmid 1641
                                                else if (layBlend == "hLit")
6766 fschmid 1642
                                                {
1643
                                                        src_r = src_r < 128 ? src_r * d[0] / 128 : 255 - ((255-src_r) * (255-d[0]) / 128);
1644
                                                        src_g = src_g < 128 ? src_g * d[1] / 128 : 255 - ((255-src_g) * (255-d[1]) / 128);
1645
                                                        src_b = src_b < 128 ? src_b * d[2] / 128 : 255 - ((255-src_b) * (255-d[2]) / 128);
6850 fschmid 1646
                                                        if (header.color_mode == CM_CMYK)
1647
                                                                src_a = src_a < 128 ? src_a * d[3] / 128 : 255 - ((255-src_a) * (255-d[3]) / 128);
6766 fschmid 1648
                                                }
6850 fschmid 1649
                                                else if (layBlend == "sLit")
6766 fschmid 1650
                                                {
1651
                                                        src_r = src_r * d[0] / 256 + src_r * (255 - ((255-src_r)*(255-d[0]) / 256) - src_r * d[0] / 256) / 256;
1652
                                                        src_g = src_g * d[1] / 256 + src_g * (255 - ((255-src_g)*(255-d[1]) / 256) - src_g * d[1] / 256) / 256;
1653
                                                        src_b = src_b * d[2] / 256 + src_b * (255 - ((255-src_b)*(255-d[2]) / 256) - src_b * d[2] / 256) / 256;
6850 fschmid 1654
                                                        if (header.color_mode == CM_CMYK)
1655
                                                                src_a = src_a * d[3] / 256 + src_a * (255 - ((255-src_a)*(255-d[3]) / 256) - src_a * d[3] / 256) / 256;
6766 fschmid 1656
                                                }
6850 fschmid 1657
                                                else if (layBlend == "lite")
6766 fschmid 1658
                                                {
1659
                                                        src_r = d[0] < src_r ? src_r : d[0];
1660
                                                        src_g = d[1] < src_g ? src_g : d[1];
1661
                                                        src_b = d[2] < src_b ? src_b : d[2];
6850 fschmid 1662
                                                        if (header.color_mode == CM_CMYK)
1663
                                                                src_a = d[3] < src_a ? src_a : d[3];
6766 fschmid 1664
                                                }
6850 fschmid 1665
                                                else if (layBlend == "smud")
6766 fschmid 1666
                                                {
1667
                                                        src_r = d[0] + src_r - src_r * d[0] / 128;
1668
                                                        src_g = d[1] + src_g - src_g * d[1] / 128;
1669
                                                        src_b = d[2] + src_b - src_b * d[2] / 128;
6850 fschmid 1670
                                                        if (header.color_mode == CM_CMYK)
1671
                                                                src_a = d[3] + src_a - src_a * d[3] / 128;
6766 fschmid 1672
                                                }
6850 fschmid 1673
                                                else if (layBlend == "div ")
6766 fschmid 1674
                                                {
1675
                                                        src_r = src_r == 255 ? 255 : ((d[0] * 256) / (255-src_r)) > 255 ? 255 : (d[0] * 256) / (255-src_r);
1676
                                                        src_g = src_g == 255 ? 255 : ((d[1] * 256) / (255-src_g)) > 255 ? 255 : (d[1] * 256) / (255-src_g);
1677
                                                        src_b = src_b == 255 ? 255 : ((d[2] * 256) / (255-src_b)) > 255 ? 255 : (d[2] * 256) / (255-src_b);
6850 fschmid 1678
                                                        if (header.color_mode == CM_CMYK)
1679
                                                                src_a = src_a == 255 ? 255 : ((d[3] * 256) / (255-src_a)) > 255 ? 255 : (d[3] * 256) / (255-src_a);
6766 fschmid 1680
                                                }
6850 fschmid 1681
                                                else if (layBlend == "idiv")
6766 fschmid 1682
                                                {
1683
                                                        src_r = src_r == 0 ? 0 : (255 - (((255-d[0]) * 256) / src_r)) < 0 ? 0 : 255 - (((255-d[0]) * 256) / src_r);
1684
                                                        src_g = src_g == 0 ? 0 : (255 - (((255-d[1]) * 256) / src_g)) < 0 ? 0 : 255 - (((255-d[1]) * 256) / src_g);
1685
                                                        src_b = src_b == 0 ? 0 : (255 - (((255-d[2]) * 256) / src_b)) < 0 ? 0 : 255 - (((255-d[2]) * 256) / src_b);
6850 fschmid 1686
                                                        if (header.color_mode == CM_CMYK)
1687
                                                                src_a = src_a == 0 ? 0 : (255 - (((255-d[3]) * 256) / src_a)) < 0 ? 0 : 255 - (((255-d[3]) * 256) / src_a);
6766 fschmid 1688
                                                }
6850 fschmid 1689
                                                else if (layBlend == "hue ")
6766 fschmid 1690
                                                {
6850 fschmid 1691
                                                        if (header.color_mode != CM_CMYK)
6766 fschmid 1692
                                                        {
1693
                                                                uchar new_r = d[0];
1694
                                                                uchar new_g = d[1];
1695
                                                                uchar new_b = d[2];
1696
                                                                RGBTOHSV(src_r, src_g, src_b);
1697
                                                                RGBTOHSV(new_r, new_g, new_b);
1698
                                                                new_r = src_r;
1699
                                                                HSVTORGB(new_r, new_g, new_b);
1700
                                                                src_r = new_r;
1701
                                                                src_g = new_g;
1702
                                                                src_b = new_b;
1703
                                                        }
1704
                                                }
6850 fschmid 1705
                                                else if (layBlend == "sat ")
6766 fschmid 1706
                                                {
6850 fschmid 1707
                                                        if (header.color_mode != CM_CMYK)
6766 fschmid 1708
                                                        {
1709
                                                                uchar new_r = d[0];
1710
                                                                uchar new_g = d[1];
1711
                                                                uchar new_b = d[2];
1712
                                                                RGBTOHSV(src_r, src_g, src_b);
1713
                                                                RGBTOHSV(new_r, new_g, new_b);
1714
                                                                new_g = src_g;
1715
                                                                HSVTORGB(new_r, new_g, new_b);
1716
                                                                src_r = new_r;
1717
                                                                src_g = new_g;
1718
                                                                src_b = new_b;
1719
                                                        }
1720
                                                }
6850 fschmid 1721
                                                else if (layBlend == "lum ")
6766 fschmid 1722
                                                {
6850 fschmid 1723
                                                        if (header.color_mode != CM_CMYK)
6766 fschmid 1724
                                                        {
1725
                                                                uchar new_r = d[0];
1726
                                                                uchar new_g = d[1];
1727
                                                                uchar new_b = d[2];
1728
                                                                RGBTOHSV(src_r, src_g, src_b);
1729
                                                                RGBTOHSV(new_r, new_g, new_b);
1730
                                                                new_b = src_b;
1731
                                                                HSVTORGB(new_r, new_g, new_b);
1732
                                                                src_r = new_r;
1733
                                                                src_g = new_g;
1734
                                                                src_b = new_b;
1735
                                                        }
1736
                                                }
6850 fschmid 1737
                                                else if (layBlend == "colr")
6766 fschmid 1738
                                                {
6850 fschmid 1739
                                                        if (header.color_mode != CM_CMYK)
6766 fschmid 1740
                                                        {
1741
                                                                uchar new_r = d[0];
1742
                                                                uchar new_g = d[1];
1743
                                                                uchar new_b = d[2];
1744
                                                                RGBTOHLS(src_r, src_g, src_b);
1745
                                                                RGBTOHLS(new_r, new_g, new_b);
1746
                                                                new_r = src_r;
1747
                                                                new_b = src_b;
1748
                                                                HLSTORGB(new_r, new_g, new_b);
1749
                                                                src_r = new_r;
1750
                                                                src_g = new_g;
1751
                                                                src_b = new_b;
1752
                                                        }
1753
                                                }
1754
                                        }
6850 fschmid 1755
                                        if (dst_alpha == 0)
6766 fschmid 1756
                                        {
6850 fschmid 1757
                                                r = src_r;
1758
                                                g = src_g;
1759
                                                b = src_b;
1760
                                                a = src_a;
6766 fschmid 1761
                                        }
1762
                                        else
1763
                                        {
6850 fschmid 1764
                                                if (src_alpha > 0)
6766 fschmid 1765
                                                {
6850 fschmid 1766
                                                        r = (d[0] * (255 - src_alpha) + src_r * src_alpha) / 255;
1767
                                                        g = (d[1] * (255 - src_alpha) + src_g * src_alpha) / 255;
1768
                                                        b = (d[2] * (255 - src_alpha) + src_b * src_alpha) / 255;
1769
                                                        if (header.color_mode == CM_CMYK)
1770
                                                                a = (d[3] * (255 - src_alpha) + src_a * src_alpha) / 255;
1771
                                                        if (layBlend != "diss")
1772
                                                                src_alpha = dst_alpha + INT_MULT(255 - dst_alpha, src_alpha);
6766 fschmid 1773
                                                }
1774
                                        }
6850 fschmid 1775
                                        if (src_alpha > 0)
6766 fschmid 1776
                                        {
1777
                                                d[0] = r;
1778
                                                d[1] = g;
1779
                                                d[2] = b;
6850 fschmid 1780
                                                if (header.color_mode == CM_CMYK)
6766 fschmid 1781
                                                {
1782
                                                        d[3] = a;
6850 fschmid 1783
                                                        d[4] = src_alpha;
6766 fschmid 1784
                                                }
6850 fschmid 1785
                                                else
1786
                                                        d[3] = src_alpha;
6766 fschmid 1787
                                        }
6850 fschmid 1788
                                        s += r2_image.channels();
1789
                                        d += r_image.channels();
1790
                                        if (hasMask)
1791
                                                sm += mask.channels();
6766 fschmid 1792
                                }
1793
                        }
1794
                }
1795
        }
1796
        *firstLayer = false;
1797
        return true;
1798
}