Subversion Repositories Scribus

Rev

Rev 5947 | Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
5937 jghali 1
#include <qfile.h>
2
#include <qfileinfo.h>
3
#include "scconfig.h"
4
#include "scimgdataloader_tiff.h"
5
 
6
#ifdef HAVE_TIFF
7
        #include <tiffio.h>
8
#endif
9
 
10
#ifdef HAVE_CMS
11
        #include CMS_INC
12
#endif
13
 
14
ScImgDataLoader_TIFF::ScImgDataLoader_TIFF(void) : ScImgDataLoader()
15
{
16
        initSupportedFormatList();
17
}
18
 
19
void ScImgDataLoader_TIFF::initSupportedFormatList(void)
20
{
21
        m_supportedFormats.clear();
22
        m_supportedFormats.append( "tif" );
23
        m_supportedFormats.append( "tiff" );
24
}
25
 
26
void ScImgDataLoader_TIFF::loadEmbeddedProfile(const QString& fn)
27
{
28
        m_embeddedProfile.resize(0);
29
        m_profileComponents = 0;
30
#ifdef HAVE_CMS
31
        if ( !QFile::exists(fn) )
32
                return;
33
        TIFF* tif = TIFFOpen(fn.local8Bit(), "r");
34
        if(tif)
35
        {
36
                DWORD EmbedLen = 0;
37
                LPBYTE EmbedBuffer;
38
                if (TIFFGetField(tif, TIFFTAG_ICCPROFILE, &EmbedLen, &EmbedBuffer))
39
                {
40
                        cmsHPROFILE tiffProf = cmsOpenProfileFromMem(EmbedBuffer, EmbedLen);
41
                        if (tiffProf)
42
                        {
43
                                if (static_cast<int>(cmsGetColorSpace(tiffProf)) == icSigRgbData)
44
                                        m_profileComponents = 3;
45
                                if (static_cast<int>(cmsGetColorSpace(tiffProf)) == icSigCmykData)
46
                                        m_profileComponents = 4;
47
                                m_embeddedProfile.duplicate((const char*) EmbedBuffer, EmbedLen);
48
                        }
49
                        cmsCloseProfile(tiffProf);
50
                }
51
                TIFFClose(tif);
52
        }
53
#endif
54
}
55
 
56
void ScImgDataLoader_TIFF::preloadAlphaChannel(const QString& fn, int res)
57
{
58
        float xres, yres;
59
        short resolutionunit = 0;
60
        initialize();
61
        QFileInfo fi = QFileInfo(fn);
62
        if (!fi.exists())
63
                return;
64
        QString tmp, BBox, tmp2;
65
#ifdef HAVE_TIFF
66
        TIFF* tif = TIFFOpen(fn.local8Bit(), "r");
67
        if(tif)
68
        {
69
                unsigned width, height, size;
70
                TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &width);
71
                TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &height);
72
                TIFFGetField(tif, TIFFTAG_XRESOLUTION, &xres);
73
                TIFFGetField(tif, TIFFTAG_YRESOLUTION, &yres);
74
                TIFFGetField(tif, TIFFTAG_RESOLUTIONUNIT , &resolutionunit);
75
                size = width * height;
76
                uint16 photometric, bitspersample, samplesperpixel, fillorder;
77
                TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &photometric);
78
                TIFFGetField(tif, TIFFTAG_BITSPERSAMPLE, &bitspersample);
79
                TIFFGetField(tif, TIFFTAG_SAMPLESPERPIXEL, &samplesperpixel);
80
                TIFFGetField(tif, TIFFTAG_FILLORDER, &fillorder);
81
                uint32 *bits = 0;
82
                if (photometric == PHOTOMETRIC_SEPARATED)
83
                {
84
                        TIFFClose(tif);
85
                        return;
86
                }
87
                else
88
                {
89
                        m_image.create(width,height,32);
90
                        m_image.setAlphaBuffer(true);
91
                        bits = (uint32 *) _TIFFmalloc(size * sizeof(uint32));
92
                        if(bits)
93
                        {
94
                                if (TIFFReadRGBAImage(tif, width, height, bits, 0))
95
                                {
96
                                        for(unsigned int y = 0; y < height; y++)
97
                                                memcpy(m_image.scanLine(height - 1 - y), bits + y * width, width * 4);
98
                                }
99
                                _TIFFfree(bits);
100
                        }
101
                        else
102
                                m_image.reset();
103
                        TIFFClose(tif);
104
                }
105
        }
106
#else
107
        qDebug("TIFF Support not available");
108
#endif // HAVE_TIFF
109
}
110
 
