Subversion Repositories Scribus

Rev

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

Rev Author Line No. Line
8 paul 1
/***************************************************************************
2
                          util.cpp  -  description
3
                             -------------------
4
    begin                : Fri Sep 14 2001
5
    copyright            : (C) 2001 by Franz Schmid
6
    email                : Franz.Schmid@altmuehlnet.de
7
 ***************************************************************************/
8
 
9
/***************************************************************************
10
 *                                                                         *
11
 *   This program is free software; you can redistribute it and/or modify  *
12
 *   it under the terms of the GNU General Public License as published by  *
13
 *   the Free Software Foundation; either version 2 of the License, or     *
14
 *   (at your option) any later version.                                   *
15
 *                                                                         *
16
 ***************************************************************************/
9 Franz 17
 
8 paul 18
#include <qstring.h>
19
#include <qpixmap.h>
20
#include <qbitmap.h>
21
#include <qpainter.h>
22
#include <qfile.h>
23
#include <qfileinfo.h>
24
#include <qtextstream.h>
1541 fschmid 25
#include <qdatastream.h>
8 paul 26
#include <qstringlist.h>
27
#include <qmap.h>
28
#include <qdom.h>
29
#include <qimage.h>
19 Franz 30
#include <qdir.h>
8 paul 31
#include <qpointarray.h>
90 Franz 32
#include <qmessagebox.h>
8 paul 33
#include <cstdlib>
34
#include <cmath>
213 Franz 35
#include <unistd.h>
8 paul 36
#include "md5.h"
201 Franz 37
#include <setjmp.h>
204 Franz 38
#include "qprocess.h"
128 Franz 39
 
617 cbradney 40
#ifdef _MSC_VER
41
 #if (_MSC_VER >= 1200)
42
  #include "win-config.h"
43
 #endif
128 Franz 44
#else
45
 #include "config.h"
46
#endif
47
 
1555 fschmid 48
extern "C"
49
{
201 Franz 50
#define XMD_H           // shut JPEGlib up
51
#if defined(Q_OS_UNIXWARE)
52
#  define HAVE_BOOLEAN  // libjpeg under Unixware seems to need this
53
#endif
54
#include <jpeglib.h>
55
#include <jerror.h>
56
#undef HAVE_STDLIB_H
57
#ifdef const
58
#  undef const          // remove crazy C hackery in jconfig.h
59
#endif
60
}
61
 
214 Franz 62
#include "scribus.h"
8 paul 63
#include "libpdf/pdflib.h"
68 Franz 64
#include <ft2build.h>
65
#include FT_FREETYPE_H
66
#include FT_OUTLINE_H
67
#include FT_GLYPH_H
8 paul 68
#ifdef HAVE_LIBZ
69
        #include <zlib.h>
70
#endif
71
#ifdef HAVE_TIFF
72
        #include <tiffio.h>
73
#endif
74
#ifdef HAVE_CMS
44 Franz 75
        #include CMS_INC
1555 fschmid 76
extern cmsHPROFILE CMSoutputProf;
77
extern cmsHPROFILE CMSprinterProf;
78
extern cmsHTRANSFORM stdTrans;
79
extern cmsHTRANSFORM stdProof;
80
extern cmsHTRANSFORM stdTransImg;
81
extern cmsHTRANSFORM stdProofImg;
82
extern bool BlackPoint;
83
extern bool SoftProofing;
84
extern bool Gamut;
85
extern bool CMSuse;
86
extern int IntentMonitor;
87
extern int IntentPrinter;
8 paul 88
#endif
89
extern ProfilesL InputProfiles;
214 Franz 90
extern ScribusApp* ScApp;
8 paul 91
 
690 cbradney 92
using namespace std;
93
 
94
 
95
QColor SetColor(ScribusDoc *currentDoc, QString color, int shad);
1065 cbradney 96
void GetItemProps(bool newVersion, QDomElement *obj, struct CopyPasteBuffer *OB);
456 fschmid 97
QStringList sortQStringList(QStringList aList);
690 cbradney 98
void ReOrderText(ScribusDoc *currentDoc, ScribusView *view);
125 Franz 99
void WordAndPara(PageItem* b, int *w, int *p, int *c, int *wN, int *pN, int *cN);
1065 cbradney 100
void CopyPageItem(struct CopyPasteBuffer *Buffer, PageItem *b);
90 Franz 101
bool overwrite(QWidget *parent, QString filename);
1065 cbradney 102
int setBestEncoding(FT_Face face);
220 Franz 103
FPointArray traceChar(FT_Face face, uint chr, int chs, double *x, double *y, bool &err);
1065 cbradney 104
FPoint getMaxClipF(FPointArray* Clip);
105
FPoint getMinClipF(FPointArray* Clip);
1068 fschmid 106
QPixmap FontSample(QString da, int s, QString ts, QColor back, bool force = false);
418 Franz 107
QPixmap fontSamples(QString da, int s, QString ts, QColor back);
19 Franz 108
QString Path2Relative(QString Path);
690 cbradney 109
QPixmap LoadPDF(QString fn, int Page, int Size, int *w, int *h);
8 paul 110
bool GlyNames(QMap<uint, QString> *GList, QString Dat);
111
bool GlyIndex(QMap<uint, PDFlib::GlNamInd> *GListInd, QString Dat);
112
QByteArray ComputeMD5Sum(QByteArray *in);
113
char *toHex( uchar u );
114
QString String2Hex(QString *in, bool lang = true);
115
QString CompressStr(QString *in);
116
QString ImageToTxt(QImage *im);
117
QString ImageToCMYK(QImage *im);
1476 fschmid 118
QString ImageToGray(QImage *im);
8 paul 119
QString ImageToCMYK_PS(QImage *im, int pl, bool pre);
1488 fschmid 120
QString ImageToCMYK_PDF(QImage *im, bool pre);
1476 fschmid 121
void Convert2JPG(QString fn, QImage *image, int Quality, bool isCMYK, bool isGray);
8 paul 122
QString MaskToTxt(QImage *im, bool PDF = true);
203 Franz 123
QString MaskToTxt14(QImage *im);
690 cbradney 124
void Level2Layer(ScribusDoc *currentDoc, struct Layer *ll, int Level);
8 paul 125
void BezierPoints(QPointArray *ar, QPoint n1, QPoint n2, QPoint n3, QPoint n4);
80 Franz 126
double xy2Deg(double x, double y);
8 paul 127
QPointArray FlattenPath(FPointArray ina, QValueList<uint> &Segs);
80 Franz 128
QPointArray RegularPolygon(double w, double h, uint c, bool star, double factor, double rota);
129
FPointArray RegularPolygonF(double w, double h, uint c, bool star, double factor, double rota);
8 paul 130
QPixmap loadIcon(QString nam);
1109 fschmid 131
uint getDouble(QString in, bool raw);
8 paul 132
bool loadText(QString nam, QString *Buffer);
690 cbradney 133
double Cwidth(ScribusDoc *currentDoc, QString name, QString ch, int Siz, QString ch2 = " ");
134
double RealCWidth(ScribusDoc *currentDoc, QString name, QString ch, int Siz);
80 Franz 135
double QStodouble(QString in);
8 paul 136
int QStoInt(QString in);
137
QString GetAttr(QDomElement *el, QString at, QString def="0");
138
#ifdef HAVE_CMS
1555 fschmid 139
QImage ProofPict(QImage *Im, QString Prof, int Rend, cmsHPROFILE emPr=0);
8 paul 140
#else
1555 fschmid 141
QImage ProofPict(QImage *Im, QString Prof, int Rend);
8 paul 142
#endif
143
QImage ProofImage(QImage *Im);
1555 fschmid 144
QImage LoadPicture(QString fn, QString Prof, int rend, bool useEmbedded, bool useProf, int requestType, int gsRes, bool *realCMYK = 0, ImageInfoRecord *info = 0);
1505 fschmid 145
QString getAlpha(QString fn, bool PDF, bool pdf14);
204 Franz 146
int System(const QStringList & args);
147
int callGS(const QStringList & args_in);
148
int copyFile(QString source, QString target);
149
int moveFile(QString source, QString target);
8 paul 150
 
1492 fschmid 151
typedef struct my_error_mgr
152
{
1555 fschmid 153
        struct jpeg_error_mgr pub;            /* "public" fields */
154
        jmp_buf setjmp_buffer;  /* for return to caller */
155
}
156
*my_error_ptr;
1492 fschmid 157
 
158
/*
159
 * Here's the routine that will replace the standard error_exit method:
160
 */
161
 
162
static void my_error_exit (j_common_ptr cinfo)
163
{
1555 fschmid 164
        my_error_ptr myerr = (my_error_ptr) cinfo->err;
165
        (*cinfo->err->output_message) (cinfo);
166
        longjmp (myerr->setjmp_buffer, 1);
1492 fschmid 167
}
168
 
169
void Convert2JPG(QString fn, QImage *image, int Quality, bool isCMYK, bool isGray)
170
{
171
        struct jpeg_compress_struct cinfo;
172
        struct my_error_mgr         jerr;
173
        FILE     *outfile;
174
        JSAMPROW row_pointer[1];
175
        row_pointer[0] = 0;
176
        cinfo.err = jpeg_std_error (&jerr.pub);
177
        jerr.pub.error_exit = my_error_exit;
178
        outfile = NULL;
179
        if (setjmp (jerr.setjmp_buffer))
180
        {
181
                jpeg_destroy_compress (&cinfo);
182
                if (outfile)
183
                        fclose (outfile);
184
                return;
185
        }
186
        jpeg_create_compress (&cinfo);
187
        if ((outfile = fopen (fn, "wb")) == NULL)
188
                return;
189
        jpeg_stdio_dest (&cinfo, outfile);
190
        cinfo.image_width  = image->width();
191
        cinfo.image_height = image->height();
192
        if (isCMYK)
193
        {
194
                cinfo.in_color_space = JCS_CMYK;
195
                cinfo.input_components = 4;
196
        }
197
        else
198
        {
199
                if (isGray)
200
                {
201
                        cinfo.in_color_space = JCS_GRAYSCALE;
202
                        cinfo.input_components = 1;
203
                }
204
                else
205
                {
206
                        cinfo.in_color_space = JCS_RGB;
207
                        cinfo.input_components = 3;
208
                }
209
        }
210
        jpeg_set_defaults (&cinfo);
211
        int qual[] = { 95, 85, 75, 50, 25 };  // These are the JPEG Quality settings 100 means best, 0 .. don't discuss
212
        jpeg_set_quality (&cinfo, qual[Quality], true);
213
        jpeg_start_compress (&cinfo, TRUE);
214
        row_pointer[0] = new uchar[cinfo.image_width*cinfo.input_components];
215
        int w = cinfo.image_width;
216
        while (cinfo.next_scanline < cinfo.image_height)
217
        {
218
                uchar *row = row_pointer[0];
219
                if (isCMYK)
220
                {
221
                        QRgb* rgba = (QRgb*)image->scanLine(cinfo.next_scanline);
222
                        for (int i=0; i<w; ++i)
223
                        {
1555 fschmid 224
                                *row++ = qAlpha(*rgba);
225
                                *row++ = qRed(*rgba);
226
                                *row++ = qGreen(*rgba);
227
                                *row++ = qBlue(*rgba);
228
                                ++rgba;
1492 fschmid 229
                        }
230
                }
231
                else
232
                {
233
                        if (isGray)
234
                        {
235
                                QRgb* rgba = (QRgb*)image->scanLine(cinfo.next_scanline);
236
                                for (int i=0; i<w; ++i)
237
                                {
238
                                        *row++ = qRed(*rgba);
239
                                        ++rgba;
240
                                }
241
                        }
242
                        else
243
                        {
244
                                QRgb* rgb = (QRgb*)image->scanLine(cinfo.next_scanline);
245
                                for (int i=0; i<w; i++)
246
                                {
247
                                        *row++ = qRed(*rgb);
248
                                        *row++ = qGreen(*rgb);
249
                                        *row++ = qBlue(*rgb);
250
                                        ++rgb;
251
                                }
252
                        }
253
                }
254
                jpeg_write_scanlines (&cinfo, row_pointer, 1);
255
        }
256
        jpeg_finish_compress (&cinfo);
257
        fclose (outfile);
258
        jpeg_destroy_compress (&cinfo);
259
        delete [] row_pointer[0];
260
}
261
 
