Subversion Repositories Scribus

Rev

Rev 6138 | Rev 6412 | 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"
5937 jghali 11
#include "scimgdataloader_jpeg.h"
12
#include "scimgdataloader_pdf.h"
13
#include "scimgdataloader_ps.h"
14
#include "scimgdataloader_psd.h"
15
#include "scimgdataloader_pdf.h"
16
#include "scimgdataloader_qt.h"
17
#include "scimgdataloader_tiff.h"
5977 jghali 18
#include <qmessagebox.h>
2074 fschmid 19
#include <qtextstream.h>
5937 jghali 20
#include <memory>
2125 cbradney 21
#include <cassert>
2004 fschmid 22
#ifdef HAVE_CMS
23
        #include CMS_INC
6070 jghali 24
        #include "cmsutil.h"
2004 fschmid 25
#endif
4506 cbradney 26
#include "gsutil.h"
3685 fschmid 27
#include "exif.h"
4546 subik 28
#include "commonstrings.h"
6125 cbradney 29
#include "colorutil.h"
2004 fschmid 30
 
5937 jghali 31
using namespace std;
32
 
2004 fschmid 33
typedef struct my_error_mgr
34
{
35
        struct jpeg_error_mgr pub;            /* "public" fields */
36
        jmp_buf setjmp_buffer;  /* for return to caller */
37
}
38
*my_error_ptr;
39
 
40
static void my_error_exit (j_common_ptr cinfo)
41
{
42
        my_error_ptr myerr = (my_error_ptr) cinfo->err;
43
        (*cinfo->err->output_message) (cinfo);
44
        longjmp (myerr->setjmp_buffer, 1);
45
}
46
 
4222 craig 47
ScImage::ScImage(const QImage & image) : QImage(image)
2004 fschmid 48
{
2012 fschmid 49
        initialize();
2004 fschmid 50
}
51
 
5593 avox 52
 
53
// ScImage will use implicit sharing:
54
ScImage::ScImage(const ScImage & image) : QImage(image.copy())
55
{
56
        initialize();
57
}
58
 
59
 
2004 fschmid 60
ScImage::ScImage() : QImage()
61
{
2012 fschmid 62
        initialize();
2004 fschmid 63
}
64
 
65
ScImage::ScImage( int width, int height ) : QImage( width, height, 32 )
66
{
2012 fschmid 67
        initialize();
68
}
69
 
5593 avox 70
const QImage& ScImage::qImage()
71
{
72
        return *this;
73
}
74
 
6063 fschmid 75
QImage* ScImage::qImagePtr()
76
{
77
        return this;
78
}
79
 
5593 avox 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();
6085 fschmid 103
        imgInfo.duotoneColors.clear();
3703 fschmid 104
        imgInfo.exifInfo.cameraName = "";
105
        imgInfo.exifInfo.cameraVendor = "";
106
        imgInfo.exifInfo.thumbnail = QImage();
4331 fschmid 107
        imgInfo.BBoxX = 0;
108
        imgInfo.BBoxH = 0;
2004 fschmid 109
}
110
 
4050 cbradney 111
ScImage::~ScImage()
112
{
113
        curveTable.resize(0);
114
}
115
 
2886 fschmid 116
void ScImage::applyEffect(QValueList<imageEffect> effectsList, QMap<QString,ScColor> colors, bool cmyk)
2074 fschmid 117
{
118
        if (effectsList.count() != 0)
119
        {
120
                for (uint a = 0; a < effectsList.count(); ++a)
121
                {
2082 fschmid 122
                        if ((*effectsList.at(a)).effectCode == EF_INVERT)
2074 fschmid 123
                                invert(cmyk);
2082 fschmid 124
                        if ((*effectsList.at(a)).effectCode == EF_GRAYSCALE)
2074 fschmid 125
                                toGrayscale(cmyk);
2082 fschmid 126
                        if ((*effectsList.at(a)).effectCode == EF_COLORIZE)
2074 fschmid 127
                        {
128
                                QString tmpstr = (*effectsList.at(a)).effectParameters;
4546 subik 129
                                QString col = CommonStrings::None;
2074 fschmid 130
                                int shading = 100;
131
                                QTextStream fp(&tmpstr, IO_ReadOnly);
6011 fschmid 132
                                col = fp.readLine();
2074 fschmid 133
                                fp >> shading;
134
                                colorize(colors[col], shading, cmyk);
135
                        }
2082 fschmid 136
                        if ((*effectsList.at(a)).effectCode == EF_BRIGHTNESS)
137
                        {
138
                                QString tmpstr = (*effectsList.at(a)).effectParameters;
139
                                int brightnessValue = 0;
140
                                QTextStream fp(&tmpstr, IO_ReadOnly);
141
                                fp >> brightnessValue;
142
                                brightness(brightnessValue, cmyk);
143
                        }
144
                        if ((*effectsList.at(a)).effectCode == EF_CONTRAST)
145
                        {
146
                                QString tmpstr = (*effectsList.at(a)).effectParameters;
147
                                int contrastValue = 0;
148
                                QTextStream fp(&tmpstr, IO_ReadOnly);
149
                                fp >> contrastValue;
150
                                contrast(contrastValue, cmyk);
151
                        }
2092 fschmid 152
                        if ((*effectsList.at(a)).effectCode == EF_SHARPEN)
153
                        {
154
                                QString tmpstr = (*effectsList.at(a)).effectParameters;
155
                                double radius, sigma;
156
                                QTextStream fp(&tmpstr, IO_ReadOnly);
157
                                fp >> radius;
158
                                fp >> sigma;
159
                                sharpen(radius, sigma);
160
                        }
2095 fschmid 161
                        if ((*effectsList.at(a)).effectCode == EF_BLUR)
162
                        {
163
                                QString tmpstr = (*effectsList.at(a)).effectParameters;
164
                                double radius, sigma;
165
                                QTextStream fp(&tmpstr, IO_ReadOnly);
166
                                fp >> radius;
167
                                fp >> sigma;
6011 fschmid 168
                                blur(static_cast<int>(radius));
2095 fschmid 169
                        }
2096 fschmid 170
                        if ((*effectsList.at(a)).effectCode == EF_SOLARIZE)
171
                        {
172
                                QString tmpstr = (*effectsList.at(a)).effectParameters;
173
                                double sigma;
174
                                QTextStream fp(&tmpstr, IO_ReadOnly);
175
                                fp >> sigma;
176
                                solarize(sigma, cmyk);
177
                        }
6080 fschmid 178
                        if ((*effectsList.at(a)).effectCode == EF_DUOTONE)
179
                        {
180
                                QString tmpstr = (*effectsList.at(a)).effectParameters;
181
                                QString col1 = CommonStrings::None;
182
                                int shading1 = 100;
183
                                QString col2 = CommonStrings::None;
184
                                int shading2 = 100;
185
                                QTextStream fp(&tmpstr, IO_ReadOnly);
186
                                col1 = fp.readLine();
187
                                col2 = fp.readLine();
188
                                fp >> shading1;
189
                                fp >> shading2;
6129 fschmid 190
                                int numVals;
191
                                double xval, yval;
192
                                FPointArray curve1;
193
                                curve1.resize(0);
194
                                fp >> numVals;
195
                                for (int nv = 0; nv < numVals; nv++)
196
                                {
197
                                        fp >> xval;
198
                                        fp >> yval;
199
                                        curve1.addPoint(xval, yval);
200
                                }
6193 fschmid 201
                                int lin1;
202
                                fp >> lin1;
6129 fschmid 203
                                FPointArray curve2;
204
                                curve2.resize(0);
205
                                fp >> numVals;
206
                                for (int nv = 0; nv < numVals; nv++)
207
                                {
208
                                        fp >> xval;
209
                                        fp >> yval;
210
                                        curve2.addPoint(xval, yval);
211
                                }
6193 fschmid 212
                                int lin2;
213
                                fp >> lin2;
214
                                duotone(colors[col1], shading1, curve1, lin1, colors[col2], shading2, curve2, lin2, cmyk);
6080 fschmid 215
                        }
216
                        if ((*effectsList.at(a)).effectCode == EF_TRITONE)
217
                        {
218
                                QString tmpstr = (*effectsList.at(a)).effectParameters;
219
                                QString col1 = CommonStrings::None;
220
                                QString col2 = CommonStrings::None;
221
                                QString col3 = CommonStrings::None;
222
                                int shading1 = 100;
223
                                int shading2 = 100;
224
                                int shading3 = 100;
225
                                QTextStream fp(&tmpstr, IO_ReadOnly);
226
                                col1 = fp.readLine();
227
                                col2 = fp.readLine();
228
                                col3 = fp.readLine();
229
                                fp >> shading1;
230
                                fp >> shading2;
231
                                fp >> shading3;
6129 fschmid 232
                                int numVals;
233
                                double xval, yval;
234
                                FPointArray curve1;
235
                                curve1.resize(0);
236
                                fp >> numVals;
237
                                for (int nv = 0; nv < numVals; nv++)
238
                                {
239
                                        fp >> xval;
240
                                        fp >> yval;
241
                                        curve1.addPoint(xval, yval);
242
                                }
6193 fschmid 243
                                int lin1;
244
                                fp >> lin1;
6129 fschmid 245
                                FPointArray curve2;
246
                                curve2.resize(0);
247
                                fp >> numVals;
248
                                for (int nv = 0; nv < numVals; nv++)
249
                                {
250
                                        fp >> xval;
251
                                        fp >> yval;
252
                                        curve2.addPoint(xval, yval);
253
                                }
6193 fschmid 254
                                int lin2;
255
                                fp >> lin2;
6129 fschmid 256
                                FPointArray curve3;
257
                                curve3.resize(0);
258
                                fp >> numVals;
259
                                for (int nv = 0; nv < numVals; nv++)
260
                                {
261
                                        fp >> xval;
262
                                        fp >> yval;
263
                                        curve3.addPoint(xval, yval);
264
                                }
6193 fschmid 265
                                int lin3;
266
                                fp >> lin3;
267
                                tritone(colors[col1], shading1, curve1, lin1, colors[col2], shading2, curve2, lin2, colors[col3], shading3, curve3, lin3, cmyk);
6080 fschmid 268
                        }
269
                        if ((*effectsList.at(a)).effectCode == EF_QUADTONE)
270
                        {
271
                                QString tmpstr = (*effectsList.at(a)).effectParameters;
272
                                QString col1 = CommonStrings::None;
273
                                QString col2 = CommonStrings::None;
274
                                QString col3 = CommonStrings::None;
275
                                QString col4 = CommonStrings::None;
276
                                int shading1 = 100;
277
                                int shading2 = 100;
278
                                int shading3 = 100;
279
                                int shading4 = 100;
280
                                QTextStream fp(&tmpstr, IO_ReadOnly);
281
                                col1 = fp.readLine();
282
                                col2 = fp.readLine();
283
                                col3 = fp.readLine();
284
                                col4 = fp.readLine();
285
                                fp >> shading1;
286
                                fp >> shading2;
287
                                fp >> shading3;
288
                                fp >> shading4;
6129 fschmid 289
                                int numVals;
290
                                double xval, yval;
291
                                FPointArray curve1;
292
                                curve1.resize(0);
293
                                fp >> numVals;
294
                                for (int nv = 0; nv < numVals; nv++)
295
                                {
296
                                        fp >> xval;
297
                                        fp >> yval;
298
                                        curve1.addPoint(xval, yval);
299
                                }
6193 fschmid 300
                                int lin1;
301
                                fp >> lin1;
6129 fschmid 302
                                FPointArray curve2;
303
                                curve2.resize(0);
304
                                fp >> numVals;
305
                                for (int nv = 0; nv < numVals; nv++)
306
                                {
307
                                        fp >> xval;
308
                                        fp >> yval;
309
                                        curve2.addPoint(xval, yval);
310
                                }
6193 fschmid 311
                                int lin2;
312
                                fp >> lin2;
6129 fschmid 313
                                FPointArray curve3;
314
                                curve3.resize(0);
315
                                fp >> numVals;
316
                                for (int nv = 0; nv < numVals; nv++)
317
                                {
318
                                        fp >> xval;
319
                                        fp >> yval;
320
                                        curve3.addPoint(xval, yval);
321
                                }
6193 fschmid 322
                                int lin3;
323
                                fp >> lin3;
6129 fschmid 324
                                FPointArray curve4;
325
                                curve4.resize(0);
326
                                fp >> numVals;
327
                                for (int nv = 0; nv < numVals; nv++)
328
                                {
329
                                        fp >> xval;
330
                                        fp >> yval;
331
                                        curve4.addPoint(xval, yval);
332
                                }
6193 fschmid 333
                                int lin4;
334
                                fp >> lin4;
335
                                quadtone(colors[col1], shading1, curve1, lin1, colors[col2], shading2, curve2, lin2, colors[col3], shading3, curve3, lin3, colors[col4], shading4, curve4, lin4, cmyk);
6080 fschmid 336
                        }
6116 fschmid 337
                        if ((*effectsList.at(a)).effectCode == EF_GRADUATE)
338
                        {
339
                                QString tmpstr = (*effectsList.at(a)).effectParameters;
340
                                int numVals;
341
                                double xval, yval;
342
                                FPointArray curve;
343
                                curve.resize(0);
344
                                QTextStream fp(&tmpstr, IO_ReadOnly);
345
                                fp >> numVals;
346
                                for (int nv = 0; nv < numVals; nv++)
347
                                {
348
                                        fp >> xval;
349
                                        fp >> yval;
350
                                        curve.addPoint(xval, yval);
351
                                }
6193 fschmid 352
                                int lin;
353
                                fp >> lin;
354
                                doGraduate(curve, cmyk, lin);
6116 fschmid 355
                        }
2074 fschmid 356
                }
357
        }
358
}
359
 
