Subversion Repositories Scribus

Rev

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