Subversion Repositories Scribus

Rev

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