2095 fschmid 360
void ScImage::liberateMemory(void **memory)
361
{
362
        assert(memory != (void **)NULL);
363
        if(*memory == (void *)NULL)
364
                return;
365
        free(*memory);
366
        *memory=(void *) NULL;
367
}
368
 
2096 fschmid 369
void ScImage::solarize(double factor, bool cmyk)
370
{
371
        curveTable.resize(256);
372
        int fk = qRound(255 / factor);
373
        for (int i = 0; i < 256; ++i)
374
        {
375
                curveTable[i] = QMIN(255, static_cast<int>(i / fk) * fk);
376
        }
377
        applyCurve(cmyk);
378
}
2095 fschmid 379
 
6011 fschmid 380
// Stack Blur Algorithm by Mario Klingemann <mario@quasimondo.com>
381
void ScImage::blur(int radius)
382
{
383
    if (radius < 1) {
384
        return;
385
    }
2095 fschmid 386
 
6011 fschmid 387
    QRgb *pix = (QRgb*)bits();
388
    int w   = width();
389
    int h   = height();
390
    int wm  = w-1;
391
    int hm  = h-1;
392
    int wh  = w*h;
393
    int div = radius+radius+1;
394
 
395
    int *r = new int[wh];
396
    int *g = new int[wh];
397
    int *b = new int[wh];
398
    int *a = new int[wh];
399
    int rsum, gsum, bsum, asum, x, y, i, yp, yi, yw;
400
    QRgb p;
401
    int *vmin = new int[QMAX(w,h)];
402
 
403
    int divsum = (div+1)>>1;
404
    divsum *= divsum;
405
    int *dv = new int[256*divsum];
406
    for (i=0; i < 256*divsum; ++i) {
407
        dv[i] = (i/divsum);
408
    }
409
 
410
    yw = yi = 0;
411
 
412
    int **stack = new int*[div];
413
    for(int i = 0; i < div; ++i) {
414
        stack[i] = new int[4];
415
    }
416
 
417
 
418
    int stackpointer;
419
    int stackstart;
420
    int *sir;
421
    int rbs;
422
    int r1 = radius+1;
423
    int routsum, goutsum, boutsum, aoutsum;
424
    int rinsum, ginsum, binsum, ainsum;
425
 
426
    for (y = 0; y < h; ++y){
427
        rinsum = ginsum = binsum = ainsum
428
               = routsum = goutsum = boutsum = aoutsum
429
               = rsum = gsum = bsum = asum = 0;
430
        for(i =- radius; i <= radius; ++i) {
431
            p = pix[yi+QMIN(wm,QMAX(i,0))];
432
            sir = stack[i+radius];
433
            sir[0] = qRed(p);
434
            sir[1] = qGreen(p);
435
            sir[2] = qBlue(p);
436
            sir[3] = qAlpha(p);
437
 
438
            rbs = r1-abs(i);
439
            rsum += sir[0]*rbs;
440
            gsum += sir[1]*rbs;
441
            bsum += sir[2]*rbs;
442
            asum += sir[3]*rbs;
443
 
444
            if (i > 0){
445
                rinsum += sir[0];
446
                ginsum += sir[1];
447
                binsum += sir[2];
448
                ainsum += sir[3];
449
            } else {
450
                routsum += sir[0];
451
                goutsum += sir[1];
452
                boutsum += sir[2];
453
                aoutsum += sir[3];
454
            }
455
        }
456
        stackpointer = radius;
457
 
458
        for (x=0; x < w; ++x) {
459
 
460
            r[yi] = dv[rsum];
461
            g[yi] = dv[gsum];
462
            b[yi] = dv[bsum];
463
            a[yi] = dv[asum];
464
 
465
            rsum -= routsum;
466
            gsum -= goutsum;
467
            bsum -= boutsum;
468
            asum -= aoutsum;
469
 
470
            stackstart = stackpointer-radius+div;
471
            sir = stack[stackstart%div];
472
 
473
            routsum -= sir[0];
474
            goutsum -= sir[1];
475
            boutsum -= sir[2];
476
            aoutsum -= sir[3];
477
 
478
            if (y == 0) {
479
                vmin[x] = QMIN(x+radius+1,wm);
480
            }
481
            p = pix[yw+vmin[x]];
482
 
483
            sir[0] = qRed(p);
484
            sir[1] = qGreen(p);
485
            sir[2] = qBlue(p);
486
            sir[3] = qAlpha(p);
487
 
488
            rinsum += sir[0];
489
            ginsum += sir[1];
490
            binsum += sir[2];
491
            ainsum += sir[3];
492
 
493
            rsum += rinsum;
494
            gsum += ginsum;
495
            bsum += binsum;
496
            asum += ainsum;
497
 
498
            stackpointer = (stackpointer+1)%div;
499
            sir = stack[(stackpointer)%div];
500
 
501
            routsum += sir[0];
502
            goutsum += sir[1];
503
            boutsum += sir[2];
504
            aoutsum += sir[3];
505
 
506
            rinsum -= sir[0];
507
            ginsum -= sir[1];
508
            binsum -= sir[2];
509
            ainsum -= sir[3];
510
 
511
            ++yi;
512
        }
513
        yw += w;
514
    }
515
    for (x=0; x < w; ++x){
516
        rinsum = ginsum = binsum = ainsum
517
               = routsum = goutsum = boutsum = aoutsum
518
               = rsum = gsum = bsum = asum = 0;
519
 
520
        yp =- radius * w;
521
 
522
        for(i=-radius; i <= radius; ++i) {
523
            yi=QMAX(0,yp)+x;
524
 
525
            sir = stack[i+radius];
526
 
527
            sir[0] = r[yi];
528
            sir[1] = g[yi];
529
            sir[2] = b[yi];
530
            sir[3] = a[yi];
531
 
532
            rbs = r1-abs(i);
533
 
534
            rsum += r[yi]*rbs;
535
            gsum += g[yi]*rbs;
536
            bsum += b[yi]*rbs;
537
            asum += a[yi]*rbs;
538
 
539
            if (i > 0) {
540
                rinsum += sir[0];
541
                ginsum += sir[1];
542
                binsum += sir[2];
543
                ainsum += sir[3];
544
            } else {
545
                routsum += sir[0];
546
                goutsum += sir[1];
547
                boutsum += sir[2];
548
                aoutsum += sir[3];
549
            }
550
 
551
            if (i < hm){
552
                yp += w;
553
            }
554
        }
555
 
556
        yi = x;
557
        stackpointer = radius;
558
 
559
        for (y=0; y < h; ++y){
560
            pix[yi] = qRgba(dv[rsum], dv[gsum], dv[bsum], dv[asum]);
561
 
562
            rsum -= routsum;
563
            gsum -= goutsum;
564
            bsum -= boutsum;
565
            asum -= aoutsum;
566
 
567
            stackstart = stackpointer-radius+div;
568
            sir = stack[stackstart%div];
569
 
570
            routsum -= sir[0];
571
            goutsum -= sir[1];
572
            boutsum -= sir[2];
573
            aoutsum -= sir[3];
574
 
575
            if (x==0){
576
                vmin[y] = QMIN(y+r1,hm)*w;
577
            }
578
            p = x+vmin[y];
579
 
580
            sir[0] = r[p];
581
            sir[1] = g[p];
582
            sir[2] = b[p];
583
            sir[3] = a[p];
584
 
585
            rinsum += sir[0];
586
            ginsum += sir[1];
587
            binsum += sir[2];
588
            ainsum += sir[3];
589
 
590
            rsum += rinsum;
591
            gsum += ginsum;
592
            bsum += binsum;
593
            asum += ainsum;
594
 
595
            stackpointer = (stackpointer+1)%div;
596
            sir = stack[stackpointer];
597
 
598
            routsum += sir[0];
599
            goutsum += sir[1];
600
            boutsum += sir[2];
601
            aoutsum += sir[3];
602
 
603
            rinsum -= sir[0];
604
            ginsum -= sir[1];
605
            binsum -= sir[2];
606
            ainsum -= sir[3];
607
 
608
            yi += w;
609
        }
610
    }
611
    delete [] r;
612
    delete [] g;
613
    delete [] b;
614
    delete [] a;
615
    delete [] vmin;
616
    delete [] dv;
617
 
618
    for(int i = 0; i < div; ++i) {
619
        delete [] stack[i];
620
    }
621
    delete [] stack;
622
}
6116 fschmid 623
 
2092 fschmid 624
bool ScImage::convolveImage(QImage *dest, const unsigned int order, const double *kernel)
625
{
626
        long widthk;
627
        double red, green, blue, alpha;
628
        double normalize, *normal_kernel;
629
        register const double *k;
630
        register unsigned int *q;
631
        int x, y, mx, my, sx, sy;
632
        long i;
633
        int mcx, mcy;
634
        widthk = order;
635
        if((widthk % 2) == 0)
636
                return(false);
637
        normal_kernel = (double *)malloc(widthk*widthk*sizeof(double));
638
        if(!normal_kernel)
639
                return(false);
640
        dest->reset();
641
        dest->create(width(), height(), 32);
642
        normalize=0.0;
643
        for(i=0; i < (widthk*widthk); i++)
644
                normalize += kernel[i];
645
        if(fabs(normalize) <= 1.0e-12)
646
                normalize=1.0;
647
        normalize=1.0/normalize;
648
        for(i=0; i < (widthk*widthk); i++)
649
                normal_kernel[i] = normalize*kernel[i];
650
        unsigned int **jumpTablek = (unsigned int **)jumpTable();
651
        for(y=0; y < dest->height(); ++y)
652
        {
653
                sy = y-(widthk/2);
654
                q = (unsigned int *)dest->scanLine(y);
655
                for(x=0; x < dest->width(); ++x)
656
                {
657
                        k = normal_kernel;
658
                        red = green = blue = alpha = 0;
659
                        sy = y-(widthk/2);
660
                        for(mcy=0; mcy < widthk; ++mcy, ++sy)
661
                        {
662
                                my = sy < 0 ? 0 : sy > height()-1 ? height()-1 : sy;
663
                                sx = x+(-widthk/2);
664
                                for(mcx=0; mcx < widthk; ++mcx, ++sx)
665
                                {
666
                                        mx = sx < 0 ? 0 : sx > width()-1 ? width()-1 : sx;
667
                                        red += (*k)*(qRed(jumpTablek[my][mx])*257);
668
                                        green += (*k)*(qGreen(jumpTablek[my][mx])*257);
669
                                        blue += (*k)*(qBlue(jumpTablek[my][mx])*257);
670
                                        alpha += (*k)*(qAlpha(jumpTablek[my][mx])*257);
671
                                        ++k;
672
                                }
673
                        }
674
                        red = red < 0 ? 0 : red > 65535 ? 65535 : red+0.5;
675
                        green = green < 0 ? 0 : green > 65535 ? 65535 : green+0.5;
676
                        blue = blue < 0 ? 0 : blue > 65535 ? 65535 : blue+0.5;
677
                        alpha = alpha < 0 ? 0 : alpha > 65535 ? 65535 : alpha+0.5;
678
                        *q++ = qRgba((unsigned char)(red/257UL),
2095 fschmid 679
                                     (unsigned char)(green/257UL),
680
                                     (unsigned char)(blue/257UL),
681
                                     (unsigned char)(alpha/257UL));
2092 fschmid 682
                }
683
        }
2095 fschmid 684
        free(normal_kernel);
2092 fschmid 685
        return(true);
686
}
687
 
