Subversion Repositories Scribus

Rev

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

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