Subversion Repositories Scribus

Rev

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

Rev Author Line No. Line
4430 cbradney 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
*/
2004 fschmid 7
#include "scimage.h"
8
#include "scribus.h"
2074 fschmid 9
#include <qtextstream.h>
2125 cbradney 10
#include <cassert>
2004 fschmid 11
#ifdef HAVE_CMS
12
        #include CMS_INC
13
extern cmsHPROFILE CMSoutputProf;
14
extern cmsHPROFILE CMSprinterProf;
15
extern cmsHTRANSFORM stdTransG;
16
extern cmsHTRANSFORM stdProofG;
17
extern cmsHTRANSFORM stdTransImgG;
18
extern cmsHTRANSFORM stdProofImgG;
19
extern bool BlackPoint;
20
extern bool SoftProofing;
21
extern bool Gamut;
22
extern bool CMSuse;
23
extern int IntentMonitor;
24
extern int IntentPrinter;
25
#endif
4506 cbradney 26
#include "gsutil.h"
3685 fschmid 27
#include "exif.h"
4546 subik 28
#include "commonstrings.h"
2004 fschmid 29
 
30
 
31
typedef struct my_error_mgr
32
{
33
        struct jpeg_error_mgr pub;            /* "public" fields */
34
        jmp_buf setjmp_buffer;  /* for return to caller */
35
}
36
*my_error_ptr;
37
 
38
static void my_error_exit (j_common_ptr cinfo)
39
{
40
        my_error_ptr myerr = (my_error_ptr) cinfo->err;
41
        (*cinfo->err->output_message) (cinfo);
42
        longjmp (myerr->setjmp_buffer, 1);
43
}
44
 
45
static QDataStream & operator>> ( QDataStream & s, ScImage::PSDHeader & header )
46
{
47
        s >> header.signature;
48
        s >> header.version;
49
        for( int i = 0; i < 6; i++ )
50
        {
51
                s >> header.reserved[i];
52
        }
53
        s >> header.channel_count;
54
        s >> header.height;
55
        s >> header.width;
56
        s >> header.depth;
57
        s >> header.color_mode;
58
        return s;
59
}
60
 
4222 craig 61
ScImage::ScImage(const QImage & image) : QImage(image)
2004 fschmid 62
{
2012 fschmid 63
        initialize();
2004 fschmid 64
}
65
 
66
ScImage::ScImage() : QImage()
67
{
2012 fschmid 68
        initialize();
2004 fschmid 69
}
70
 
71
ScImage::ScImage( int width, int height ) : QImage( width, height, 32 )
72
{
2012 fschmid 73
        initialize();
74
}
75
 
76
void ScImage::initialize()
77
{
2004 fschmid 78
        imgInfo.xres = 72;
79
        imgInfo.yres = 72;
80
        imgInfo.colorspace = 0;
81
        imgInfo.valid = false;
82
        imgInfo.isRequest = false;
83
        imgInfo.progressive = false;
3703 fschmid 84
        imgInfo.exifDataValid = false;
2025 fschmid 85
        imgInfo.lowResType = 1;
86
        imgInfo.lowResScale = 1.0;
2004 fschmid 87
        imgInfo.PDSpathData.clear();
88
        imgInfo.RequestProps.clear();
89
        imgInfo.clipPath = "";
90
        imgInfo.usedPath = "";
91
        imgInfo.layerInfo.clear();
3703 fschmid 92
        imgInfo.exifInfo.cameraName = "";
93
        imgInfo.exifInfo.cameraVendor = "";
94
        imgInfo.exifInfo.thumbnail = QImage();
4331 fschmid 95
        imgInfo.BBoxX = 0;
96
        imgInfo.BBoxH = 0;
2004 fschmid 97
}
98
 
4050 cbradney 99
ScImage::~ScImage()
100
{
101
        curveTable.resize(0);
102
}
103
 
2886 fschmid 104
void ScImage::applyEffect(QValueList<imageEffect> effectsList, QMap<QString,ScColor> colors, bool cmyk)
2074 fschmid 105
{
106
        if (effectsList.count() != 0)
107
        {
108
                for (uint a = 0; a < effectsList.count(); ++a)
109
                {
2082 fschmid 110
                        if ((*effectsList.at(a)).effectCode == EF_INVERT)
2074 fschmid 111
                                invert(cmyk);
2082 fschmid 112
                        if ((*effectsList.at(a)).effectCode == EF_GRAYSCALE)
2074 fschmid 113
                                toGrayscale(cmyk);
2082 fschmid 114
                        if ((*effectsList.at(a)).effectCode == EF_COLORIZE)
2074 fschmid 115
                        {
116
                                QString tmpstr = (*effectsList.at(a)).effectParameters;
4546 subik 117
                                QString col = CommonStrings::None;
2074 fschmid 118
                                int shading = 100;
119
                                QTextStream fp(&tmpstr, IO_ReadOnly);
120
                                fp >> col;
121
                                fp >> shading;
122
                                colorize(colors[col], shading, cmyk);
123
                        }
2082 fschmid 124
                        if ((*effectsList.at(a)).effectCode == EF_BRIGHTNESS)
125
                        {
126
                                QString tmpstr = (*effectsList.at(a)).effectParameters;
127
                                int brightnessValue = 0;
128
                                QTextStream fp(&tmpstr, IO_ReadOnly);
129
                                fp >> brightnessValue;
130
                                brightness(brightnessValue, cmyk);
131
                        }
132
                        if ((*effectsList.at(a)).effectCode == EF_CONTRAST)
133
                        {
134
                                QString tmpstr = (*effectsList.at(a)).effectParameters;
135
                                int contrastValue = 0;
136
                                QTextStream fp(&tmpstr, IO_ReadOnly);
137
                                fp >> contrastValue;
138
                                contrast(contrastValue, cmyk);
139
                        }
2092 fschmid 140
                        if ((*effectsList.at(a)).effectCode == EF_SHARPEN)
141
                        {
142
                                QString tmpstr = (*effectsList.at(a)).effectParameters;
143
                                double radius, sigma;
144
                                QTextStream fp(&tmpstr, IO_ReadOnly);
145
                                fp >> radius;
146
                                fp >> sigma;
147
                                sharpen(radius, sigma);
148
                        }
2095 fschmid 149
                        if ((*effectsList.at(a)).effectCode == EF_BLUR)
150
                        {
151
                                QString tmpstr = (*effectsList.at(a)).effectParameters;
152
                                double radius, sigma;
153
                                QTextStream fp(&tmpstr, IO_ReadOnly);
154
                                fp >> radius;
155
                                fp >> sigma;
156
                                blur(radius, sigma);
157
                        }
2096 fschmid 158
                        if ((*effectsList.at(a)).effectCode == EF_SOLARIZE)
159
                        {
160
                                QString tmpstr = (*effectsList.at(a)).effectParameters;
161
                                double sigma;
162
                                QTextStream fp(&tmpstr, IO_ReadOnly);
163
                                fp >> sigma;
164
                                solarize(sigma, cmyk);
165
                        }
2074 fschmid 166
                }
167
        }
168
}
169
 
2095 fschmid 170
void ScImage::liberateMemory(void **memory)
171
{
172
        assert(memory != (void **)NULL);
173
        if(*memory == (void *)NULL)
174
                return;
175
        free(*memory);
176
        *memory=(void *) NULL;
177
}
178
 
2096 fschmid 179
void ScImage::solarize(double factor, bool cmyk)
180
{
181
        curveTable.resize(256);
182
        int fk = qRound(255 / factor);
183
        for (int i = 0; i < 256; ++i)
184
        {
185
                curveTable[i] = QMIN(255, static_cast<int>(i / fk) * fk);
186
        }
187
        applyCurve(cmyk);
188
}
189
 
2095 fschmid 190
void ScImage::blurScanLine(double *kernel, int width, unsigned int *src, unsigned int *dest, int columns)
191
{
192
        register double *p;
193
        unsigned int *q;
194
        register int x;
195
        register long i;
196
        double red, green, blue, alpha;
197
        double scale = 0.0;
198
        if(width > columns)
199
        {
200
                for(x=0; x < columns; ++x)
201
                {
202
                        scale = 0.0;
203
                        red = blue = green = alpha = 0.0;
204
                        p = kernel;
205
                        q = src;
206
                        for(i=0; i < columns; ++i)
207
                        {
208
                                if((i >= (x-width/2)) && (i <= (x+width/2)))
209
                                {
210
                                        red += (*p)*(qRed(*q)*257);
211
                                        green += (*p)*(qGreen(*q)*257);
212
                                        blue += (*p)*(qBlue(*q)*257);
213
                                        alpha += (*p)*(qAlpha(*q)*257);
214
                                }
215
                                if(((i+width/2-x) >= 0) && ((i+width/2-x) < width))
216
                                        scale+=kernel[i+width/2-x];
217
                                p++;
218
                                q++;
219
                        }
220
                        scale = 1.0/scale;
221
                        red = scale*(red+0.5);
222
                        green = scale*(green+0.5);
223
                        blue = scale*(blue+0.5);
224
                        alpha = scale*(alpha+0.5);
225
                        red = red < 0 ? 0 : red > 65535 ? 65535 : red;
226
                        green = green < 0 ? 0 : green > 65535 ? 65535 : green;
227
                        blue = blue < 0 ? 0 : blue > 65535 ? 65535 : blue;
228
                        alpha = alpha < 0 ? 0 : alpha > 65535 ? 65535 : alpha;
229
                        dest[x] = qRgba((unsigned char)(red/257UL),
230
                                        (unsigned char)(green/257UL),
231
                                        (unsigned char)(blue/257UL),
232
                                        (unsigned char)(alpha/257UL));
233
                }
234
                return;
235
        }
236
 
237
        for(x=0; x < width/2; ++x)
238
        {
239
                scale = 0.0;
240
                red = blue = green = alpha = 0.0;
241
                p = kernel+width/2-x;
242
                q = src;
243
                for(i=width/2-x; i < width; ++i)
244
                {
245
                        red += (*p)*(qRed(*q)*257);
246
                        green += (*p)*(qGreen(*q)*257);
247
                        blue += (*p)*(qBlue(*q)*257);
248
                        alpha += (*p)*(qAlpha(*q)*257);
249
                        scale += (*p);
250
                        p++;
251
                        q++;
252
                }
253
                scale=1.0/scale;
254
                red = scale*(red+0.5);
255
                green = scale*(green+0.5);
256
                blue = scale*(blue+0.5);
257
                alpha = scale*(alpha+0.5);
258
                red = red < 0 ? 0 : red > 65535 ? 65535 : red;
259
                green = green < 0 ? 0 : green > 65535 ? 65535 : green;
260
                blue = blue < 0 ? 0 : blue > 65535 ? 65535 : blue;
261
                alpha = alpha < 0 ? 0 : alpha > 65535 ? 65535 : alpha;
262
                dest[x] = qRgba((unsigned char)(red/257UL),
263
                                (unsigned char)(green/257UL),
264
                                (unsigned char)(blue/257UL),
265
                                (unsigned char)(alpha/257UL));
266
        }
267
        for(; x < columns-width/2; ++x)
268
        {
269
                red = blue = green = alpha = 0.0;
270
                p = kernel;
271
                q = src+(x-width/2);
272
                for (i=0; i < (long) width; ++i)
273
                {
274
                        red += (*p)*(qRed(*q)*257);
275
                        green += (*p)*(qGreen(*q)*257);
276
                        blue += (*p)*(qBlue(*q)*257);
277
                        alpha += (*p)*(qAlpha(*q)*257);
278
                        p++;
279
                        q++;
280
                }
281
                red = scale*(red+0.5);
282
                green = scale*(green+0.5);
283
                blue = scale*(blue+0.5);
284
                alpha = scale*(alpha+0.5);
285
                red = red < 0 ? 0 : red > 65535 ? 65535 : red;
286
                green = green < 0 ? 0 : green > 65535 ? 65535 : green;
287
                blue = blue < 0 ? 0 : blue > 65535 ? 65535 : blue;
288
                alpha = alpha < 0 ? 0 : alpha > 65535 ? 65535 : alpha;
289
                dest[x] = qRgba((unsigned char)(red/257UL),
290
                                (unsigned char)(green/257UL),
291
                                (unsigned char)(blue/257UL),
292
                                (unsigned char)(alpha/257UL));
293
        }
294
        for(; x < columns; ++x)
295
        {
296
                red = blue = green = alpha = 0.0;
297
                scale=0;
298
                p = kernel;
299
                q = src+(x-width/2);
300
                for(i=0; i < columns-x+width/2; ++i)
301
                {
302
                        red += (*p)*(qRed(*q)*257);
303
                        green += (*p)*(qGreen(*q)*257);
304
                        blue += (*p)*(qBlue(*q)*257);
305
                        alpha += (*p)*(qAlpha(*q)*257);
306
                        scale += (*p);
307
                        p++;
308
                        q++;
309
                }
310
                scale=1.0/scale;
311
                red = scale*(red+0.5);
312
                green = scale*(green+0.5);
313
                blue = scale*(blue+0.5);
314
                alpha = scale*(alpha+0.5);
315
                red = red < 0 ? 0 : red > 65535 ? 65535 : red;
316
                green = green < 0 ? 0 : green > 65535 ? 65535 : green;
317
                blue = blue < 0 ? 0 : blue > 65535 ? 65535 : blue;
318
                alpha = alpha < 0 ? 0 : alpha > 65535 ? 65535 : alpha;
319
                dest[x] = qRgba((unsigned char)(red/257UL),
320
                                (unsigned char)(green/257UL),
321
                                (unsigned char)(blue/257UL),
322
                                (unsigned char)(alpha/257UL));
323
        }
324
}
325
 