688
int ScImage::getOptimalKernelWidth(double radius, double sigma)
689
{
690
        double normalize, value;
691
        long width;
692
        register long u;
693
        assert(sigma != 0.0);
694
        if(radius > 0.0)
695
                return((int)(2.0*ceil(radius)+1.0));
696
        for(width=5; ;)
697
        {
698
                normalize=0.0;
699
                for(u=(-width/2); u <= (width/2); u++)
700
                        normalize+=exp(-((double) u*u)/(2.0*sigma*sigma))/(2.50662827463100024161235523934010416269302368164062*sigma);
701
                u=width/2;
702
                value=exp(-((double) u*u)/(2.0*sigma*sigma))/(2.50662827463100024161235523934010416269302368164062*sigma)/normalize;
703
                if((long)(65535*value) <= 0)
704
                        break;
705
                width+=2;
706
        }
707
        return((int)width-2);
708
}
709
 
710
void ScImage::sharpen(double radius, double sigma)
711
{
712
        double alpha, normalize, *kernel;
713
        int widthk;
714
        register long i, u, v;
715
        QImage dest;
716
        if(sigma == 0.0)
717
                return;
718
        widthk = getOptimalKernelWidth(radius, sigma);
719
        if(width() < widthk)
720
                return;
721
        kernel = (double *)malloc(widthk*widthk*sizeof(double));
722
        if(!kernel)
723
                return;
724
        i = 0;
725
        normalize=0.0;
726
        for (v=(-widthk/2); v <= (widthk/2); v++)
727
        {
728
                for (u=(-widthk/2); u <= (widthk/2); u++)
729
                {
730
                        alpha=exp(-((double) u*u+v*v)/(2.0*sigma*sigma));
731
                        kernel[i]=alpha/(2.0*3.14159265358979323846264338327950288419716939937510*sigma*sigma);
732
                        normalize+=kernel[i];
733
                        i++;
734
                }
735
        }
736
        kernel[i/2]=(-2.0)*normalize;
737
        convolveImage(&dest, widthk, kernel);
2095 fschmid 738
        liberateMemory((void **) &kernel);
2092 fschmid 739
        for( int yi=0; yi < dest.height(); ++yi )
740
        {
741
                QRgb *s = (QRgb*)(dest.scanLine( yi ));
742
                QRgb *d = (QRgb*)(scanLine( yi ));
743
                for(int xi=0; xi < dest.width(); ++xi )
744
                {
745
                        (*d) = (*s);
746
                        s++;
747
                        d++;
748
                }
749
        }
750
        return;
751
}
752
 
2082 fschmid 753
void ScImage::contrast(int contrastValue, bool cmyk)
754
{
755
        curveTable.resize(256);
756
        QPoint p1(0,0 - contrastValue);
757
        QPoint p2(256, 256 + contrastValue);
758
        double mc = (p1.y() - p2.y()) / (double)(p1.x() - p2.x());
759
        for (int i = 0; i < 256; ++i)
760
        {
761
                curveTable[i] = QMIN(255, QMAX(0, int(i * mc) + p1.y()));
762
        }
763
        applyCurve(cmyk);
764
}
765
 
766
void ScImage::brightness(int brightnessValue, bool cmyk)
767
{
768
        curveTable.resize(256);
769
        QPoint p1(0,0 + brightnessValue);
770
        QPoint p2(256, 256 + brightnessValue);
771
        double mc = (p1.y() - p2.y()) / (double)(p1.x() - p2.x());
772
        for (int i = 0; i < 256; ++i)
773
        {
774
                curveTable[i] = QMIN(255, QMAX(0, int(i * mc) + p1.y()));
775
        }
776
        applyCurve(cmyk);
777
}
778
 
6193 fschmid 779
void ScImage::doGraduate(FPointArray curve, bool cmyk, bool linear)
6116 fschmid 780
{
781
        curveTable.resize(256);
782
        for (int x = 0 ; x < 256 ; x++)
783
        {
6193 fschmid 784
                curveTable[x] = QMIN(255, QMAX(0, qRound(getCurveYValue(curve, x / 255.0, linear) * 255)));
6116 fschmid 785
        }
786
        applyCurve(cmyk);
787
}
788
 
2082 fschmid 789
void ScImage::applyCurve(bool cmyk)
790
{
791
        int h = height();
792
        int w = width();
793
        for( int yi=0; yi < h; ++yi )
794
        {
795
                QRgb * s = (QRgb*)(scanLine( yi ));
796
                for( int xi=0; xi < w; ++xi )
797
                {
798
                        QRgb r=*s;
799
                        int c, m, y, k;
800
                        if (cmyk)
801
                        {
2766 cbradney 802
                                unsigned char *p = (unsigned char *) s;
803
                                unsigned char rc = 255 - QMIN(255, p[0] + p[3]);
804
                                unsigned char gc = 255 - QMIN(255, p[1] + p[3]);
805
                                unsigned char bc = 255 - QMIN(255, p[2] + p[3]);
4419 cbradney 806
                                c = 255 - curveTable[(int)rc];
807
                                m = 255 - curveTable[(int)gc];
808
                                y = 255 - curveTable[(int)bc];
2082 fschmid 809
                                k = QMIN(QMIN(c, m), y);
810
                                *s = qRgba(y - k, m - k, c - k, k );
811
                        }
812
                        else
813
                        {
814
                                c = curveTable[qRed(r)];
815
                                m = curveTable[qGreen(r)];
816
                                y = curveTable[qBlue(r)];
817
                                k = qAlpha(r);
818
                                *s = qRgba(c, m, y, k);
819
                        }
820
                        s++;
821
                }
822
        }
823
}
824
 
2886 fschmid 825
void ScImage::colorize(ScColor color, int shade, bool cmyk)
2053 fschmid 826
{
827
        int h = height();
828
        int w = width();
829
        int cc, cm, cy, ck;
2057 fschmid 830
        int hu, sa, v;
2886 fschmid 831
        ScColor tmp2;
2057 fschmid 832
        QColor tmpR;
2053 fschmid 833
        if (cmyk)
2057 fschmid 834
                color.getShadeColorCMYK(&cc, &cm, &cy, &ck, shade);
2053 fschmid 835
        else
836
        {
837
                ck = 0;
2057 fschmid 838
                color.getShadeColorRGB(&cc, &cm, &cy, shade);
2053 fschmid 839
        }
840
        for( int yi=0; yi < h; ++yi )
841
        {
842
                QRgb * s = (QRgb*)(scanLine( yi ));
843
                for( int xi=0; xi < w; ++xi )
844
                {
845
                        QRgb r=*s;
846
                        if (cmyk)
847
                        {
2057 fschmid 848
                                double k = QMIN(qRound(0.3 * qRed(r) + 0.59 * qGreen(r) + 0.11 * qBlue(r) + qAlpha(r)), 255) / 255.0;
2053 fschmid 849
                                *s = qRgba(QMIN(qRound(cc*k), 255), QMIN(qRound(cm*k), 255), QMIN(qRound(cy*k), 255), QMIN(qRound(ck*k), 255));
850
                        }
851
                        else
852
                        {
2057 fschmid 853
                                int k = 255 - QMIN(qRound(0.3 * qRed(r) + 0.59 * qGreen(r) + 0.11 * qBlue(r)), 255);
854
                                int cc2, cm2, cy2;
855
                                tmpR.setRgb(cc, cm, cy);
856
                                tmpR.hsv(&hu, &sa, &v);
857
                                if (cc == cm && cm == cy)
858
                                        tmpR.setHsv(hu, sa, 255 - ((255 - v) * k / 255));
859
                                else
860
                                        tmpR.setHsv(hu, sa * k / 255, v);
861
                                tmpR.getRgb(&cc2, &cm2, &cy2);
2053 fschmid 862
                                int a = qAlpha(r);
2057 fschmid 863
                                *s = qRgba(cc2, cm2, cy2, a);
2053 fschmid 864
                        }
865
                        s++;
866
                }
867
        }
868
}
869
 
6193 fschmid 870
void ScImage::duotone(ScColor color1, int shade1, FPointArray curve1, bool lin1, ScColor color2, int shade2, FPointArray curve2, bool lin2, bool cmyk)
6080 fschmid 871
{
872
        int h = height();
873
        int w = width();
874
        int c, c1, m, m1, y, y1, k, k1;
875
        int cn, c1n, mn, m1n, yn, y1n, kn, k1n;
876
        uchar cb;
6129 fschmid 877
        QMemArray<int> curveTable1;
878
        QMemArray<int> curveTable2;
6080 fschmid 879
        color1.getShadeColorCMYK(&c, &m, &y, &k, shade1);
880
        color2.getShadeColorCMYK(&c1, &m1, &y1, &k1, shade2);
6129 fschmid 881
        curveTable1.resize(256);
882
        for (int x = 0 ; x < 256 ; x++)
883
        {
6193 fschmid 884
                curveTable1[x] = QMIN(255, QMAX(0, qRound(getCurveYValue(curve1, x / 255.0, lin1) * 255)));
6129 fschmid 885
        }
886
        curveTable2.resize(256);
887
        for (int x = 0 ; x < 256 ; x++)
888
        {
6193 fschmid 889
                curveTable2[x] = QMIN(255, QMAX(0, qRound(getCurveYValue(curve2, x / 255.0, lin2) * 255)));
6129 fschmid 890
        }
6080 fschmid 891
        for( int yi=0; yi < h; ++yi )
892
        {
893
                QRgb * s = (QRgb*)(scanLine( yi ));
894
                for( int xi=0; xi < w; ++xi )
895
                {
896
                        QRgb r=*s;
897
                        if (cmyk)
898
                                cb = QMIN(qRound(0.3 * qRed(r) + 0.59 * qGreen(r) + 0.11 * qBlue(r) + qAlpha(r)), 255);
899
                        else
900
                                cb = 255 - QMIN(qRound(0.3 * qRed(r) + 0.59 * qGreen(r) + 0.11 * qBlue(r)), 255);
6129 fschmid 901
                        cn = QMIN((c * curveTable1[(int)cb]) >> 8, 255);
902
                        mn = QMIN((m * curveTable1[(int)cb]) >> 8, 255);
903
                        yn = QMIN((y * curveTable1[(int)cb]) >> 8, 255);
904
                        kn = QMIN((k * curveTable1[(int)cb]) >> 8, 255);
905
                        c1n = QMIN((c1 * curveTable1[(int)cb]) >> 8, 255);
906
                        m1n = QMIN((m1 * curveTable2[(int)cb]) >> 8, 255);
907
                        y1n = QMIN((y1 * curveTable2[(int)cb]) >> 8, 255);
908
                        k1n = QMIN((k1 * curveTable2[(int)cb]) >> 8, 255);
6080 fschmid 909
                        ScColor col = ScColor(QMIN(cn+c1n, 255), QMIN(mn+m1n, 255), QMIN(yn+y1n, 255), QMIN(kn+k1n, 255));
910
                        if (cmyk)
911
                                col.getCMYK(&cn, &mn, &yn, &kn);
912
                        else
913
                        {
914
                                col.getRawRGBColor(&cn, &mn, &yn);
915
                                kn = qAlpha(r);
916
                        }
917
                        *s = qRgba(cn, mn, yn, kn);
918
                        s++;
919
                }
920
        }
921
}
922
 
