Subversion Repositories Scribus

Rev

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