326
int ScImage::getBlurKernel(int width, double sigma, double **kernel)
327
{
328
        double alpha, normalize;
329
        register long i;
330
        int bias;
331
        assert(sigma != 0.0);
332
        if(width == 0)
333
                width = 3;
334
        *kernel=(double *)malloc(width*sizeof(double));
335
        if(*kernel == (double *)NULL)
336
                return(0);
337
        memset(*kernel, 0, width*sizeof(double));
338
        bias = 3*width/2;
339
        for(i=(-bias); i <= bias; i++)
340
        {
341
                alpha=exp(-((double) i*i)/(2.0*3*3*sigma*sigma));
342
                (*kernel)[(i+bias)/3]+=alpha/(2.50662827463100024161235523934010416269302368164062*sigma);
343
        }
344
        normalize=0;
345
        for(i=0; i < width; i++)
346
                normalize+=(*kernel)[i];
347
        for(i=0; i < width; i++)
348
                (*kernel)[i]/=normalize;
349
        return(width);
350
}
351
 
352
void ScImage::blur(double radius, double sigma)
353
{
354
        double *kernel;
355
        QImage dest;
356
        int widthk;
357
        int x, y;
358
        unsigned int *scanline, *temp;
359
        unsigned int *p, *q;
360
        if(sigma == 0.0)
361
                return;
362
        kernel=(double *) NULL;
363
        if(radius > 0)
364
                widthk=getBlurKernel((int) (2*ceil(radius)+1),sigma,&kernel);
365
        else
366
        {
367
                double *last_kernel;
368
                last_kernel=(double *) NULL;
369
                widthk=getBlurKernel(3,sigma,&kernel);
370
                while ((long) (255*kernel[0]) > 0)
371
                {
372
                        if(last_kernel != (double *)NULL)
373
                        {
374
                                liberateMemory((void **) &last_kernel);
375
                        }
376
                        last_kernel=kernel;
377
                        kernel = (double *)NULL;
378
                        widthk = getBlurKernel(widthk+2, sigma, &kernel);
379
                }
380
                if(last_kernel != (double *) NULL)
381
                {
382
                        liberateMemory((void **) &kernel);
383
                        widthk-=2;
384
                        kernel = last_kernel;
385
                }
386
        }
387
        if(widthk < 3)
388
        {
389
                liberateMemory((void **) &kernel);
390
                return;
391
        }
392
        dest.create(width(), height(), 32);
393
        scanline = (unsigned int *)malloc(sizeof(unsigned int)*height());
394
        temp = (unsigned int *)malloc(sizeof(unsigned int)*height());
395
        for(y=0; y < height(); ++y)
396
        {
397
                p = (unsigned int *)scanLine(y);
398
                q = (unsigned int *)dest.scanLine(y);
399
                blurScanLine(kernel, widthk, p, q, width());
400
        }
401
        unsigned int **srcTable = (unsigned int **)jumpTable();
402
        unsigned int **destTable = (unsigned int **)dest.jumpTable();
403
        for(x=0; x < width(); ++x)
404
        {
405
                for(y=0; y < height(); ++y)
406
                {
407
                        scanline[y] = srcTable[y][x];
408
                }
409
                blurScanLine(kernel, widthk, scanline, temp, height());
410
                for(y=0; y < height(); ++y)
411
                {
412
                        destTable[y][x] = temp[y];
413
                }
414
        }
415
        liberateMemory((void **) &scanline);
416
        liberateMemory((void **) &temp);
417
        liberateMemory((void **) &kernel);
418
        for( int yi=0; yi < dest.height(); ++yi )
419
        {
420
                QRgb *s = (QRgb*)(dest.scanLine( yi ));
421
                QRgb *d = (QRgb*)(scanLine( yi ));
422
                for(int xi=0; xi < dest.width(); ++xi )
423
                {
424
                        (*d) = (*s);
425
                        s++;
426
                        d++;
427
                }
428
        }
429
        return;
430
}
431
 
2092 fschmid 432
bool ScImage::convolveImage(QImage *dest, const unsigned int order, const double *kernel)
433
{
434
        long widthk;
435
        double red, green, blue, alpha;
436
        double normalize, *normal_kernel;
437
        register const double *k;
438
        register unsigned int *q;
439
        int x, y, mx, my, sx, sy;
440
        long i;
441
        int mcx, mcy;
442
        widthk = order;
443
        if((widthk % 2) == 0)
444
                return(false);
445
        normal_kernel = (double *)malloc(widthk*widthk*sizeof(double));
446
        if(!normal_kernel)
447
                return(false);
448
        dest->reset();
449
        dest->create(width(), height(), 32);
450
        normalize=0.0;
451
        for(i=0; i < (widthk*widthk); i++)
452
                normalize += kernel[i];
453
        if(fabs(normalize) <= 1.0e-12)
454
                normalize=1.0;
455
        normalize=1.0/normalize;
456
        for(i=0; i < (widthk*widthk); i++)
457
                normal_kernel[i] = normalize*kernel[i];
458
        unsigned int **jumpTablek = (unsigned int **)jumpTable();
459
        for(y=0; y < dest->height(); ++y)
460
        {
461
                sy = y-(widthk/2);
462
                q = (unsigned int *)dest->scanLine(y);
463
                for(x=0; x < dest->width(); ++x)
464
                {
465
                        k = normal_kernel;
466
                        red = green = blue = alpha = 0;
467
                        sy = y-(widthk/2);
468
                        for(mcy=0; mcy < widthk; ++mcy, ++sy)
469
                        {
470
                                my = sy < 0 ? 0 : sy > height()-1 ? height()-1 : sy;
471
                                sx = x+(-widthk/2);
472
                                for(mcx=0; mcx < widthk; ++mcx, ++sx)
473
                                {
474
                                        mx = sx < 0 ? 0 : sx > width()-1 ? width()-1 : sx;
475
                                        red += (*k)*(qRed(jumpTablek[my][mx])*257);
476
                                        green += (*k)*(qGreen(jumpTablek[my][mx])*257);
477
                                        blue += (*k)*(qBlue(jumpTablek[my][mx])*257);
478
                                        alpha += (*k)*(qAlpha(jumpTablek[my][mx])*257);
479
                                        ++k;
480
                                }
481
                        }
482
                        red = red < 0 ? 0 : red > 65535 ? 65535 : red+0.5;
483
                        green = green < 0 ? 0 : green > 65535 ? 65535 : green+0.5;
484
                        blue = blue < 0 ? 0 : blue > 65535 ? 65535 : blue+0.5;
485
                        alpha = alpha < 0 ? 0 : alpha > 65535 ? 65535 : alpha+0.5;
486
                        *q++ = qRgba((unsigned char)(red/257UL),
2095 fschmid 487
                                     (unsigned char)(green/257UL),
488
                                     (unsigned char)(blue/257UL),
489
                                     (unsigned char)(alpha/257UL));
2092 fschmid 490
                }
491
        }
2095 fschmid 492
        free(normal_kernel);
2092 fschmid 493
        return(true);
494
}
495
 
496
int ScImage::getOptimalKernelWidth(double radius, double sigma)
497
{
498
        double normalize, value;
499
        long width;
500
        register long u;
501
        assert(sigma != 0.0);
502
        if(radius > 0.0)
503
                return((int)(2.0*ceil(radius)+1.0));
504
        for(width=5; ;)
505
        {
506
                normalize=0.0;
507
                for(u=(-width/2); u <= (width/2); u++)
508
                        normalize+=exp(-((double) u*u)/(2.0*sigma*sigma))/(2.50662827463100024161235523934010416269302368164062*sigma);
509
                u=width/2;
510
                value=exp(-((double) u*u)/(2.0*sigma*sigma))/(2.50662827463100024161235523934010416269302368164062*sigma)/normalize;
511
                if((long)(65535*value) <= 0)
512
                        break;
513
                width+=2;
514
        }
515
        return((int)width-2);
516
}
517
 
518
void ScImage::sharpen(double radius, double sigma)
519
{
520
        double alpha, normalize, *kernel;
521
        int widthk;
522
        register long i, u, v;
523
        QImage dest;
524
        if(sigma == 0.0)
525
                return;
526
        widthk = getOptimalKernelWidth(radius, sigma);
527
        if(width() < widthk)
528
                return;
529
        kernel = (double *)malloc(widthk*widthk*sizeof(double));
530
        if(!kernel)
531
                return;
532
        i = 0;
533
        normalize=0.0;
534
        for (v=(-widthk/2); v <= (widthk/2); v++)
535
        {
536
                for (u=(-widthk/2); u <= (widthk/2); u++)
537
                {
538
                        alpha=exp(-((double) u*u+v*v)/(2.0*sigma*sigma));
539
                        kernel[i]=alpha/(2.0*3.14159265358979323846264338327950288419716939937510*sigma*sigma);
540
                        normalize+=kernel[i];
541
                        i++;
542
                }
543
        }
544
        kernel[i/2]=(-2.0)*normalize;
545
        convolveImage(&dest, widthk, kernel);
2095 fschmid 546
        liberateMemory((void **) &kernel);
2092 fschmid 547
        for( int yi=0; yi < dest.height(); ++yi )
548
        {
549
                QRgb *s = (QRgb*)(dest.scanLine( yi ));
550
                QRgb *d = (QRgb*)(scanLine( yi ));
551
                for(int xi=0; xi < dest.width(); ++xi )
552
                {
553
                        (*d) = (*s);
554
                        s++;
555
                        d++;
556
                }
557
        }
558
        return;
559
}
560
 
