Subversion Repositories Scribus

Rev

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

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