Subversion Repositories Scribus

Rev

Rev 15677 | 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>
15677 christoph 12
#include "scimgdataloader_gmagick.h"
13960 herm 13
#include "scconfig.h"
14
 
13964 herm 15
 
15677 christoph 16
 
17
bool ScImgDataLoader_GMagick::gm_initialized = false;
18
 
19
ScImgDataLoader_GMagick::ScImgDataLoader_GMagick(void)
13960 herm 20
{
15677 christoph 21
        initSupportedFormatList();
22
        m_useRawImage = true;
23
}
24
 
25
 
26
void ScImgDataLoader_GMagick::initSupportedFormatList(void)
27
{
28
        //This is unused! See util_formats.{h,cpp}
29
        m_supportedFormats.clear();
30
        m_supportedFormats.append("bmp"); //TODO
31
}
32
 
33
 
34
void ScImgDataLoader_GMagick::initGraphicsMagick()
35
{
36
        if (!gm_initialized) {
37
                InitializeMagick(0); //TODO: Get path
38
                gm_initialized = true;
39
        }
40
}
41
 
42
 
43
bool ScImgDataLoader_GMagick::readCMYK(Image *input, RawImage *output, int width, int height)
44
{
13960 herm 45
        /* Mapping:
46
                red:     cyan
47
                green:   magenta
48
                blue:    yellow
49
                opacity: black
50
                index:   alpha
51
        */
52
        //Copied from GraphicsMagick header and modified
53
        #define GetCyanSample(p) (p.red)
54
        #define GetMagentaSample(p) (p.green)
55
        #define GetYellowSample(p) (p.blue)
56
        #define GetCMYKBlackSample(p) (p.opacity)
57
        #define GetAlphaSample(p) (p)
15677 christoph 58
 
59
        bool hasAlpha = input->matte;
60
 
13960 herm 61
        if (!output->create(width, height, hasAlpha ? 5 : 4)) return false;
15677 christoph 62
 
63
        ExceptionInfo exception;
64
        GetExceptionInfo(&exception);
65
        const PixelPacket *pixels = AcquireImagePixels(input, 0, 0, width, height, &exception);
66
        if (exception.severity != UndefinedException)
67
                CatchException(&exception);
13986 herm 68
        if (!pixels) {
15677 christoph 69
                qCritical() << QObject::tr("Could not get pixel data!");
70
                return false;
71
        }
13986 herm 72
 
15677 christoph 73
    const IndexPacket *alpha = 0;
13986 herm 74
    if (hasAlpha) {
15677 christoph 75
        alpha = AccessImmutableIndexes(input);
13986 herm 76
        if (!alpha) {
77
            qCritical() << QObject::tr("Could not get alpha channel data!");
78
            return false;
79
        }
80
    }
15677 christoph 81
 
13960 herm 82
        unsigned char *buffer = output->bits();
13986 herm 83
        if (!buffer) {
84
           qCritical() << QObject::tr("Could not allocate output buffer!");
85
           return false;
86
    }
13960 herm 87
 
88
        int i;
89
        for (i = 0; i < width*height; i++) {
90
                *buffer++ = ScaleQuantumToChar(GetCyanSample(pixels[i]));
91
                *buffer++ = ScaleQuantumToChar(GetMagentaSample(pixels[i]));
92
                *buffer++ = ScaleQuantumToChar(GetYellowSample(pixels[i]));
93
                *buffer++ = ScaleQuantumToChar(GetCMYKBlackSample(pixels[i]));
94
                if (hasAlpha) {
95
                        *buffer++ = 255 - ScaleQuantumToChar(GetAlphaSample(alpha[i]));
96
                }
97
        }
98
        return true;
99
}
100
 
101
 
15677 christoph 102
bool ScImgDataLoader_GMagick::readRGB(Image *input, QImage *output, int width, int height)
13960 herm 103
{
104
        //Copied from GraphicsMagick header and modified
15677 christoph 105
#define GetRedSample(p) (p.red)
106
#define GetGreenSample(p) (p.green)
107
#define GetBlueSample(p) (p.blue)
108
#define GetRGBAlphaSample(p) (p.opacity)
109
 
110
        bool hasAlpha = input->matte;
111
 
112
        ExceptionInfo exception;
113
        GetExceptionInfo(&exception);
114
        const PixelPacket *pixels = AcquireImagePixels(input, 0, 0, width, height, &exception);
115
        if (exception.severity != UndefinedException)
116
                CatchException(&exception);
117
        if (!pixels) {
118
                qCritical() << QObject::tr("Could not get pixel data!");
119
                return false;
120
        }
121
 
13960 herm 122
        unsigned char *buffer = output->bits();
13986 herm 123
        if (!buffer) {
15677 christoph 124
                qCritical() << QObject::tr("Could not allocate output buffer!");
125
                return false;
126
        }
127
 
13960 herm 128
        int i;
129
        for (i = 0; i < width*height; i++) {
130
                *buffer++ = ScaleQuantumToChar(GetBlueSample(pixels[i]));
131
                *buffer++ = ScaleQuantumToChar(GetGreenSample(pixels[i]));
132
                *buffer++ = ScaleQuantumToChar(GetRedSample(pixels[i]));
133
                if (hasAlpha) {
134
                        *buffer++ = 255 - ScaleQuantumToChar(GetRGBAlphaSample(pixels[i]));
135
                } else {
136
                        *buffer++ = 255;
137
                }
138
        }
139
        return true;
140
}
141
 