2082 fschmid 561
void ScImage::contrast(int contrastValue, bool cmyk)
562
{
563
        curveTable.resize(256);
564
        QPoint p1(0,0 - contrastValue);
565
        QPoint p2(256, 256 + contrastValue);
566
        double mc = (p1.y() - p2.y()) / (double)(p1.x() - p2.x());
567
        for (int i = 0; i < 256; ++i)
568
        {
569
                curveTable[i] = QMIN(255, QMAX(0, int(i * mc) + p1.y()));
570
        }
571
        applyCurve(cmyk);
572
}
573
 
574
void ScImage::brightness(int brightnessValue, bool cmyk)
575
{
576
        curveTable.resize(256);
577
        QPoint p1(0,0 + brightnessValue);
578
        QPoint p2(256, 256 + brightnessValue);
579
        double mc = (p1.y() - p2.y()) / (double)(p1.x() - p2.x());
580
        for (int i = 0; i < 256; ++i)
581
        {
582
                curveTable[i] = QMIN(255, QMAX(0, int(i * mc) + p1.y()));
583
        }
584
        applyCurve(cmyk);
585
}
586
 
587
void ScImage::applyCurve(bool cmyk)
588
{
589
        int h = height();
590
        int w = width();
591
        for( int yi=0; yi < h; ++yi )
592
        {
593
                QRgb * s = (QRgb*)(scanLine( yi ));
594
                for( int xi=0; xi < w; ++xi )
595
                {
596
                        QRgb r=*s;
597
                        int c, m, y, k;
598
                        if (cmyk)
599
                        {
2766 cbradney 600
                                unsigned char *p = (unsigned char *) s;
601
                                unsigned char rc = 255 - QMIN(255, p[0] + p[3]);
602
                                unsigned char gc = 255 - QMIN(255, p[1] + p[3]);
603
                                unsigned char bc = 255 - QMIN(255, p[2] + p[3]);
4419 cbradney 604
                                c = 255 - curveTable[(int)rc];
605
                                m = 255 - curveTable[(int)gc];
606
                                y = 255 - curveTable[(int)bc];
2082 fschmid 607
                                k = QMIN(QMIN(c, m), y);
608
                                *s = qRgba(y - k, m - k, c - k, k );
609
                        }
610
                        else
611
                        {
612
                                c = curveTable[qRed(r)];
613
                                m = curveTable[qGreen(r)];
614
                                y = curveTable[qBlue(r)];
615
                                k = qAlpha(r);
616
                                *s = qRgba(c, m, y, k);
617
                        }
618
                        s++;
619
                }
620
        }
621
}
622
 
2886 fschmid 623
void ScImage::colorize(ScColor color, int shade, bool cmyk)
2053 fschmid 624
{
625
        int h = height();
626
        int w = width();
627
        int cc, cm, cy, ck;
2057 fschmid 628
        int hu, sa, v;
2886 fschmid 629
        ScColor tmp2;
2057 fschmid 630
        QColor tmpR;
2053 fschmid 631
        if (cmyk)
2057 fschmid 632
                color.getShadeColorCMYK(&cc, &cm, &cy, &ck, shade);
2053 fschmid 633
        else
634
        {
635
                ck = 0;
2057 fschmid 636
                color.getShadeColorRGB(&cc, &cm, &cy, shade);
2053 fschmid 637
        }
638
        for( int yi=0; yi < h; ++yi )
639
        {
640
                QRgb * s = (QRgb*)(scanLine( yi ));
641
                for( int xi=0; xi < w; ++xi )
642
                {
643
                        QRgb r=*s;
644
                        if (cmyk)
645
                        {
2057 fschmid 646
                                double k = QMIN(qRound(0.3 * qRed(r) + 0.59 * qGreen(r) + 0.11 * qBlue(r) + qAlpha(r)), 255) / 255.0;
2053 fschmid 647
                                *s = qRgba(QMIN(qRound(cc*k), 255), QMIN(qRound(cm*k), 255), QMIN(qRound(cy*k), 255), QMIN(qRound(ck*k), 255));
648
                        }
649
                        else
650
                        {
2057 fschmid 651
                                int k = 255 - QMIN(qRound(0.3 * qRed(r) + 0.59 * qGreen(r) + 0.11 * qBlue(r)), 255);
652
                                int cc2, cm2, cy2;
653
                                tmpR.setRgb(cc, cm, cy);
654
                                tmpR.hsv(&hu, &sa, &v);
655
                                if (cc == cm && cm == cy)
656
                                        tmpR.setHsv(hu, sa, 255 - ((255 - v) * k / 255));
657
                                else
658
                                        tmpR.setHsv(hu, sa * k / 255, v);
659
                                tmpR.getRgb(&cc2, &cm2, &cy2);
2053 fschmid 660
                                int a = qAlpha(r);
2057 fschmid 661
                                *s = qRgba(cc2, cm2, cy2, a);
2053 fschmid 662
                        }
663
                        s++;
664
                }
665
        }
666
}
667
 
2057 fschmid 668
void ScImage::invert(bool cmyk)
669
{
670
        int h = height();
671
        int w = width();
672
        for( int yi=0; yi < h; ++yi )
673
        {
674
                QRgb * s = (QRgb*)(scanLine( yi ));
675
                for( int xi=0; xi < w; ++xi )
676
                {
677
                        if (cmyk)
678
                        {
2766 cbradney 679
                                unsigned char *p = (unsigned char *) s;
2057 fschmid 680
                                unsigned char c, m, y, k;
2766 cbradney 681
                                c = 255 - QMIN(255, p[0] + p[3]);
682
                                m = 255 - QMIN(255, p[1] + p[3]);
683
                                y = 255 - QMIN(255, p[2] + p[3]);
2061 fschmid 684
                                k = QMIN(QMIN(c, m), y);
2766 cbradney 685
                                p[0] = c - k;
686
                                p[1] = m - k;
687
                                p[2] = y - k;
688
                                p[3] = k;
2057 fschmid 689
                        }
690
                        else
2766 cbradney 691
                                *s ^= 0x00ffffff;
2057 fschmid 692
                        s++;
693
                }
694
        }
695
}
696
 
2053 fschmid 697
void ScImage::toGrayscale(bool cmyk)
698
{
699
        int h = height();
700
        int w = width();
701
        for( int yi=0; yi < h; ++yi )
702
        {
703
                QRgb * s = (QRgb*)(scanLine( yi ));
704
                for( int xi=0; xi < w; ++xi )
705
                {
706
                        QRgb r=*s;
707
                        int k;
708
                        if (cmyk)
709
                        {
2056 fschmid 710
                                k = QMIN(qRound(0.3 * qRed(r) + 0.59 * qGreen(r) + 0.11 * qBlue(r) + qAlpha(r)), 255);
2053 fschmid 711
                                *s = qRgba(0, 0, 0, k);
712
                        }
713
                        else
714
                        {
715
                                k = QMIN(qRound(0.3 * qRed(r) + 0.59 * qGreen(r) + 0.11 * qBlue(r)), 255);
716
                                int a = qAlpha(r);
717
                                *s = qRgba(k, k, k, a);
718
                        }
719
                        s++;
720
                }
721
        }
722
}
723
 
2012 fschmid 724
void ScImage::swapRGBA()
725
{
726
        for (int i = 0; i < height(); ++i)
727
        {
2766 cbradney 728
                unsigned int *ptr = (unsigned int *) scanLine(i);
729
                unsigned char r, b;
2012 fschmid 730
                for (int j = 0; j < width(); ++j)
731
                {
732
                        unsigned char *p = (unsigned char *) ptr;
2766 cbradney 733
                        r = p[0];
734
                        b = p[2];
735
                        p[2] = r;
736
                        p[0] = b;
737
                        ptr++;
2012 fschmid 738
                }
739
        }
740
}
741
 
2025 fschmid 742
void ScImage::createLowRes(double scale)
2012 fschmid 743
{
2025 fschmid 744
        int w = qRound(width() / scale);
745
        int h = qRound(height() / scale);
2012 fschmid 746
        QImage tmp = smoothScale(w, h);
747
        create(w, h, 32);
748
        for( int yi=0; yi < tmp.height(); ++yi )
749
        {
750
                QRgb *s = (QRgb*)(tmp.scanLine( yi ));
751
                QRgb *d = (QRgb*)(scanLine( yi ));
752
                for(int xi=0; xi < tmp.width(); ++xi )
753
                {
754
                        (*d) = (*s);
755
                        s++;
756
                        d++;
757
                }
758
        }
759
}
760
 
2004 fschmid 761
void ScImage::Convert2JPG(QString fn, int Quality, bool isCMYK, bool isGray)
762
{
763
        struct jpeg_compress_struct cinfo;
764
        struct my_error_mgr         jerr;
765
        FILE     *outfile;
766
        JSAMPROW row_pointer[1];
767
        row_pointer[0] = 0;
768
        cinfo.err = jpeg_std_error (&jerr.pub);
769
        jerr.pub.error_exit = my_error_exit;
770
        outfile = NULL;
771
        if (setjmp (jerr.setjmp_buffer))
772
        {
773
                jpeg_destroy_compress (&cinfo);
774
                if (outfile)
775
                        fclose (outfile);
776
                return;
777
        }
778
        jpeg_create_compress (&cinfo);
2643 craig 779
        if ((outfile = fopen (fn.local8Bit(), "wb")) == NULL)
2004 fschmid 780
                return;
781
        jpeg_stdio_dest (&cinfo, outfile);
782
        cinfo.image_width  = width();
783
        cinfo.image_height = height();
784
        if (isCMYK)
785
        {
786
                cinfo.in_color_space = JCS_CMYK;
787
                cinfo.input_components = 4;
788
        }
789
        else
790
        {
791
                if (isGray)
792
                {
793
                        cinfo.in_color_space = JCS_GRAYSCALE;
794
                        cinfo.input_components = 1;
795
                }
796
                else
797
                {
798
                        cinfo.in_color_space = JCS_RGB;
799
                        cinfo.input_components = 3;
800
                }
801
        }
802
        jpeg_set_defaults (&cinfo);
803
        int qual[] = { 95, 85, 75, 50, 25 };  // These are the JPEG Quality settings 100 means best, 0 .. don't discuss
804
        jpeg_set_quality (&cinfo, qual[Quality], true);
2680 cbradney 805
        jpeg_start_compress (&cinfo, true);
2004 fschmid 806
        row_pointer[0] = new uchar[cinfo.image_width*cinfo.input_components];
807
        int w = cinfo.image_width;
808
        while (cinfo.next_scanline < cinfo.image_height)
809
        {
810
                uchar *row = row_pointer[0];
811
                if (isCMYK)
812
                {
813
                        QRgb* rgba = (QRgb*)scanLine(cinfo.next_scanline);
814
                        for (int i=0; i<w; ++i)
815
                        {
3963 fschmid 816
                                *row++ = 255-qRed(*rgba);
817
                                *row++ = 255-qGreen(*rgba);
818
                                *row++ = 255-qBlue(*rgba);
819
                                *row++ = 255-qAlpha(*rgba);
2004 fschmid 820
                                ++rgba;
821
                        }
822
                }
823
                else
824
                {
825
                        if (isGray)
826
                        {
827
                                QRgb* rgba = (QRgb*)scanLine(cinfo.next_scanline);
828
                                for (int i=0; i<w; ++i)
829
                                {
830
                                        *row++ = qRed(*rgba);
831
                                        ++rgba;
832
                                }
833
                        }
834
                        else
835
                        {
836
                                QRgb* rgb = (QRgb*)scanLine(cinfo.next_scanline);
837
                                for (int i=0; i<w; i++)
838
                                {
839
                                        *row++ = qRed(*rgb);
840
                                        *row++ = qGreen(*rgb);
841
                                        *row++ = qBlue(*rgb);
842
                                        ++rgb;
843
                                }
844
                        }
845
                }
846
                jpeg_write_scanlines (&cinfo, row_pointer, 1);
847
        }
848
        jpeg_finish_compress (&cinfo);
849
        fclose (outfile);
850
        jpeg_destroy_compress (&cinfo);
851
        delete [] row_pointer[0];
852
}
853
 
