Subversion Repositories Scribus

Rev

Rev 5937 | Rev 5949 | Go to most recent revision | Details | Compare with Previous | 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
 
5947 jghali 157
                if( xres <= 1.0 || yres <= 1.0 )
158
                {
159
                        xres = yres = 72.0;
160
                        QFileInfo qfi(fn);
161
                        qWarning("Warning: %s may be corrupted", qfi.fileName().local8Bit());
162
                }
163
 
5937 jghali 164
                if (!m_image.create(widtht,heightt,32))
165
                {
166
                        TIFFClose(tif);
167
                        return false;
168
                }
169
                m_image.setAlphaBuffer(true);
170
                uint32 *bits = 0;
171
                if (photometric == PHOTOMETRIC_SEPARATED)
172
                {
173
                        if (TIFFIsTiled(tif))
174
                        {
175
                                uint32 columns, rows;
176
                                uint32 *tile_buf;
177
                                uint32 xt, yt;
178
                                TIFFGetField(tif, TIFFTAG_TILEWIDTH,  &columns);
179
                                TIFFGetField(tif, TIFFTAG_TILELENGTH, &rows);
180
                                tile_buf = (uint32*) _TIFFmalloc(columns*rows*sizeof(uint32));
181
                                if (tile_buf == NULL)
182
                                {
183
                                        TIFFClose(tif);
184
                                        return false;
185
                                }
186
                                uint32 tileW = columns, tileH = rows;
187
                                for (yt = 0; yt < (uint32) m_image.height(); yt += rows)
188
                                {
189
                                        if (yt > (uint) m_image.height())
190
                                                break;
191
                                        if (m_image.height()-yt < rows)
192
                                                tileH = m_image.height()-yt;
193
                                        tileW = columns;
194
                                        register uint32 yi;
195
                                        for (xt = 0; xt < (uint) m_image.width(); xt += columns)
196
                                        {
197
                                                TIFFReadTile(tif, tile_buf, xt, yt, 0, 0);
198
                                                for (yi = 0; yi < tileH; yi++)
199
                                                        _TIFFmemcpy(m_image.scanLine(yt+(tileH-1-yi))+xt, tile_buf+tileW*yi, tileW*4);
200
                                        }
201
                                }
202
                                _TIFFfree(tile_buf);
203
                        }
204
                        else
205
                        {
206
                                tsize_t bytesperrow = TIFFScanlineSize(tif);
207
                                bits = (uint32 *) _TIFFmalloc(bytesperrow);
208
                                if (bits)
209
                                {
210
                                        for (unsigned int y = 0; y < heightt; y++)
211
                                        {
212
                                                if (TIFFReadScanline(tif, bits, y, 0))
213
                                                {
214
                                                        memcpy(m_image.scanLine(y), bits, widtht * 4);
215
                                                }
216
                                        }
217
                                        _TIFFfree(bits);
218
                                }
219
                        }
220
                        isCMYK = true;
221
                }
222
                else
223
                {
224
                        bits = (uint32 *) _TIFFmalloc(size * sizeof(uint32));
225
                        if(bits)
226
                        {
227
                                if (TIFFReadRGBAImage(tif, widtht, heightt, bits, 0))
228
                                {
229
                                        for(unsigned int y = 0; y < heightt; y++)
230
                                                memcpy(m_image.scanLine(heightt - 1 - y), bits + y * widtht, widtht * 4);
231
                                }
232
                                _TIFFfree(bits);
233
                                if (bitspersample == 1)
234
                                        bilevel = true;
235
                        }
236
                }
237
                swapRGBA();
238
#ifdef HAVE_CMS
239
                DWORD EmbedLen = 0;
240
                LPBYTE EmbedBuffer;
241
                if (TIFFGetField(tif, TIFFTAG_ICCPROFILE, &EmbedLen, &EmbedBuffer))
242
                {
243
                        const char *Descriptor;
244
                        cmsHPROFILE tiffProf = cmsOpenProfileFromMem(EmbedBuffer, EmbedLen);
245
                        Descriptor = cmsTakeProductDesc(tiffProf);
246
                        m_embeddedProfile.duplicate((const char*) EmbedBuffer, EmbedLen);
247
                        m_imageInfoRecord.profileName = QString(Descriptor);
248
                        m_imageInfoRecord.isEmbedded = true;
249
                        cmsCloseProfile(tiffProf);
250
                }
251
                else
252
                {
253
                        m_imageInfoRecord.isEmbedded = false;
254
                        m_imageInfoRecord.profileName = "";
255
                }
256
#endif // HAVE_CMS
257
                unsigned int PhotoshopLen = 0;
258
                unsigned char* PhotoshopBuffer;
259
                if (TIFFGetField(tif, TIFFTAG_PHOTOSHOP, &PhotoshopLen, &PhotoshopBuffer) )
260
                {
261
                        if (PhotoshopLen != 0)
262
                        {
263
                                QByteArray arrayPhot(PhotoshopLen);
264
                                arrayPhot.duplicate((const char*)PhotoshopBuffer,PhotoshopLen);
265
                                QDataStream strPhot(arrayPhot,IO_ReadOnly);
266
                                strPhot.setByteOrder( QDataStream::BigEndian );
267
                                PSDHeader fakeHeader;
268
                                fakeHeader.width = m_image.width();
269
                                fakeHeader.height = m_image.height();
270
                                parseRessourceData(strPhot, fakeHeader, PhotoshopLen);
271
                                m_imageInfoRecord.valid = (m_imageInfoRecord.PDSpathData.size())>0?true:false;
272
                        }
273
                }
274
                TIFFClose(tif);
275
                if (resolutionunit == RESUNIT_INCH)
276
                {
277
                        m_image.setDotsPerMeterX ((int) (xres / 0.0254));
278
                        m_image.setDotsPerMeterY ((int) (yres / 0.0254));
279
                        m_imageInfoRecord.xres = qRound(xres);
280
                        m_imageInfoRecord.yres = qRound(yres);
281
                }
282
                else if (resolutionunit == RESUNIT_CENTIMETER)
283
                {
284
                        m_image.setDotsPerMeterX ((int) (xres * 100.0));
285
                        m_image.setDotsPerMeterY ((int) (yres * 100.0));
286
                        m_imageInfoRecord.xres = qRound(xres*2.54);
287
                        m_imageInfoRecord.yres = qRound(yres*2.54);
288
                }
289
                if (isCMYK)
290
                        m_imageInfoRecord.colorspace = 1;
291
                else if (bilevel)
292
                        m_imageInfoRecord.colorspace = 2;
293
                else
294
                        m_imageInfoRecord.colorspace = 0;
295
                m_imageInfoRecord.layerInfo.clear();
296
                m_imageInfoRecord.BBoxX = 0;
297
                m_imageInfoRecord.BBoxH = m_image.height();
298
                return true;
299
        }
300
        return false;
301
}