142
 
15677 christoph 143
bool ScImgDataLoader_GMagick::loadPicture(const QString& fn, int /*page*/, int res, bool thumbnail)
13960 herm 144
{
15677 christoph 145
        initGraphicsMagick();
146
        qDebug() << "Loading image" << fn << "Tumbnail:" << thumbnail;
13960 herm 147
 
15677 christoph 148
        if (!QFile::exists(fn))
149
                return false;
150
 
151
        initialize();
152
 
153
        ExceptionInfo exception;
154
        GetExceptionInfo(&exception);
155
        ImageInfo *image_info = CloneImageInfo(0);
156
        strcpy(image_info->filename, fn.toUtf8().data());
157
        image_info->units = PixelsPerInchResolution;
158
        Image *image = ReadImage(image_info, &exception);
159
        if (exception.severity != UndefinedException)
160
                CatchException(&exception);
161
        if (!image) {
162
                qCritical() << "Failed to read image" << fn;
163
                return false;
13960 herm 164
        }
165
 
15714 christoph 166
//      qDebug() << "has matte(alpha):" << image->matte;
167
        int width = image->columns;
168
        int height = image->rows;
15677 christoph 169
 
15714 christoph 170
        double xres = image->x_resolution;
171
        double yres = image->y_resolution;
15677 christoph 172
 
173
        if (image->colorspace == CMYKColorspace) {
174
                qDebug() << "CMYK image";
175
                m_useRawImage = true;
176
                if (!readCMYK(image, &r_image, width, height)) return false;
177
                m_imageInfoRecord.colorspace = ColorSpaceCMYK;
178
                m_pixelFormat = (r_image.channels() == 5) ? Format_CMYKA_8 : Format_CMYK_8;
179
        } else {
180
                m_useRawImage = false;
181
                m_image = QImage(width, height, QImage::Format_ARGB32);
182
                if (!readRGB(image, &m_image, width, height)) return false;
183
                m_imageInfoRecord.colorspace = ColorSpaceRGB;
184
                m_pixelFormat = Format_BGRA_8;
13960 herm 185
        }
15677 christoph 186
        m_imageInfoRecord.type = ImageTypeOther;
187
        m_imageInfoRecord.exifDataValid = false;
188
        m_imageInfoRecord.xres = qMax(72, qRound(xres));
189
        m_imageInfoRecord.yres = qMax(72, qRound(yres));
190
        m_imageInfoRecord.BBoxX = 0;
191
        m_imageInfoRecord.BBoxH = m_image.height();
192
        m_imageInfoRecord.valid = true;
193
        return true;
13960 herm 194
}
195
 
15677 christoph 196
 
13960 herm 197
bool ScImgDataLoader_GMagick::preloadAlphaChannel(const QString& fn, int /*page*/, int res, bool& hasAlpha)
198
{
15677 christoph 199
        initGraphicsMagick();
13960 herm 200
        qDebug() << "GMAGICK: preloadAlpha" << fn;
201
        initialize();
202
        hasAlpha = false;
15677 christoph 203
 
13960 herm 204
        if (!QFile::exists(fn))
205
                return false;
206
 
15677 christoph 207
        ExceptionInfo exception;
208
        GetExceptionInfo(&exception);
209
        ImageInfo *image_info = CloneImageInfo(0);
210
        strcpy(image_info->filename, fn.toUtf8().data());
211
        image_info->units = PixelsPerInchResolution;
212
        Image *image = PingImage(image_info, &exception);
213
        if (exception.severity != UndefinedException)
214
                CatchException(&exception);
215
        if (!image) {
216
                qCritical() << "Failed to read image" << fn;
13960 herm 217
                return false;
218
        }
15677 christoph 219
 
220
        hasAlpha = image->matte;
221
        if (!hasAlpha) return true;
222
        return loadPicture(fn, 0, 0, false);
13960 herm 223
}
224
 
15677 christoph 225
 
226
void ScImgDataLoader_GMagick::loadEmbeddedProfile(const QString& fn, int /*page*/)
13960 herm 227
{
15677 christoph 228
        qDebug() << "GMAGICK: loadEmbeddedProfile";
13960 herm 229
 
15677 christoph 230
        initGraphicsMagick();
231
        m_embeddedProfile.resize(0);
232
        m_profileComponents = 0;
233
        if (!QFile::exists(fn)) return;
13960 herm 234
 
15677 christoph 235
        ExceptionInfo exception;
236
        GetExceptionInfo(&exception);
237
        ImageInfo *image_info = CloneImageInfo(0);
238
        strcpy(image_info->filename, fn.toUtf8().data());
239
        image_info->units = PixelsPerInchResolution;
240
        Image *image = ReadImage(image_info, &exception);
241
        if (exception.severity != UndefinedException)
242
                CatchException(&exception);
243
        if (!image) {
244
                qCritical() << "Failed to read image" << fn;
245
                return;
13960 herm 246
        }
15677 christoph 247
 
248
        size_t length = 0;
249
        const unsigned char *src = GetImageProfile(image, "ICM", &length);
250
        char *dest = m_embeddedProfile.data();
251
 
252
        if (image->colorspace == CMYKColorspace) {
253
                m_profileComponents = 4;
254
        } else if (image->colorspace == RGBColorspace) {
255
                m_profileComponents = 3;
256
        }
257
 
258
        m_embeddedProfile.resize(length);
259
        memcpy(dest, src, length);
13964 herm 260
}
261