5234 fschmid 854
QByteArray ScImage::ImageToArray()
2004 fschmid 855
{
2884 fschmid 856
        int i = 0;
2004 fschmid 857
        int h = height();
858
        int w = width();
2884 fschmid 859
        unsigned char u;
5234 fschmid 860
        QByteArray imgArray(3 * h * w);
2004 fschmid 861
        for( int yi=0; yi < h; ++yi )
862
        {
863
                QRgb * s = (QRgb*)(scanLine( yi ));
864
                for( int xi=0; xi < w; ++xi )
865
                {
866
                        QRgb r=*s++;
2884 fschmid 867
                        u=qRed(r);
5234 fschmid 868
                        imgArray[i++] = u;
2004 fschmid 869
                        u=qGreen(r);
5234 fschmid 870
                        imgArray[i++] = u;
2004 fschmid 871
                        u=qBlue(r);
5234 fschmid 872
                        imgArray[i++] = u;
2004 fschmid 873
                }
874
        }
5234 fschmid 875
        return imgArray;
2004 fschmid 876
}
877
 
5234 fschmid 878
QByteArray ScImage::ImageToGray()
2004 fschmid 879
{
2884 fschmid 880
        int i = 0;
2004 fschmid 881
        int h = height();
882
        int w = width();
5234 fschmid 883
        QByteArray imgArray(h * w);
2004 fschmid 884
        for( int yi=0; yi < h; ++yi )
885
        {
886
                QRgb * s = (QRgb*)(scanLine( yi ));
887
                for( int xi=0; xi < w; ++xi )
888
                {
889
                        QRgb r=*s;
890
                        int k = QMIN(qRound(0.3 * qRed(r) + 0.59 * qGreen(r) + 0.11 * qBlue(r)), 255);
891
                        *s = qRgba(k, 0, 0, 0);
5234 fschmid 892
                        imgArray[i++] = k;
2004 fschmid 893
                        s++;
894
                }
895
        }
5234 fschmid 896
        return imgArray;
2004 fschmid 897
}
898
 
5234 fschmid 899
QByteArray ScImage::ImageToCMYK_PDF(bool pre)
2004 fschmid 900
{
2884 fschmid 901
        int i = 0;
2004 fschmid 902
        int h = height();
903
        int w = width();
5234 fschmid 904
        QByteArray imgArray( 4 * h * w );
2004 fschmid 905
        if (pre)
906
        {
907
                for( int yi=0; yi < h; ++yi )
908
                {
909
                        QRgb * s = (QRgb*)(scanLine( yi ));
910
                        for( int xi=0; xi < w; ++xi )
911
                        {
912
                                QRgb r=*s;
913
                                int c = qRed(r);
914
                                int m = qGreen(r);
915
                                int y = qBlue(r);
916
                                int k = qAlpha(r);
5234 fschmid 917
                                imgArray[i++] = static_cast<unsigned char> (c);
918
                                imgArray[i++] = static_cast<unsigned char> (m);
919
                                imgArray[i++] = static_cast<unsigned char> (y);
920
                                imgArray[i++] = static_cast<unsigned char> (k);
2004 fschmid 921
                                s++;
922
                        }
923
                }
924
        }
925
        else
926
        {
927
                for( int yi=0; yi < h; ++yi )
928
                {
929
                        QRgb * s = (QRgb*)(scanLine( yi ));
930
                        for( int xi=0; xi < w; ++xi )
931
                        {
932
                                QRgb r=*s;
933
                                int c = 255 - qRed(r);
934
                                int m = 255 - qGreen(r);
935
                                int y = 255 - qBlue(r);
936
                                int k = QMIN(QMIN(c, m), y);
5234 fschmid 937
                                imgArray[i++] = static_cast<unsigned char> (c - k);
938
                                imgArray[i++] = static_cast<unsigned char> (m - k);
939
                                imgArray[i++] = static_cast<unsigned char> (y - k);
940
                                imgArray[i++] = static_cast<unsigned char> (k);
2004 fschmid 941
                                s++;
942
                        }
943
                }
944
        }
5234 fschmid 945
        return imgArray;
2004 fschmid 946
}
947
 
5234 fschmid 948
QByteArray ScImage::ImageToCMYK_PS(int pl, bool pre)
2004 fschmid 949
{
2884 fschmid 950
        int i = 0;
2004 fschmid 951
        int h = height();
952
        int w = width();
5234 fschmid 953
        QByteArray imgArray;
2884 fschmid 954
        if(pl == -1)
5234 fschmid 955
                imgArray.resize(4 * h * w);
2884 fschmid 956
        else
5234 fschmid 957
                imgArray.resize(h * w);
2004 fschmid 958
        if (pre)
959
        {
960
                for( int yi=0; yi < h; ++yi )
961
                {
962
                        QRgb * s = (QRgb*)(scanLine( yi ));
963
                        for( int xi=0; xi < w; ++xi )
964
                        {
965
                                QRgb r=*s++;
966
                                int c = qRed(r);
967
                                int m = qGreen(r);
968
                                int y = qBlue(r);
969
                                int k = qAlpha(r);
970
                                if (pl == -1)
971
                                {
5234 fschmid 972
                                        imgArray[i++] = static_cast<unsigned char> (c);
973
                                        imgArray[i++] = static_cast<unsigned char> (m);
974
                                        imgArray[i++] = static_cast<unsigned char> (y);
975
                                        imgArray[i++] = static_cast<unsigned char> (k);
2004 fschmid 976
                                }
977
                                else
978
                                {
979
                                        if (pl == -2)
5234 fschmid 980
                                                imgArray[i++] = static_cast<unsigned char> (QMIN(255, qRound(0.3 * c + 0.59 * m + 0.11 * y + k)));
2004 fschmid 981
                                        if (pl == 1)
5234 fschmid 982
                                                imgArray[i++] = static_cast<unsigned char> (c);
2004 fschmid 983
                                        if (pl == 2)
5234 fschmid 984
                                                imgArray[i++] = static_cast<unsigned char> (m);
2004 fschmid 985
                                        if (pl == 3)
5234 fschmid 986
                                                imgArray[i++] = static_cast<unsigned char> (y);
2004 fschmid 987
                                        if (pl == 0)
5234 fschmid 988
                                                imgArray[i++] = static_cast<unsigned char> (k);
2004 fschmid 989
                                }
990
                        }
991
                }
992
        }
993
        else
994
        {
995
                for( int yi=0; yi < h; ++yi )
996
                {
997
                        QRgb * s = (QRgb*)(scanLine( yi ));
998
                        for( int xi=0; xi < w; ++xi )
999
                        {
1000
                                QRgb r=*s++;
1001
                                int c = 255 - qRed(r);
1002
                                int m = 255 - qGreen(r);
1003
                                int y = 255 - qBlue(r);
1004
                                int k = QMIN(QMIN(c, m), y);
1005
                                if (pl == -1)
1006
                                {
5234 fschmid 1007
                                        imgArray[i++] = static_cast<unsigned char> (c - k);
1008
                                        imgArray[i++] = static_cast<unsigned char> (m - k);
1009
                                        imgArray[i++] = static_cast<unsigned char> (y - k);
1010
                                        imgArray[i++] = static_cast<unsigned char> (k);
2004 fschmid 1011
                                }
1012
                                else
1013
                                {
1014
                                        if (pl == -2)
5234 fschmid 1015
                                                imgArray[i++] = static_cast<unsigned char> (QMIN(255, qRound(0.3 * c + 0.59 * m + 0.11 * y + k)));
2004 fschmid 1016
                                        if (pl == 1)
5234 fschmid 1017
                                                imgArray[i++] = static_cast<unsigned char> (c - k);
2004 fschmid 1018
                                        if (pl == 2)
5234 fschmid 1019
                                                imgArray[i++] = static_cast<unsigned char> (m - k);
2004 fschmid 1020
                                        if (pl == 3)
5234 fschmid 1021
                                                imgArray[i++] = static_cast<unsigned char> (y - k);
2004 fschmid 1022
                                        if (pl == 0)
5234 fschmid 1023
                                                imgArray[i++] = static_cast<unsigned char> (k);
2004 fschmid 1024
                                }
1025
                        }
1026
                }
1027
        }
5234 fschmid 1028
        return imgArray;
2004 fschmid 1029
}
1030
 
1031
// Check that the header is a valid PSD.
1032
bool ScImage::IsValid( const PSDHeader & header )
1033
{
1034
        if( header.signature != 0x38425053 )
1035
                return false;
1036
        return true;
1037
}
1038
 
1039
// Check that the header is supported.
1040
bool ScImage::IsSupported( const PSDHeader & header )
1041
{
1042
        if ( header.version != 1 )
1043
                return false;
1044
        if ( header.channel_count > 16 )
1045
                return false;
1046
        if ( header.depth != 8 )
1047
                return false;
3836 fschmid 1048
        if ((header.color_mode == CM_RGB) || (header.color_mode == CM_CMYK)
1049
         || (header.color_mode == CM_GRAYSCALE) || (header.color_mode == CM_INDEXED))
2004 fschmid 1050
                return true;
1051
        return false;
1052
}
1053
 
1054
unsigned char ScImage::INT_MULT ( unsigned char a, unsigned char b )
1055
{
1056
        int c = a * b + 0x80;
1057
        return (unsigned char)(( ( c >> 8 ) + c ) >> 8);
1058
}
1059
 
1060
/*!
1061
 * Convert a color in RGB space to HSV space (Hue, Saturation, Value).
1062
 * \param red the red component (modified in place).
1063
 * \param green the green component (modified in place).
1064
 * \param blue the blue component (modified in place).
1065
 */
1066
void ScImage::RGBTOHSV ( uchar& red, uchar& green, uchar& blue )
1067
{
1068
        int r, g, b;
1069
        double h, s, v;
1070
        int min, max;
1071
        h = 0.;
1072
        r = red;
1073
        g = green;
1074
        b = blue;
1075
        if ( r > g )
1076
        {
1077
                max = QMAX( r, b );
1078
                min = QMIN( g, b );
1079
        }
1080
        else
1081
        {
1082
                max = QMAX( g, b );
1083
                min = QMIN( r, b );
1084
        }
1085
        v = max;
1086
        if ( max != 0 )
1087
                s = ( ( max - min ) * 255 ) / (double)max;
1088
        else
1089
                s = 0;
1090
        if ( s == 0 )
1091
                h = 0;
1092
        else
1093
        {
1094
                int delta = max - min;
1095
                if ( r == max )
1096
                        h = ( g - b ) / (double)delta;
1097
                else if ( g == max )
1098
                        h = 2 + ( b - r ) / (double)delta;
1099
                else if ( b == max )
1100
                        h = 4 + ( r - g ) / (double)delta;
1101
                h *= 42.5;
1102
                if ( h < 0 )
1103
                        h += 255;
1104
                if ( h > 255 )
1105
                        h -= 255;
1106
        }
1107
        red   = (uchar)h;
1108
        green = (uchar)s;
1109
        blue  = (uchar)v;
1110
}
1111
 