1541 fschmid 262
enum PSDColorMode
263
{
1555 fschmid 264
    CM_BITMAP = 0,
265
    CM_GRAYSCALE = 1,
266
    CM_INDEXED = 2,
267
    CM_RGB = 3,
268
    CM_CMYK = 4,
269
    CM_MULTICHANNEL = 7,
270
    CM_DUOTONE = 8,
271
    CM_LABCOLOR = 9
1541 fschmid 272
};
273
 
1555 fschmid 274
struct PSDHeader
1541 fschmid 275
{
276
        uint signature;
277
        ushort version;
278
        uchar reserved[6];
279
        ushort channel_count;
280
        uint height;
281
        uint width;
282
        ushort depth;
283
        ushort color_mode;
284
};
285
 
286
static QDataStream & operator>> ( QDataStream & s, PSDHeader & header )
287
{
288
        s >> header.signature;
289
        s >> header.version;
290
        for( int i = 0; i < 6; i++ )
291
        {
292
                s >> header.reserved[i];
293
        }
294
        s >> header.channel_count;
295
        s >> header.height;
296
        s >> header.width;
297
        s >> header.depth;
298
        s >> header.color_mode;
299
        return s;
300
}
301
 
302
// Check that the header is a valid PSD.
303
static bool IsValid( const PSDHeader & header )
304
{
305
        if( header.signature != 0x38425053 )
306
                return false;
307
        return true;
308
}
309
 
310
// Check that the header is supported.
311
static bool IsSupported( const PSDHeader & header )
312
{
1551 fschmid 313
        if ( header.version != 1 )
1541 fschmid 314
                return false;
1551 fschmid 315
        if ( header.channel_count > 16 )
1541 fschmid 316
                return false;
1551 fschmid 317
        if ( header.depth != 8 )
1541 fschmid 318
                return false;
1551 fschmid 319
        if (( header.color_mode == CM_RGB ) || (header.color_mode == CM_CMYK))
320
                return true;
321
        return false;
1541 fschmid 322
}
323
 
1553 fschmid 324
static unsigned char INT_MULT ( unsigned char a, unsigned char b )
325
{
1555 fschmid 326
        int c = a * b + 0x80;
327
        return (unsigned char)(( ( c >> 8 ) + c ) >> 8);
1553 fschmid 328
}
329
 
1555 fschmid 330
/*!
331
 * Convert a color in RGB space to HSV space (Hue, Saturation, Value).
332
 * \param red the red component (modified in place).
333
 * \param green the green component (modified in place).
334
 * \param blue the blue component (modified in place).
335
 */
336
static void RGBTOHSV ( uchar& red, uchar& green, uchar& blue )
337
{
338
        int r, g, b;
339
        double h, s, v;
340
        int min, max;
341
        h = 0.;
342
        r = red;
343
        g = green;
344
        b = blue;
345
        if ( r > g )
346
        {
347
                max = QMAX( r, b );
348
                min = QMIN( g, b );
349
        }
350
        else
351
        {
352
                max = QMAX( g, b );
353
                min = QMIN( r, b );
354
        }
355
        v = max;
356
        if ( max != 0 )
357
                s = ( ( max - min ) * 255 ) / (double)max;
358
        else
359
                s = 0;
360
        if ( s == 0 )
361
                h = 0;
362
        else
363
        {
364
                int delta = max - min;
365
                if ( r == max )
366
                        h = ( g - b ) / (double)delta;
367
                else if ( g == max )
368
                        h = 2 + ( b - r ) / (double)delta;
369
                else if ( b == max )
370
                        h = 4 + ( r - g ) / (double)delta;
371
                h *= 42.5;
372
                if ( h < 0 )
373
                        h += 255;
374
                if ( h > 255 )
375
                        h -= 255;
376
        }
377
        red   = (uchar)h;
378
        green = (uchar)s;
379
        blue  = (uchar)v;
380
}
381
 
382
/*!
383
 * Convert a color in HSV space to RGB space.
384
 * \param hue the hue component (modified in place).
385
 * \param saturation the saturation component (modified in place).
386
 * \param value the value component (modified in place).
387
 */
388
static void HSVTORGB ( uchar& hue, uchar& saturation, uchar& value )
389
{
390
        if ( saturation == 0 )
391
        {
392
                hue        = value;
393
                saturation = value;
394
                value      = value;
395
        }
396
        else
397
        {
398
                double h = hue * 6. / 255.;
399
                double s = saturation / 255.;
400
                double v = value / 255.;
401
 
402
                double f = h - (int)h;
403
                double p = v * ( 1. - s );
404
                double q = v * ( 1. - ( s * f ) );
405
                double t = v * ( 1. - ( s * ( 1. - f ) ) );
406
                // Worth a note here that gcc 2.96 will generate different results
407
                // depending on optimization mode on i386.
408
                switch ((int)h)
409
                {
410
                case 0:
411
                        hue        = (uchar)( v * 255 );
412
                        saturation = (uchar)( t * 255 );
413
                        value      = (uchar)( p * 255 );
414
                        break;
415
                case 1:
416
                        hue        = (uchar)( q * 255 );
417
                        saturation = (uchar)( v * 255 );
418
                        value      = (uchar)( p * 255 );
419
                        break;
420
                case 2:
421
                        hue        = (uchar)( p * 255 );
422
                        saturation = (uchar)( v * 255 );
423
                        value      = (uchar)( t * 255 );
424
                        break;
425
                case 3:
426
                        hue        = (uchar)( p * 255 );
427
                        saturation = (uchar)( q * 255 );
428
                        value      = (uchar)( v * 255 );
429
                        break;
430
                case 4:
431
                        hue        = (uchar)( t * 255 );
432
                        saturation = (uchar)( p * 255 );
433
                        value      = (uchar)( v * 255 );
434
                        break;
435
                case 5:
436
                        hue        = (uchar)( v * 255 );
437
                        saturation = (uchar)( p * 255 );
438
                        value      = (uchar)( q * 255 );
439
                }
440
        }
441
}
442
 
443
/*!
444
 * Convert a color in RGB space to HLS space (Hue, Lightness, Saturation).
445
 * \param red the red component (modified in place).
446
 * \param green the green component (modified in place).
447
 * \param blue the blue component (modified in place).
448
 */
449
static void RGBTOHLS ( uchar& red, uchar& green, uchar& blue )
450
{
451
        int r = red;
452
        int g = green;
453
        int b = blue;
454
        int min, max;
455
        if ( r > g )
456
        {
457
                max = QMAX( r, b );
458
                min = QMIN( g, b );
459
        }
460
        else
461
        {
462
                max = QMAX( g, b );
463
                min = QMIN( r, b );
464
        }
465
        double h;
466
        double l = ( max + min ) / 2.;
467
        double s;
468
        if ( max == min )
469
        {
470
                s = 0.;
471
                h = 0.;
472
        }
473
        else
474
        {
475
                int delta = max - min;
476
                if ( l < 128 )
477
                        s = 255 * (double)delta / (double)( max + min );
478
                else
479
                        s = 255 * (double)delta / (double)( 511 - max - min );
480
                if ( r == max )
481
                        h = ( g - b ) / (double)delta;
482
                else if ( g == max )
483
                        h = 2 + ( b - r ) / (double)delta;
484
                else
485
                        h = 4 + ( r - g ) / (double)delta;
486
                h *= 42.5;
487
                if ( h < 0 )
488
                        h += 255;
489
                else if ( h > 255 )
490
                        h -= 255;
491
        }
492
        red   = (uchar)h;
493
        green = (uchar)l;
494
        blue  = (uchar)s;
495
}
496
 
497
/*!
498
 * Implement the HLS "double hex-cone".
499
 * \param n1 lightness fraction (?)
500
 * \param n2 saturation fraction (?)
501
 * \param hue hue "angle".
502
 * \return HLS value.
503
 */
504
static int HLSVALUE ( double n1, double n2, double hue )
505
{
506
        double value;
507
        if ( hue > 255 )
508
                hue -= 255;
509
        else if ( hue < 0 )
510
                hue += 255;
511
        if ( hue < 42.5 )
512
                value = n1 + ( n2 - n1 ) * ( hue / 42.5 );
513
        else if ( hue < 127.5 )
514
                value = n2;
515
        else if ( hue < 170 )
516
                value = n1 + ( n2 - n1 ) * ( ( 170 - hue ) / 42.5 );
517
        else
518
                value = n1;
519
        return (int)( value * 255 );
520
}
521
 
522
/*!
523
 * Convert a color in HLS space to RGB space.
524
 * \param hue the hue component (modified in place).
525
 * \param lightness the lightness component (modified in place).
526
 * \param saturation the saturation component (modified in place).
527
 */
528
static void HLSTORGB ( uchar& hue, uchar& lightness, uchar& saturation )
529
{
530
        double h = hue;
531
        double l = lightness;
532
        double s = saturation;
533
        if ( s == 0 )
534
        {
535
                hue        = (uchar)l;
536
                lightness  = (uchar)l;
537
                saturation = (uchar)l;
538
        }
539
        else
540
        {
541
                double m1, m2;
542
                if ( l < 128 )
543
                        m2 = ( l * ( 255 + s ) ) / 65025.;
544
                else
545
                        m2 = ( l + s - ( l * s ) / 255. ) / 255.;
546
                m1 = ( l / 127.5 ) - m2;
547
                hue        = HLSVALUE( m1, m2, h + 85 );
548
                lightness  = HLSVALUE( m1, m2, h );
549
                saturation = HLSVALUE( m1, m2, h - 85 );
550
        }
551
}
552
 
