Subversion Repositories Scribus

Rev

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

Rev Author Line No. Line
13960 herm 1
/*
2
For general Scribus (>=1.3.2) copyright and licensing information please refer
3
to the COPYING file provided with the program. Following this notice may exist
4
a copyright and/or license notice that predates the release of Scribus 1.3.2
5
for which a new license (GPL+exception) is in place.
6
*/
7
#include <QFile>
8
#include <QFileInfo>
9
#include <QObject>
10
#include <QDebug>
11
#include <setjmp.h>
12
#include "scconfig.h"
13
#include "scimgdataloader_gmagick.h"
14
#include <Magick++.h>
15
using namespace Magick;
16
 
13964 herm 17
#ifndef ScaleQuantumToChar
13968 herm 18
    #define ScaleQuantumToChar MagickLib::ScaleQuantumToChar
13964 herm 19
#endif
20
 
13960 herm 21
static bool read_cmyk(Image *input, RawImage *output, int width, int height)
22
{
23
        /* Mapping:
24
                red:     cyan
25
                green:   magenta
26
                blue:    yellow
27
                opacity: black
28
                index:   alpha
29
        */
30
        //Copied from GraphicsMagick header and modified
31
        #define GetCyanSample(p) (p.red)
32
        #define GetMagentaSample(p) (p.green)
33
        #define GetYellowSample(p) (p.blue)
34
        #define GetCMYKBlackSample(p) (p.opacity)
35
        #define GetAlphaSample(p) (p)
36
 
37
        bool hasAlpha = input->matte();
38
        if (!output->create(width, height, hasAlpha ? 5 : 4)) return false;
39
        const PixelPacket *pixels = input->getConstPixels(0, 0, width, height);
13986 herm 40
        if (!pixels) {
41
           qCritical() << QObject::tr("Could not get pixel data!");
42
           return false;
43
    }
44
 
45
    const IndexPacket *alpha;
46
    if (hasAlpha) {
47
        alpha = input->getConstIndexes();
48
        if (!alpha) {
49
            qCritical() << QObject::tr("Could not get alpha channel data!");
50
            return false;
51
        }
52
    }
13960 herm 53
        unsigned char *buffer = output->bits();
13986 herm 54
        if (!buffer) {
55
           qCritical() << QObject::tr("Could not allocate output buffer!");
56
           return false;
57
    }
13960 herm 58
 
59
        int i;
60
        for (i = 0; i < width*height; i++) {
61
                *buffer++ = ScaleQuantumToChar(GetCyanSample(pixels[i]));
62
                *buffer++ = ScaleQuantumToChar(GetMagentaSample(pixels[i]));
63
                *buffer++ = ScaleQuantumToChar(GetYellowSample(pixels[i]));
64
                *buffer++ = ScaleQuantumToChar(GetCMYKBlackSample(pixels[i]));
65
                if (hasAlpha) {
66
                        *buffer++ = 255 - ScaleQuantumToChar(GetAlphaSample(alpha[i]));
67
                }
68
        }
69
        return true;
70
}
71
 
72
 
73
static bool read_rgb(Image *input, QImage *output, int width, int height)
74
{
75
        //Copied from GraphicsMagick header and modified
76
        #define GetRedSample(p) (p.red)
77
        #define GetGreenSample(p) (p.green)
78
        #define GetBlueSample(p) (p.blue)
79
        #define GetRGBAlphaSample(p) (p.opacity)
80
 
81
        bool hasAlpha = input->matte();
82
        const PixelPacket *pixels = input->getConstPixels(0, 0, width, height);
13986 herm 83
    if (!pixels) {
84
           qCritical() << QObject::tr("Could not get pixel data!");
85
           return false;
86
    }
13960 herm 87
        unsigned char *buffer = output->bits();
13986 herm 88
        if (!buffer) {
89
           qCritical() << QObject::tr("Could not allocate output buffer!");
90
           return false;
91
    }
92
 
13960 herm 93
        int i;
94
        for (i = 0; i < width*height; i++) {
95
                *buffer++ = ScaleQuantumToChar(GetBlueSample(pixels[i]));
96
                *buffer++ = ScaleQuantumToChar(GetGreenSample(pixels[i]));
97
                *buffer++ = ScaleQuantumToChar(GetRedSample(pixels[i]));
98
                if (hasAlpha) {
99
                        *buffer++ = 255 - ScaleQuantumToChar(GetRGBAlphaSample(pixels[i]));
100
                } else {
101
                        *buffer++ = 255;
102
                }
103
        }
104
        return true;
105
}
106
 
107
ScImgDataLoader_GMagick::ScImgDataLoader_GMagick(void)
108
{
109
        initSupportedFormatList();
110
        m_useRawImage = true;
111
}
112
 
113
void ScImgDataLoader_GMagick::initSupportedFormatList(void)
114
{
115
        //This is unused! See util_formats.{h,cpp}
116
        m_supportedFormats.clear();
117
        m_supportedFormats.append("bmp"); //TODO
118
}
119
 