1112
/*!
1113
 * Convert a color in HSV space to RGB space.
1114
 * \param hue the hue component (modified in place).
1115
 * \param saturation the saturation component (modified in place).
1116
 * \param value the value component (modified in place).
1117
 */
1118
void ScImage::HSVTORGB ( uchar& hue, uchar& saturation, uchar& value )
1119
{
1120
        if ( saturation == 0 )
1121
        {
1122
                hue        = value;
1123
                saturation = value;
1124
                value      = value;
1125
        }
1126
        else
1127
        {
1128
                double h = hue * 6. / 255.;
1129
                double s = saturation / 255.;
1130
                double v = value / 255.;
1131
 
1132
                double f = h - (int)h;
1133
                double p = v * ( 1. - s );
1134
                double q = v * ( 1. - ( s * f ) );
1135
                double t = v * ( 1. - ( s * ( 1. - f ) ) );
1136
                // Worth a note here that gcc 2.96 will generate different results
1137
                // depending on optimization mode on i386.
1138
                switch ((int)h)
1139
                {
1140
                case 0:
1141
                        hue        = (uchar)( v * 255 );
1142
                        saturation = (uchar)( t * 255 );
1143
                        value      = (uchar)( p * 255 );
1144
                        break;
1145
                case 1:
1146
                        hue        = (uchar)( q * 255 );
1147
                        saturation = (uchar)( v * 255 );
1148
                        value      = (uchar)( p * 255 );
1149
                        break;
1150
                case 2:
1151
                        hue        = (uchar)( p * 255 );
1152
                        saturation = (uchar)( v * 255 );
1153
                        value      = (uchar)( t * 255 );
1154
                        break;
1155
                case 3:
1156
                        hue        = (uchar)( p * 255 );
1157
                        saturation = (uchar)( q * 255 );
1158
                        value      = (uchar)( v * 255 );
1159
                        break;
1160
                case 4:
1161
                        hue        = (uchar)( t * 255 );
1162
                        saturation = (uchar)( p * 255 );
1163
                        value      = (uchar)( v * 255 );
1164
                        break;
1165
                case 5:
1166
                        hue        = (uchar)( v * 255 );
1167
                        saturation = (uchar)( p * 255 );
1168
                        value      = (uchar)( q * 255 );
1169
                }
1170
        }
1171
}
1172
 
1173
/*!
1174
 * Convert a color in RGB space to HLS space (Hue, Lightness, Saturation).
1175
 * \param red the red component (modified in place).
1176
 * \param green the green component (modified in place).
1177
 * \param blue the blue component (modified in place).
1178
 */
1179
void ScImage::RGBTOHLS ( uchar& red, uchar& green, uchar& blue )
1180
{
1181
        int r = red;
1182
        int g = green;
1183
        int b = blue;
1184
        int min, max;
1185
        if ( r > g )
1186
        {
1187
                max = QMAX( r, b );
1188
                min = QMIN( g, b );
1189
        }
1190
        else
1191
        {
1192
                max = QMAX( g, b );
1193
                min = QMIN( r, b );
1194
        }
1195
        double h;
1196
        double l = ( max + min ) / 2.;
1197
        double s;
1198
        if ( max == min )
1199
        {
1200
                s = 0.;
1201
                h = 0.;
1202
        }
1203
        else
1204
        {
1205
                int delta = max - min;
1206
                if ( l < 128 )
1207
                        s = 255 * (double)delta / (double)( max + min );
1208
                else
1209
                        s = 255 * (double)delta / (double)( 511 - max - min );
1210
                if ( r == max )
1211
                        h = ( g - b ) / (double)delta;
1212
                else if ( g == max )
1213
                        h = 2 + ( b - r ) / (double)delta;
1214
                else
1215
                        h = 4 + ( r - g ) / (double)delta;
1216
                h *= 42.5;
1217
                if ( h < 0 )
1218
                        h += 255;
1219
                else if ( h > 255 )
1220
                        h -= 255;
1221
        }
1222
        red   = (uchar)h;
1223
        green = (uchar)l;
1224
        blue  = (uchar)s;
1225
}
1226
 
1227
/*!
1228
 * Implement the HLS "double hex-cone".
1229
 * \param n1 lightness fraction (?)
1230
 * \param n2 saturation fraction (?)
1231
 * \param hue hue "angle".
1232
 * \return HLS value.
1233
 */
1234
int ScImage::HLSVALUE ( double n1, double n2, double hue )
1235
{
1236
        double value;
1237
        if ( hue > 255 )
1238
                hue -= 255;
1239
        else if ( hue < 0 )
1240
                hue += 255;
1241
        if ( hue < 42.5 )
1242
                value = n1 + ( n2 - n1 ) * ( hue / 42.5 );
1243
        else if ( hue < 127.5 )
1244
                value = n2;
1245
        else if ( hue < 170 )
1246
                value = n1 + ( n2 - n1 ) * ( ( 170 - hue ) / 42.5 );
1247
        else
1248
                value = n1;
1249
        return (int)( value * 255 );
1250
}
1251
 
1252
/*!
1253
 * Convert a color in HLS space to RGB space.
1254
 * \param hue the hue component (modified in place).
1255
 * \param lightness the lightness component (modified in place).
1256
 * \param saturation the saturation component (modified in place).
1257
 */
1258
void ScImage::HLSTORGB ( uchar& hue, uchar& lightness, uchar& saturation )
1259
{
1260
        double h = hue;
1261
        double l = lightness;
1262
        double s = saturation;
1263
        if ( s == 0 )
1264
        {
1265
                hue        = (uchar)l;
1266
                lightness  = (uchar)l;
1267
                saturation = (uchar)l;
1268
        }
1269
        else
1270
        {
1271
                double m1, m2;
1272
                if ( l < 128 )
1273
                        m2 = ( l * ( 255 + s ) ) / 65025.;
1274
                else
1275
                        m2 = ( l + s - ( l * s ) / 255. ) / 255.;
1276
                m1 = ( l / 127.5 ) - m2;
1277
                hue        = HLSVALUE( m1, m2, h + 85 );
1278
                lightness  = HLSVALUE( m1, m2, h );
1279
                saturation = HLSVALUE( m1, m2, h - 85 );
1280
        }
1281
}
1282
 
3802 fschmid 1283
bool ScImage::loadChannel( QDataStream & s, const PSDHeader & header, QValueList<PSDLayer> &layerInfo, uint layer, int channel, int component, QImage &tmpImg)
1284
{
1285
        uint base = s.device()->at();
1286
        uchar cbyte;
1287
        ushort compression;
1288
        s >> compression;
1289
        if( compression > 1 )
1290
                return false;
1291
        if (compression == 0)
1292
        {
1293
                int count = layerInfo[layer].channelLen[channel]-2;
1294
                for (int i = 0; i < tmpImg.height(); i++)
1295
                {
1296
                        uchar *ptr =  tmpImg.scanLine(i);
1297
                        for (int j = 0; j < tmpImg.width(); j++)
1298
                        {
1299
                                s >> cbyte;
1300
                                count--;
1301
                                if (header.color_mode == CM_CMYK)
1302
                                        cbyte = 255 - cbyte;
3814 fschmid 1303
                                if ((header.color_mode == CM_GRAYSCALE) && (component != 3))
1304
                                {
1305
                                        ptr[0] = cbyte;
1306
                                        ptr[1] = cbyte;
1307
                                        ptr[2] = cbyte;
1308
                                }
3836 fschmid 1309
                                else if ((header.color_mode == CM_INDEXED) && (component != 3))
1310
                                {
1311
                                        int ccol = colorTable[cbyte];
4099 fschmid 1312
                                        ptr[2] = qRed(ccol);
3836 fschmid 1313
                                        ptr[1] = qGreen(ccol);
4099 fschmid 1314
                                        ptr[0] = qBlue(ccol);
3836 fschmid 1315
                                }
3814 fschmid 1316
                                else
1317
                                {
1318
                                        if (channel < 4)
1319
                                                ptr[component] = cbyte;
1320
                                }
3802 fschmid 1321
                                if (count == 0)
1322
                                        break;
1323
                                ptr += 4;
1324
                        }
1325
                        if (count == 0)
1326
                                break;
1327
                }
1328
        }
1329
        else
1330
        {
1331
                s.device()->at( s.device()->at() + tmpImg.height() * 2 );
1332
                uint pixel_count = tmpImg.width();
1333
                for (int hh = 0; hh < tmpImg.height(); hh++)
1334
                {
1335
                        uint count = 0;
1336
                        uchar *ptr = tmpImg.scanLine(hh);
1337
                        uchar *ptr2 = ptr+tmpImg.width() * 4;
1338
                        ptr += component;
1339
                        while( count < pixel_count )
1340
                        {
1341
                                uchar c;
1342
                                if(s.atEnd())
1343
                                        return false;
1344
                                s >> c;
1345
                                uint len = c;
1346
                                if( len < 128 )
1347
                                {
1348
                                        // Copy next len+1 bytes literally.
1349
                                        len++;
1350
                                        count += len;
1351
                                        while( len != 0 )
1352
                                        {
1353
                                                s >> cbyte;
1354
                                                if (ptr < ptr2)
1355
                                                {
1356
                                                        if (header.color_mode == CM_CMYK)
1357
                                                                cbyte = 255 - cbyte;
3814 fschmid 1358
                                                        if ((header.color_mode == CM_GRAYSCALE) && (component != 3))
1359
                                                        {
1360
                                                                ptr -= component;
1361
                                                                ptr[0] = cbyte;
1362
                                                                ptr[1] = cbyte;
1363
                                                                ptr[2] = cbyte;
1364
                                                                ptr += component;
1365
                                                        }
3836 fschmid 1366
                                                        else if ((header.color_mode == CM_INDEXED) && (component != 3))
1367
                                                        {
1368
                                                                ptr -= component;
1369
                                                                int ccol = colorTable[cbyte];
4099 fschmid 1370
                                                                ptr[2] = qRed(ccol);
3836 fschmid 1371
                                                                ptr[1] = qGreen(ccol);
4099 fschmid 1372
                                                                ptr[0] = qBlue(ccol);
3836 fschmid 1373
                                                                ptr += component;
1374
                                                        }
3814 fschmid 1375
                                                        else
1376
                                                        {
1377
                                                                *ptr = cbyte;
1378
                                                        }
3802 fschmid 1379
                                                }
1380
                                                ptr += 4;
1381
                                                len--;
1382
                                        }
1383
                                }
1384
                                else if( len > 128 )
1385
                                {
1386
                                        // Next -len+1 bytes in the dest are replicated from next source byte.
1387
                                        // (Interpret len as a negative 8-bit int.)
1388
                                        len ^= 0xFF;
1389
                                        len += 2;
1390
                                        count += len;
1391
                                        uchar val;
1392
                                        s >> val;
1393
                                        if (header.color_mode == CM_CMYK)
1394
                                                val = 255 - val;
1395
                                        while( len != 0 )
1396
                                        {
1397
                                                if (ptr < ptr2)
3814 fschmid 1398
                                                {
1399
                                                        if ((header.color_mode == CM_GRAYSCALE) && (component != 3))
1400
                                                        {
1401
                                                                ptr -= component;
1402
                                                                ptr[0] = val;
1403
                                                                ptr[1] = val;
1404
                                                                ptr[2] = val;
1405
                                                                ptr += component;
1406
                                                        }
3836 fschmid 1407
                                                        else if ((header.color_mode == CM_INDEXED) && (component != 3))
1408
                                                        {
1409
                                                                ptr -= component;
1410
                                                                int ccol = colorTable[val];
4099 fschmid 1411
                                                                ptr[2] = qRed(ccol);
3836 fschmid 1412
                                                                ptr[1] = qGreen(ccol);
4099 fschmid 1413
                                                                ptr[0] = qBlue(ccol);
3836 fschmid 1414
                                                                ptr += component;
1415
                                                        }
3814 fschmid 1416
                                                        else
1417
                                                                *ptr = val;
1418
                                                }
3802 fschmid 1419
                                                ptr += 4;
1420
                                                len--;
1421
                                        }
1422
                                }
1423
                                else if( len == 128 )
1424
                                {
1425
                                        // No-op.
1426
                                }
1427
                        }
1428
                }
1429
        }
1430
        s.device()->at( base+layerInfo[layer].channelLen[channel] );
1431
        return true;
1432
}
1433
 