1633 fschmid 553
static bool loadLayerChannels( QDataStream & s, const PSDHeader & header, QImage & img, QValueList<PSDLayer> &layerInfo, uint layer, bool* firstLayer )
1541 fschmid 554
{
555
        // Find out if the data is compressed.
556
        // Known values:
557
        //   0: no compression
558
        //   1: RLE compressed
1553 fschmid 559
        QImage tmpImg;
560
        if( !tmpImg.create( header.width, header.height, 32 ))
561
                return false;
562
        tmpImg.setAlphaBuffer( true );
563
        tmpImg.fill(qRgba(0, 0, 0, 0));
1541 fschmid 564
        uint base = s.device()->at();
1551 fschmid 565
        uchar cbyte;
1541 fschmid 566
        ushort compression;
567
        s >> compression;
568
        if( compression > 1 )
569
                return false;
570
        uint channel_num = layerInfo[layer].channelLen.count();
1551 fschmid 571
        channel_num = QMIN(channel_num, 39);
572
        uint components[40];
1541 fschmid 573
        for(uint channel = 0; channel < channel_num; channel++)
574
        {
575
                switch(layerInfo[layer].channelType[channel])
576
                {
1555 fschmid 577
                case 0:
578
                        components[channel] = 2;
579
                        break;
580
                case 1:
581
                        components[channel] = 1;
582
                        break;
583
                case 2:
584
                        components[channel] = 0;
585
                        break;
586
                case 3:
587
                        components[channel] = 3;
588
                        break;
589
                case -1:
590
                case -2:
591
                        components[channel] = 3;
592
                        break;
1541 fschmid 593
                }
594
        }
595
        if( compression )
596
        {
597
                // Skip row lengths.
1551 fschmid 598
                s.device()->at( s.device()->at() + layerInfo[layer].height * 2 );
599
                // Read RLE data
600
                bool first = true;
1541 fschmid 601
                for(uint channel = 0; channel < channel_num; channel++)
602
                {
1551 fschmid 603
                        if ((layerInfo[layer].channelType[channel] < 0) && (header.color_mode == CM_CMYK))
1541 fschmid 604
                        {
1551 fschmid 605
                                first = false;
606
                                continue;
607
                        }
608
                        if (!first)
609
                        {
1541 fschmid 610
                                s.device()->at(layerInfo[layer].channelLen[channel-1]+base);
611
                                base += layerInfo[layer].channelLen[channel-1];
612
                                s >> compression;
1551 fschmid 613
                                s.device()->at( s.device()->at() + layerInfo[layer].height * 2 );
1541 fschmid 614
                        }
1551 fschmid 615
                        first = false;
616
                        uint pixel_count = layerInfo[layer].width;
1569 fschmid 617
                        for (int hh = 0; hh < layerInfo[layer].height; hh++)
1541 fschmid 618
                        {
1551 fschmid 619
                                uint count = 0;
1569 fschmid 620
                                uchar *ptr = tmpImg.scanLine(QMIN(QMAX(layerInfo[layer].ypos, 0)+hh, static_cast<int>(tmpImg.height()-1)));
621
                                uchar *ptr2 = ptr+tmpImg.width() * 4;
622
                                ptr += QMAX(layerInfo[layer].xpos, 0) * 4;
1551 fschmid 623
                                ptr += components[channel];
624
                                while( count < pixel_count )
1541 fschmid 625
                                {
1551 fschmid 626
                                        uchar c;
627
                                        s >> c;
628
                                        uint len = c;
629
                                        if( len < 128 )
1541 fschmid 630
                                        {
1551 fschmid 631
                                                // Copy next len+1 bytes literally.
632
                                                len++;
633
                                                count += len;
634
                                                while( len != 0 )
635
                                                {
636
                                                        s >> cbyte;
637
                                                        if (ptr < ptr2)
638
                                                        {
639
                                                                if (header.color_mode == CM_CMYK)
1553 fschmid 640
                                                                        cbyte = 255 - cbyte;
641
                                                                *ptr = cbyte;
1551 fschmid 642
                                                        }
643
                                                        ptr += 4;
644
                                                        len--;
645
                                                }
1555 fschmid 646
                                        }
1551 fschmid 647
                                        else if( len > 128 )
648
                                        {
649
                                                // Next -len+1 bytes in the dest are replicated from next source byte.
650
                                                // (Interpret len as a negative 8-bit int.)
651
                                                len ^= 0xFF;
652
                                                len += 2;
653
                                                count += len;
654
                                                uchar val;
655
                                                s >> val;
656
                                                if (header.color_mode == CM_CMYK)
657
                                                        val = 255 - val;
658
                                                while( len != 0 )
659
                                                {
660
                                                        if (ptr < ptr2)
661
                                                                *ptr = val;
662
                                                        ptr += 4;
663
                                                        len--;
664
                                                }
1541 fschmid 665
                                        }
1551 fschmid 666
                                        else if( len == 128 )
1541 fschmid 667
                                        {
1551 fschmid 668
                                                // No-op.
1541 fschmid 669
                                        }
670
                                }
671
                        }
672
                }
673
        }
674
        else
675
        {
676
                // We're at the raw image data.  It's each channel in order (Red, Green, Blue, Alpha, ...)
677
                // where each channel consists of an 8-bit value for each pixel in the image.
678
                // Read the data by channel.
1633 fschmid 679
                int count = 0;
1541 fschmid 680
                for(uint channel = 0; channel < channel_num; channel++)
681
                {
1633 fschmid 682
                        count += layerInfo[layer].channelLen[channel];
683
                }
684
                uchar * ptr = tmpImg.bits();
685
                if (channel_num < 4)
686
                        tmpImg.fill(qRgba(0, 0, 0, 255));
687
                while( count >= 0 )
688
                {
689
                        for(uint channel = 0; channel < channel_num; channel++)
1541 fschmid 690
                        {
1633 fschmid 691
                                s >> cbyte;
692
                                count--;
693
                                if (header.color_mode == CM_CMYK)
694
                                        cbyte = 255 - cbyte;
695
                                if (channel < 4)
696
                                        ptr[components[channel]] = cbyte;
1551 fschmid 697
                        }
1633 fschmid 698
                        ptr += 4;
699
                }
700
        }
701
        QImage tmpImg2 = tmpImg.copy();
702
        if (header.color_mode == CM_CMYK)
703
        {
704
                for (int i = 0; i < tmpImg.height(); i++)
705
                {
706
                        unsigned int *ptr = (unsigned int *) tmpImg.scanLine(i);
707
                        unsigned int *ptr2 = (unsigned int *) tmpImg2.scanLine(i);
708
                        unsigned char r, g, b;
709
                        for (int j = 0; j < tmpImg.width(); j++)
1551 fschmid 710
                        {
1633 fschmid 711
                                unsigned char *p = (unsigned char *) ptr;
712
                                unsigned char *p2 = (unsigned char *) ptr2;
713
                                r = 255 - QMIN(255, p[0] + p[3]);
714
                                g = 255 - QMIN(255, p[1] + p[3]);
715
                                b = 255 - QMIN(255, p[2] + p[3]);
716
                                p2[0] = r;
717
                                p2[1] = g;
718
                                p2[2] = b;
719
                                p2[3] = 255;
720
                                ptr++;
721
                                ptr2++;
1541 fschmid 722
                        }
723
                }
724
        }
1633 fschmid 725
        QImage imt;
726
        double sx = tmpImg.width() / 40.0;
727
        double sy = tmpImg.height() / 40.0;
728
        imt = sy < sx ?  tmpImg2.smoothScale(qRound(tmpImg.width() / sx), qRound(tmpImg.height() / sx)) :
729
                                                        tmpImg2.smoothScale(qRound(tmpImg.width() / sy), qRound(tmpImg.height() / sy));
730
        layerInfo[layer].thumb = imt.copy();
1553 fschmid 731
        if (!(layerInfo[layer].flags & 2))
732
        {
1633 fschmid 733
                if (*firstLayer)
734
                {
1553 fschmid 735
                        img = tmpImg.copy();
1633 fschmid 736
                        *firstLayer = false;
737
                }
1553 fschmid 738
                else
739
                {
1569 fschmid 740
                        for (int i = 0; i < layerInfo[layer].height; i++)
1553 fschmid 741
                        {
1633 fschmid 742
                                unsigned int *dst = (unsigned int *)img.scanLine(QMIN(QMAX(layerInfo[layer].ypos, 0)+i, img.height()-1));
743
                                unsigned int *src = (unsigned int *)tmpImg.scanLine(QMIN(QMAX(layerInfo[layer].ypos, 0)+i, tmpImg.height()-1));
1569 fschmid 744
                                dst += QMAX(layerInfo[layer].xpos, 0);
745
                                src += QMAX(layerInfo[layer].xpos, 0);
746
                                unsigned int adj = 0;
747
                                if (layerInfo[layer].xpos < 0)
748
                                        adj = abs(layerInfo[layer].xpos);
1553 fschmid 749
                                unsigned char r, g, b, a, src_r, src_g, src_b, src_a;
1569 fschmid 750
                                for (unsigned int j = 0; j < layerInfo[layer].width-adj; j++)
1553 fschmid 751
                                {
752
                                        unsigned char *d = (unsigned char *) dst;
753
                                        unsigned char *s = (unsigned char *) src;
754
                                        src_r = s[0];
755
                                        src_g = s[1];
756
                                        src_b = s[2];
757
                                        src_a = s[3];
758
                                        if (layerInfo[layer].blend == "mul ")
759
                                        {
760
                                                src_r = INT_MULT(src_r, d[0]);
761
                                                src_g = INT_MULT(src_g, d[1]);
762
                                                src_b = INT_MULT(src_b, d[2]);
763
                                                if (header.color_mode == CM_CMYK)
764
                                                        src_a = INT_MULT(src_a, d[3]);
765
                                                else
766
                                                        src_a = QMIN(src_a, d[3]);
767
                                        }
768
                                        else if (layerInfo[layer].blend == "scrn")
769
                                        {
770
                                                src_r = 255 - INT_MULT(255 - d[0], 255 - src_r);
771
                                                src_g = 255 - INT_MULT(255 - d[1], 255 - src_g);
772
                                                src_b = 255 - INT_MULT(255 - d[2], 255 - src_b);
773
                                                if (header.color_mode == CM_CMYK)
774
                                                        src_a = 255 - INT_MULT(255 - d[3], 255 - src_a);
775
                                                else
776
                                                        src_a = QMIN(src_a, d[3]);
777
                                        }
778
                                        else if (layerInfo[layer].blend == "over")
779
                                        {
780
                                                src_r = INT_MULT(d[0], d[0] + INT_MULT(2 * src_r, 255 - d[0]));
781
                                                src_g = INT_MULT(d[1], d[1] + INT_MULT(2 * src_g, 255 - d[1]));
782
                                                src_b = INT_MULT(d[2], d[2] + INT_MULT(2 * src_b, 255 - d[2]));
783
                                                if (header.color_mode == CM_CMYK)
784
                                                        src_a = INT_MULT(d[3], d[3] + INT_MULT(2 * src_a, 255 - d[3]));
785
                                                else
786
                                                        src_a = QMIN(src_a, d[3]);
787
                                        }
788
                                        else if (layerInfo[layer].blend == "diff")
789
                                        {
790
                                                src_r = d[0] > src_r ? d[0] - src_r : src_r - d[0];
791
                                                src_g = d[1] > src_g ? d[1] - src_g : src_g - d[1];
792
                                                src_b = d[2] > src_b ? d[2] - src_b : src_b - d[2];
793
                                                if (header.color_mode == CM_CMYK)
794
                                                        src_a = d[3] > src_a ? d[3] - src_a : src_a - d[3];
795
                                                else
796
                                                        src_a = QMIN(src_a, d[3]);
797
                                        }
798
                                        else if (layerInfo[layer].blend == "dark")
799
                                        {
800
                                                src_r = d[0]  < src_r ? d[0]  : src_r;
801
                                                src_g = d[1] < src_g ? d[1] : src_g;
802
                                                src_b = d[2] < src_b ? d[2] : src_b;
803
                                                if (header.color_mode == CM_CMYK)
804
                                                        src_a = d[3] < src_a ? d[3] : src_a;
805
                                                else
806
                                                        src_a = QMIN( src_a, d[3] );
807
                                        }
808
                                        else if (layerInfo[layer].blend == "lite")
809
                                        {
810
                                                src_r = d[0] < src_r ? src_r : d[0];
811
                                                src_g = d[1] < src_g ? src_g : d[1];
812
                                                src_b = d[2] < src_b ? src_b : d[2];
813
                                                if (header.color_mode == CM_CMYK)
814
                                                        src_a = d[3] < src_a ? src_a : d[3];
815
                                                else
816
                                                        src_a = QMIN( src_a, d[3] );
817
                                        }
1555 fschmid 818
                                        else if (layerInfo[layer].blend == "hue ")
819
                                        {
820
                                                if (header.color_mode != CM_CMYK)
821
                                                {
822
                                                        uchar new_r = d[0];
823
                                                        uchar new_g = d[1];
824
                                                        uchar new_b = d[2];
825
                                                        RGBTOHSV(src_r, src_g, src_b);
826
                                                        RGBTOHSV(new_r, new_g, new_b);
827
                                                        new_r = src_r;
828
                                                        HSVTORGB(new_r, new_g, new_b);
829
                                                        src_r = new_r;
830
                                                        src_g = new_g;
831
                                                        src_b = new_b;
832
                                                        src_a = QMIN( src_a, d[3] );
833
                                                }
834
                                        }
835
                                        else if (layerInfo[layer].blend == "sat ")
836
                                        {
837
                                                if (header.color_mode != CM_CMYK)
838
                                                {
839
                                                        uchar new_r = d[0];
840
                                                        uchar new_g = d[1];
841
                                                        uchar new_b = d[2];
842
                                                        RGBTOHSV(src_r, src_g, src_b);
843
                                                        RGBTOHSV(new_r, new_g, new_b);
844
                                                        new_g = src_g;
845
                                                        HSVTORGB(new_r, new_g, new_b);
846
                                                        src_r = new_r;
847
                                                        src_g = new_g;
848
                                                        src_b = new_b;
849
                                                        src_a = QMIN(src_a, d[3]);
850
                                                }
851
                                        }
852
                                        else if (layerInfo[layer].blend == "lum ")
853
                                        {
854
                                                if (header.color_mode != CM_CMYK)
855
                                                {
856
                                                        uchar new_r = d[0];
857
                                                        uchar new_g = d[1];
858
                                                        uchar new_b = d[2];
859
                                                        RGBTOHSV(src_r, src_g, src_b);
860
                                                        RGBTOHSV(new_r, new_g, new_b);
861
                                                        new_b = src_b;
862
                                                        HSVTORGB(new_r, new_g, new_b);
863
                                                        src_r = new_r;
864
                                                        src_g = new_g;
865
                                                        src_b = new_b;
866
                                                        src_a = QMIN(src_a, d[3]);
867
                                                }
868
                                        }
869
                                        else if (layerInfo[layer].blend == "colr")
870
                                        {
871
                                                if (header.color_mode != CM_CMYK)
872
                                                {
873
                                                        uchar new_r = d[0];
874
                                                        uchar new_g = d[1];
875
                                                        uchar new_b = d[2];
876
                                                        RGBTOHLS(src_r, src_g, src_b);
877
                                                        RGBTOHLS(new_r, new_g, new_b);
878
                                                        new_r = src_r;
879
                                                        new_b = src_b;
880
                                                        HLSTORGB(new_r, new_g, new_b);
881
                                                        src_r = new_r;
882
                                                        src_g = new_g;
883
                                                        src_b = new_b;
884
                                                        src_a = QMIN(src_a, d[3]);
885
                                                }
886
                                        }
1553 fschmid 887
                                        r = (d[0] * (255 - layerInfo[layer].opacity) + src_r * layerInfo[layer].opacity) / 255;
888
                                        g = (d[1] * (255 - layerInfo[layer].opacity) + src_g * layerInfo[layer].opacity) / 255;
889
                                        b = (d[2] * (255 - layerInfo[layer].opacity) + src_b * layerInfo[layer].opacity) / 255;
890
                                        a = (d[3] * (255 - layerInfo[layer].opacity) + src_a * layerInfo[layer].opacity) / 255;
891
                                        if (header.color_mode == CM_CMYK)
892
                                        {
893
                                                d[0] = r;
894
                                                d[1] = g;
895
                                                d[2] = b;
896
                                                d[3] = a;
897
                                        }
898
                                        else
899
                                        {
900
                                                if (s[3] > 0)
901
                                                {
902
                                                        d[0] = r;
903
                                                        d[1] = g;
904
                                                        d[2] = b;
905
                                                }
906
                                        }
907
                                        dst++;
908
                                        src++;
909
                                }
910
                        }
911
                }
912
        }
1541 fschmid 913
        return true;
914
}
915
 
