Subversion Repositories Scribus

Rev

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