Subversion Repositories Scribus

Rev

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

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