916
static bool loadLayer( QDataStream & s, const PSDHeader & header, QImage & img )
917
{
918
        // Find out if the data is compressed.
919
        // Known values:
920
        //   0: no compression
921
        //   1: RLE compressed
922
        ushort compression;
1551 fschmid 923
        uchar cbyte;
1541 fschmid 924
        s >> compression;
925
        if( compression > 1 )
926
        {
927
                // Unknown compression type.
928
                return false;
929
        }
930
        uint channel_num = header.channel_count;
931
        // Clear the image.
1555 fschmid 932
        /*      if( channel_num < 4 )
933
                {
934
                        img.fill(qRgba(0, 0, 0, 0xFF));
935
                }
936
                else
937
                { */
938
        // Enable alpha.
939
        //              img.setAlphaBuffer( true );
940
        // Ignore the other channels.
941
        channel_num = 4;
942
        //      }
1541 fschmid 943
        const uint pixel_count = header.height * header.width;
1555 fschmid 944
        static const uint components[4] = {2, 1, 0, 3}
945
                                          ; // @@ Is this endian dependant?
1541 fschmid 946
        if( compression )
947
        {
948
                // Skip row lengths.
949
                ushort w;
950
                for(uint i = 0; i < header.height * header.channel_count; i++)
951
                {
952
                        s >> w;
1555 fschmid 953
                }
954
                // Read RLE data.
1541 fschmid 955
                for(uint channel = 0; channel < channel_num; channel++)
956
                {
957
                        uchar * ptr = img.bits() + components[channel];
958
                        uint count = 0;
959
                        while( count < pixel_count )
960
                        {
961
                                uchar c;
962
                                s >> c;
963
                                uint len = c;
964
                                if( len < 128 )
965
                                {
966
                                        // Copy next len+1 bytes literally.
967
                                        len++;
968
                                        count += len;
969
                                        while( len != 0 )
970
                                        {
1551 fschmid 971
                                                if (header.color_mode == CM_CMYK)
972
                                                {
973
                                                        s >> cbyte;
974
                                                        *ptr = 255 - cbyte;
975
                                                }
976
                                                else
977
                                                        s >> *ptr;
1541 fschmid 978
                                                ptr += 4;
979
                                                len--;
980
                                        }
1555 fschmid 981
                                }
1541 fschmid 982
                                else if( len > 128 )
983
                                {
984
                                        // Next -len+1 bytes in the dest are replicated from next source byte.
985
                                        // (Interpret len as a negative 8-bit int.)
986
                                        len ^= 0xFF;
987
                                        len += 2;
988
                                        count += len;
989
                                        uchar val;
990
                                        s >> val;
1551 fschmid 991
                                        if (header.color_mode == CM_CMYK)
992
                                                val = 255 - val;
1541 fschmid 993
                                        while( len != 0 )
994
                                        {
995
                                                *ptr = val;
996
                                                ptr += 4;
997
                                                len--;
998
                                        }
999
                                }
1000
                                else if( len == 128 )
1001
                                {
1002
                                        // No-op.
1003
                                }
1004
                        }
1005
                }
1006
        }
1007
        else
1008
        {
1009
                // We're at the raw image data.  It's each channel in order (Red, Green, Blue, Alpha, ...)
1010
                // where each channel consists of an 8-bit value for each pixel in the image.
1011
                // Read the data by channel.
1012
                for(uint channel = 0; channel < channel_num; channel++)
1013
                {
1014
                        uchar * ptr = img.bits() + components[channel];
1015
                        // Read the data.
1016
                        uint count = pixel_count;
1017
                        while( count != 0 )
1018
                        {
1551 fschmid 1019
                                if (header.color_mode == CM_CMYK)
1020
                                {
1021
                                        s >> cbyte;
1022
                                        *ptr = 255 - cbyte;
1023
                                }
1024
                                else
1025
                                        s >> *ptr;
1541 fschmid 1026
                                ptr += 4;
1027
                                count--;
1028
                        }
1029
                }
1030
        }
1031
        return true;
1032
}
1033
 
1551 fschmid 1034
static QString getLayerString(QDataStream & s)
1035
{
1036
        uchar len, tmp;
1037
        uint adj;
1038
        QString ret = "";
1039
        s >> len;
1040
        if (len == 0)
1041
        {
1042
                s >> tmp;
1569 fschmid 1043
                s >> tmp;
1044
                s >> tmp;
1551 fschmid 1045
                return ret;
1046
        }
1047
        for( int i = 0; i < len; i++ )
1048
        {
1049
                s >> tmp;
1050
                ret += QChar(tmp);
1051
        }
1569 fschmid 1052
        adj = 0;
1053
        if (((ret.length()+1) % 4) != 0)
1054
                adj = 4 - ((ret.length()+1) % 4);
1551 fschmid 1055
        s.device()->at( s.device()->at() + adj );
1056
        return ret;
1057
}
1058
 
1541 fschmid 1059
static QString getPascalString(QDataStream & s)
1060
{
1061
        uchar len, tmp;
1551 fschmid 1062
        uint adj;
1541 fschmid 1063
        QString ret = "";
1064
        s >> len;
1065
        if (len == 0)
1551 fschmid 1066
        {
1067
                s >> tmp;
1541 fschmid 1068
                return ret;
1551 fschmid 1069
        }
1541 fschmid 1070
        for( int i = 0; i < len; i++ )
1071
        {
1072
                s >> tmp;
1073
                ret += QChar(tmp);
1074
        }
1569 fschmid 1075
        adj = (ret.length()+1) % 2;
1551 fschmid 1076
        s.device()->at( s.device()->at() + adj );
1541 fschmid 1077
        return ret;
1078
}
1079
 
1633 fschmid 1080
static void parseRessourceData( QDataStream & s, const PSDHeader & header, uint size, ImageInfoRecord *info )
1541 fschmid 1081
{
1551 fschmid 1082
        uint signature, resSize, offset, resBase, vRes, hRes, adj;
1541 fschmid 1083
        ushort resID, hResUnit, vResUnit, dummyW;
1624 fschmid 1084
        QString resName;
1541 fschmid 1085
        uchar filler;
1086
        offset = 0;
1614 fschmid 1087
        bool first = false;
1088
        bool pathOpen = false;
1089
        FPoint firstPoint, firstControl;
1090
        FPointArray clip2;
1541 fschmid 1091
        while (offset < size)
1092
        {
1093
                s >> signature;
1094
                offset += 4;
1095
                s >> resID;
1096
                offset += 2;
1551 fschmid 1097
                adj = s.device()->at();
1541 fschmid 1098
                resName = getPascalString(s);
1551 fschmid 1099
                offset += s.device()->at() - adj;
1541 fschmid 1100
                s >> resSize;
1101
                resBase = s.device()->at();
1614 fschmid 1102
                if ( (resID >= 0x07d0) && (resID <= 0x0bb6) )
1541 fschmid 1103
                {
1614 fschmid 1104
                        QString db1, db2;
1105
                        short type;
1106
                        uint data1, data2, data3, data4, data5, data6;
1107
                        double frac1, frac2, frac3, frac4, frac5, frac6;
1108
                        ushort man1, man2, man3, man4, man5, man6;
1109
                        uint offset2;
1110
                        offset2 = 0;
1111
                        first = false;
1112
                        pathOpen = false;
1624 fschmid 1113
                        clip2.resize(0);
1614 fschmid 1114
                        while (offset2 < resSize)
1115
                        {
1116
                                s >> type;
1117
                                s >> data1;
1118
                                frac1 = (data1 & 0x00FFFFFF) / 16777215.0;
1119
                                man1 = (data1 & 0xFF000000) >> 24;
1120
                                s >> data2;
1121
                                frac2 = (data2 & 0x00FFFFFF) / 16777215.0;
1122
                                man2 = (data2 & 0xFF000000) >> 24;
1123
                                s >> data3;
1124
                                frac3 = (data3 & 0x00FFFFFF) / 16777215.0;
1125
                                man3 = (data3 & 0xFF000000) >> 24;
1126
                                s >> data4;
1127
                                frac4 = (data4 & 0x00FFFFFF) / 16777215.0;
1128
                                man4 = (data4 & 0xFF000000) >> 24;
1129
                                s >> data5;
1130
                                frac5 = (data5 & 0x00FFFFFF) / 16777215.0;
1131
                                man5 = (data5 & 0xFF000000) >> 24;
1132
                                s >> data6;
1133
                                frac6 = (data6 & 0x00FFFFFF) / 16777215.0;
1134
                                man6 = (data6 & 0xFF000000) >> 24;
1135
                                switch (type)
1136
                                {
1137
                                        case 0:
1138
                                        case 3:
1139
                                                if (pathOpen)
1140
                                                {
1141
                                                        clip2.addPoint(firstPoint);
1142
                                                        clip2.addPoint(firstControl);
1143
                                                        clip2.setMarker();
1144
                                                }
1145
                                                pathOpen = false;
1146
                                                first = true;
1147
                                                break;
1148
                                        case 1:
1149
                                                if (first)
1150
                                                {
1151
                                                        firstControl = FPoint(frac2 * header.width, frac1 * header.height);
1152
                                                        firstPoint = FPoint(frac4 * header.width, frac3 * header.height);
1153
                                                        clip2.addPoint(FPoint(frac4 * header.width, frac3 * header.height));
1154
                                                        clip2.addPoint(FPoint(frac6 * header.width, frac5 * header.height));
1155
                                                }
1156
                                                else
1157
                                                {
1158
                                                        clip2.addPoint(FPoint(frac4 * header.width, frac3 * header.height));
1159
                                                        clip2.addPoint(FPoint(frac2 * header.width, frac1 * header.height));
1160
                                                        clip2.addPoint(FPoint(frac4 * header.width, frac3 * header.height));
1161
                                                        clip2.addPoint(FPoint(frac6 * header.width, frac5 * header.height));
1162
                                                }
1163
                                                pathOpen = true;
1164
                                                first = false;
1165
                                                break;
1166
                                        case 6:
1167
                                                first = true;
1168
                                                break;
1169
                                        default:
1170
                                                break;
1171
                                }
1172
                                offset2 += 26;
1173
                        }
1174
                        clip2.addPoint(firstPoint);
1175
                        clip2.addPoint(firstControl);
1633 fschmid 1176
                        info->PDSpathData.insert(resName, clip2.copy());
1541 fschmid 1177
                }
1614 fschmid 1178
                 else
1179
                 {
1180
                        switch (resID)
1181
                        {
1182
                                case 0x0bb7:
1183
                                        adj = s.device()->at();
1624 fschmid 1184
                                        info->clipPath = getPascalString(s);
1614 fschmid 1185
                                        offset += s.device()->at() - adj;
1186
                                        break;
1187
                                case 0x03ed:
1188
                                        s >> hRes;
1189
                                        s >> hResUnit;
1190
                                        s >> dummyW;
1191
                                        s >> vRes;
1192
                                        s >> vResUnit;
1193
                                        s >> dummyW;
1624 fschmid 1194
                                        info->xres = qRound(hRes / 65536.0);
1195
                                        info->yres = qRound(vRes / 65536.0);
1614 fschmid 1196
                                        break;
1197
                                default:
1198
                                        break;
1199
                        }
1200
                }
1541 fschmid 1201
                s.device()->at( resBase + resSize );
1202
                offset += resSize;
1203
                if (resSize & 1)
1204
                {
1205
                        s >> filler;
1206
                        offset += 1;
1207
                }
1208
        }
1209
}
1210
 