6193 fschmid 923
void ScImage::tritone(ScColor color1, int shade1, FPointArray curve1, bool lin1, ScColor color2, int shade2, FPointArray curve2, bool lin2, ScColor color3, int shade3, FPointArray curve3, bool lin3, bool cmyk)
6080 fschmid 924
{
925
        int h = height();
926
        int w = width();
927
        int c, c1, c2, m, m1, m2, y, y1, y2, k, k1, k2;
928
        int cn, c1n, c2n, mn, m1n, m2n, yn, y1n, y2n, kn, k1n, k2n;
929
        uchar cb;
6129 fschmid 930
        QMemArray<int> curveTable1;
931
        QMemArray<int> curveTable2;
932
        QMemArray<int> curveTable3;
6080 fschmid 933
        color1.getShadeColorCMYK(&c, &m, &y, &k, shade1);
934
        color2.getShadeColorCMYK(&c1, &m1, &y1, &k1, shade2);
935
        color3.getShadeColorCMYK(&c2, &m2, &y2, &k2, shade3);
6129 fschmid 936
        curveTable1.resize(256);
937
        for (int x = 0 ; x < 256 ; x++)
938
        {
6193 fschmid 939
                curveTable1[x] = QMIN(255, QMAX(0, qRound(getCurveYValue(curve1, x / 255.0, lin1) * 255)));
6129 fschmid 940
        }
941
        curveTable2.resize(256);
942
        for (int x = 0 ; x < 256 ; x++)
943
        {
6193 fschmid 944
                curveTable2[x] = QMIN(255, QMAX(0, qRound(getCurveYValue(curve2, x / 255.0, lin2) * 255)));
6129 fschmid 945
        }
946
        curveTable3.resize(256);
947
        for (int x = 0 ; x < 256 ; x++)
948
        {
6193 fschmid 949
                curveTable3[x] = QMIN(255, QMAX(0, qRound(getCurveYValue(curve2, x / 255.0, lin3) * 255)));
6129 fschmid 950
        }
6080 fschmid 951
        for( int yi=0; yi < h; ++yi )
952
        {
953
                QRgb * s = (QRgb*)(scanLine( yi ));
954
                for( int xi=0; xi < w; ++xi )
955
                {
956
                        QRgb r=*s;
957
                        if (cmyk)
958
                                cb = QMIN(qRound(0.3 * qRed(r) + 0.59 * qGreen(r) + 0.11 * qBlue(r) + qAlpha(r)), 255);
959
                        else
960
                                cb = 255 - QMIN(qRound(0.3 * qRed(r) + 0.59 * qGreen(r) + 0.11 * qBlue(r)), 255);
6129 fschmid 961
                        cn = QMIN((c * curveTable1[(int)cb]) >> 8, 255);
962
                        mn = QMIN((m * curveTable1[(int)cb]) >> 8, 255);
963
                        yn = QMIN((y * curveTable1[(int)cb]) >> 8, 255);
964
                        kn = QMIN((k * curveTable1[(int)cb]) >> 8, 255);
965
                        c1n = QMIN((c1 * curveTable2[(int)cb]) >> 8, 255);
966
                        m1n = QMIN((m1 * curveTable2[(int)cb]) >> 8, 255);
967
                        y1n = QMIN((y1 * curveTable2[(int)cb]) >> 8, 255);
968
                        k1n = QMIN((k1 * curveTable2[(int)cb]) >> 8, 255);
969
                        c2n = QMIN((c2 * curveTable3[(int)cb]) >> 8, 255);
970
                        m2n = QMIN((m2 * curveTable3[(int)cb]) >> 8, 255);
971
                        y2n = QMIN((y2 * curveTable3[(int)cb]) >> 8, 255);
972
                        k2n = QMIN((k2 * curveTable3[(int)cb]) >> 8, 255);
6080 fschmid 973
                        ScColor col = ScColor(QMIN(cn+c1n+c2n, 255), QMIN(mn+m1n+m2n, 255), QMIN(yn+y1n+y2n, 255), QMIN(kn+k1n+k2n, 255));
974
                        if (cmyk)
975
                                col.getCMYK(&cn, &mn, &yn, &kn);
976
                        else
977
                        {
978
                                col.getRawRGBColor(&cn, &mn, &yn);
979
                                kn = qAlpha(r);
980
                        }
981
                        *s = qRgba(cn, mn, yn, kn);
982
                        s++;
983
                }
984
        }
985
}
986
 
6193 fschmid 987
void ScImage::quadtone(ScColor color1, int shade1, FPointArray curve1, bool lin1, ScColor color2, int shade2, FPointArray curve2, bool lin2, ScColor color3, int shade3, FPointArray curve3, bool lin3, ScColor color4, int shade4, FPointArray curve4, bool lin4, bool cmyk)
6080 fschmid 988
{
989
        int h = height();
990
        int w = width();
991
        int c, c1, c2, c3, m, m1, m2, m3, y, y1, y2, y3, k, k1, k2, k3;
992
        int cn, c1n, c2n, c3n, mn, m1n, m2n, m3n, yn, y1n, y2n, y3n, kn, k1n, k2n, k3n;
993
        uchar cb;
6129 fschmid 994
        QMemArray<int> curveTable1;
995
        QMemArray<int> curveTable2;
996
        QMemArray<int> curveTable3;
997
        QMemArray<int> curveTable4;
6080 fschmid 998
        color1.getShadeColorCMYK(&c, &m, &y, &k, shade1);
999
        color2.getShadeColorCMYK(&c1, &m1, &y1, &k1, shade2);
1000
        color3.getShadeColorCMYK(&c2, &m2, &y2, &k2, shade3);
1001
        color4.getShadeColorCMYK(&c3, &m3, &y3, &k3, shade4);
6129 fschmid 1002
        curveTable1.resize(256);
1003
        for (int x = 0 ; x < 256 ; x++)
1004
        {
6193 fschmid 1005
                curveTable1[x] = QMIN(255, QMAX(0, qRound(getCurveYValue(curve1, x / 255.0, lin1) * 255)));
6129 fschmid 1006
        }
1007
        curveTable2.resize(256);
1008
        for (int x = 0 ; x < 256 ; x++)
1009
        {
6193 fschmid 1010
                curveTable2[x] = QMIN(255, QMAX(0, qRound(getCurveYValue(curve2, x / 255.0, lin2) * 255)));
6129 fschmid 1011
        }
1012
        curveTable3.resize(256);
1013
        for (int x = 0 ; x < 256 ; x++)
1014
        {
6193 fschmid 1015
                curveTable3[x] = QMIN(255, QMAX(0, qRound(getCurveYValue(curve3, x / 255.0, lin3) * 255)));
6129 fschmid 1016
        }
1017
        curveTable4.resize(256);
1018
        for (int x = 0 ; x < 256 ; x++)
1019
        {
6193 fschmid 1020
                curveTable4[x] = QMIN(255, QMAX(0, qRound(getCurveYValue(curve4, x / 255.0, lin4) * 255)));
6129 fschmid 1021
        }
6080 fschmid 1022
        for( int yi=0; yi < h; ++yi )
1023
        {
1024
                QRgb * s = (QRgb*)(scanLine( yi ));
1025
                for( int xi=0; xi < w; ++xi )
1026
                {
1027
                        QRgb r=*s;
1028
                        if (cmyk)
1029
                                cb = QMIN(qRound(0.3 * qRed(r) + 0.59 * qGreen(r) + 0.11 * qBlue(r) + qAlpha(r)), 255);
1030
                        else
1031
                                cb = 255 - QMIN(qRound(0.3 * qRed(r) + 0.59 * qGreen(r) + 0.11 * qBlue(r)), 255);
6129 fschmid 1032
                        cn = QMIN((c * curveTable1[(int)cb]) >> 8, 255);
1033
                        mn = QMIN((m * curveTable1[(int)cb]) >> 8, 255);
1034
                        yn = QMIN((y * curveTable1[(int)cb]) >> 8, 255);
1035
                        kn = QMIN((k * curveTable1[(int)cb]) >> 8, 255);
1036
                        c1n = QMIN((c1 * curveTable2[(int)cb]) >> 8, 255);
1037
                        m1n = QMIN((m1 * curveTable2[(int)cb]) >> 8, 255);
1038
                        y1n = QMIN((y1 * curveTable2[(int)cb]) >> 8, 255);
1039
                        k1n = QMIN((k1 * curveTable2[(int)cb]) >> 8, 255);
1040
                        c2n = QMIN((c2 * curveTable3[(int)cb]) >> 8, 255);
1041
                        m2n = QMIN((m2 * curveTable3[(int)cb]) >> 8, 255);
1042
                        y2n = QMIN((y2 * curveTable3[(int)cb]) >> 8, 255);
1043
                        k2n = QMIN((k2 * curveTable3[(int)cb]) >> 8, 255);
1044
                        c3n = QMIN((c3 * curveTable4[(int)cb]) >> 8, 255);
1045
                        m3n = QMIN((m3 * curveTable4[(int)cb]) >> 8, 255);
1046
                        y3n = QMIN((y3 * curveTable4[(int)cb]) >> 8, 255);
1047
                        k3n = QMIN((k3 * curveTable4[(int)cb]) >> 8, 255);
6080 fschmid 1048
                        ScColor col = ScColor(QMIN(cn+c1n+c2n+c3n, 255), QMIN(mn+m1n+m2n+m3n, 255), QMIN(yn+y1n+y2n+y3n, 255), QMIN(kn+k1n+k2n+k3n, 255));
1049
                        if (cmyk)
1050
                                col.getCMYK(&cn, &mn, &yn, &kn);
1051
                        else
1052
                        {
1053
                                col.getRawRGBColor(&cn, &mn, &yn);
1054
                                kn = qAlpha(r);
1055
                        }
1056
                        *s = qRgba(cn, mn, yn, kn);
1057
                        s++;
1058
                }
1059
        }
1060
}
1061
 
2057 fschmid 1062
void ScImage::invert(bool cmyk)
1063
{
1064
        int h = height();
1065
        int w = width();
1066
        for( int yi=0; yi < h; ++yi )
1067
        {
1068
                QRgb * s = (QRgb*)(scanLine( yi ));
1069
                for( int xi=0; xi < w; ++xi )
1070
                {
1071
                        if (cmyk)
1072
                        {
2766 cbradney 1073
                                unsigned char *p = (unsigned char *) s;
2057 fschmid 1074
                                unsigned char c, m, y, k;
2766 cbradney 1075
                                c = 255 - QMIN(255, p[0] + p[3]);
1076
                                m = 255 - QMIN(255, p[1] + p[3]);
1077
                                y = 255 - QMIN(255, p[2] + p[3]);
2061 fschmid 1078
                                k = QMIN(QMIN(c, m), y);
2766 cbradney 1079
                                p[0] = c - k;
1080
                                p[1] = m - k;
1081
                                p[2] = y - k;
1082
                                p[3] = k;
2057 fschmid 1083
                        }
1084
                        else
2766 cbradney 1085
                                *s ^= 0x00ffffff;
2057 fschmid 1086
                        s++;
1087
                }
1088
        }
1089
}
1090
 
