Subversion Repositories Scribus

Rev

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