1633 fschmid 1211
static bool parseLayer( QDataStream & s, const PSDHeader & header, QImage & img, ImageInfoRecord *info )
1541 fschmid 1212
{
1569 fschmid 1213
        uint addRes, layerinfo, channelLen, signature, extradata, layermasksize, layerRange, dummy;
1214
        int top, left, bottom, right;
1215
        short numLayers, numChannels;
1541 fschmid 1216
        short channelType;
1217
        uchar blendKey[4];
1218
        uchar opacity, clipping, flags, filler;
1219
        QString layerName, blend;
1220
        struct PSDLayer lay;
1221
        s >> layerinfo;
1222
        s >> numLayers;
1569 fschmid 1223
        if (numLayers < 0)
1224
                numLayers = -numLayers;
1551 fschmid 1225
        if (numLayers != 0)
1541 fschmid 1226
        {
1569 fschmid 1227
                for (int layer = 0; layer < numLayers; layer++)
1541 fschmid 1228
                {
1551 fschmid 1229
                        s >> top;
1230
                        lay.ypos = top;
1231
                        s >> left;
1232
                        lay.xpos = left;
1233
                        s >> bottom;
1234
                        lay.height = bottom - top;
1235
                        s >> right;
1236
                        lay.width = right - left;
1237
                        s >> numChannels;
1238
                        lay.channelType.clear();
1239
                        lay.channelLen.clear();
1569 fschmid 1240
                        for (int channels = 0; channels < numChannels; channels++)
1551 fschmid 1241
                        {
1242
                                s >> channelType;
1243
                                s >> channelLen;
1244
                                lay.channelType.append(channelType);
1245
                                lay.channelLen.append(channelLen);
1246
                        }
1247
                        s >> signature;
1248
                        blend = "";
1249
                        for( int i = 0; i < 4; i++ )
1250
                        {
1251
                                s >> blendKey[i];
1252
                                blend += QChar(blendKey[i]);
1253
                        }
1254
                        lay.blend = blend;
1255
                        s >> opacity;
1553 fschmid 1256
                        lay.opacity = opacity;
1551 fschmid 1257
                        s >> clipping;
1553 fschmid 1258
                        lay.clipping = clipping;
1551 fschmid 1259
                        s >> flags;
1553 fschmid 1260
                        lay.flags = flags;
1551 fschmid 1261
                        s >> filler;
1262
                        s >> extradata;
1263
                        s >> layermasksize;
1264
                        if (layermasksize != 0)
1265
                        {
1266
                                s >> dummy;
1267
                                s >> dummy;
1268
                                s >> dummy;
1269
                                s >> dummy;
1270
                                s >> dummy;
1271
                        }
1272
                        s >> layerRange;
1273
                        s.device()->at( s.device()->at() + layerRange );
1633 fschmid 1274
                        lay.layerName = getLayerString(s);
1624 fschmid 1275
                        info->layerInfo.append(lay);
1551 fschmid 1276
                        s >> signature;
1277
                        if( signature == 0x3842494D )
1278
                        {
1279
                                while (signature == 0x3842494D )
1280
                                {
1281
                                        s >> signature;
1282
                                        s >> addRes;
1283
                                        s.device()->at( s.device()->at() + addRes );
1284
                                        s >> signature;
1285
                                }
1286
                                s.device()->at( s.device()->at() - 4 );
1287
                        }
1288
                        else
1289
                        {
1290
                                s.device()->at( s.device()->at() - 2 );
1291
                                s >> signature;
1292
                                if( signature == 0x3842494D )
1293
                                {
1294
                                        while (signature == 0x3842494D )
1295
                                        {
1296
                                                s >> signature;
1297
                                                s >> addRes;
1298
                                                s.device()->at( s.device()->at() + addRes );
1299
                                                s >> signature;
1300
                                        }
1301
                                        s.device()->at( s.device()->at() - 4 );
1302
                                }
1303
                                else
1304
                                        s.device()->at( s.device()->at() - 6 );
1305
                        }
1541 fschmid 1306
                }
1633 fschmid 1307
                bool firstLayer = true;
1569 fschmid 1308
                for (int layer = 0; layer < numLayers; layer++)
1541 fschmid 1309
                {
1633 fschmid 1310
                        loadLayerChannels( s, header, img, info->layerInfo, layer, &firstLayer );
1541 fschmid 1311
                }
1312
        }
1551 fschmid 1313
        else
1541 fschmid 1314
        {
1551 fschmid 1315
                s >> numLayers;
1316
                loadLayer( s, header, img );
1541 fschmid 1317
        }
1318
        return true;
1319
}
1320
 
1321
// Load the PSD image.
1624 fschmid 1322
static bool LoadPSD( QDataStream & s, const PSDHeader & header, QImage & img, ImageInfoRecord *info)
1541 fschmid 1323
{
1324
        // Create dst image.
1325
        if( !img.create( header.width, header.height, 32 ))
1326
                return false;
1551 fschmid 1327
        img.setAlphaBuffer( true );
1541 fschmid 1328
        uint tmp;
1329
        uint ressourceDataLen;
1330
        uint startRessource;
1331
        uint layerDataLen;
1332
        uint startLayers;
1333
        // Skip mode data. FIX: this is incorrect, it's the Colormap Data for indexed Images
1334
        s >> tmp;
1335
        s.device()->at( s.device()->at() + tmp );
1336
        s >> ressourceDataLen;
1337
        startRessource = s.device()->at();
1338
        if (ressourceDataLen != 0)
1633 fschmid 1339
                parseRessourceData(s, header, ressourceDataLen, info);
1541 fschmid 1340
        s.device()->at( startRessource + ressourceDataLen );
1341
        // Skip the reserved data. FIX: Also incorrect, this is the actual Layer Data for Images with Layers
1342
        s >> layerDataLen;
1343
        startLayers = s.device()->at();
1344
        if (layerDataLen != 0)
1633 fschmid 1345
                return parseLayer( s, header, img, info);
1541 fschmid 1346
        else
1347
        {
1555 fschmid 1348
                // Decoding simple psd file, no layers
1541 fschmid 1349
                s.device()->at( s.device()->at() + layerDataLen );
1350
                loadLayer( s, header, img );
1351
        }
1352
        return true;
1353
}
1354
 
1505 fschmid 1355
QString getAlpha(QString fn, bool PDF, bool pdf14)
1488 fschmid 1356
{
1505 fschmid 1357
        QImage img;
1358
        QString retS = "";
1359
        bool miniswhite = false;
1360
        bool bilevel = false;
1361
        float xres, yres;
1362
        short resolutionunit = 0;
1624 fschmid 1363
        ImageInfoRecord imgInfo;
1505 fschmid 1364
        QFileInfo fi = QFileInfo(fn);
1365
        if (!fi.exists())
1366
                return retS;
1367
        QString ext = fi.extension(false).lower();
1368
        QString tmpFile = QDir::convertSeparators(QDir::homeDirPath()+"/.scribus/sc.png");
1369
        if ((ext == "pdf") || (ext == "eps") || (ext == "ps") || (ext == "jpg") || (ext == "jpeg"))
1370
                return retS;
1371
        if (ext == "tif")
1372
        {
1373
#ifdef HAVE_TIFF
1374
                TIFF* tif = TIFFOpen(fn, "r");
1375
                if(tif)
1376
                {
1377
                        unsigned width, height, size;
1378
                        TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &width);
1379
                        TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &height);
1380
                        TIFFGetField(tif, TIFFTAG_XRESOLUTION, &xres);
1381
                        TIFFGetField(tif, TIFFTAG_YRESOLUTION, &yres);
1382
                        TIFFGetField(tif, TIFFTAG_RESOLUTIONUNIT , &resolutionunit);
1383
                        size = width * height;
1384
                        uint16 photometric, bitspersample, samplesperpixel, fillorder;
1385
                        TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &photometric);
1386
                        TIFFGetField(tif, TIFFTAG_BITSPERSAMPLE, &bitspersample);
1387
                        TIFFGetField(tif, TIFFTAG_SAMPLESPERPIXEL, &samplesperpixel);
1388
                        TIFFGetField(tif, TIFFTAG_FILLORDER, &fillorder);
1389
                        uint32 *bits = 0;
1390
                        img.create(width,height,32);
1555 fschmid 1391
                        img.setAlphaBuffer(true);
1392
                        if (TIFFIsTiled(tif))
1393
                        {
1394
                                uint32 columns, rows;
1541 fschmid 1395
                                uint32 *tile_buf;
1396
                                uint32 xt, yt;
1397
                                TIFFGetField(tif, TIFFTAG_TILEWIDTH,  &columns);
1398
                                TIFFGetField(tif, TIFFTAG_TILELENGTH, &rows);
1399
                                tile_buf = (uint32*) _TIFFmalloc(columns*rows*sizeof(uint32));
1400
                                if (tile_buf == NULL)
1401
                                {
1402
                                        TIFFClose(tif);
1403
                                        return retS;
1404
                                }
1405
                                uint32 tileW = columns, tileH = rows;
1406
                                for (yt = 0; yt < (uint32)img.height(); yt += rows)
1407
                                {
1408
                                        if (yt > (uint)img.height())
1505 fschmid 1409
                                                break;
1541 fschmid 1410
                                        if (img.height()-yt < rows)
1555 fschmid 1411
                                                tileH = img.height()-yt;
1541 fschmid 1412
                                        tileW = columns;
1413
                                        register uint32 xi, yi;
1414
                                        for (xt = 0; xt < (uint)img.width(); xt += columns)
1505 fschmid 1415
                                        {
1541 fschmid 1416
                                                switch (photometric)
1505 fschmid 1417
                                                {
1555 fschmid 1418
                                                case PHOTOMETRIC_SEPARATED:
1419
                                                        TIFFReadTile(tif, tile_buf, xt, yt, 0, 0);
1420
                                                        for (yi = 0; yi < tileH; yi++)
1421
                                                                _TIFFmemcpy(img.scanLine(yt+(tileH-1-yi))+xt, tile_buf+tileW*yi, tileW*4);
1422
                                                        break;
1423
                                                default:
1424
                                                        TIFFReadRGBATile(tif, xt, yt, tile_buf);
1425
                                                        for(yi = 0; yi < tileH; yi++)
1426
                                                        {
1427
                                                                QRgb *row= (QRgb*) ( img.scanLine(yt+yi) );
1428
                                                                for(xi = 0; xi < tileW; xi++)
1541 fschmid 1429
                                                                {
1555 fschmid 1430
                                                                        const uint32 pix = *(tile_buf + ((tileH-1-yi)*tileW)+xi);
1431
                                                                        row[xi + xt] = qRgba(TIFFGetB(pix), TIFFGetG(pix), TIFFGetR(pix) , TIFFGetA(pix));
1432
                                                                } // for xi
1433
                                                        } // for yi
1434
                                                        break;
1541 fschmid 1435
                                                } // else per pixel method
1436
                                        } // for x by tiles
1437
                                } // for y by tiles
1438
                                _TIFFfree(tile_buf);
1439
                        }