2053 fschmid 1091
void ScImage::toGrayscale(bool cmyk)
1092
{
1093
        int h = height();
1094
        int w = width();
1095
        for( int yi=0; yi < h; ++yi )
1096
        {
1097
                QRgb * s = (QRgb*)(scanLine( yi ));
1098
                for( int xi=0; xi < w; ++xi )
1099
                {
1100
                        QRgb r=*s;
1101
                        int k;
1102
                        if (cmyk)
1103
                        {
2056 fschmid 1104
                                k = QMIN(qRound(0.3 * qRed(r) + 0.59 * qGreen(r) + 0.11 * qBlue(r) + qAlpha(r)), 255);
2053 fschmid 1105
                                *s = qRgba(0, 0, 0, k);
1106
                        }
1107
                        else
1108
                        {
1109
                                k = QMIN(qRound(0.3 * qRed(r) + 0.59 * qGreen(r) + 0.11 * qBlue(r)), 255);
1110
                                int a = qAlpha(r);
1111
                                *s = qRgba(k, k, k, a);
1112
                        }
1113
                        s++;
1114
                }
1115
        }
1116
}
1117
 
2012 fschmid 1118
void ScImage::swapRGBA()
1119
{
1120
        for (int i = 0; i < height(); ++i)
1121
        {
2766 cbradney 1122
                unsigned int *ptr = (unsigned int *) scanLine(i);
1123
                unsigned char r, b;
2012 fschmid 1124
                for (int j = 0; j < width(); ++j)
1125
                {
1126
                        unsigned char *p = (unsigned char *) ptr;
2766 cbradney 1127
                        r = p[0];
1128
                        b = p[2];
1129
                        p[2] = r;
1130
                        p[0] = b;
1131
                        ptr++;
2012 fschmid 1132
                }
1133
        }
1134
}
1135
 
2025 fschmid 1136
void ScImage::createLowRes(double scale)
2012 fschmid 1137
{
2025 fschmid 1138
        int w = qRound(width() / scale);
1139
        int h = qRound(height() / scale);
2012 fschmid 1140
        QImage tmp = smoothScale(w, h);
1141
        create(w, h, 32);
6020 fschmid 1142
        setAlphaBuffer(true);
1143
        tmp = tmp.convertDepth(32);
2012 fschmid 1144
        for( int yi=0; yi < tmp.height(); ++yi )
1145
        {
1146
                QRgb *s = (QRgb*)(tmp.scanLine( yi ));
1147
                QRgb *d = (QRgb*)(scanLine( yi ));
1148
                for(int xi=0; xi < tmp.width(); ++xi )
1149
                {
1150
                        (*d) = (*s);
1151
                        s++;
1152
                        d++;
1153
                }
1154
        }
1155
}
1156
 
2004 fschmid 1157
void ScImage::Convert2JPG(QString fn, int Quality, bool isCMYK, bool isGray)
1158
{
1159
        struct jpeg_compress_struct cinfo;
1160
        struct my_error_mgr         jerr;
1161
        FILE     *outfile;
1162
        JSAMPROW row_pointer[1];
1163
        row_pointer[0] = 0;
1164
        cinfo.err = jpeg_std_error (&jerr.pub);
1165
        jerr.pub.error_exit = my_error_exit;
1166
        outfile = NULL;
1167
        if (setjmp (jerr.setjmp_buffer))
1168
        {
1169
                jpeg_destroy_compress (&cinfo);
1170
                if (outfile)
1171
                        fclose (outfile);
1172
                return;
1173
        }
1174
        jpeg_create_compress (&cinfo);
2643 craig 1175
        if ((outfile = fopen (fn.local8Bit(), "wb")) == NULL)
2004 fschmid 1176
                return;
1177
        jpeg_stdio_dest (&cinfo, outfile);
1178
        cinfo.image_width  = width();
1179
        cinfo.image_height = height();
1180
        if (isCMYK)
1181
        {
1182
                cinfo.in_color_space = JCS_CMYK;
1183
                cinfo.input_components = 4;
1184
        }
1185
        else
1186
        {
1187
                if (isGray)
1188
                {
1189
                        cinfo.in_color_space = JCS_GRAYSCALE;
1190
                        cinfo.input_components = 1;
1191
                }
1192
                else
1193
                {
1194
                        cinfo.in_color_space = JCS_RGB;
1195
                        cinfo.input_components = 3;
1196
                }
1197
        }
1198
        jpeg_set_defaults (&cinfo);
1199
        int qual[] = { 95, 85, 75, 50, 25 };  // These are the JPEG Quality settings 100 means best, 0 .. don't discuss
1200
        jpeg_set_quality (&cinfo, qual[Quality], true);
2680 cbradney 1201
        jpeg_start_compress (&cinfo, true);
2004 fschmid 1202
        row_pointer[0] = new uchar[cinfo.image_width*cinfo.input_components];
1203
        int w = cinfo.image_width;
1204
        while (cinfo.next_scanline < cinfo.image_height)
1205
        {
1206
                uchar *row = row_pointer[0];
1207
                if (isCMYK)
1208
                {
1209
                        QRgb* rgba = (QRgb*)scanLine(cinfo.next_scanline);
1210
                        for (int i=0; i<w; ++i)
1211
                        {
3963 fschmid 1212
                                *row++ = 255-qRed(*rgba);
1213
                                *row++ = 255-qGreen(*rgba);
1214
                                *row++ = 255-qBlue(*rgba);
1215
                                *row++ = 255-qAlpha(*rgba);
2004 fschmid 1216
                                ++rgba;
1217
                        }
1218
                }
1219
                else
1220
                {
1221
                        if (isGray)
1222
                        {
1223
                                QRgb* rgba = (QRgb*)scanLine(cinfo.next_scanline);
1224
                                for (int i=0; i<w; ++i)
1225
                                {
1226
                                        *row++ = qRed(*rgba);
1227
                                        ++rgba;
1228
                                }
1229
                        }
1230
                        else
1231
                        {
1232
                                QRgb* rgb = (QRgb*)scanLine(cinfo.next_scanline);
1233
                                for (int i=0; i<w; i++)
1234
                                {
1235
                                        *row++ = qRed(*rgb);
1236
                                        *row++ = qGreen(*rgb);
1237
                                        *row++ = qBlue(*rgb);
1238
                                        ++rgb;
1239
                                }
1240
                        }
1241
                }
1242
                jpeg_write_scanlines (&cinfo, row_pointer, 1);
1243
        }
1244
        jpeg_finish_compress (&cinfo);
1245
        fclose (outfile);
1246
        jpeg_destroy_compress (&cinfo);
1247
        delete [] row_pointer[0];
1248
}
1249
 
5234 fschmid 1250
QByteArray ScImage::ImageToArray()
2004 fschmid 1251
{
2884 fschmid 1252
        int i = 0;
2004 fschmid 1253
        int h = height();
1254
        int w = width();
2884 fschmid 1255
        unsigned char u;
5234 fschmid 1256
        QByteArray imgArray(3 * h * w);
2004 fschmid 1257
        for( int yi=0; yi < h; ++yi )
1258
        {
1259
                QRgb * s = (QRgb*)(scanLine( yi ));
1260
                for( int xi=0; xi < w; ++xi )
1261
                {
1262
                        QRgb r=*s++;
2884 fschmid 1263
                        u=qRed(r);
5234 fschmid 1264
                        imgArray[i++] = u;
2004 fschmid 1265
                        u=qGreen(r);
5234 fschmid 1266
                        imgArray[i++] = u;
2004 fschmid 1267
                        u=qBlue(r);
5234 fschmid 1268
                        imgArray[i++] = u;
2004 fschmid 1269
                }
1270
        }
5234 fschmid 1271
        return imgArray;
2004 fschmid 1272
}
1273
 
5234 fschmid 1274
QByteArray ScImage::ImageToGray()
2004 fschmid 1275
{
2884 fschmid 1276
        int i = 0;
2004 fschmid 1277
        int h = height();
1278
        int w = width();
5234 fschmid 1279
        QByteArray imgArray(h * w);
2004 fschmid 1280
        for( int yi=0; yi < h; ++yi )
1281
        {
1282
                QRgb * s = (QRgb*)(scanLine( yi ));
1283
                for( int xi=0; xi < w; ++xi )
1284
                {
1285
                        QRgb r=*s;
1286
                        int k = QMIN(qRound(0.3 * qRed(r) + 0.59 * qGreen(r) + 0.11 * qBlue(r)), 255);
1287
                        *s = qRgba(k, 0, 0, 0);
5234 fschmid 1288
                        imgArray[i++] = k;
2004 fschmid 1289
                        s++;
1290
                }
1291
        }
5234 fschmid 1292
        return imgArray;
2004 fschmid 1293
}
1294
 
5234 fschmid 1295
QByteArray ScImage::ImageToCMYK_PDF(bool pre)
2004 fschmid 1296
{
2884 fschmid 1297
        int i = 0;
2004 fschmid 1298
        int h = height();
1299
        int w = width();
5234 fschmid 1300
        QByteArray imgArray( 4 * h * w );
2004 fschmid 1301
        if (pre)
1302
        {
1303
                for( int yi=0; yi < h; ++yi )
1304
                {
1305
                        QRgb * s = (QRgb*)(scanLine( yi ));
1306
                        for( int xi=0; xi < w; ++xi )
1307
                        {
1308
                                QRgb r=*s;
1309
                                int c = qRed(r);
1310
                                int m = qGreen(r);
1311
                                int y = qBlue(r);
1312
                                int k = qAlpha(r);
5234 fschmid 1313
                                imgArray[i++] = static_cast<unsigned char> (c);
1314
                                imgArray[i++] = static_cast<unsigned char> (m);
1315
                                imgArray[i++] = static_cast<unsigned char> (y);
1316
                                imgArray[i++] = static_cast<unsigned char> (k);
2004 fschmid 1317
                                s++;
1318
                        }
1319
                }
1320
        }
1321
        else
1322
        {
1323
                for( int yi=0; yi < h; ++yi )
1324
                {
1325
                        QRgb * s = (QRgb*)(scanLine( yi ));
1326
                        for( int xi=0; xi < w; ++xi )
1327
                        {
1328
                                QRgb r=*s;
1329
                                int c = 255 - qRed(r);
1330
                                int m = 255 - qGreen(r);
1331
                                int y = 255 - qBlue(r);
1332
                                int k = QMIN(QMIN(c, m), y);
5234 fschmid 1333
                                imgArray[i++] = static_cast<unsigned char> (c - k);
1334
                                imgArray[i++] = static_cast<unsigned char> (m - k);
1335
                                imgArray[i++] = static_cast<unsigned char> (y - k);
1336
                                imgArray[i++] = static_cast<unsigned char> (k);
2004 fschmid 1337
                                s++;
1338
                        }
1339
                }
1340
        }
5234 fschmid 1341
        return imgArray;
2004 fschmid 1342
}
1343
 