111
bool ScImgDataLoader_TIFF::loadPicture(const QString& fn, int /*gsRes*/, bool /*thumbnail*/)
112
{
113
        bool bilevel = false;
114
        short resolutionunit = 0;
115
        float xres = 72.0, yres = 72.0;
116
        if (!QFile::exists(fn))
117
                return false;
118
 
119
        initialize();
120
        m_imageInfoRecord.type = 1;
121
        TIFF* tif = TIFFOpen(fn.local8Bit(), "r");
122
        if(tif)
123
        {
124
                bool isCMYK = false;
125
                unsigned widtht, heightt, size;
126
                char *description=0, *copyright=0, *datetime=0, *artist=0, *scannerMake=0, *scannerModel=0;
127
 
128
                TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &widtht);
129
                TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &heightt);
130
                TIFFGetField(tif, TIFFTAG_XRESOLUTION, &xres);
131
                TIFFGetField(tif, TIFFTAG_YRESOLUTION, &yres);
132
                TIFFGetField(tif, TIFFTAG_RESOLUTIONUNIT , &resolutionunit);
133
                size = widtht * heightt;
134
                uint16 photometric, bitspersample, samplesperpixel, fillorder;
135
                TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &photometric);
136
                TIFFGetField(tif, TIFFTAG_BITSPERSAMPLE, &bitspersample);
137
                TIFFGetField(tif, TIFFTAG_SAMPLESPERPIXEL, &samplesperpixel);
138
                TIFFGetField(tif, TIFFTAG_FILLORDER, &fillorder);
139
 
140
                TIFFGetField(tif, TIFFTAG_MAKE, &scannerMake);
141
                TIFFGetField(tif, TIFFTAG_MODEL, &scannerModel);
142
                TIFFGetField(tif, TIFFTAG_IMAGEDESCRIPTION, &description);
143
                TIFFGetField(tif, TIFFTAG_COPYRIGHT, &copyright);
144
                TIFFGetField(tif, TIFFTAG_DATETIME, &datetime);
145
                TIFFGetField(tif, TIFFTAG_ARTIST, &artist);
146
                m_imageInfoRecord.exifInfo.cameraName = QString(scannerModel);
147
                m_imageInfoRecord.exifInfo.cameraVendor = QString(scannerMake);
148
                m_imageInfoRecord.exifInfo.comment = QString(description);
149
                m_imageInfoRecord.exifInfo.userComment = QString(copyright);
150
                m_imageInfoRecord.exifInfo.width = widtht;
151
                m_imageInfoRecord.exifInfo.height = heightt;
152
                m_imageInfoRecord.exifInfo.dateTime = QString(datetime);
153
                m_imageInfoRecord.exifInfo.artist = QString(artist);
154
                m_imageInfoRecord.exifInfo.thumbnail = QImage();
155
                m_imageInfoRecord.exifDataValid = true;
156
 
157
                if (!m_image.create(widtht,heightt,32))
158
                {
159
                        TIFFClose(tif);
160
                        return false;
161
                }
162
                m_image.setAlphaBuffer(true);
163
                uint32 *bits = 0;
164
                if (photometric == PHOTOMETRIC_SEPARATED)
165
                {
166
                        if (TIFFIsTiled(tif))
167
                        {
168
                                uint32 columns, rows;
169
                                uint32 *tile_buf;
170
                                uint32 xt, yt;
171
                                TIFFGetField(tif, TIFFTAG_TILEWIDTH,  &columns);
172
                                TIFFGetField(tif, TIFFTAG_TILELENGTH, &rows);
173
                                tile_buf = (uint32*) _TIFFmalloc(columns*rows*sizeof(uint32));
174
                                if (tile_buf == NULL)
175
                                {
176
                                        TIFFClose(tif);
177
                                        return false;
178
                                }
179
                                uint32 tileW = columns, tileH = rows;
180
                                for (yt = 0; yt < (uint32) m_image.height(); yt += rows)
181
                                {
182
                                        if (yt > (uint) m_image.height())
183
                                                break;
184
                                        if (m_image.height()-yt < rows)
185
                                                tileH = m_image.height()-yt;
186
                                        tileW = columns;
187
                                        register uint32 yi;
188
                                        for (xt = 0; xt < (uint) m_image.width(); xt += columns)
189
                                        {
190
                                                TIFFReadTile(tif, tile_buf, xt, yt, 0, 0);
191
                                                for (yi = 0; yi < tileH; yi++)
192
                                                        _TIFFmemcpy(m_image.scanLine(yt+(tileH-1-yi))+xt, tile_buf+tileW*yi, tileW*4);
193
                                        }
194
                                }
195
                                _TIFFfree(tile_buf);
196
                        }
197
                        else
198
                        {
199
                                tsize_t bytesperrow = TIFFScanlineSize(tif);
200
                                bits = (uint32 *) _TIFFmalloc(bytesperrow);
201
                                if (bits)
202
                                {
203
                                        for (unsigned int y = 0; y < heightt; y++)
204
                                        {
205
                                                if (TIFFReadScanline(tif, bits, y, 0))
206
                                                {
207
                                                        memcpy(m_image.scanLine(y), bits, widtht * 4);
208
                                                }
209
                                        }
210
                                        _TIFFfree(bits);
211
                                }
212
                        }
213
                        isCMYK = true;
214
                }