1440
                        else
1441
                        {
1442
                                tsize_t bytesperrow = TIFFScanlineSize(tif);
1443
                                switch (photometric)
1444
                                {
1555 fschmid 1445
                                case PHOTOMETRIC_MINISWHITE:
1446
                                        miniswhite = true;
1447
                                case PHOTOMETRIC_MINISBLACK:
1448
                                        if (bitspersample == 1)
1449
                                                bilevel = true;
1450
                                        if (samplesperpixel != 1)
1451
                                                break;
1452
                                        bits = (uint32 *) _TIFFmalloc(bytesperrow);
1453
                                        if (bits)
1454
                                        {
1455
                                                QImage img2;
1456
                                                QImage::Endian bitorder = QImage::IgnoreEndian;
1457
                                                if (bilevel)
1505 fschmid 1458
                                                {
1555 fschmid 1459
                                                        if (fillorder == FILLORDER_MSB2LSB)
1460
                                                                bitorder = QImage::BigEndian;
1461
                                                        else
1462
                                                                bitorder = QImage::LittleEndian;
1463
                                                }
1464
                                                img2.create(width, height, bitspersample, 0, bitorder);
1465
                                                for (unsigned int y = 0; y < height; y++)
1466
                                                {
1467
                                                        if (TIFFReadScanline(tif, bits, y, 0))
1468
                                                                memcpy(img2.scanLine(y), bits, bytesperrow);
1469
                                                }
1470
                                                _TIFFfree(bits);
1471
                                                img2 = img2.convertDepth(8);
1472
                                                if (!miniswhite)
1473
                                                        img2.invertPixels();
1474
                                                for (unsigned int y = 0; y < height; y++)
1475
                                                {
1476
                                                        unsigned char *ptr = (unsigned char *) img.scanLine(y);
1477
                                                        unsigned char *ptr2 = (unsigned char *) img2.scanLine(y);
1478
                                                        for (unsigned int x = 0; x < width; x++)
1505 fschmid 1479
                                                        {
1555 fschmid 1480
                                                                if (bilevel)
1481
                                                                        ptr[3] = (unsigned char) -img2.pixelIndex(x, y);
1505 fschmid 1482
                                                                else
1555 fschmid 1483
                                                                        ptr[3] = ptr2[x];
1484
                                                                ptr+=4;
1505 fschmid 1485
                                                        }
1486
                                                }
1555 fschmid 1487
                                        }
1488
                                        break;
1489
                                case PHOTOMETRIC_SEPARATED:
1490
                                        bits = (uint32 *) _TIFFmalloc(bytesperrow);
1491
                                        if (bits)
1492
                                        {
1493
                                                for (unsigned int y = 0; y < height; y++)
1505 fschmid 1494
                                                {
1555 fschmid 1495
                                                        if (TIFFReadScanline(tif, bits, y, 0))
1541 fschmid 1496
                                                        {
1555 fschmid 1497
                                                                memcpy(img.scanLine(y), bits, width * 4);
1505 fschmid 1498
                                                        }
1499
                                                }
1555 fschmid 1500
                                                _TIFFfree(bits);
1501
                                        }
1502
                                        break;
1503
                                default:
1504
                                        bits = (uint32 *) _TIFFmalloc(size * sizeof(uint32));
1505
                                        if(bits)
1506
                                        {
1507
                                                if (TIFFReadRGBAImage(tif, width, height, bits, 0))
1505 fschmid 1508
                                                {
1555 fschmid 1509
                                                        for(unsigned int y = 0; y < height; y++)
1510
                                                                memcpy(img.scanLine(height - 1 - y), bits + y * width, width * 4);
1505 fschmid 1511
                                                }
1555 fschmid 1512
                                                _TIFFfree(bits);
1513
                                        }
1541 fschmid 1514
                                }
1515
                                TIFFClose(tif);
1505 fschmid 1516
                        }
1517
                }
1518
#else
1519
                qDebug("TIFF Support not available");
1520
#endif // HAVE_TIFF
1555 fschmid 1521
 
1505 fschmid 1522
        }
1541 fschmid 1523
        else if (ext == "psd")
1524
        {
1525
                QFile f(fn);
1526
                if (f.open(IO_ReadOnly))
1527
                {
1528
                        xres = 72.0;
1529
                        yres = 72.0;
1530
                        QDataStream s( &f );
1531
                        s.setByteOrder( QDataStream::BigEndian );
1532
                        PSDHeader header;
1533
                        s >> header;
1555 fschmid 1534
                        // Check image file format.
1535
                        if( s.atEnd() || !IsValid( header ) )
1541 fschmid 1536
                                return retS;
1555 fschmid 1537
                        // Check if it's a supported format.
1541 fschmid 1538
                        if( !IsSupported( header ) )
1539
                                return retS;
1555 fschmid 1540
                        FPointArray clip;
1624 fschmid 1541
                        if( !LoadPSD(s, header, img, &imgInfo) )
1541 fschmid 1542
                                return retS;
1543
                        img = img.convertDepth(32);
1544
                        img.setAlphaBuffer(true);
1545
                        f.close();
1546
                }
1547
                else
1548
                        return retS;
1549
        }
1505 fschmid 1550
        else
1551
        {
1552
                if (img.load(fn))
1553
                {
1554
                        img = img.convertDepth(32);
1555
                        img.setAlphaBuffer(true);
1556
                }
1557
                else
1558
                        return retS;
1559
        }
1560
        if (img.isNull())
1561
                return retS;
1562
        int hm = img.height();
1563
        int wm = img.width();
1564
        int w2;
1565
        if (pdf14)
1566
        {
1567
                for( int yi=0; yi < hm; ++yi )
1568
                {
1569
                        QRgb * s = (QRgb*)(img.scanLine( yi ));
1570
                        for( int xi=0; xi < wm; ++xi )
1571
                        {
1572
                                QRgb r=*s++;
1573
                                unsigned char u=qAlpha(r);
1574
                                retS += u;
1575
                        }
1576
                }
1577
        }
1578
        else
1579
        {
1580
                QImage iMask = img.createAlphaMask();
1581
                hm = iMask.height();
1582
                wm = iMask.width();
1583
                w2 = wm / 8;
1584
                if ((wm % 8) != 0)
1585
                        w2++;
1586
                for( int yi=0; yi < hm; ++yi )
1587
                {
1588
                        uchar * s = iMask.scanLine( yi );
1589
                        for( int xi=0; xi < w2; ++xi )
1590
                        {
1591
                                unsigned char u = *(s+xi);
1592
                                retS += PDF ? ~u : u;
1593
                        }
1594
                }
1595
        }
1596
        return retS;
1597
}
1598
 
1555 fschmid 1599
QImage LoadPicture(QString fn, QString Prof, int rend, bool useEmbedded, bool useProf, int requestType, int gsRes, bool *realCMYK, ImageInfoRecord *info)
1505 fschmid 1600
{
1488 fschmid 1601
        // requestType - 0: CMYK, 1: RGB, 2: RGB Proof
1602
        // gsRes - is the resolution that ghostscript will render at
1603
        QImage img;
1604
        bool isCMYK = false;
1505 fschmid 1605
        if (realCMYK != 0)
1606
                *realCMYK = false;
1488 fschmid 1607
        bool miniswhite = false;
1608
        bool bilevel = false;
1609
        float xres, yres;
1492 fschmid 1610
        short resolutionunit = 0;
8 paul 1611
#ifdef HAVE_CMS
1488 fschmid 1612
        cmsHTRANSFORM xform = 0;
1613
        cmsHPROFILE inputProf = 0;
1614
        cmsHPROFILE tiffProf = 0;
1615
        int cmsFlags = 0;
1616
#endif
1617
        QFileInfo fi = QFileInfo(fn);
1618
        if (!fi.exists())
1619
                return img;
1620
        QString ext = fi.extension(false).lower();
1621
        QString tmp, dummy, cmd1, cmd2, BBox, tmp2;
1622
        QChar tc;
1623
        double x, y, b, h;
1624
        bool found = false;
1625
        int ret = -1;
1626
        QString tmpFile = QDir::convertSeparators(QDir::homeDirPath()+"/.scribus/sc.png");
1627
        if (ext == "pdf")
1628
        {
1629
                QStringList args;
1491 fschmid 1630
                xres = gsRes;
1631
                yres = gsRes;
1488 fschmid 1632
                args.append("-r"+QString::number(gsRes));
1633
                args.append("-sOutputFile="+tmpFile);
1634
                args.append("-dFirstPage=1");
1635
                args.append("-dLastPage=1");
1636
                args.append(fn);
1637
                ret = callGS(args);
1638
                if (ret == 0)
1639
                {
1640
                        QImage image;
1641
                        image.load(tmpFile);
1642
                        unlink(tmpFile);
1643
                        image = image.convertDepth(32);
1644
                        image.setAlphaBuffer(true);
1645
                        int wi = image.width();
1646
                        int hi = image.height();
1647
                        if (ScApp->HavePngAlpha != 0)
1648
                        {
1649
                                for( int yi=0; yi < hi; ++yi )
1650
                                {
1651
                                        QRgb *s = (QRgb*)(image.scanLine( yi ));
1652
                                        for(int xi=0; xi < wi; ++xi )
1653
                                        {
1654
                                                if((*s) == 0xffffffff)
1655
                                                        (*s) &= 0x00ffffff;
1656
                                                s++;
1657
                                        }
1658
                                }
1659
                        }
1505 fschmid 1660
                        img = image.convertDepth(32);
1488 fschmid 1661
                }
1662
        }
1663
        if ((ext == "eps") || (ext == "ps"))
1664
        {
1665
                QFile f(fn);
1666
                if (f.open(IO_ReadOnly))
1667
                {
1668
                        QTextStream ts(&f);
1669
                        while (!ts.atEnd())
1670
                        {
1671
                                tc = ' ';
1672
                                tmp = "";
1673
                                while ((tc != '\n') && (tc != '\r'))
1674
                                {
1675
                                        ts >> tc;
1676
                                        if ((tc != '\n') && (tc != '\r'))
1677
                                                tmp += tc;
1678
                                }
1679
                                if (tmp.startsWith("%%BoundingBox:"))
1680
                                {
1681
                                        found = true;
1682
                                        BBox = tmp.remove("%%BoundingBox:");
1683
                                }
1684
                                if (!found)
1685
                                {
1686
                                        if (tmp.startsWith("%%BoundingBox"))
1687
                                        {
1688
                                                found = true;
1689
                                                BBox = tmp.remove("%%BoundingBox");
1690
                                        }
1691
                                }
1692
                                if (tmp.startsWith("%%EndComments"))
1693
                                        break;
1694
                        }
1695
                }
1696
                f.close();
1697
                if (found)
1698
                {
1699
                        QTextStream ts2(&BBox, IO_ReadOnly);
1700
                        ts2 >> x >> y >> b >> h;
1701
                        x = x * gsRes / 72.0;
1702
                        y = y * gsRes / 72.0;
1703
                        b = b * gsRes / 72.0;
1704
                        h = h * gsRes / 72.0;
1705
                        QStringList args;
1491 fschmid 1706
                        xres = gsRes;
1707
                        yres = gsRes;
1488 fschmid 1708
                        args.append("-r"+QString::number(gsRes));
1709
                        args.append("-sOutputFile="+tmpFile);
1710
                        args.append("-g"+tmp.setNum(qRound(b))+"x"+tmp2.setNum(qRound(h)));
1711
                        args.append(fn);
1712
                        ret = callGS(args);
1713
                        if (ret == 0)
1714
                        {
1715
                                QImage image;
1716
                                image.load(tmpFile);
1555 fschmid 1717
                                image = image.convertDepth(32);
1488 fschmid 1718
                                image.setAlphaBuffer(true);
1719
                                if (ScApp->HavePngAlpha != 0)
1720
                                {
1721
                                        int wi = image.width();
1722
                                        int hi = image.height();
1723
                                        for( int yi=0; yi < hi; ++yi )
1724
                                        {
1725
                                                QRgb *s = (QRgb*)(image.scanLine( yi ));
1726
                                                for(int xi=0; xi < wi; ++xi )
1727
                                                {
1728
                                                        if((*s) == 0xffffffff)
1729
                                                                (*s) &= 0x00ffffff;
1730
                                                        s++;
1731
                                                }
1555 fschmid 1732
                                        }
1488 fschmid 1733
                                }
1734
                                img = image.copy(static_cast<int>(x), 0, static_cast<int>(b-x), static_cast<int>(h-y));
1735
                                unlink(tmpFile);
1736
                        }
1737
                }
1738
        }
1739
#ifdef HAVE_TIFF
1740
        else if (ext == "tif")
1741
        {
1536 cbradney 1742
                QImage img2;
1488 fschmid 1743
                TIFF* tif = TIFFOpen(fn, "r");
1744
                if(tif)
1745
                {
1746
                        unsigned width, height, size;
1747
                        TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &width);
1748
                        TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &height);
1749
                        TIFFGetField(tif, TIFFTAG_XRESOLUTION, &xres);
1750
                        TIFFGetField(tif, TIFFTAG_YRESOLUTION, &yres);
1492 fschmid 1751
                        TIFFGetField(tif, TIFFTAG_RESOLUTIONUNIT , &resolutionunit);
1488 fschmid 1752
                        size = width * height;
1753
                        uint16 photometric, bitspersample, samplesperpixel, fillorder;
1754
                        TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &photometric);