120
void ScImgDataLoader_GMagick::loadEmbeddedProfile(const QString& fn, int /*page*/)
121
{      
122
        if (!QFile::exists(fn)) {
123
                m_embeddedProfile.resize(0);
124
                m_profileComponents = 0;
125
                return;
126
        }
127
 
128
        try {
129
                Image image(std::string(fn.toUtf8()));
130
                Blob icc = image.iccColorProfile();
131
 
132
                if (image.colorSpace() == CMYKColorspace) {
133
                        m_profileComponents = 4;
134
                } else if (image.colorSpace() == RGBColorspace) {
135
                        m_profileComponents = 3;
136
                } else {
137
                        m_profileComponents = 0;
138
                        m_embeddedProfile.resize(0);
139
                }
140
 
141
                m_embeddedProfile.resize(icc.length());
142
 
143
                char *dest = m_embeddedProfile.data();
144
                const char *src = (const char *)icc.data();
145
 
146
                unsigned int i;
147
                for (i=0; i<icc.length(); i++) {
148
                        dest[i] = src[i];
149
                }
150
 
151
        } catch (std::exception &error_) {
152
                m_profileComponents = 0;
153
                m_embeddedProfile.resize(0);
154
 
155
                qDebug() << "GraphicsMagic Exception in ScImgDataLoader_GMagick::loadEmbeddedProfile("
156
                        << fn << "):" << error_.what();
157
 
158
                return;
159
        }
160
}
161
 
162
bool ScImgDataLoader_GMagick::preloadAlphaChannel(const QString& fn, int /*page*/, int res, bool& hasAlpha)
163
{
164
        qDebug() << "GMAGICK: preloadAlpha" << fn;
165
 
166
        initialize();
167
        hasAlpha = false;
168
 
169
        if (!QFile::exists(fn))
170
                return false;
171
 
172
        try {
173
                Image image(std::string(fn.toUtf8()));
174
 
175
                hasAlpha = image.matte();
176
 
177
                if (!hasAlpha) {
178
                        return true; //No need to load any image data
179
                } else {
180
                        return loadPicture(fn, 0, 0, false);
181
                }
182
 
183
        } catch (std::exception &error_) {
184
                qDebug() << "GraphicsMagic Exception in ScImgDataLoader_GMagick::preloadAlphaChannel("
185
                        << fn << "):" << error_.what();
186
                return false;
187
        }
188
        return true;
189
}
190
 
191
bool ScImgDataLoader_GMagick::loadPicture(const QString& fn, int /*page*/, int res, bool thumbnail)
192
{
193
        qDebug() << "Loading image" << fn << "Tumbnail:" << thumbnail;
194
 
195
        if (!QFile::exists(fn))
196
                return false;
197
 
198
        initialize();
199
 
200
        try {
201
                Image image(std::string(fn.toUtf8()));
202
 
203
                qDebug() << "Detected format:" << QString(image.format().c_str())
204
                        << ", has matte(alpha):" << image.matte();
205
 
206
                int width = image.baseColumns();
207
                int height = image.baseRows();
208
 
209
                image.resolutionUnits(PixelsPerInchResolution);
210
                double xres = image.xResolution();
211
                double yres = image.yResolution();
212
                int resInf = m_imageInfoRecord.lowResType;
213
 
214
                if (image.colorSpace() == CMYKColorspace) {
215
                        qDebug() << "CMYK image";
216
                        m_useRawImage = true;
217
                        if (!read_cmyk(&image, &r_image, width, height)) return false;
218
                        m_imageInfoRecord.colorspace = ColorSpaceCMYK;
15132 jghali 219
                        m_pixelFormat = (r_image.channels() == 5) ? Format_CMYKA_8 : Format_CMYK_8;
13960 herm 220
                } else {
221
                        m_useRawImage = false;
222
                        m_image = QImage(width, height, QImage::Format_ARGB32);
223
                        if (!read_rgb(&image, &m_image, width, height)) return false;
224
                        m_imageInfoRecord.colorspace = ColorSpaceRGB;
15132 jghali 225
                        m_pixelFormat = Format_BGRA_8;
13960 herm 226
                }
227
                m_imageInfoRecord.type = ImageTypeOther;
228
                m_imageInfoRecord.exifDataValid = false;
229
                m_imageInfoRecord.xres = qMax(72, qRound(xres));
230
                m_imageInfoRecord.yres = qMax(72, qRound(yres));
231
                m_imageInfoRecord.lowResType = resInf;
232
                m_imageInfoRecord.BBoxX = 0;
233
                m_imageInfoRecord.BBoxH = m_image.height();
234
                m_imageInfoRecord.valid = true;
235
        } catch (std::exception &error_) {
236
                qDebug() << "GraphicsMagic Exception in ScImgDataLoader_GMagick::loadImage("
237
                        << fn << "):" << error_.what();
238
                return false;
239
        }
240
        return true;
13964 herm 241
}
242