215
                else
216
                {
217
                        bits = (uint32 *) _TIFFmalloc(size * sizeof(uint32));
218
                        if(bits)
219
                        {
220
                                if (TIFFReadRGBAImage(tif, widtht, heightt, bits, 0))
221
                                {
222
                                        for(unsigned int y = 0; y < heightt; y++)
223
                                                memcpy(m_image.scanLine(heightt - 1 - y), bits + y * widtht, widtht * 4);
224
                                }
225
                                _TIFFfree(bits);
226
                                if (bitspersample == 1)
227
                                        bilevel = true;
228
                        }
229
                }
230
                swapRGBA();
231
#ifdef HAVE_CMS
232
                DWORD EmbedLen = 0;
233
                LPBYTE EmbedBuffer;
234
                if (TIFFGetField(tif, TIFFTAG_ICCPROFILE, &EmbedLen, &EmbedBuffer))
235
                {
236
                        const char *Descriptor;
237
                        cmsHPROFILE tiffProf = cmsOpenProfileFromMem(EmbedBuffer, EmbedLen);
238
                        Descriptor = cmsTakeProductDesc(tiffProf);
239
                        m_embeddedProfile.duplicate((const char*) EmbedBuffer, EmbedLen);
240
                        m_imageInfoRecord.profileName = QString(Descriptor);
241
                        m_imageInfoRecord.isEmbedded = true;
242
                        cmsCloseProfile(tiffProf);
243
                }
244
                else
245
                {
246
                        m_imageInfoRecord.isEmbedded = false;
247
                        m_imageInfoRecord.profileName = "";
248
                }
249
#endif // HAVE_CMS
250
                unsigned int PhotoshopLen = 0;
251
                unsigned char* PhotoshopBuffer;
252
                if (TIFFGetField(tif, TIFFTAG_PHOTOSHOP, &PhotoshopLen, &PhotoshopBuffer) )
253
                {
254
                        if (PhotoshopLen != 0)
255
                        {
256
                                QByteArray arrayPhot(PhotoshopLen);
257
                                arrayPhot.duplicate((const char*)PhotoshopBuffer,PhotoshopLen);
258
                                QDataStream strPhot(arrayPhot,IO_ReadOnly);
259
                                strPhot.setByteOrder( QDataStream::BigEndian );
260
                                PSDHeader fakeHeader;
261
                                fakeHeader.width = m_image.width();
262
                                fakeHeader.height = m_image.height();
263
                                parseRessourceData(strPhot, fakeHeader, PhotoshopLen);
264
                                m_imageInfoRecord.valid = (m_imageInfoRecord.PDSpathData.size())>0?true:false;
265
                        }
266
                }
267
                TIFFClose(tif);
268
                if (resolutionunit == RESUNIT_INCH)
269
                {
270
                        m_image.setDotsPerMeterX ((int) (xres / 0.0254));
271
                        m_image.setDotsPerMeterY ((int) (yres / 0.0254));
272
                        m_imageInfoRecord.xres = qRound(xres);
273
                        m_imageInfoRecord.yres = qRound(yres);
274
                }
275
                else if (resolutionunit == RESUNIT_CENTIMETER)
276
                {
277
                        m_image.setDotsPerMeterX ((int) (xres * 100.0));
278
                        m_image.setDotsPerMeterY ((int) (yres * 100.0));
279
                        m_imageInfoRecord.xres = qRound(xres*2.54);
280
                        m_imageInfoRecord.yres = qRound(yres*2.54);
281
                }
282
                if (isCMYK)
283
                        m_imageInfoRecord.colorspace = 1;
284
                else if (bilevel)
285
                        m_imageInfoRecord.colorspace = 2;
286
                else
287
                        m_imageInfoRecord.colorspace = 0;
288
                m_imageInfoRecord.layerInfo.clear();
289
                m_imageInfoRecord.BBoxX = 0;
290
                m_imageInfoRecord.BBoxH = m_image.height();
291
                return true;
292
        }
293
        return false;
294
}