Subversion Repositories Scribus

Rev

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

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