1755
                        TIFFGetField(tif, TIFFTAG_BITSPERSAMPLE, &bitspersample);
1756
                        TIFFGetField(tif, TIFFTAG_SAMPLESPERPIXEL, &samplesperpixel);
1757
                        TIFFGetField(tif, TIFFTAG_FILLORDER, &fillorder);
1536 cbradney 1758
                        if (!img.create(width,height,32))
1759
                        {
1760
                                TIFFClose(tif);
1761
                                return img;
1762
                        }
1555 fschmid 1763
                        img.setAlphaBuffer(true);
1764
                        if (TIFFIsTiled(tif))
1765
                        {
1766
                                uint32 columns, rows;
1536 cbradney 1767
                                uint32 *tile_buf;
1768
                                uint32 xt, yt;
1769
                                TIFFGetField(tif, TIFFTAG_TILEWIDTH,  &columns);
1770
                                TIFFGetField(tif, TIFFTAG_TILELENGTH, &rows);
1771
                                tile_buf = (uint32*) _TIFFmalloc(columns*rows*sizeof(uint32));
1772
                                if (tile_buf == NULL)
1773
                                {
1774
                                        TIFFClose(tif);
1775
                                        return img;
1776
                                }
1777
                                uint32 tileW = columns, tileH = rows;
1778
                                for (yt = 0; yt < (uint32)img.height(); yt += rows)
1779
                                {
1780
                                        if (yt > (uint)img.height())
1488 fschmid 1781
                                                break;
1536 cbradney 1782
                                        if (img.height()-yt < rows)
1555 fschmid 1783
                                                tileH = img.height()-yt;
1536 cbradney 1784
                                        tileW = columns;
1785
                                        register uint32 xi, yi;
1786
                                        for (xt = 0; xt < (uint)img.width(); xt += columns)
1488 fschmid 1787
                                        {
1536 cbradney 1788
                                                switch (photometric)
1488 fschmid 1789
                                                {
1555 fschmid 1790
                                                case PHOTOMETRIC_SEPARATED:
1791
                                                        TIFFReadTile(tif, tile_buf, xt, yt, 0, 0);
1792
                                                        for (yi = 0; yi < tileH; yi++)
1793
                                                                _TIFFmemcpy(img.scanLine(yt+(tileH-1-yi))+xt, tile_buf+tileW*yi, tileW*4);
1794
                                                        isCMYK = true;
1795
                                                        if (realCMYK != 0)
1796
                                                                *realCMYK = true;
1797
                                                        break;
1798
                                                default:
1799
                                                        TIFFReadRGBATile(tif, xt, yt, tile_buf);
1800
                                                        for(yi = 0; yi < tileH; yi++)
1801
                                                        {
1802
                                                                QRgb *row= (QRgb*) ( img.scanLine(yt+yi) );
1803
                                                                for(xi = 0; xi < tileW; xi++)
1536 cbradney 1804
                                                                {
1555 fschmid 1805
                                                                        const uint32 pix = *(tile_buf + ((tileH-1-yi)*tileW)+xi);
1806
                                                                        row[xi + xt] = qRgba(TIFFGetB(pix), TIFFGetG(pix), TIFFGetR(pix) , TIFFGetA(pix));
1807
                                                                } // for xi
1808
                                                        } // for yi
1809
                                                        isCMYK = false;
1810
                                                        if (realCMYK != 0)
1811
                                                                *realCMYK = false;
1812
                                                        break;
1536 cbradney 1813
                                                } // else per pixel method
1814
                                        } // for x by tiles
1815
                                } // for y by tiles
1816
                                _TIFFfree(tile_buf);
1817
                        }
1818
                        else
1819
                        {
1820
                                tsize_t bytesperrow = TIFFScanlineSize(tif);
1821
                                uint32 *bits = 0;
1822
                                switch (photometric)
1823
                                {
1555 fschmid 1824
                                case PHOTOMETRIC_MINISWHITE:
1825
                                        miniswhite = true;
1826
                                case PHOTOMETRIC_MINISBLACK:
1827
                                        if (bitspersample == 1)
1828
                                                bilevel = true;
1829
                                        if (samplesperpixel != 1)
1830
                                                break;
1831
                                        bits = (uint32 *) _TIFFmalloc(bytesperrow);
1832
                                        if (bits)
1833
                                        {
1834
                                                QImage::Endian bitorder = QImage::IgnoreEndian;
1835
                                                if (bilevel)
1488 fschmid 1836
                                                {
1555 fschmid 1837
                                                        if (fillorder == FILLORDER_MSB2LSB)
1838
                                                                bitorder = QImage::BigEndian;
1839
                                                        else
1840
                                                                bitorder = QImage::LittleEndian;
1841
                                                }
1842
                                                if (!img2.create(width, height, bitspersample, 0, bitorder))
1843
                                                {
1536 cbradney 1844
                                                        _TIFFfree(bits);
1555 fschmid 1845
                                                        TIFFClose(tif);
1846
                                                        return img;
1488 fschmid 1847
                                                }
1555 fschmid 1848
                                                for (unsigned int y = 0; y < height; y++)
1488 fschmid 1849
                                                {
1555 fschmid 1850
                                                        if (TIFFReadScanline(tif, bits, y, 0))
1851
                                                                memcpy(img2.scanLine(y), bits, bytesperrow);
1852
                                                }
1853
                                                _TIFFfree(bits);
1854
                                                img2 = img2.convertDepth(8);
1855
                                                if (!miniswhite)
1856
                                                        img2.invertPixels();
1857
                                                for (unsigned int y = 0; y < height; y++)
1858
                                                {
1859
                                                        unsigned char *ptr = (unsigned char *) img.scanLine(y);
1860
                                                        unsigned char *ptr2 = (unsigned char *) img2.scanLine(y);
1861
                                                        for (unsigned int x = 0; x < width; x++)
1536 cbradney 1862
                                                        {
1555 fschmid 1863
                                                                if (bilevel)
1864
                                                                        ptr[3] = (unsigned char) -img2.pixelIndex(x, y);
1865
                                                                else
1866
                                                                        ptr[3] = ptr2[x];
1867
                                                                ptr+=4;
1488 fschmid 1868
                                                        }
1869
                                                }
1555 fschmid 1870
                                        }
1871
                                        isCMYK = true;
1872
                                        if (realCMYK != 0)
1873
                                                *realCMYK = true;
1874
                                        break;
1875
                                case PHOTOMETRIC_SEPARATED:
1876
                                        bits = (uint32 *) _TIFFmalloc(bytesperrow);
1877
                                        if (bits)
1878
                                        {
1879
                                                for (unsigned int y = 0; y < height; y++)
1488 fschmid 1880
                                                {
1555 fschmid 1881
                                                        if (TIFFReadScanline(tif, bits, y, 0))
1536 cbradney 1882
                                                        {
1555 fschmid 1883
                                                                memcpy(img.scanLine(y), bits, width * 4);
1536 cbradney 1884
                                                        }
1488 fschmid 1885
                                                }
1555 fschmid 1886
                                                _TIFFfree(bits);
1887
                                        }
1888
                                        isCMYK = true;
1889
                                        if (realCMYK != 0)
1890
                                                *realCMYK = true;
1891
                                        break;
1892
                                default:
1893
                                        bits = (uint32 *) _TIFFmalloc(size * sizeof(uint32));
1894
                                        if(bits)
1895
                                        {
1896
                                                if (TIFFReadRGBAImage(tif, width, height, bits, 0))
1897
                                                {
1898
                                                        for(unsigned int y = 0; y < height; y++)
1899
                                                                memcpy(img.scanLine(height - 1 - y), bits + y * width, width * 4);
1900
                                                }
1901
                                                _TIFFfree(bits);
1902
                                        }
1536 cbradney 1903
                                }
1488 fschmid 1904
                        }
1905
#ifdef HAVE_CMS
1505 fschmid 1906
                        DWORD EmbedLen = 0;
1488 fschmid 1907
                        LPBYTE EmbedBuffer;
1908
                        if (TIFFGetField(tif, TIFFTAG_ICCPROFILE, &EmbedLen, &EmbedBuffer) && useEmbedded && CMSuse && useProf)
1909
                                tiffProf = cmsOpenProfileFromMem(EmbedBuffer, EmbedLen);
1910
#endif // HAVE_CMS
1505 fschmid 1911
                        img = img.swapRGB();
1626 craig 1912
                        uint32 ClipLen = 0;
1913
                        uint8 ClipBuffer;
1536 cbradney 1914
                        QString db;
1915
                        if (TIFFGetField(tif, TIFFTAG_CLIPPATH, &ClipLen, &ClipBuffer))
1916
                                qDebug(db.setNum(ClipLen));
1488 fschmid 1917
                        TIFFClose(tif);
1492 fschmid 1918
                        if (resolutionunit == RESUNIT_INCH)
1919
                        {
1920
                                img.setDotsPerMeterX ((int) (xres / 0.0254));
1921
                                img.setDotsPerMeterY ((int) (yres / 0.0254));
1922
                        }
1923
                        else if (resolutionunit == RESUNIT_CENTIMETER)
1924
                        {
1925
                                img.setDotsPerMeterX ((int) (xres / 100.0));
1926
                                img.setDotsPerMeterY ((int) (yres / 100.0));
1927
                        }
1488 fschmid 1928
                }
1929
        }
1930
#endif // HAVE_TIFF
1541 fschmid 1931
        else if (ext == "psd")