2004 fschmid 1434
bool ScImage::loadLayerChannels( QDataStream & s, const PSDHeader & header, QValueList<PSDLayer> &layerInfo, uint layer, bool* firstLayer)
1435
{
1436
        // Find out if the data is compressed.
1437
        // Known values:
1438
        //   0: no compression
1439
        //   1: RLE compressed
3814 fschmid 1440
        uint base = s.device()->at();
1441
        uint base2 = base;
1442
        uint channel_num = layerInfo[layer].channelLen.count();
3802 fschmid 1443
        QImage tmpImg = QImage();
1444
        QImage mask = QImage();
1445
        if( !tmpImg.create( layerInfo[layer].width, layerInfo[layer].height, 32 ))
3814 fschmid 1446
        {
1447
                for(uint channel = 0; channel < channel_num; channel++)
1448
                {
1449
                        base2 += layerInfo[layer].channelLen[channel];
1450
                }
1451
                s.device()->at( base2 );
3802 fschmid 1452
                return false;
3814 fschmid 1453
        }
5010 fschmid 1454
        tmpImg.fill(qRgba(255, 255, 255, 0));
2004 fschmid 1455
        tmpImg.setAlphaBuffer( true );
1456
        channel_num = QMIN(channel_num, 39);
1457
        uint components[40];
1458
        for(uint channel = 0; channel < channel_num; channel++)
1459
        {
1460
                switch(layerInfo[layer].channelType[channel])
1461
                {
1462
                case 0:
1463
                        components[channel] = 2;
1464
                        break;
1465
                case 1:
1466
                        components[channel] = 1;
1467
                        break;
1468
                case 2:
1469
                        components[channel] = 0;
1470
                        break;
1471
                case 3:
1472
                        components[channel] = 3;
1473
                        break;
1474
                case -1:
1475
                case -2:
1476
                        components[channel] = 3;
1477
                        break;
1478
                }
1479
        }
3802 fschmid 1480
        if (channel_num < 4)
2004 fschmid 1481
        {
3802 fschmid 1482
                for (int i = 0; i < tmpImg.height(); i++)
2004 fschmid 1483
                {
3802 fschmid 1484
                        QRgb * s = (QRgb*)(tmpImg.scanLine( i ));
1485
                        for (int j = 0; j < tmpImg.width(); j++)
2004 fschmid 1486
                        {
3922 fschmid 1487
                                *s++ = qRgba(255, 255, 255, 255);
2004 fschmid 1488
                        }
1489
                }
1490
        }
3802 fschmid 1491
        for(uint channel = 0; channel < channel_num; channel++)
2004 fschmid 1492
        {
3802 fschmid 1493
                if ((layerInfo[layer].channelType[channel] < 0) && (header.color_mode == CM_CMYK))
3764 fschmid 1494
                {
3802 fschmid 1495
                        s.device()->at( base+layerInfo[layer].channelLen[channel] );
1496
                        base = base+layerInfo[layer].channelLen[channel];
1497
                        continue;
3764 fschmid 1498
                }
4268 fschmid 1499
//              if ((layerInfo[layer].channelType[channel] == -2) || (layerInfo[layer].channelType[channel] == -1))
3802 fschmid 1500
                if (layerInfo[layer].channelType[channel] == -2)
2004 fschmid 1501
                {
3802 fschmid 1502
                        if (!mask.create( layerInfo[layer].maskWidth, layerInfo[layer].maskHeight, 32 ))
4268 fschmid 1503
//                      {
1504
//                              if (!mask.create(layerInfo[layer].width, layerInfo[layer].height, 32 ))
1505
                                        break;
1506
//                      }
5010 fschmid 1507
                        mask.fill(qRgba(255, 255, 255, 0));
3802 fschmid 1508
                        mask.setAlphaBuffer( true );
1509
                        if (!loadChannel(s, header, layerInfo, layer, channel, components[channel], mask))
1510
                                break;
2004 fschmid 1511
                }
3802 fschmid 1512
                else
1513
                {
1514
                        if (!loadChannel(s, header, layerInfo, layer, channel, components[channel], tmpImg))
1515
                                break;
1516
                }
2004 fschmid 1517
        }
3799 fschmid 1518
        for(uint channel = 0; channel < channel_num; channel++)
1519
        {
1520
                base2 += layerInfo[layer].channelLen[channel];
1521
        }
1522
        s.device()->at( base2 );
2004 fschmid 1523
        QImage tmpImg2 = tmpImg.copy();
1524
        if (header.color_mode == CM_CMYK)
1525
        {
1526
                for (int i = 0; i < tmpImg.height(); i++)
1527
                {
2766 cbradney 1528
                        unsigned int *ptr = (unsigned int *) tmpImg.scanLine(i);
1529
                        unsigned int *ptr2 = (unsigned int *) tmpImg2.scanLine(i);
2004 fschmid 1530
                        unsigned char r, g, b;
1531
                        for (int j = 0; j < tmpImg.width(); j++)
1532
                        {
2766 cbradney 1533
                                unsigned char *p = (unsigned char *) ptr;
1534
                                unsigned char *p2 = (unsigned char *) ptr2;
1535
                                r = 255 - QMIN(255, p[0] + p[3]);
1536
                                g = 255 - QMIN(255, p[1] + p[3]);
1537
                                b = 255 - QMIN(255, p[2] + p[3]);
1538
                                p2[0] = r;
1539
                                p2[1] = g;
1540
                                p2[2] = b;
1541
                                p2[3] = 255;
2004 fschmid 1542
                                ptr++;
2766 cbradney 1543
                                ptr2++;
2004 fschmid 1544
                        }
1545
                }
1546
        }
1547
        QImage imt;
1548
        double sx = tmpImg.width() / 40.0;
1549
        double sy = tmpImg.height() / 40.0;
1550
        imt = sy < sx ?  tmpImg2.smoothScale(qRound(tmpImg.width() / sx), qRound(tmpImg.height() / sx)) :
2095 fschmid 1551
              tmpImg2.smoothScale(qRound(tmpImg.width() / sy), qRound(tmpImg.height() / sy));
2004 fschmid 1552
        layerInfo[layer].thumb = imt.copy();
1553
        bool visible = !(layerInfo[layer].flags & 2);
1554
        if ((imgInfo.isRequest) && (imgInfo.RequestProps.contains(layer)))
1555
                visible = imgInfo.RequestProps[layer].visible;
1556
        if (visible)
1557
        {
3799 fschmid 1558
                unsigned int startSrcY, startSrcX, startDstY, startDstX;
1559
                if (layerInfo[layer].ypos < 0)
1560
                {
1561
                        startSrcY = abs(layerInfo[layer].ypos);
1562
                        startDstY = 0;
1563
                }
1564
                else
1565
                {
1566
                        startSrcY = 0;
1567
                        startDstY = layerInfo[layer].ypos;
1568
                }
1569
                if (layerInfo[layer].xpos < 0)
1570
                {
1571
                        startSrcX = abs(layerInfo[layer].xpos);
1572
                        startDstX = 0;
1573
                }
1574
                else
1575
                {
1576
                        startSrcX = 0;
1577
                        startDstX = layerInfo[layer].xpos;
1578
                }
3802 fschmid 1579
                unsigned int startSrcYm, startSrcXm, startDstYm, startDstXm;
1580
                if (layerInfo[layer].maskYpos < 0)
1581
                {
1582
                        startSrcYm = abs(layerInfo[layer].maskYpos);
1583
                        startDstYm = 0;
1584
                }
1585
                else
1586
                {
1587
                        startSrcYm = 0;
1588
                        startDstYm = layerInfo[layer].maskYpos;
1589
                }
1590
                if (layerInfo[layer].maskXpos < 0)
1591
                {
1592
                        startSrcXm = abs(layerInfo[layer].maskXpos);
1593
                        startDstXm = 0;
1594
                }
1595
                else
1596
                {
1597
                        startSrcXm = 0;
1598
                        startDstXm = layerInfo[layer].maskXpos;
1599
                }
3922 fschmid 1600
                QString layBlend2 = layerInfo[layer].blend;
1601
                if ((imgInfo.isRequest) && (imgInfo.RequestProps.contains(layer)))
1602
                        layBlend2 = imgInfo.RequestProps[layer].blend;
1603
                if ((layBlend2 == "diss") && (header.color_mode != CM_CMYK))
1604
                {
1605
                        for (int l = 0; l < tmpImg.height(); l++)
1606
                        {
1607
                                srand(random_table[ l  % 4096]);
1608
                                for (int k = 0; k < tmpImg.width(); k++)
1609
                                {
1610
                                        int rand_val = rand() & 0xff;
1611
                                        QRgb pixel = tmpImg.pixel(k, l);
1612
                                        if (rand_val > 128)
1613
                                                tmpImg.setPixel(k, l, qRgba(qRed(pixel), qGreen(pixel), qBlue(pixel), 0));
1614
                                }
1615
                        }
1616
                }
2004 fschmid 1617
                if (*firstLayer)
1618
                {
3799 fschmid 1619
                        for( int yi=static_cast<int>(startSrcY); yi < QMIN(tmpImg.height(), height()); ++yi )
2004 fschmid 1620
                        {
1621
                                QRgb *s = (QRgb*)(tmpImg.scanLine( yi ));
3799 fschmid 1622
                                QRgb *d = (QRgb*)(scanLine( QMIN(static_cast<int>(startDstY), height()-1) ));
1623
                                d += QMIN(static_cast<int>(startDstX), width()-1);
3802 fschmid 1624
                                s += QMIN(static_cast<int>(startSrcX), tmpImg.width()-1);
4268 fschmid 1625
/*                              unsigned int *srcm;
1626
                                if (!mask.isNull())
1627
                                {
1628
                                        srcm = (unsigned int *)mask.scanLine(QMIN(yi, mask.height()-1));
1629
                                        srcm += QMIN(static_cast<int>(startSrcXm), mask.width()-1);
1630
                                } */
3799 fschmid 1631
                                for(int xi=static_cast<int>(startSrcX); xi < QMIN(tmpImg.width(), width()); ++xi )
2004 fschmid 1632
                                {
1633
                                        (*d) = (*s);
4268 fschmid 1634
/*                                      unsigned char *sm = (unsigned char *) srcm;
1635
                                        unsigned char *sc = (unsigned char *) d;
1636
                                        unsigned char *ss = (unsigned char *) s;
1637
                                        if (!mask.isNull())
1638
                                        {
1639
                                                if (header.color_mode == CM_CMYK)
1640
                                                {
1641
                                                        sc[0] = (sc[0] * (255 - sm[3]) + ss[0] * sm[3]) / 255;
1642
                                                        sc[1] = (sc[1] * (255 - sm[3]) + ss[1] * sm[3]) / 255;
1643
                                                        sc[2] = (sc[2] * (255 - sm[3]) + ss[2] * sm[3]) / 255;
1644
                                                        sc[3] = (sc[3] * (255 - sm[3]) + ss[3] * sm[3]) / 255;
1645
                                                }
1646
                                                else
1647
                                                        sc[3] = sm[3];
1648
                                        }
1649
                                        srcm++; */
2004 fschmid 1650
                                        s++;
1651
                                        d++;
1652
                                }
3799 fschmid 1653
                                startDstY++;
2004 fschmid 1654
                        }
1655
                }
1656
                else
1657
                {
3799 fschmid 1658
                        for (int i = static_cast<int>(startSrcY); i < layerInfo[layer].height; i++)
2004 fschmid 1659
                        {
3799 fschmid 1660
                                unsigned int *dst = (unsigned int *)scanLine(QMIN(static_cast<int>(startDstY), height()-1));
1661
                                unsigned int *src = (unsigned int *)tmpImg.scanLine(QMIN(i, tmpImg.height()-1));
1662
                                dst += QMIN(static_cast<int>(startDstX), width()-1);
3802 fschmid 1663
                                src += QMIN(static_cast<int>(startSrcX), tmpImg.width()-1);
4849 cbradney 1664
                                unsigned int *srcm = 0;
3802 fschmid 1665
                                if (!mask.isNull())
1666
                                {
1667
                                        srcm = (unsigned int *)mask.scanLine(QMIN(i, mask.height()-1));
1668
                                        srcm += QMIN(static_cast<int>(startSrcXm), mask.width()-1);
1669
                                }
3799 fschmid 1670
                                startDstY++;
3802 fschmid 1671
                                unsigned char r, g, b, a, src_r, src_g, src_b, src_a, mask_a;
4849 cbradney 1672
                                //<<#3356
1673
                                unsigned int maxDestX = width() - startDstX + startSrcX - 1;
1674
                                for (unsigned int j = startSrcX; j < QMIN(maxDestX, static_cast<unsigned int>(layerInfo[layer].width)); j++)
1675
                                //for (unsigned int j = startSrcX; j < static_cast<unsigned int>(layerInfo[layer].width); j++)
1676
                                //>>#3356
2004 fschmid 1677
                                {
2766 cbradney 1678
                                        unsigned char *d = (unsigned char *) dst;
1679
                                        unsigned char *s = (unsigned char *) src;
3802 fschmid 1680
                                        unsigned char *sm = (unsigned char *) srcm;
2766 cbradney 1681
                                        src_r = s[0];
1682
                                        src_g = s[1];
1683
                                        src_b = s[2];
1684
                                        src_a = s[3];
3802 fschmid 1685
                                        if (!mask.isNull())
1686
                                                mask_a = sm[3];
2004 fschmid 1687
                                        QString layBlend = layerInfo[layer].blend;
1688
                                        if ((imgInfo.isRequest) && (imgInfo.RequestProps.contains(layer)))
1689
                                                layBlend = imgInfo.RequestProps[layer].blend;
1690
                                        if (layBlend == "mul ")
1691
                                        {
1692
                                                if (header.color_mode == CM_CMYK)
3764 fschmid 1693
                                                {
1694
                                                        src_r = INT_MULT(src_r, d[0]);
1695
                                                        src_g = INT_MULT(src_g, d[1]);
1696
                                                        src_b = INT_MULT(src_b, d[2]);
2766 cbradney 1697
                                                        src_a = INT_MULT(src_a, d[3]);
3764 fschmid 1698
                                                }
2004 fschmid 1699
                                                else
3764 fschmid 1700
                                                {
1701
                                                        if (d[3] > 0)
1702
                                                        {
1703
                                                                src_r = INT_MULT(src_r, d[0]);
1704
                                                                src_g = INT_MULT(src_g, d[1]);
1705
                                                                src_b = INT_MULT(src_b, d[2]);
1706
                                                        }
1707
                                                }
2004 fschmid 1708
                                        }
1709
                                        else if (layBlend == "scrn")
1710
                                        {
1711
                                                if (header.color_mode == CM_CMYK)
3764 fschmid 1712
                                                {
1713
                                                        src_r = 255 - INT_MULT(255 - d[0], 255 - src_r);
1714
                                                        src_g = 255 - INT_MULT(255 - d[1], 255 - src_g);
1715
                                                        src_b = 255 - INT_MULT(255 - d[2], 255 - src_b);
2766 cbradney 1716
                                                        src_a = 255 - INT_MULT(255 - d[3], 255 - src_a);
3764 fschmid 1717
                                                }
2004 fschmid 1718
                                                else
3764 fschmid 1719
                                                {
1720
                                                        if (d[3] > 0)
1721
                                                        {
1722
                                                                src_r = 255 - INT_MULT(255 - d[0], 255 - src_r);
1723
                                                                src_g = 255 - INT_MULT(255 - d[1], 255 - src_g);
1724
                                                                src_b = 255 - INT_MULT(255 - d[2], 255 - src_b);
1725
                                                        }
1726
                                                }
2004 fschmid 1727
                                        }
1728
                                        else if (layBlend == "over")
1729
                                        {
1730
                                                if (header.color_mode == CM_CMYK)
3764 fschmid 1731
                                                {
1732
                                                        src_r = INT_MULT(d[0], d[0] + INT_MULT(2 * src_r, 255 - d[0]));
1733
                                                        src_g = INT_MULT(d[1], d[1] + INT_MULT(2 * src_g, 255 - d[1]));
1734
                                                        src_b = INT_MULT(d[2], d[2] + INT_MULT(2 * src_b, 255 - d[2]));
2766 cbradney 1735
                                                        src_a = INT_MULT(d[3], d[3] + INT_MULT(2 * src_a, 255 - d[3]));
3764 fschmid 1736
                                                }
2004 fschmid 1737
                                                else
3764 fschmid 1738
                                                {
1739
                                                        if (d[3] > 0)
1740
                                                        {
1741
                                                                src_r = INT_MULT(d[0], d[0] + INT_MULT(2 * src_r, 255 - d[0]));
1742
                                                                src_g = INT_MULT(d[1], d[1] + INT_MULT(2 * src_g, 255 - d[1]));
1743
                                                                src_b = INT_MULT(d[2], d[2] + INT_MULT(2 * src_b, 255 - d[2]));
1744
                                                        }
1745
                                                }
2004 fschmid 1746
                                        }
1747
                                        else if (layBlend == "diff")
1748
                                        {
1749
                                                if (header.color_mode == CM_CMYK)
3764 fschmid 1750
                                                {
1751
                                                        src_r = d[0] > src_r ? d[0] - src_r : src_r - d[0];
1752
                                                        src_g = d[1] > src_g ? d[1] - src_g : src_g - d[1];
1753
                                                        src_b = d[2] > src_b ? d[2] - src_b : src_b - d[2];
2766 cbradney 1754
                                                        src_a = d[3] > src_a ? d[3] - src_a : src_a - d[3];
3764 fschmid 1755
                                                }
2004 fschmid 1756
                                                else
3764 fschmid 1757
                                                {
1758
                                                        if (d[3] > 0)
1759
                                                        {
1760
                                                                src_r = d[0] > src_r ? d[0] - src_r : src_r - d[0];
1761
                                                                src_g = d[1] > src_g ? d[1] - src_g : src_g - d[1];
1762
                                                                src_b = d[2] > src_b ? d[2] - src_b : src_b - d[2];
1763
                                                        }
1764
                                                }
2004 fschmid 1765
                                        }
1766
                                        else if (layBlend == "dark")
1767
                                        {
1768
                                                if (header.color_mode == CM_CMYK)
3764 fschmid 1769
                                                {
1770
                                                        src_r = d[0]  < src_r ? d[0]  : src_r;
1771
                                                        src_g = d[1] < src_g ? d[1] : src_g;
1772
                                                        src_b = d[2] < src_b ? d[2] : src_b;
2766 cbradney 1773
                                                        src_a = d[3] < src_a ? d[3] : src_a;
3764 fschmid 1774
                                                }
2004 fschmid 1775
                                                else
3764 fschmid 1776
                                                {
1777
                                                        if (d[3] > 0)
1778
                                                        {
1779
                                                                src_r = d[0]  < src_r ? d[0]  : src_r;
1780
                                                                src_g = d[1] < src_g ? d[1] : src_g;
1781
                                                                src_b = d[2] < src_b ? d[2] : src_b;
1782
                                                        }
1783
                                                }
2004 fschmid 1784
                                        }
3871 fschmid 1785
                                        else if (layBlend == "hLit")
1786
                                        {
1787
                                                if (header.color_mode == CM_CMYK)
1788
                                                {
3872 fschmid 1789
                                                        src_r = src_r < 128 ? src_r * d[0] / 128 : 255 - ((255-src_r) * (255-d[0]) / 128);
1790
                                                        src_g = src_g < 128 ? src_g * d[1] / 128 : 255 - ((255-src_g) * (255-d[1]) / 128);
1791
                                                        src_b = src_b < 128 ? src_b * d[2] / 128 : 255 - ((255-src_b) * (255-d[2]) / 128);
1792
                                                        src_a = src_a < 128 ? src_a * d[3] / 128 : 255 - ((255-src_a) * (255-d[3]) / 128);
3871 fschmid 1793
                                                }
1794
                                                else
1795
                                                {
1796
                                                        if (d[3] > 0)
1797
                                                        {
3872 fschmid 1798
                                                                src_r = src_r < 128 ? src_r * d[0] / 128 : 255 - ((255-src_r) * (255-d[0]) / 128);
1799
                                                                src_g = src_g < 128 ? src_g * d[1] / 128 : 255 - ((255-src_g) * (255-d[1]) / 128);
1800
                                                                src_b = src_b < 128 ? src_b * d[2] / 128 : 255 - ((255-src_b) * (255-d[2]) / 128);
3871 fschmid 1801
                                                        }
1802
                                                }
1803
                                        }
3872 fschmid 1804
                                        else if (layBlend == "sLit")
1805
                                        {
1806
                                                if (header.color_mode == CM_CMYK)
1807
                                                {
1808
                                                        src_r = src_r * d[0] / 256 + src_r * (255 - ((255-src_r)*(255-d[0]) / 256) - src_r * d[0] / 256) / 256;
1809
                                                        src_g = src_g * d[1] / 256 + src_g * (255 - ((255-src_g)*(255-d[1]) / 256) - src_g * d[1] / 256) / 256;
1810
                                                        src_b = src_b * d[2] / 256 + src_b * (255 - ((255-src_b)*(255-d[2]) / 256) - src_b * d[2] / 256) / 256;
1811
                                                        src_a = src_a * d[3] / 256 + src_a * (255 - ((255-src_a)*(255-d[3]) / 256) - src_a * d[3] / 256) / 256;
1812
                                                }
1813
                                                else
1814
                                                {
1815
                                                        if (d[3] > 0)
1816
                                                        {
1817
                                                                src_r = src_r * d[0] / 256 + src_r * (255 - ((255-src_r)*(255-d[0]) / 256) - src_r * d[0] / 256) / 256;
1818
                                                                src_g = src_g * d[1] / 256 + src_g * (255 - ((255-src_g)*(255-d[1]) / 256) - src_g * d[1] / 256) / 256;
1819
                                                                src_b = src_b * d[2] / 256 + src_b * (255 - ((255-src_b)*(255-d[2]) / 256) - src_b * d[2] / 256) / 256;
1820
                                                        }
1821
                                                }
1822
                                        }
2004 fschmid 1823
                                        else if (layBlend == "lite")
1824
                                        {
1825
                                                if (header.color_mode == CM_CMYK)
3764 fschmid 1826
                                                {
1827
                                                        src_r = d[0] < src_r ? src_r : d[0];
1828
                                                        src_g = d[1] < src_g ? src_g : d[1];
1829
                                                        src_b = d[2] < src_b ? src_b : d[2];
2766 cbradney 1830
                                                        src_a = d[3] < src_a ? src_a : d[3];
3764 fschmid 1831
                                                }
2004 fschmid 1832
                                                else
3764 fschmid 1833
                                                {
1834
                                                        if (d[3] > 0)
1835
                                                        {
1836
                                                                src_r = d[0] < src_r ? src_r : d[0];
1837
                                                                src_g = d[1] < src_g ? src_g : d[1];
1838
                                                                src_b = d[2] < src_b ? src_b : d[2];
1839
                                                        }
1840
                                                }
2004 fschmid 1841
                                        }
3898 fschmid 1842
                                        else if (layBlend == "smud")
1843
                                        {
1844
                                                if (header.color_mode == CM_CMYK)
1845
                                                {
1846
                                                        src_r = d[0] + src_r - src_r * d[0] / 128;
1847
                                                        src_g = d[1] + src_g - src_g * d[1] / 128;
1848
                                                        src_b = d[2] + src_b - src_b * d[2] / 128;
1849
                                                        src_a = d[3] + src_a - src_a * d[3] / 128;
1850
                                                }
1851
                                                else
1852
                                                {
1853
                                                        if (d[3] > 0)
1854
                                                        {
1855
                                                                src_r = d[0] + src_r - src_r * d[0] / 128;
1856
                                                                src_g = d[1] + src_g - src_g * d[1] / 128;
1857
                                                                src_b = d[2] + src_b - src_b * d[2] / 128;
1858
                                                        }
1859
                                                }
1860
                                        }
1861
                                        else if (layBlend == "div ")
1862
                                        {
1863
                                                if (header.color_mode == CM_CMYK)
1864
                                                {
1865
                                                        src_r = src_r == 255 ? 255 : ((d[0] * 256) / (255-src_r)) > 255 ? 255 : (d[0] * 256) / (255-src_r);
1866
                                                        src_g = src_g == 255 ? 255 : ((d[1] * 256) / (255-src_g)) > 255 ? 255 : (d[1] * 256) / (255-src_g);
1867
                                                        src_b = src_b == 255 ? 255 : ((d[2] * 256) / (255-src_b)) > 255 ? 255 : (d[2] * 256) / (255-src_b);
1868
                                                        src_a = src_a == 255 ? 255 : ((d[3] * 256) / (255-src_a)) > 255 ? 255 : (d[3] * 256) / (255-src_a);
1869
                                                }
1870
                                                else
1871
                                                {
1872
                                                        if (d[3] > 0)
1873
                                                        {
1874
                                                                src_r = src_r == 255 ? 255 : ((d[0] * 256) / (255-src_r)) > 255 ? 255 : (d[0] * 256) / (255-src_r);
1875
                                                                src_g = src_g == 255 ? 255 : ((d[1] * 256) / (255-src_g)) > 255 ? 255 : (d[1] * 256) / (255-src_g);
1876
                                                                src_b = src_b == 255 ? 255 : ((d[2] * 256) / (255-src_b)) > 255 ? 255 : (d[2] * 256) / (255-src_b);
1877
                                                        }
1878
                                                }
1879
                                        }
1880
                                        else if (layBlend == "idiv")
1881
                                        {
1882
                                                if (header.color_mode == CM_CMYK)
1883
                                                {
1884
                                                        src_r = src_r == 0 ? 0 : (255 - (((255-d[0]) * 256) / src_r)) < 0 ? 0 : 255 - (((255-d[0]) * 256) / src_r);
1885
                                                        src_g = src_g == 0 ? 0 : (255 - (((255-d[1]) * 256) / src_g)) < 0 ? 0 : 255 - (((255-d[1]) * 256) / src_g);
1886
                                                        src_b = src_b == 0 ? 0 : (255 - (((255-d[2]) * 256) / src_b)) < 0 ? 0 : 255 - (((255-d[2]) * 256) / src_b);
1887
                                                        src_a = src_a == 0 ? 0 : (255 - (((255-d[3]) * 256) / src_a)) < 0 ? 0 : 255 - (((255-d[3]) * 256) / src_a);
1888
                                                }
1889
                                                else
1890
                                                {
1891
                                                        if (d[3] > 0)
1892
                                                        {
1893
                                                                src_r = src_r == 0 ? 0 : (255 - (((255-d[0]) * 256) / src_r)) < 0 ? 0 : 255 - (((255-d[0]) * 256) / src_r);
1894
                                                                src_g = src_g == 0 ? 0 : (255 - (((255-d[1]) * 256) / src_g)) < 0 ? 0 : 255 - (((255-d[1]) * 256) / src_g);
1895
                                                                src_b = src_b == 0 ? 0 : (255 - (((255-d[2]) * 256) / src_b)) < 0 ? 0 : 255 - (((255-d[2]) * 256) / src_b);
1896
                                                        }
1897
                                                }
1898
                                        }
2004 fschmid 1899
                                        else if (layBlend == "hue ")
1900
                                        {
1901
                                                if (header.color_mode != CM_CMYK)
1902
                                                {
3764 fschmid 1903
                                                        if (d[3] > 0)
1904
                                                        {
1905
                                                                uchar new_r = d[0];
1906
                                                                uchar new_g = d[1];
1907
                                                                uchar new_b = d[2];
1908
                                                                RGBTOHSV(src_r, src_g, src_b);
1909
                                                                RGBTOHSV(new_r, new_g, new_b);
1910
                                                                new_r = src_r;
1911
                                                                HSVTORGB(new_r, new_g, new_b);
1912
                                                                src_r = new_r;
1913
                                                                src_g = new_g;
1914
                                                                src_b = new_b;
1915
                                                        }
2004 fschmid 1916
                                                }
1917
                                        }
1918
                                        else if (layBlend == "sat ")
1919
                                        {
1920
                                                if (header.color_mode != CM_CMYK)
1921
                                                {
3764 fschmid 1922
                                                        if (d[3] > 0)
1923
                                                        {
1924
                                                                uchar new_r = d[0];
1925
                                                                uchar new_g = d[1];
1926
                                                                uchar new_b = d[2];
1927
                                                                RGBTOHSV(src_r, src_g, src_b);
1928
                                                                RGBTOHSV(new_r, new_g, new_b);
1929
                                                                new_g = src_g;
1930
                                                                HSVTORGB(new_r, new_g, new_b);
1931
                                                                src_r = new_r;
1932
                                                                src_g = new_g;
1933
                                                                src_b = new_b;
1934
                                                        }
2004 fschmid 1935
                                                }
1936
                                        }
1937
                                        else if (layBlend == "lum ")
1938
                                        {
1939
                                                if (header.color_mode != CM_CMYK)
1940
                                                {
3764 fschmid 1941
                                                        if (d[3] > 0)
1942
                                                        {
1943
                                                                uchar new_r = d[0];
1944
                                                                uchar new_g = d[1];
1945
                                                                uchar new_b = d[2];
1946
                                                                RGBTOHSV(src_r, src_g, src_b);
1947
                                                                RGBTOHSV(new_r, new_g, new_b);
1948
                                                                new_b = src_b;
1949
                                                                HSVTORGB(new_r, new_g, new_b);
1950
                                                                src_r = new_r;
1951
                                                                src_g = new_g;
1952
                                                                src_b = new_b;
1953
                                                        }
2004 fschmid 1954
                                                }
1955
                                        }
1956
                                        else if (layBlend == "colr")
1957
                                        {
1958
                                                if (header.color_mode != CM_CMYK)
1959
                                                {
3764 fschmid 1960
                                                        if (d[3] > 0)
1961
                                                        {
1962
                                                                uchar new_r = d[0];
1963
                                                                uchar new_g = d[1];
1964
                                                                uchar new_b = d[2];
1965
                                                                RGBTOHLS(src_r, src_g, src_b);
1966
                                                                RGBTOHLS(new_r, new_g, new_b);
1967
                                                                new_r = src_r;
1968
                                                                new_b = src_b;
1969
                                                                HLSTORGB(new_r, new_g, new_b);
1970
                                                                src_r = new_r;
1971
                                                                src_g = new_g;
1972
                                                                src_b = new_b;
1973
                                                        }
2004 fschmid 1974
                                                }
1975
                                        }
4849 cbradney 1976
 
2004 fschmid 1977
                                        int layOpa = layerInfo[layer].opacity;
1978
                                        if ((imgInfo.isRequest) && (imgInfo.RequestProps.contains(layer)))
1979
                                                layOpa = imgInfo.RequestProps[layer].opacity;
3802 fschmid 1980
                                        if (!mask.isNull())
1981
                                                layOpa = INT_MULT(mask_a, layOpa);
5010 fschmid 1982
                                        if (header.color_mode != CM_CMYK)
1983
                                                src_a = INT_MULT(src_a, layOpa);
3764 fschmid 1984
                                        if (d[3] > 0)
1985
                                        {
1986
                                                r = (d[0] * (255 - layOpa) + src_r * layOpa) / 255;
1987
                                                g = (d[1] * (255 - layOpa) + src_g * layOpa) / 255;
1988
                                                b = (d[2] * (255 - layOpa) + src_b * layOpa) / 255;
5010 fschmid 1989
                                                if (header.color_mode == CM_CMYK)
3764 fschmid 1990
                                                        a = (d[3] * (255 - layOpa) + src_a * layOpa) / 255;
5010 fschmid 1991
                                                else
1992
                                                {
1993
                                                        a = d[3] + INT_MULT(255 - d[3], src_a);
1994
                                                        r = (d[0] * (255 - src_a) + src_r * src_a) / 255;
1995
                                                        g = (d[1] * (255 - src_a) + src_g * src_a) / 255;
1996
                                                        b = (d[2] * (255 - src_a) + src_b * src_a) / 255;
1997
                                                }
3764 fschmid 1998
                                        }
1999
                                        else
2000
                                        {
2001
                                                r = src_r;
2002
                                                g = src_g;
2003
                                                b = src_b;
5010 fschmid 2004
                                                a = src_a;
3764 fschmid 2005
                                        }
2004 fschmid 2006
                                        if (header.color_mode == CM_CMYK)