5234 fschmid 1344
QByteArray ScImage::ImageToCMYK_PS(int pl, bool pre)
2004 fschmid 1345
{
2884 fschmid 1346
        int i = 0;
2004 fschmid 1347
        int h = height();
1348
        int w = width();
5234 fschmid 1349
        QByteArray imgArray;
2884 fschmid 1350
        if(pl == -1)
5234 fschmid 1351
                imgArray.resize(4 * h * w);
2884 fschmid 1352
        else
5234 fschmid 1353
                imgArray.resize(h * w);
2004 fschmid 1354
        if (pre)
1355
        {
1356
                for( int yi=0; yi < h; ++yi )
1357
                {
1358
                        QRgb * s = (QRgb*)(scanLine( yi ));
1359
                        for( int xi=0; xi < w; ++xi )
1360
                        {
1361
                                QRgb r=*s++;
1362
                                int c = qRed(r);
1363
                                int m = qGreen(r);
1364
                                int y = qBlue(r);
1365
                                int k = qAlpha(r);
1366
                                if (pl == -1)
1367
                                {
5234 fschmid 1368
                                        imgArray[i++] = static_cast<unsigned char> (c);
1369
                                        imgArray[i++] = static_cast<unsigned char> (m);
1370
                                        imgArray[i++] = static_cast<unsigned char> (y);
1371
                                        imgArray[i++] = static_cast<unsigned char> (k);
2004 fschmid 1372
                                }
1373
                                else
1374
                                {
1375
                                        if (pl == -2)
5234 fschmid 1376
                                                imgArray[i++] = static_cast<unsigned char> (QMIN(255, qRound(0.3 * c + 0.59 * m + 0.11 * y + k)));
2004 fschmid 1377
                                        if (pl == 1)
5234 fschmid 1378
                                                imgArray[i++] = static_cast<unsigned char> (c);
2004 fschmid 1379
                                        if (pl == 2)
5234 fschmid 1380
                                                imgArray[i++] = static_cast<unsigned char> (m);
2004 fschmid 1381
                                        if (pl == 3)
5234 fschmid 1382
                                                imgArray[i++] = static_cast<unsigned char> (y);
2004 fschmid 1383
                                        if (pl == 0)
5234 fschmid 1384
                                                imgArray[i++] = static_cast<unsigned char> (k);
2004 fschmid 1385
                                }
1386
                        }
1387
                }
1388
        }
1389
        else
1390
        {
1391
                for( int yi=0; yi < h; ++yi )
1392
                {
1393
                        QRgb * s = (QRgb*)(scanLine( yi ));
1394
                        for( int xi=0; xi < w; ++xi )
1395
                        {
1396
                                QRgb r=*s++;
1397
                                int c = 255 - qRed(r);
1398
                                int m = 255 - qGreen(r);
1399
                                int y = 255 - qBlue(r);
1400
                                int k = QMIN(QMIN(c, m), y);
1401
                                if (pl == -1)
1402
                                {
5234 fschmid 1403
                                        imgArray[i++] = static_cast<unsigned char> (c - k);
1404
                                        imgArray[i++] = static_cast<unsigned char> (m - k);
1405
                                        imgArray[i++] = static_cast<unsigned char> (y - k);
1406
                                        imgArray[i++] = static_cast<unsigned char> (k);
2004 fschmid 1407
                                }
1408
                                else
1409
                                {
1410
                                        if (pl == -2)
5234 fschmid 1411
                                                imgArray[i++] = static_cast<unsigned char> (QMIN(255, qRound(0.3 * c + 0.59 * m + 0.11 * y + k)));
2004 fschmid 1412
                                        if (pl == 1)
5234 fschmid 1413
                                                imgArray[i++] = static_cast<unsigned char> (c - k);
2004 fschmid 1414
                                        if (pl == 2)
5234 fschmid 1415
                                                imgArray[i++] = static_cast<unsigned char> (m - k);
2004 fschmid 1416
                                        if (pl == 3)
5234 fschmid 1417
                                                imgArray[i++] = static_cast<unsigned char> (y - k);
2004 fschmid 1418
                                        if (pl == 0)
5234 fschmid 1419
                                                imgArray[i++] = static_cast<unsigned char> (k);
2004 fschmid 1420
                                }
1421
                        }
1422
                }
1423
        }
5234 fschmid 1424
        return imgArray;
2004 fschmid 1425
}
1426
 
1427
void ScImage::scaleImage(int nwidth, int nheight)
1428
{
1429
        QImage dst;
1430
        dst.create(nwidth, nheight,32);
1431
        QRgb* xelrow = 0;
1432
        QRgb* tempxelrow = 0;
1433
        register QRgb* xP;
1434
        register QRgb* nxP;
1435
        int rows, cols, rowsread, newrows, newcols;
1436
        register int row, col, needtoreadrow;
1437
        const uchar maxval = 255;
1438
        double xscale, yscale;
1439
        long sxscale, syscale;
1440
        register long fracrowtofill, fracrowleft;
1441
        long* as;
1442
        long* rs;
1443
        long* gs;
1444
        long* bs;
1445
        int rowswritten = 0;
1446
        cols = width();
1447
        rows = height();
1448
        newcols = dst.width();
1449
        newrows = dst.height();
1450
        long SCALE;
1451
        long HALFSCALE;
1452
        if (cols > 4096)
1453
        {
1454
                SCALE = 4096;
1455
                HALFSCALE = 2048;
1456
        }
1457
        else
1458
        {
1459
                int fac = 4096;
1460
                while (cols * fac > 4096)
1461
                {
1462
                        fac /= 2;
1463
                }
1464
                SCALE = fac * cols;
1465
                HALFSCALE = fac * cols / 2;
1466
        }
1467
        xscale = (double) newcols / (double) cols;
1468
        yscale = (double) newrows / (double) rows;
1469
        sxscale = (long)(xscale * SCALE);
1470
        syscale = (long)(yscale * SCALE);
1471
        if ( newrows != rows )  /* shortcut Y scaling if possible */
1472
                tempxelrow = new QRgb[cols];
1473
        as = new long[cols];
1474
        rs = new long[cols];
1475
        gs = new long[cols];
1476
        bs = new long[cols];
1477
        rowsread = 0;
1478
        fracrowleft = syscale;
1479
        needtoreadrow = 1;
1480
        for ( col = 0; col < cols; ++col )
1481
                rs[col] = gs[col] =  as[col] = bs[col] = HALFSCALE;
1482
        fracrowtofill = SCALE;
1483
        for ( row = 0; row < newrows; ++row )
1484
        {
1485
                if ( newrows == rows )
1486
                        tempxelrow = xelrow = (QRgb*)scanLine(rowsread++);
1487
                else
1488
                {
1489
                        while ( fracrowleft < fracrowtofill )
1490
                        {
1491
                                if ( needtoreadrow && rowsread < rows )
1492
                                        xelrow = (QRgb*)scanLine(rowsread++);
1493
                                for ( col = 0, xP = xelrow; col < cols; ++col, ++xP )
1494
                                {
1495
                                        as[col] += fracrowleft * qAlpha( *xP );
1496
                                        rs[col] += fracrowleft * qRed( *xP );
1497
                                        gs[col] += fracrowleft * qGreen( *xP );
1498
                                        bs[col] += fracrowleft * qBlue( *xP );
1499
                                }
1500
                                fracrowtofill -= fracrowleft;
1501
                                fracrowleft = syscale;
1502
                                needtoreadrow = 1;
1503
                        }
1504
                        if ( needtoreadrow && rowsread < rows )
1505
                        {
1506
                                xelrow = (QRgb*)scanLine(rowsread++);
1507
                                needtoreadrow = 0;
1508
                        }
1509
                        register long a=0;
1510
                        for ( col = 0, xP = xelrow, nxP = tempxelrow; col < cols; ++col, ++xP, ++nxP )
1511
                        {
1512
                                register long r, g, b;
1513
                                a = as[col] + fracrowtofill * qAlpha( *xP );
1514
                                r = rs[col] + fracrowtofill * qRed( *xP );
1515
                                g = gs[col] + fracrowtofill * qGreen( *xP );
1516
                                b = bs[col] + fracrowtofill * qBlue( *xP );
1517
                                r /= SCALE;
1518
                                if ( r > maxval ) r = maxval;
1519
                                g /= SCALE;
1520
                                if ( g > maxval ) g = maxval;
1521
                                b /= SCALE;
1522
                                if ( b > maxval ) b = maxval;
1523
                                a /= SCALE;
1524
                                if ( a > maxval ) a = maxval;
1525
                                *nxP = qRgba( (int)r, (int)g, (int)b , (int)a);
1526
                                rs[col] = as[col] = gs[col] = bs[col] = HALFSCALE;
1527
                        }
1528
                        fracrowleft -= fracrowtofill;
1529
                        if ( fracrowleft == 0 )
1530
                        {
1531
                                fracrowleft = syscale;
1532
                                needtoreadrow = 1;
1533
                        }
1534
                        fracrowtofill = SCALE;
1535
                }
1536
                if ( newcols == cols )
1537
                        memcpy(dst.scanLine(rowswritten++), tempxelrow, newcols*4);
1538
                else
1539
                {
1540
                        register long a, r, g, b;
1541
                        register long fraccoltofill, fraccolleft = 0;
1542
                        register int needcol;
1543
                        nxP = (QRgb*)dst.scanLine(rowswritten++);
1544
                        fraccoltofill = SCALE;
1545
                        a = r = g = b = HALFSCALE;
1546
                        needcol = 0;
1547
                        for ( col = 0, xP = tempxelrow; col < cols; ++col, ++xP )
1548
                        {
1549
                                fraccolleft = sxscale;
1550
                                while ( fraccolleft >= fraccoltofill )
1551
                                {
1552
                                        if ( needcol )
1553
                                        {
1554
                                                ++nxP;
1555
                                                a = r = g = b = HALFSCALE;
1556
                                        }
1557
                                        a += fraccoltofill * qAlpha( *xP );
1558
                                        r += fraccoltofill * qRed( *xP );
1559
                                        g += fraccoltofill * qGreen( *xP );
1560
                                        b += fraccoltofill * qBlue( *xP );
1561
                                        r /= SCALE;
1562
                                        if ( r > maxval ) r = maxval;
1563
                                        g /= SCALE;
1564
                                        if ( g > maxval ) g = maxval;
1565
                                        b /= SCALE;
1566
                                        if ( b > maxval ) b = maxval;
1567
                                        a /= SCALE;
1568
                                        if ( a > maxval ) a = maxval;
1569
                                        *nxP = qRgba( (int)r, (int)g, (int)b, (int)a );
1570
                                        fraccolleft -= fraccoltofill;
1571
                                        fraccoltofill = SCALE;
1572
                                        needcol = 1;
1573
                                }
1574
                                if ( fraccolleft > 0 )
1575
                                {
1576
                                        if ( needcol )
1577
                                        {
1578
                                                ++nxP;
1579
                                                a = r = g = b = HALFSCALE;
1580
                                                needcol = 0;
1581
                                        }
1582
                                        a += fraccolleft * qAlpha( *xP );
1583
                                        r += fraccolleft * qRed( *xP );
1584
                                        g += fraccolleft * qGreen( *xP );
1585
                                        b += fraccolleft * qBlue( *xP );
1586
                                        fraccoltofill -= fraccolleft;
1587
                                }
1588
                        }
1589
                        if ( fraccoltofill > 0 )
1590
                        {
1591
                                --xP;
1592
                                a += fraccolleft * qAlpha( *xP );
1593
                                r += fraccoltofill * qRed( *xP );
1594
                                g += fraccoltofill * qGreen( *xP );
1595
                                b += fraccoltofill * qBlue( *xP );
1596
                        }
1597
                        if ( ! needcol )
1598
                        {
1599
                                r /= SCALE;
1600
                                if ( r > maxval ) r = maxval;
1601
                                g /= SCALE;
1602
                                if ( g > maxval ) g = maxval;
1603
                                b /= SCALE;
1604
                                if ( b > maxval ) b = maxval;
1605
                                a /= SCALE;
1606
                                if ( a > maxval ) a = maxval;
1607
                                *nxP = qRgba( (int)r, (int)g, (int)b, (int)a );
1608
                        }
1609
                }
1610
        }
1611
        if ( newrows != rows && tempxelrow )// Robust, tempxelrow might be 0 1 day
1612
                delete [] tempxelrow;
1613
        if ( as )                               // Avoid purify complaint
1614
                delete [] as;
1615
        if ( rs )                               // Robust, rs might be 0 one day
1616
                delete [] rs;
1617
        if ( gs )                               // Robust, gs might be 0 one day
1618
                delete [] gs;
1619
        if ( bs )                               // Robust, bs might be 0 one day
1620
                delete [] bs;
1621
        create(nwidth, nheight,32);
1622
        for( int yi=0; yi < dst.height(); ++yi )
1623
        {
1624
                QRgb *s = (QRgb*)(dst.scanLine( yi ));
1625
                QRgb *d = (QRgb*)(scanLine( yi ));
1626
                for(int xi=0; xi < dst.width(); ++xi )
1627
                {
1628
                        (*d) = (*s);
1629
                        s++;
1630
                        d++;
1631
                }
1632
        }
1633
        return;
1634
}
1635
 