1932
        {
1933
                QFile f(fn);
1934
                if (f.open(IO_ReadOnly))
1935
                {
1624 fschmid 1936
                        ImageInfoRecord imgInfo;
1937
                        imgInfo.xres = 72;
1938
                        imgInfo.yres = 72;
1541 fschmid 1939
                        QDataStream s( &f );
1940
                        s.setByteOrder( QDataStream::BigEndian );
1941
                        PSDHeader header;
1942
                        s >> header;
1555 fschmid 1943
                        // Check image file format.
1944
                        if( s.atEnd() || !IsValid( header ) )
1541 fschmid 1945
                                return img;
1555 fschmid 1946
                        // Check if it's a supported format.
1541 fschmid 1947
                        if( !IsSupported( header ) )
1948
                                return img;
1555 fschmid 1949
                        FPointArray clip;
1624 fschmid 1950
                        if (info != 0)
1951
                        {
1952
                                if( !LoadPSD(s, header, img, info) )
1953
                                        return img;
1954
                        }
1955
                        else
1956
                        {
1957
                                if( !LoadPSD(s, header, img, &imgInfo) )
1958
                                        return img;
1959
                        }
1551 fschmid 1960
                        if (header.color_mode == CM_CMYK)
1961
                                isCMYK = true;
1962
                        else
1963
                                isCMYK = false;
1964
                        if (realCMYK != 0)
1965
                                *realCMYK = isCMYK;
1555 fschmid 1966
                        if (info != 0)
1967
                        {
1968
                                info->colorspace = isCMYK;
1624 fschmid 1969
                                info->valid = true;
1970
                                img.setDotsPerMeterX ((int) (info->xres / 0.0254));
1971
                                img.setDotsPerMeterY ((int) (info->yres / 0.0254));
1972
                                xres = info->xres;
1973
                                yres = info->yres;
1555 fschmid 1974
                        }
1624 fschmid 1975
                        else
1976
                        {
1977
                                img.setDotsPerMeterX ((int) (imgInfo.xres / 0.0254));
1978
                                img.setDotsPerMeterY ((int) (imgInfo.yres / 0.0254));
1979
                                xres = imgInfo.xres;
1980
                                yres = imgInfo.yres;
1981
                        }
1541 fschmid 1982
                        f.close();
1983
                }
1984
                else
1985
                        return img;
1986
        }
1492 fschmid 1987
        else if ((ext == "jpg") || (ext == "jpeg"))
1988
        {
1989
                struct jpeg_decompress_struct cinfo;
1990
                struct my_error_mgr         jerr;
1991
                FILE     *infile;
1992
                cinfo.err = jpeg_std_error (&jerr.pub);
1993
                jerr.pub.error_exit = my_error_exit;
1994
                infile = NULL;
1995
                if (setjmp (jerr.setjmp_buffer))
1996
                {
1997
                        jpeg_destroy_decompress (&cinfo);
1998
                        if (infile)
1999
                                fclose (infile);
2000
                        return img;
2001
                }
2002
                jpeg_create_decompress (&cinfo);
2003
                if ((infile = fopen (fn, "rb")) == NULL)
2004
                        return img;
2005
                jpeg_stdio_src(&cinfo, infile);
2006
                jpeg_read_header(&cinfo, TRUE);
2007
                jpeg_start_decompress(&cinfo);
2008
                if ( cinfo.output_components == 3 || cinfo.output_components == 4)
2009
                        img.create( cinfo.output_width, cinfo.output_height, 32 );
2010
                else if ( cinfo.output_components == 1 )
2011
                {
2012
                        img.create( cinfo.output_width, cinfo.output_height, 8, 256 );
2013
                        for (int i=0; i<256; i++)
2014
                                img.setColor(i, qRgb(i,i,i));
2015
                }
2016
                if (!img.isNull())
2017
                {
2018
                        uchar** lines = img.jumpTable();
2019
                        while (cinfo.output_scanline < cinfo.output_height)
2020
                                (void) jpeg_read_scanlines(&cinfo, lines + cinfo.output_scanline, cinfo.output_height);
2021
                        if ( cinfo.output_components == 3 )
2022
                        {
2023
                                for (uint j=0; j<cinfo.output_height; j++)
2024
                                {
2025
                                        uchar *in = img.scanLine(j) + cinfo.output_width * 3;
2026
                                        QRgb *out = (QRgb*)img.scanLine(j);
2027
                                        for (uint i=cinfo.output_width; i--; )
2028
                                        {
2029
                                                in -= 3;
2030
                                                out[i] = qRgb(in[0], in[1], in[2]);
2031
                                        }
2032
                                }
2033
                        }
2034
                        if ( cinfo.output_components == 4 )
2035
                        {
2036
                                for (int i = 0; i < img.height(); i++)
2037
                                {
2038
                                        unsigned int *ptr = (unsigned int *) img.scanLine(i);
2039
                                        unsigned char c, m, y ,k;
1505 fschmid 2040
                                        if ((cinfo.saw_Adobe_marker) && (cinfo.Adobe_transform == 2))
1492 fschmid 2041
                                        {
2042
                                                for (int j = 0; j < img.width(); j++)
2043
                                                {
2044
                                                        unsigned char *p = (unsigned char *) ptr;
2045
                                                        c = p[0];
2046
                                                        m = p[1];
2047
                                                        y =  p[2];
2048
                                                        k =  p[3];
2049
                                                        p[0] = 255 - y;
2050
                                                        p[1] = 255 - m;
2051
                                                        p[2] = 255 - c;
2052
                                                        p[3] = 255 - k;
2053
                                                        ptr++;
2054
                                                }
2055
                                        }
2056
                                        else
2057
                                        {
2058
                                                for (int j = 0; j < img.width(); j++)
2059
                                                {
2060
                                                        unsigned char *p = (unsigned char *) ptr;
2061
                                                        c = p[0];
2062
                                                        m = p[1];
2063
                                                        y =  p[2];
2064
                                                        k =  p[3];
2065
                                                        p[0] = y;
2066
                                                        p[1] = m;
2067
                                                        p[2] = c;
2068
                                                        p[3] = k;
2069
                                                        ptr++;
2070
                                                }
2071
                                        }
2072
                                }
2073
                                isCMYK = true;
1505 fschmid 2074
                                if (realCMYK != 0)
2075
                                        *realCMYK = true;
1492 fschmid 2076
                        }
2077
                        else
2078
                                isCMYK = false;
2079
                        img = img.convertDepth(32);
2080
                        img.setAlphaBuffer(true);
2081
                        if ( cinfo.density_unit == 1 )
2082
                        {
2083
                                xres = cinfo.X_density;
2084
                                yres = cinfo.Y_density;
2085
                                img.setDotsPerMeterX( int(100. * cinfo.X_density / 2.54) );
2086
                                img.setDotsPerMeterY( int(100. * cinfo.Y_density / 2.54) );
2087
                        }
2088
                        else if ( cinfo.density_unit == 2 )
2089
                        {
2090
                                xres = cinfo.X_density * 2.54;
2091
                                yres = cinfo.Y_density * 2.54;
2092
                                img.setDotsPerMeterX( int(100. * cinfo.X_density) );
2093
                                img.setDotsPerMeterY( int(100. * cinfo.Y_density) );
2094
                        }
2095
                }
2096
                (void) jpeg_finish_decompress(&cinfo);
2097
                fclose (infile);
2098
                jpeg_destroy_decompress (&cinfo);
2099
        }
1488 fschmid 2100
        else
2101
        {
2102
                if (img.load(fn))
2103
                {
1491 fschmid 2104
                        xres = img.dotsPerMeterX() * 0.0254;
2105
                        yres = img.dotsPerMeterY() * 0.0254;
1488 fschmid 2106
                        img = img.convertDepth(32);
2107
                        img.setAlphaBuffer(true);
2108
                }
2109
        }
2110
        if (img.isNull())
2111
                return img;
2112
#ifdef HAVE_CMS
2113
        if (CMSuse && useProf)
2114
        {
2115
                if (tiffProf)
2116
                        inputProf = tiffProf;
2117
                else
2118
                {
2119
                        if (isCMYK)
2120
                                inputProf = CMSprinterProf;
2121
                        else
2122
                                inputProf = cmsOpenProfileFromFile(InputProfiles[Prof], "r");
2123
                }
2124
        }
2125
        if (CMSuse && useProf && inputProf)
2126
        {
2127
                DWORD inputProfFormat = TYPE_RGBA_8;
2128
                switch (static_cast<int>(cmsGetColorSpace(inputProf)))
2129
                {
1555 fschmid 2130
                case icSigRgbData:
2131
                        inputProfFormat = TYPE_RGBA_8;
2132
                        break;
2133
                case icSigCmykData:
2134
                        inputProfFormat = TYPE_CMYK_8;
2135
                        break;
1488 fschmid 2136
                }
2137
                if (SoftProofing)
2138
                {
2139
                        cmsFlags |= cmsFLAGS_SOFTPROOFING;
2140
                        if (Gamut)
2141
                                cmsFlags |= cmsFLAGS_GAMUTCHECK;
2142
                }
2143
#ifdef cmsFLAGS_BLACKPOINTCOMPENSATION
2144
                if (BlackPoint)
2145
                        cmsFlags |= cmsFLAGS_BLACKPOINTCOMPENSATION;
2146
#endif
2147
                switch (requestType)
2148
                {
1555 fschmid 2149
                case 0: // CMYK
2150
                        if (!isCMYK)
2151
                                xform = cmsCreateTransform(inputProf, inputProfFormat,
2152
                                                           CMSprinterProf, TYPE_CMYK_8, IntentPrinter, 0);
2153
                        break;
2154
                case 1: // RGB
2155
                        if (isCMYK)
2156
                                xform = cmsCreateTransform(inputProf, inputProfFormat,
2157
                                                           CMSoutputProf, TYPE_RGBA_8, rend, 0);
2158
                        break;
2159
                case 2: // RGB Proof
2160
                        xform = cmsCreateProofingTransform(inputProf, inputProfFormat,
2161
                                                           CMSoutputProf, TYPE_RGBA_8, CMSprinterProf,
2162
                                                           IntentPrinter, rend, cmsFlags);
2163
                        break;
1488 fschmid 2164
                }
2165
                if (xform)
2166
                {
2167
                        for (int i = 0; i < img.height(); i++)
2168
                        {
2169
                                LPBYTE ptr = img.scanLine(i);
2170
                                cmsDoTransform(xform, ptr, ptr, img.width());
2171
                                // if transforming from CMYK to RGB, flatten the alpha channel
2172
                                // which will still contain the black channel
2173
                                if (isCMYK && requestType != 0 && !bilevel)
2174
                                {
2175
                                        unsigned int *p = (unsigned int *) ptr;
2176
                                        for (int j = 0; j < img.width(); j++, p++)
2177
                                                *p |= 0xff000000;
2178
                                }
1555 fschmid 2179
 
1488 fschmid 2180
                        }
2181
                        cmsDeleteTransform (xform);
2182
                }
2183
                if (inputProf && inputProf != CMSprinterProf)
2184
                        cmsCloseProfile(inputProf);
2185
        }
2186
        else
2187
#endif // HAVE_CMS
1555 fschmid 2188
 
1488 fschmid 2189
        {
2190
                switch (requestType)
2191
                {
1555 fschmid 2192
                case 0:
2193
                        if (!isCMYK)
2194
                        {
2195
                                for (int i = 0; i < img.height(); i++)
1488 fschmid 2196
                                {
1555 fschmid 2197
                                        unsigned int *ptr = (unsigned int *) img.scanLine(i);
2198
                                        unsigned char c, m, y ,k;
2199
                                        for (int j = 0; j < img.width(); j++)
1488 fschmid 2200
                                        {
1555 fschmid 2201
                                                unsigned char *p = (unsigned char *) ptr;
2202
                                                c = 255 - p[0];
2203
                                                m = 255 - p[1];
2204
                                                y = 255 - p[2];
2205
                                                k = QMIN(QMIN(c, m), y);
2206
                                                p[0] = c - k;
2207
                                                p[1] = m - k;
2208
                                                p[2] = y - k;
2209
                                                p[3] = k;
2210
                                                ptr++;
1488 fschmid 2211
                                        }
2212
                                }
1555 fschmid 2213
                        }
2214
                        break;
2215
                case 1:
2216
                case 2:
2217
                        if (isCMYK)
2218
                        {
2219
                                for (int i = 0; i < img.height(); i++)
1488 fschmid 2220
                                {
1555 fschmid 2221
                                        unsigned int *ptr = (unsigned int *) img.scanLine(i);