5234 fschmid 1636
QByteArray ScImage::getAlpha(QString fn, bool PDF, bool pdf14, int gsRes)
2004 fschmid 1637
{
5234 fschmid 1638
        QByteArray retArray;
5937 jghali 1639
        ScImgDataLoader* pDataLoader = NULL;
2004 fschmid 1640
        short resolutionunit = 0;
1641
        imgInfo.valid = false;
1642
        imgInfo.clipPath = "";
1643
        imgInfo.PDSpathData.clear();
1644
        imgInfo.layerInfo.clear();
1645
        QFileInfo fi = QFileInfo(fn);
1646
        if (!fi.exists())
5234 fschmid 1647
                return retArray;
2995 fschmid 1648
        QString tmp, BBox, tmp2;
2004 fschmid 1649
        QString ext = fi.extension(false).lower();
2995 fschmid 1650
        if ((ext == "jpg") || (ext == "jpeg"))
5234 fschmid 1651
                return retArray;
2995 fschmid 1652
        bool found = false;
1653
        int retg = -1;
1654
        QChar tc;
5937 jghali 1655
 
2995 fschmid 1656
        if (ext == "pdf")
5937 jghali 1657
                pDataLoader = new ScImgDataLoader_PDF();
2995 fschmid 1658
        else if ((ext == "eps") || (ext == "ps"))
5937 jghali 1659
                pDataLoader = new ScImgDataLoader_PS();
1660
#ifdef HAVE_TIFF
1661
        else if ((ext == "tif") || (ext == "tiff"))
1662
                pDataLoader = new ScImgDataLoader_TIFF();
1663
#endif // HAVE_TIFF
1664
        else if (ext == "psd")
1665
                pDataLoader = new ScImgDataLoader_PSD();
1666
        else
1667
                pDataLoader = new ScImgDataLoader_QT();
1668
 
1669
        if      (pDataLoader)
2995 fschmid 1670
        {
5937 jghali 1671
                pDataLoader->preloadAlphaChannel(fn, gsRes);
1672
                QImage& rImage = pDataLoader->image();
1673
                if (rImage.isNull())
2995 fschmid 1674
                {
5937 jghali 1675
                        delete pDataLoader;
1676
                        return retArray;
2995 fschmid 1677
                }
5937 jghali 1678
                int i = 0;
1679
                unsigned char u;
1680
                int hm = rImage.height();
1681
                int wm = rImage.width();
1682
                int w2;
1683
                if (pdf14)
2995 fschmid 1684
                {
5937 jghali 1685
                        retArray.resize(hm * wm);
1686
                        for( int yi=0; yi < hm; ++yi )
2995 fschmid 1687
                        {
5937 jghali 1688
                                QRgb * s = (QRgb*)(rImage.scanLine( yi ));
1689
                                for( int xi=0; xi < wm; ++xi )
2995 fschmid 1690
                                {
5937 jghali 1691
                                        QRgb r=*s++;
1692
                                        u=qAlpha(r);
1693
                                        retArray[i++] = u;
2995 fschmid 1694
                                }
1695
                        }
1696
                }
5937 jghali 1697
                else
2004 fschmid 1698
                {
5937 jghali 1699
                        QImage iMask = rImage.createAlphaMask();
1700
                        hm = iMask.height();
1701
                        wm = iMask.width();
1702
                        w2 = wm / 8;
1703
                        if ((wm % 8) != 0)
1704
                                w2++;
1705
                        retArray.resize(hm * w2);
1706
                        for( int yi=0; yi < hm; ++yi )
2004 fschmid 1707
                        {
5937 jghali 1708
                                uchar * s = iMask.scanLine( yi );
1709
                                for( int xi=0; xi < w2; ++xi )
2004 fschmid 1710
                                {
5937 jghali 1711
                                        u = *(s+xi);
1712
                                        if(PDF) u = ~u;
1713
                                        retArray[i++] = u;
2004 fschmid 1714
                                }
1715
                        }
1716
                }
5937 jghali 1717
                delete pDataLoader;
2004 fschmid 1718
        }
5234 fschmid 1719
        return retArray;
2004 fschmid 1720
}
1721
 
5234 fschmid 1722
void ScImage::getEmbeddedProfile(const QString & fn, QByteArray *profile, int *components)
1723
{
1724
        Q_ASSERT(profile);
1725
        Q_ASSERT(components);
5937 jghali 1726
        ScImgDataLoader* pDataLoader = NULL;
5234 fschmid 1727
#ifdef HAVE_CMS
5937 jghali 1728
        cmsHPROFILE prof = 0;
1729
 
1730
        profile->resize(0);
1731
        *components = 0;
5234 fschmid 1732
        QFileInfo fi = QFileInfo(fn);
1733
        if (!fi.exists())
1734
                return;
1735
        QString ext = fi.extension(false).lower();
5937 jghali 1736
 
5234 fschmid 1737
        if (ext == "psd")
5937 jghali 1738
                pDataLoader = new ScImgDataLoader_PSD();
5234 fschmid 1739
#ifdef HAVE_TIFF
1740
        else if ((ext == "tif") || (ext == "tiff"))
5937 jghali 1741
                pDataLoader = new ScImgDataLoader_TIFF();
1742
#endif
5234 fschmid 1743
        else if ((ext == "jpg") || (ext == "jpeg"))
5937 jghali 1744
                pDataLoader = new ScImgDataLoader_JPEG();
1745
 
1746
        if      (pDataLoader)
5234 fschmid 1747
        {
5937 jghali 1748
                pDataLoader->loadEmbeddedProfile(fn);
1749
                QByteArray embeddedProfile = pDataLoader->embeddedProfile();
1750
                if      (embeddedProfile.size())
5234 fschmid 1751
                {
5937 jghali 1752
                        prof = cmsOpenProfileFromMem(embeddedProfile.data(), embeddedProfile.size());
1753
                        if (prof)
5234 fschmid 1754
                        {
5937 jghali 1755
                                if (static_cast<int>(cmsGetColorSpace(prof)) == icSigRgbData)
5234 fschmid 1756
                                        *components = 3;
5937 jghali 1757
                                if (static_cast<int>(cmsGetColorSpace(prof)) == icSigCmykData)
5234 fschmid 1758
                                        *components = 4;
5937 jghali 1759
                                *profile = embeddedProfile;
5234 fschmid 1760
                        }
5937 jghali 1761
                        cmsCloseProfile(prof);
5234 fschmid 1762
                }
5937 jghali 1763
                delete pDataLoader;
5234 fschmid 1764
        }
1765
#endif // HAVE_CMS
1766
}
1767
 
5781 cbradney 1768
bool ScImage::LoadPicture(const QString & fn, const CMSettings& cmSettings,
5977 jghali 1769
                                                  bool useEmbedded, bool useProf, RequestType requestType,
1770
                                                  int gsRes, bool *realCMYK, bool showMsg)
2004 fschmid 1771
{
3685 fschmid 1772
        // requestType - 0: CMYK, 1: RGB, 2: RGB Proof 3 : RawData, 4: Thumbnail
2004 fschmid 1773
        // gsRes - is the resolution that ghostscript will render at
1774
        bool isCMYK = false;
1775
        bool ret = false;
1776
        if (realCMYK != 0)
1777
                *realCMYK = false;
1778
        bool bilevel = false;
1779
        short resolutionunit = 0;
5345 mrdocs 1780
        RequestType reqType = requestType;
2004 fschmid 1781
#ifdef HAVE_CMS
1782
        cmsHTRANSFORM xform = 0;
1783
        cmsHPROFILE inputProf = 0;
1784
        int cmsFlags = 0;
1785
#endif
5937 jghali 1786
        auto_ptr<ScImgDataLoader> pDataLoader;
2004 fschmid 1787
        QFileInfo fi = QFileInfo(fn);
1788
        if (!fi.exists())
1789
                return ret;
1790
        QString ext = fi.extension(false).lower();
1791
        QString tmp, dummy, cmd1, cmd2, BBox, tmp2;
1792
        QChar tc;
1793
        bool found = false;
5937 jghali 1794
 
2004 fschmid 1795
        if (ext == "pdf")
5937 jghali 1796
                pDataLoader.reset( new ScImgDataLoader_PDF() );
1797
        else if ((ext == "eps") || (ext == "ps"))
1798
                pDataLoader.reset( new ScImgDataLoader_PS() );
2004 fschmid 1799
#ifdef HAVE_TIFF
1800
        else if ((ext == "tif") || (ext == "tiff"))
5937 jghali 1801
                pDataLoader.reset( new ScImgDataLoader_TIFF() );
2004 fschmid 1802
#endif // HAVE_TIFF
1803
        else if (ext == "psd")
6138 fschmid 1804
        {
5937 jghali 1805
                pDataLoader.reset( new ScImgDataLoader_PSD() );
6138 fschmid 1806
                pDataLoader->setRequest(imgInfo.isRequest, imgInfo.RequestProps);
1807
        }
2004 fschmid 1808
        else if ((ext == "jpg") || (ext == "jpeg"))
5937 jghali 1809
                pDataLoader.reset( new ScImgDataLoader_JPEG() );
1810
        else
1811
                pDataLoader.reset( new ScImgDataLoader_QT() );
1812
 
1813
        if      (pDataLoader->loadPicture(fn, gsRes, (requestType == Thumbnail)))
2004 fschmid 1814
        {
5937 jghali 1815
                *this = pDataLoader->image();
1816
                imgInfo = pDataLoader->imageInfoRecord();
1817
                if (requestType == Thumbnail)
1818
                        requestType = RGBData;
1819
                if (!cmSettings.useColorManagement() || !useProf)
2004 fschmid 1820
                {
3005 fschmid 1821
                        imgInfo.isEmbedded = false;
2004 fschmid 1822
                        imgInfo.profileName = "";
3005 fschmid 1823
                }
5937 jghali 1824
                if (imgInfo.colorspace == 1)
2004 fschmid 1825
                {
2742 fschmid 1826
                        isCMYK = true;
5937 jghali 1827
                        if(realCMYK)
1828
                                *realCMYK = true;
2742 fschmid 1829
                }
5941 jghali 1830
                else if (imgInfo.colorspace == 2)
1831
                        bilevel = true;
5937 jghali 1832
                pDataLoader->image() = QImage();
2004 fschmid 1833
        }
1834
        else
5977 jghali 1835
        {
1836
                if      (ScCore->usingGUI() && pDataLoader->issuedErrorMsg() && showMsg)
1837
                {
1838
                        QMessageBox::critical(ScCore->primaryMainWindow(), CommonStrings::trWarning, pDataLoader->getMessage(), 1, 0, 0);
1839
                }
1840
                else if (pDataLoader->issuedErrorMsg())
1841
                {
1842
                        QString msg = pDataLoader->getMessage();
1843
                        qWarning( msg.local8Bit().data() );
1844
                }
5937 jghali 1845
                return false;
5977 jghali 1846
        }
5937 jghali 1847
 
2004 fschmid 1848
        if (isNull())
1849
                return  ret;
5937 jghali 1850
 
2004 fschmid 1851
#ifdef HAVE_CMS
5937 jghali 1852
        QByteArray embeddedProfile = pDataLoader->embeddedProfile();
5788 jghali 1853
        if (cmSettings.useColorManagement() && useProf)
2004 fschmid 1854
        {
5937 jghali 1855
                if (embeddedProfile.size() > 0 )
1856
                {
1857
                        inputProf = cmsOpenProfileFromMem(embeddedProfile.data(), embeddedProfile.size());
1858
                }
2004 fschmid 1859
                else
1860
                {
3745 craig 1861
                        QCString profilePath;
5781 cbradney 1862
                        //CB If this is null, customfiledialog/picsearch/ScPreview might be sending it
1863
                        Q_ASSERT(cmSettings.doc()!=0);
2004 fschmid 1864
                        if (isCMYK)
2995 fschmid 1865
                        {
5781 cbradney 1866
                                if (ScCore->InputProfilesCMYK.contains(cmSettings.profileName()))
1867
                                        imgInfo.profileName = cmSettings.profileName();
3005 fschmid 1868
                                else
5781 cbradney 1869
                                        imgInfo.profileName = cmSettings.doc()->CMSSettings.DefaultImageCMYKProfile;
5243 cbradney 1870
                                profilePath = ScCore->InputProfilesCMYK[imgInfo.profileName].local8Bit();
2995 fschmid 1871
                        }
2004 fschmid 1872
                        else
2995 fschmid 1873
                        {
5781 cbradney 1874
                                if (ScCore->InputProfiles.contains(cmSettings.profileName()))
1875
                                        imgInfo.profileName = cmSettings.profileName();
3005 fschmid 1876
                                else
5781 cbradney 1877
                                        imgInfo.profileName = cmSettings.doc()->CMSSettings.DefaultImageRGBProfile;
5243 cbradney 1878
                                profilePath = ScCore->InputProfiles[imgInfo.profileName].local8Bit();
2995 fschmid 1879
                        }
3745 craig 1880
                        inputProf = cmsOpenProfileFromFile(profilePath.data(), "r");
2004 fschmid 1881
                }
1882
        }
5788 jghali 1883
        if (cmSettings.useColorManagement() && useProf && inputProf)
2004 fschmid 1884
        {
1885
                DWORD inputProfFormat = TYPE_RGBA_8;
6070 jghali 1886
                DWORD outputProfFormat = TYPE_CMYK_8;
5555 mrdocs 1887
                int inputProfColorSpace = static_cast<int>(cmsGetColorSpace(inputProf));
1888
                if ( inputProfColorSpace == icSigRgbData )
2004 fschmid 1889
                        inputProfFormat = TYPE_RGBA_8;
5555 mrdocs 1890
                else if ( inputProfColorSpace == icSigCmykData )
2004 fschmid 1891
                        inputProfFormat = TYPE_CMYK_8;
5555 mrdocs 1892
                else if ( inputProfColorSpace == icSigGrayData )
1893
                        inputProfFormat = TYPE_GRAY_8;
6070 jghali 1894
                int outputProfColorSpace = static_cast<int>(cmsGetColorSpace(cmSettings.printerProfile()));
1895
                if ( outputProfColorSpace == icSigRgbData )
1896
                        outputProfFormat = TYPE_RGBA_8;
1897
                else if ( outputProfColorSpace == icSigCmykData )
1898
                        outputProfFormat = TYPE_CMYK_8;
5788 jghali 1899
                if (cmSettings.doSoftProofing())
2004 fschmid 1900
                {
1901
                        cmsFlags |= cmsFLAGS_SOFTPROOFING;
5788 jghali 1902
                        if (cmSettings.doGamutCheck())
2004 fschmid 1903
                                cmsFlags |= cmsFLAGS_GAMUTCHECK;
1904
                }
5788 jghali 1905
                if (cmSettings.useBlackPoint())
2004 fschmid 1906
                        cmsFlags |= cmsFLAGS_BLACKPOINTCOMPENSATION;
3685 fschmid 1907
                switch (reqType)
2004 fschmid 1908
                {
5345 mrdocs 1909
                case CMYKData: // CMYK
6070 jghali 1910
                        if ((!isCMYK && (outputProfColorSpace == icSigCmykData)) || (isCMYK && (outputProfColorSpace == icSigRgbData)) )
1911
                                xform = scCmsCreateTransform(inputProf, inputProfFormat, cmSettings.printerProfile(), outputProfFormat, cmSettings.imageRenderingIntent(), 0);
1912
                        if (outputProfColorSpace != icSigCmykData )
5846 jghali 1913
                                *realCMYK = isCMYK = false;
2004 fschmid 1914
                        break;
5992 fschmid 1915
                case Thumbnail:
5345 mrdocs 1916
                case RGBData: // RGB
2004 fschmid 1917
                        if (isCMYK)
6070 jghali 1918
                                xform = scCmsCreateTransform(inputProf, inputProfFormat, cmSettings.monitorProfile(), TYPE_RGBA_8, cmSettings.intent(), 0);
2004 fschmid 1919
                        break;
5345 mrdocs 1920
                case RGBProof: // RGB Proof
2004 fschmid 1921
                        {
5555 mrdocs 1922
                                if (inputProfFormat == TYPE_CMYK_8)
1923
                                        inputProfFormat = (COLORSPACE_SH(PT_CMYK)|CHANNELS_SH(4)|BYTES_SH(1)|DOSWAP_SH(1)|SWAPFIRST_SH(1));//TYPE_YMCK_8;
1924
                                else if(inputProfFormat == TYPE_RGBA_8)
1925
                                        inputProfFormat = TYPE_BGRA_8;
5788 jghali 1926
                                if (cmSettings.doSoftProofing())
6070 jghali 1927
                                {
1928
                                        xform = scCmsCreateProofingTransform(inputProf, inputProfFormat,
1929
                                                             cmSettings.monitorProfile(), TYPE_BGRA_8, cmSettings.printerProfile(),
1930
                                                             cmSettings.intent(), INTENT_RELATIVE_COLORIMETRIC, cmsFlags);
1931
                                }
2095 fschmid 1932
                                else
6070 jghali 1933
                                        xform = scCmsCreateTransform(inputProf, inputProfFormat, cmSettings.monitorProfile(),
1934
                                                                                 TYPE_BGRA_8, cmSettings.intent(), cmsFlags);
2095 fschmid 1935
                        }
2004 fschmid 1936
                        break;
5345 mrdocs 1937
                case RawData: // no Conversion just raw Data
2004 fschmid 1938
                        xform = 0;
1939
                        break;
1940
                }
1941
                if (xform)
1942
                {
1943
                        for (int i = 0; i < height(); i++)
1944
                        {
1945
                                LPBYTE ptr = scanLine(i);
5555 mrdocs 1946
                                if ( inputProfFormat == TYPE_GRAY_8 && (reqType != CMYKData) )
1947
                                {
1948
                                        unsigned char* ucs = ptr + 1;
1949
                                        unsigned char* uc = new unsigned char[width()];
1950
                                        for( int uci = 0; uci < width(); uci++ )
1951
                                        {
1952
                                                uc[uci] = *ucs;
1953
                                                ucs += 4;
1954
                                        }
1955
                                        cmsDoTransform(xform, uc, ptr, width());
1956
                                        delete[] uc;
1957
                                }
1958
                                else if ( inputProfFormat == TYPE_GRAY_8 && (reqType == CMYKData) )
1959
                                {
1960
                                        unsigned char  value;
1961
                                        unsigned char* ucs = ptr;
1962
                                        for( int uci = 0; uci < width(); uci++ )
1963
                                        {
1964
                                                value = 255 - *(ucs + 1);
1965
                                                ucs[0] = ucs[1] = ucs[2] = 0;
1966
                                                ucs[3] = value;
1967
                                                ucs += 4;
1968
                                        }
1969
                                }
1970
                                else
1971
                                        cmsDoTransform(xform, ptr, ptr, width());
2004 fschmid 1972
                                // if transforming from CMYK to RGB, flatten the alpha channel
1973
                                // which will still contain the black channel
5345 mrdocs 1974
                                if (isCMYK && reqType != CMYKData && !bilevel)
2004 fschmid 1975
                                {
2633 cbradney 1976
                                        QRgb *p = (QRgb *) ptr;
1977
                                        QRgb alphaFF = qRgba(0,0,0,255);
2004 fschmid 1978
                                        for (int j = 0; j < width(); j++, p++)
2633 cbradney 1979
                                                *p |= alphaFF;
2004 fschmid 1980
                                }
1981
                        }
1982
                        cmsDeleteTransform (xform);
1983
                }
2995 fschmid 1984
                if (inputProf)
2004 fschmid 1985
                        cmsCloseProfile(inputProf);
1986
        }
1987
        else
1988
#endif // HAVE_CMS
1989
        {
3685 fschmid 1990
                switch (reqType)
2004 fschmid 1991
                {
5345 mrdocs 1992
                case CMYKData:
2004 fschmid 1993
                        if (!isCMYK)
1994
                        {
1995
                                for (int i = 0; i < height(); i++)
1996
                                {
2633 cbradney 1997
                                        QRgb *ptr = (QRgb *) scanLine(i);
2866 fschmid 1998
                                        unsigned char cc, cm, cy ,ck;
2004 fschmid 1999
                                        for (int j = 0; j < width(); j++)
2000
                                        {
2866 fschmid 2001
                                                cc = 255 - qRed(*ptr);
2002
                                                cm = 255 - qGreen(*ptr);
2003
                                                cy = 255 - qBlue(*ptr);
2004
                                                ck = QMIN(QMIN(cc, cm), cy);
2005
                                                *ptr++ = qRgba(cc-ck,cm-ck,cy-ck,ck);
2004 fschmid 2006
                                        }
2007
                                }
2008
                        }
2009
                        break;
5345 mrdocs 2010
                case RGBData:
2011
                case RGBProof:
5992 fschmid 2012
                case Thumbnail:
2004 fschmid 2013
                        if (isCMYK)
2014
                        {
2015
                                for (int i = 0; i < height(); i++)
2016
                                {
2633 cbradney 2017
                                        QRgb *ptr = (QRgb *) scanLine(i);
2866 fschmid 2018
                                        unsigned char cr, cg, cb, ck;
2004 fschmid 2019
                                        for (int j = 0; j < width(); j++)
2020
                                        {
2866 fschmid 2021
                                                ck = qAlpha(*ptr);
2022
                                                cr = 255 - QMIN(255, qRed(*ptr) + ck);
2023
                                                cg = 255 - QMIN(255, qGreen(*ptr) + ck);
2024
                                                cb = 255 - QMIN(255, qBlue(*ptr) + ck);
2025
                                                *ptr++ = qRgba(cr,cg,cb,255);
2004 fschmid 2026
                                        }
2027
                                }
2028
                        }
2029
                        break;
5345 mrdocs 2030
                case RawData:
2004 fschmid 2031
                        break;
2032
                }
2033
        }
5345 mrdocs 2034
        if ((reqType == CMYKData || isCMYK) && !bilevel)
2004 fschmid 2035
                setAlphaBuffer(false);
4582 fschmid 2036
/*      setDotsPerMeterX (QMAX(2834, (int) (xres / 0.0254)));
2004 fschmid 2037
        setDotsPerMeterY (QMAX(2834, (int) (yres / 0.0254)));
2015 fschmid 2038
        imgInfo.xres = QMAX(72, qRound(xres));
4582 fschmid 2039
        imgInfo.yres = QMAX(72, qRound(yres)); */
5977 jghali 2040
        if      (ScCore->usingGUI() && pDataLoader->issuedWarningMsg() && showMsg)
2041
        {
2042
                QMessageBox::warning(ScCore->primaryMainWindow(), CommonStrings::trWarning, pDataLoader->getMessage(), 1, 0, 0);
2043
        }
2044
        else if (pDataLoader->issuedErrorMsg())
2045
        {
2046
                QString msg = pDataLoader->getMessage();
2047
                qWarning( msg.local8Bit().data() );
2048
        }
2004 fschmid 2049
        return true;
2050
}