Subversion Repositories Scribus

Compare Revisions

Ignore whitespace Rev 5936 → Rev 5937

/branches/Version13x/Scribus/scribus/extimageprops.h
33,7 → 33,7
Q_OBJECT
 
public:
ExtImageProps( QWidget* parent, ScImage::ImageInfoRecord *info, PageItem *item, ScribusView *view );
ExtImageProps( QWidget* parent, ImageInfoRecord *info, PageItem *item, ScribusView *view );
~ExtImageProps() {};
 
QTabWidget* propsTab;
/branches/Version13x/Scribus/scribus/scimgdataloader.h
0,0 → 1,45
#ifndef SCIMGDATALOADER_H
#define SCIMGDATALOADER_H
 
#include "scribusapi.h"
#include <qcstring.h>
#include <qimage.h>
#include <qstringlist.h>
 
#include "scimagestructs.h"
 
class ScImgDataLoader
{
protected:
ScImgDataLoader(void);
 
QStringList m_supportedFormats;
 
QImage m_image;
ImageInfoRecord m_imageInfoRecord;
QByteArray m_embeddedProfile;
int m_profileComponents;
 
void swapRGBA(void);
 
QString getPascalString(QDataStream & s);
void parseRessourceData( QDataStream & s, const PSDHeader & header, uint size );
 
public:
virtual ~ScImgDataLoader(void) {};
 
const QStringList& supportedFormats(void) const { return m_supportedFormats; }
bool supportFormat(const QString& fmt);
 
QImage& image(void) { return m_image; }
QByteArray& embeddedProfile(void) { return m_embeddedProfile; }
ImageInfoRecord& imageInfoRecord(void) { return m_imageInfoRecord; }
 
virtual void initialize(void);
 
virtual void preloadAlphaChannel(const QString& fn, int res) = 0;
virtual void loadEmbeddedProfile(const QString& fn) = 0;
virtual bool loadPicture(const QString& fn, int res, bool thumbnail) = 0;
};
 
#endif
Property changes:
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+Author Date Id Revision
\ No newline at end of property
Index: branches/Version13x/Scribus/scribus/scimgdataloader.cpp
===================================================================
--- branches/Version13x/Scribus/scribus/scimgdataloader.cpp (nonexistent)
+++ branches/Version13x/Scribus/scribus/scimgdataloader.cpp (revision 5937)
@@ -0,0 +1,237 @@
+#include "scimgdataloader.h"
+
+ScImgDataLoader::ScImgDataLoader(void)
+{
+ initialize();
+}
+
+void ScImgDataLoader::initialize(void)
+{
+ m_image = QImage();
+ m_imageInfoRecord.init();
+ m_embeddedProfile.resize(0);
+ m_profileComponents = 0;
+}
+
+bool ScImgDataLoader::supportFormat(const QString& fmt)
+{
+ QString format = fmt.lower();
+ return (m_supportedFormats.contains(format));
+}
+
+QString ScImgDataLoader::getPascalString(QDataStream & s)
+{
+ uchar len, tmp;
+ uint adj;
+ QString ret = "";
+ s >> len;
+ if (len == 0)
+ {
+ s >> tmp;
+ return ret;
+ }
+ for( int i = 0; i < len; i++ )
+ {
+ s >> tmp;
+ ret += QChar(tmp);
+ }
+ adj = (ret.length()+1) % 2;
+ s.device()->at( s.device()->at() + adj );
+ return ret;
+}
+
+void ScImgDataLoader::swapRGBA()
+{
+ for (int i = 0; i < m_image.height(); ++i)
+ {
+ unsigned int *ptr = (unsigned int *) m_image.scanLine(i);
+ unsigned char r, b;
+ for (int j = 0; j < m_image.width(); ++j)
+ {
+ unsigned char *p = (unsigned char *) ptr;
+ r = p[0];
+ b = p[2];
+ p[2] = r;
+ p[0] = b;
+ ptr++;
+ }
+ }
+}
+
+void ScImgDataLoader::parseRessourceData( QDataStream & s, const PSDHeader & header, uint size )
+{
+ uint signature, resSize, offset, resBase, vRes, hRes, adj;
+ ushort resID, hResUnit, vResUnit, dummyW;
+ QString resName;
+ uchar filler;
+ offset = 0;
+ bool first = false;
+ bool pathOpen = false;
+ FPoint firstPoint, firstControl;
+ FPointArray clip2;
+ while ((offset + 6)< size)
+ {
+ s >> signature;
+ offset += 4;
+ if(((signature >> 24)&0xff) != '8' ||
+ ((signature >> 16)&0xff) != 'B' ||
+ ((signature >> 8)&0xff) != 'I' ||
+ ((signature )&0xff) != 'M' )
+ break;
+ s >> resID;
+ offset += 2;
+ adj = s.device()->at();
+ resName = getPascalString(s);
+ offset += s.device()->at() - adj;
+ s >> resSize;
+ if(offset + resSize > size)
+ break;
+ resBase = s.device()->at();
+ if ( (resID >= 0x07d0) && (resID <= 0x0bb6) )
+ {
+ QString db1, db2;
+ short type;
+ uint data1, data2, data3, data4, data5, data6;
+ double frac1, frac2, frac3, frac4, frac5, frac6;
+ ushort man1, man2, man3, man4, man5, man6;
+ uint offset2;
+ offset2 = 0;
+ first = false;
+ pathOpen = false;
+ clip2.resize(0);
+ while (offset2 < resSize)
+ {
+ s >> type;
+ s >> data1;
+ frac1 = (data1 & 0x00FFFFFF) / 16777215.0;
+ man1 = (data1 & 0x0F000000) >> 24;
+ frac1 = (frac1 + man1) * header.height;
+ s >> data2;
+ frac2 = (data2 & 0x00FFFFFF) / 16777215.0;
+ man2 = (data2 & 0x0F000000) >> 24;
+ frac2 = (frac2 + man2) * header.width;
+ s >> data3;
+ frac3 = (data3 & 0x00FFFFFF) / 16777215.0;
+ man3 = (data3 & 0x0F000000) >> 24;
+ frac3 = (frac3 + man3) * header.height;
+ s >> data4;
+ frac4 = (data4 & 0x00FFFFFF) / 16777215.0;
+ man4 = (data4 & 0x0F000000) >> 24;
+ frac4 = (frac4 + man4) * header.width;
+ s >> data5;
+ frac5 = (data5 & 0x00FFFFFF) / 16777215.0;
+ man5 = (data5 & 0x0F000000) >> 24;
+ frac5 = (frac5 + man5) * header.height;
+ s >> data6;
+ frac6 = (data6 & 0x00FFFFFF) / 16777215.0;
+ man6 = (data6 & 0x0F000000) >> 24;
+ frac6 = (frac6 + man6) * header.width;
+ switch (type)
+ {
+ case 0:
+ case 3:
+ if (pathOpen)
+ {
+ clip2.addPoint(firstPoint);
+ clip2.addPoint(firstControl);
+ clip2.setMarker();
+ }
+ pathOpen = false;
+ first = true;
+ break;
+ case 1:
+ case 2:
+ case 4:
+ case 5:
+ if (first)
+ {
+ firstControl = FPoint(frac2, frac1);
+ firstPoint = FPoint(frac4, frac3);
+ clip2.addPoint(FPoint(frac4, frac3));
+ clip2.addPoint(FPoint(frac6, frac5));
+ }
+ else
+ {
+ clip2.addPoint(frac4, frac3);
+ clip2.addPoint(frac2, frac1);
+ clip2.addPoint(frac4, frac3);
+ clip2.addPoint(frac6, frac5);
+ }
+ pathOpen = true;
+ first = false;
+ break;
+ case 6:
+ first = true;
+ break;
+ default:
+ break;
+ }
+ offset2 += 26;
+ }
+ clip2.addPoint(firstPoint);
+ clip2.addPoint(firstControl);
+ m_imageInfoRecord.PDSpathData.insert(resName, clip2.copy());
+ }
+ else
+ {
+ switch (resID)
+ {
+ case 0x0bb7:
+ adj = s.device()->at();
+ m_imageInfoRecord.clipPath = getPascalString(s);
+ offset += s.device()->at() - adj;
+ break;
+ case 0x03ed:
+ s >> hRes;
+ s >> hResUnit;
+ s >> dummyW;
+ s >> vRes;
+ s >> vResUnit;
+ s >> dummyW;
+ m_imageInfoRecord.xres = qRound(hRes / 65536.0);
+ m_imageInfoRecord.yres = qRound(vRes / 65536.0);
+ break;
+ case 0x040f:
+ m_embeddedProfile.resize(resSize);
+ s.readRawBytes(m_embeddedProfile.data(), resSize);
+ break;
+ case 0x0409:
+ case 0x040C:
+ {
+ uint thdummy, thsize;
+ s >> thdummy;
+ s >> thdummy;
+ s >> thdummy;
+ s >> thdummy;
+ s >> thdummy;
+ s >> thsize;
+ s >> thdummy;
+ char* buffer = (char*)malloc(thsize);
+ s.readRawBytes(buffer, thsize);
+ QImage imth;
+ imth.loadFromData((const uchar*)buffer, thsize, "JPEG");
+ imth.convertDepth(32);
+ if (resID == 0x0409)
+ m_imageInfoRecord.exifInfo.thumbnail = imth.swapRGB();
+ else
+ m_imageInfoRecord.exifInfo.thumbnail = imth;
+ m_imageInfoRecord.exifDataValid = true;
+ free(buffer);
+ }
+ default:
+ break;
+ }
+ }
+ if (resBase + resSize <= size) {
+ s.device()->at( resBase + resSize );
+ offset += resSize;
+ }
+ if (resSize & 1)
+ {
+ s >> filler;
+ offset += 1;
+ }
+ }
+ if(offset<size)
+ s.device()->at( size );
+}
/branches/Version13x/Scribus/scribus/scimgdataloader.cpp
Property changes:
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+Author Date Id Revision
\ No newline at end of property
Index: branches/Version13x/Scribus/scribus/scimgdataloader_pdf.cpp
===================================================================
--- branches/Version13x/Scribus/scribus/scimgdataloader_pdf.cpp (nonexistent)
+++ branches/Version13x/Scribus/scribus/scimgdataloader_pdf.cpp (revision 5937)
@@ -0,0 +1,114 @@
+#include <qfile.h>
+#include <qfileinfo.h>
+#include "gsutil.h"
+#include "scpaths.h"
+#include "scribuscore.h"
+#include "scimgdataloader_pdf.h"
+
+ScImgDataLoader_PDF::ScImgDataLoader_PDF(void) : ScImgDataLoader()
+{
+ initSupportedFormatList();
+}
+
+void ScImgDataLoader_PDF::initSupportedFormatList(void)
+{
+ m_supportedFormats.clear();
+ m_supportedFormats.append( "pdf" );
+}
+
+void ScImgDataLoader_PDF::loadEmbeddedProfile(const QString& fn)
+{
+ m_embeddedProfile.resize(0);
+ m_profileComponents = 0;
+}
+
+bool ScImgDataLoader_PDF::loadPicture(const QString& fn, int gsRes, bool /*thumbnail*/)
+{
+ QStringList args;
+ if (!QFile::exists(fn))
+ return false;
+ QString tmpFile = QDir::convertSeparators(ScPaths::getTempFileDir() + "sc.png");
+ QString picFile = QDir::convertSeparators(fn);
+ float xres = gsRes;
+ float yres = gsRes;
+
+ initialize();
+ m_imageInfoRecord.type = 4;
+ m_imageInfoRecord.exifDataValid = false;
+ args.append("-r"+QString::number(gsRes));
+ args.append("-sOutputFile="+tmpFile);
+ args.append("-dFirstPage=1");
+ args.append("-dLastPage=1");
+ args.append(picFile);
+ int retg = callGS(args);
+ if (retg == 0)
+ {
+ m_image.load(tmpFile);
+ unlink(tmpFile);
+ m_image.setAlphaBuffer(true);
+ if (ScCore->havePNGAlpha() != 0)
+ {
+ for( int yi=0; yi < m_image.height(); ++yi )
+ {
+ QRgb *s = (QRgb*)(m_image.scanLine( yi ));
+ for(int xi=0; xi < m_image.width(); ++xi )
+ {
+ if((*s) == 0xffffffff)
+ (*s) &= 0x00ffffff;
+ s++;
+ }
+ }
+ }
+ m_imageInfoRecord.BBoxX = 0;
+ m_imageInfoRecord.BBoxH = m_image.height();
+ m_imageInfoRecord.xres = qRound(gsRes);
+ m_imageInfoRecord.yres = qRound(gsRes);
+ m_imageInfoRecord.colorspace = 0;
+ m_image.setDotsPerMeterX ((int) (xres / 0.0254));
+ m_image.setDotsPerMeterY ((int) (yres / 0.0254));
+ return true;
+ }
+ return false;
+}
+
+void ScImgDataLoader_PDF::preloadAlphaChannel(const QString& fn, int gsRes)
+{
+ float xres, yres;
+ short resolutionunit = 0;
+ initialize();
+ QFileInfo fi = QFileInfo(fn);
+ if (!fi.exists())
+ return;
+ QString tmp, BBox;
+ QString ext = fi.extension(false).lower();
+ QString tmpFile = QDir::convertSeparators(ScPaths::getTempFileDir() + "sc.png");
+ QString picFile = QDir::convertSeparators(fn);
+ QStringList args;
+ xres = gsRes;
+ yres = gsRes;
+ args.append("-r"+QString::number(gsRes));
+ args.append("-sOutputFile=\""+tmpFile + "\"");
+ args.append("-dFirstPage=1");
+ args.append("-dLastPage=1");
+ args.append("\""+picFile+"\"");
+ int retg = callGS(args);
+ if (retg == 0)
+ {
+ m_image.load(tmpFile);
+ unlink(tmpFile);
+ m_image.setAlphaBuffer(true);
+ if (ScCore->havePNGAlpha() != 0)
+ {
+ for( int yi=0; yi < m_image.height(); ++yi )
+ {
+ QRgb *s = (QRgb*)(m_image.scanLine( yi ));
+ for(int xi=0; xi < m_image.width(); ++xi )
+ {
+ if((*s) == 0xffffffff)
+ (*s) &= 0x00ffffff;
+ s++;
+ }
+ }
+ }
+ }
+}
/branches/Version13x/Scribus/scribus/scimgdataloader_pdf.cpp
Property changes:
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+Author Date Id Revision
\ No newline at end of property
Index: branches/Version13x/Scribus/scribus/scribusXml.cpp
===================================================================
--- branches/Version13x/Scribus/scribus/scribusXml.cpp (revision 5936)
+++ branches/Version13x/Scribus/scribus/scribusXml.cpp (revision 5937)
@@ -883,7 +883,7 @@
}
if (it.tagName() == "PSDLayer")
{
- struct ScImage::LoadRequest loadingInfo;
+ struct ImageLoadRequest loadingInfo;
loadingInfo.blend = it.attribute("Blend");
loadingInfo.opacity = it.attribute("Opacity").toInt();
loadingInfo.visible = static_cast<bool>(it.attribute("Visible").toInt());
@@ -1188,7 +1188,7 @@
}
if (((item->asImageFrame()) || (item->asTextFrame())) && (!item->Pfile.isEmpty()) && (item->pixm.imgInfo.layerInfo.count() != 0) && (item->pixm.imgInfo.isRequest))
{
- QMap<int, ScImage::LoadRequest>::iterator it2;
+ QMap<int, ImageLoadRequest>::iterator it2;
for (it2 = item->pixm.imgInfo.RequestProps.begin(); it2 != item->pixm.imgInfo.RequestProps.end(); ++it2)
{
QDomElement psd = docu.createElement("PSDLayer");
Index: branches/Version13x/Scribus/scribus/scimgdataloader_tiff.h
===================================================================
--- branches/Version13x/Scribus/scribus/scimgdataloader_tiff.h (nonexistent)
+++ branches/Version13x/Scribus/scribus/scimgdataloader_tiff.h (revision 5937)
@@ -0,0 +1,20 @@
+#ifndef SCIMGDATALOADER_TIFF_H
+#define SCIMGDATALOADER_TIFF_H
+
+#include "scimgdataloader.h"
+
+class ScImgDataLoader_TIFF : public ScImgDataLoader
+{
+protected:
+
+ void initSupportedFormatList();
+
+public:
+ ScImgDataLoader_TIFF(void);
+
+ virtual void preloadAlphaChannel(const QString& fn, int res);
+ virtual void loadEmbeddedProfile(const QString& fn);
+ virtual bool loadPicture(const QString& fn, int res, bool thumbnail);
+};
+
+#endif
/branches/Version13x/Scribus/scribus/scimgdataloader_tiff.h
Property changes:
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+Author Date Id Revision
\ No newline at end of property
Index: branches/Version13x/Scribus/scribus/scimgdataloader_psd.cpp
===================================================================
--- branches/Version13x/Scribus/scribus/scimgdataloader_psd.cpp (nonexistent)
+++ branches/Version13x/Scribus/scribus/scimgdataloader_psd.cpp (revision 5937)
@@ -0,0 +1,1383 @@
+#include "scconfig.h"
+#include "scimgdataloader_psd.h"
+#include "util.h"
+
+#include <qfile.h>
+#include <qfileinfo.h>
+
+#ifdef HAVE_CMS
+ #include CMS_INC
+#endif
+
+static QDataStream & operator>> ( QDataStream & s, PSDHeader & header )
+{
+ s >> header.signature;
+ s >> header.version;
+ for( int i = 0; i < 6; i++ )
+ {
+ s >> header.reserved[i];
+ }
+ s >> header.channel_count;
+ s >> header.height;
+ s >> header.width;
+ s >> header.depth;
+ s >> header.color_mode;
+ return s;
+}
+
+ScImgDataLoader_PSD::ScImgDataLoader_PSD(void)
+{
+ initSupportedFormatList();
+}
+
+void ScImgDataLoader_PSD::initSupportedFormatList(void)
+{
+ m_supportedFormats.clear();
+ m_supportedFormats.append( "psd" );
+}
+
+void ScImgDataLoader_PSD::loadEmbeddedProfile(const QString& fn)
+{
+ m_embeddedProfile.resize(0);
+ m_profileComponents = 0;
+#ifdef HAVE_CMS
+ cmsHPROFILE prof = 0;
+ QFileInfo fi = QFileInfo(fn);
+ if (!fi.exists())
+ return;
+ QString ext = fi.extension(false).lower();
+ if (ext == "psd")
+ {
+ QFile f(fn);
+ if (f.open(IO_ReadOnly))
+ {
+ m_imageInfoRecord.xres = 72;
+ m_imageInfoRecord.yres = 72;
+ QDataStream s( &f );
+ s.setByteOrder( QDataStream::BigEndian );
+ PSDHeader header;
+ s >> header;
+ // Check image file format.
+ if( s.atEnd() || !IsValid( header ) )
+ return;
+ // Check if it's a supported format.
+ if( !IsSupported( header ) )
+ return;
+ if( !LoadPSD(s, header) )
+ return;
+ if (m_embeddedProfile.size() > 0)
+ {
+ prof = cmsOpenProfileFromMem(m_embeddedProfile.data(), m_embeddedProfile.size());
+ if (prof)
+ {
+ if (static_cast<int>(cmsGetColorSpace(prof)) == icSigRgbData)
+ m_profileComponents = 3;
+ if (static_cast<int>(cmsGetColorSpace(prof)) == icSigCmykData)
+ m_profileComponents = 4;
+ }
+ cmsCloseProfile(prof);
+ }
+ f.close();
+ }
+ else
+ return;
+ }
+#endif
+}
+
+void ScImgDataLoader_PSD::preloadAlphaChannel(const QString& fn, int res)
+{
+ float xres, yres;
+ short resolutionunit = 0;
+ initialize();
+ QFileInfo fi = QFileInfo(fn);
+ if (!fi.exists())
+ return;
+
+ QFile f(fn);
+ if (f.open(IO_ReadOnly))
+ {
+ xres = 72.0;
+ yres = 72.0;
+ QDataStream s( &f );
+ s.setByteOrder( QDataStream::BigEndian );
+ PSDHeader header;
+ s >> header;
+ // Check image file format.
+ if( s.atEnd() || !IsValid( header ) )
+ return;
+ // Check if it's a supported format.
+ if( !IsSupported( header ) )
+ return;
+ if (header.color_mode == CM_CMYK)
+ return;
+ if( !LoadPSD(s, header) )
+ m_image.reset();
+ f.close();
+ }
+}
+
+bool ScImgDataLoader_PSD::loadPicture(const QString& fn, int res, bool thumbnail)
+{
+ bool isCMYK = false;
+ float xres = 72.0, yres = 72.0;
+ if (!QFile::exists(fn))
+ return false;
+
+ initialize();
+ m_imageInfoRecord.type = 2;
+ m_imageInfoRecord.exifDataValid = false;
+ QFile f(fn);
+ if (f.open(IO_ReadOnly))
+ {
+ m_imageInfoRecord.xres = 72;
+ m_imageInfoRecord.yres = 72;
+ QDataStream s( &f );
+ s.setByteOrder( QDataStream::BigEndian );
+ PSDHeader header;
+ s >> header;
+ // Check image file format.
+ if( s.atEnd() || !IsValid( header ) )
+ return false;
+ // Check if it's a supported format.
+ if( !IsSupported( header ) )
+ return false;
+ if (thumbnail)
+ header.reserved[0] = 't';
+ if( !LoadPSD(s, header) )
+ return false;
+#ifdef HAVE_CMS
+ if (m_embeddedProfile.size() > 0)
+ {
+ cmsHPROFILE prof = cmsOpenProfileFromMem(m_embeddedProfile.data(), m_embeddedProfile.size());
+ const char *Descriptor;
+ Descriptor = cmsTakeProductDesc(prof);
+ m_imageInfoRecord.profileName = QString(Descriptor);
+ m_imageInfoRecord.isEmbedded = true;
+ }
+#endif // HAVE_CMS
+ if (header.color_mode == CM_CMYK)
+ isCMYK = true;
+ else
+ isCMYK = false;
+ if (header.color_mode == CM_CMYK)
+ m_imageInfoRecord.colorspace = 1;
+ else if (header.color_mode == CM_RGB)
+ m_imageInfoRecord.colorspace = 0;
+ else if (header.color_mode == CM_GRAYSCALE)
+ m_imageInfoRecord.colorspace = 2;
+ m_imageInfoRecord.valid = true;
+ m_image.setDotsPerMeterX ((int) (m_imageInfoRecord.xres / 0.0254));
+ m_image.setDotsPerMeterY ((int) (m_imageInfoRecord.yres / 0.0254));
+ xres = m_imageInfoRecord.xres;
+ yres = m_imageInfoRecord.yres;
+ f.close();
+ if (thumbnail)
+ {
+ if (!m_imageInfoRecord.exifInfo.thumbnail.isNull())
+ {
+ m_image.create(m_imageInfoRecord.exifInfo.thumbnail.width(), m_imageInfoRecord.exifInfo.thumbnail.height(), 32);
+ for( int yit=0; yit < m_imageInfoRecord.exifInfo.thumbnail.height(); ++yit )
+ {
+ QRgb *s = (QRgb*)(m_imageInfoRecord.exifInfo.thumbnail.scanLine( yit ));
+ QRgb *d = (QRgb*)(m_image.scanLine( yit ));
+ for(int xit=0; xit < m_imageInfoRecord.exifInfo.thumbnail.width(); ++xit )
+ {
+ (*d) = (*s);
+ s++;
+ d++;
+ }
+ }
+ m_imageInfoRecord.exifInfo.width = header.width;
+ m_imageInfoRecord.exifInfo.height = header.height;
+ return true;
+ }
+ }
+ m_imageInfoRecord.exifInfo.width = header.width;
+ m_imageInfoRecord.exifInfo.height = header.height;
+ m_imageInfoRecord.BBoxX = 0;
+ m_imageInfoRecord.BBoxH = m_image.height();
+ return true;
+ }
+ return false;
+}
+
+bool ScImgDataLoader_PSD::LoadPSD( QDataStream & s, const PSDHeader & header)
+{
+ // Create dst image.
+ if( !m_image.create( header.width, header.height, 32 ))
+ return false;
+ m_image.setAlphaBuffer( true );
+ uint tmp;
+ uint cdataStart;
+ uint ressourceDataLen;
+ uint startRessource;
+ uint layerDataLen;
+ uint startLayers;
+
+ srand(314159265);
+ for (int i = 0; i < 4096; i++)
+ random_table[i] = rand();
+ for (int i = 0; i < 4096; i++)
+ {
+ int tmp;
+ int swap = i + rand() % (4096 - i);
+ tmp = random_table[i];
+ random_table[i] = random_table[swap];
+ random_table[swap] = tmp;
+ }
+
+ // Skip mode data. FIX: this is incorrect, it's the Colormap Data for indexed Images
+ s >> tmp;
+ cdataStart = s.device()->at();
+ if (tmp != 0)
+ {
+ QValueList<uchar> colorTableR;
+ QValueList<uchar> colorTableG;
+ QValueList<uchar> colorTableB;
+ colorTableR.clear();
+ colorTableG.clear();
+ colorTableB.clear();
+ colorTable.clear();
+ uchar r;
+ for (uint cc = 0; cc < 256; cc++)
+ {
+ s >> r;
+ colorTableR.append(r);
+ }
+ for (uint cc = 0; cc < 256; cc++)
+ {
+ s >> r;
+ colorTableG.append(r);
+ }
+ for (uint cc = 0; cc < 256; cc++)
+ {
+ s >> r;
+ colorTableB.append(r);
+ }
+ for (uint cc = 0; cc < 256; cc++)
+ {
+ colorTable.append(qRgb(colorTableR[cc], colorTableG[cc], colorTableB[cc]));
+ }
+ }
+ s.device()->at( cdataStart + tmp );
+ s >> ressourceDataLen;
+ startRessource = s.device()->at();
+ if (ressourceDataLen != 0)
+ parseRessourceData(s, header, ressourceDataLen);
+ if ((!m_imageInfoRecord.exifInfo.thumbnail.isNull()) && (header.reserved[0] == 't'))
+ return true;
+ s.device()->at( startRessource + ressourceDataLen );
+ // Skip the reserved data. FIX: Also incorrect, this is the actual Layer Data for Images with Layers
+ s >> layerDataLen;
+ startLayers = s.device()->at();
+ if (layerDataLen != 0)
+ return parseLayer( s, header);
+ else
+ {
+ // Decoding simple psd file, no layers
+ s.device()->at( s.device()->at() + layerDataLen );
+ loadLayer( s, header);
+ }
+ return true;
+}
+
+bool ScImgDataLoader_PSD::parseLayer( QDataStream & s, const PSDHeader & header )
+{
+ uint addRes, layerinfo, channelLen, signature, extradata, layermasksize, layerRange, dummy;
+ int top, left, bottom, right;
+ short numLayers, numChannels;
+ short channelType;
+ uchar blendKey[4];
+ uchar opacity, clipping, flags, filler;
+ QString layerName, blend;
+ struct PSDLayer lay;
+ s >> layerinfo;
+ s >> numLayers;
+ if (numLayers < 0)
+ numLayers = -numLayers;
+ if (numLayers != 0)
+ {
+ for (int layer = 0; layer < numLayers; layer++)
+ {
+ s >> top;
+ lay.ypos = top;
+ s >> left;
+ lay.xpos = left;
+ s >> bottom;
+ lay.height = bottom - top;
+ s >> right;
+ lay.width = right - left;
+ s >> numChannels;
+ lay.channelType.clear();
+ lay.channelLen.clear();
+ for (int channels = 0; channels < numChannels; channels++)
+ {
+ s >> channelType;
+ s >> channelLen;
+ lay.channelType.append(channelType);
+ lay.channelLen.append(channelLen);
+ }
+ s >> signature;
+ blend = "";
+ for( int i = 0; i < 4; i++ )
+ {
+ s >> blendKey[i];
+ blend += QChar(blendKey[i]);
+ }
+ lay.blend = blend;
+ s >> opacity;
+ lay.opacity = opacity;
+ s >> clipping;
+ lay.clipping = clipping;
+ s >> flags;
+ lay.flags = flags;
+ s >> filler;
+ s >> extradata;
+ s >> layermasksize;
+ lay.maskYpos = 0;
+ lay.maskXpos = 0;
+ lay.maskHeight = 0;
+ lay.maskWidth = 0;
+ if (layermasksize != 0)
+ {
+ s >> lay.maskYpos;
+ s >> lay.maskXpos;
+ s >> dummy;
+ lay.maskHeight = dummy - lay.maskYpos;
+ s >> dummy;
+ lay.maskWidth = dummy - lay.maskXpos;
+ s >> dummy;
+ }
+ s >> layerRange;
+ s.device()->at( s.device()->at() + layerRange );
+ lay.layerName = getLayerString(s);
+ m_imageInfoRecord.layerInfo.append(lay);
+ s >> signature;
+ if( signature == 0x3842494D )
+ {
+ while (signature == 0x3842494D )
+ {
+ s >> signature;
+ s >> addRes;
+ s.device()->at( s.device()->at() + addRes );
+ s >> signature;
+ }
+ s.device()->at( s.device()->at() - 4 );
+ }
+ else
+ {
+ s.device()->at( s.device()->at() - 2 );
+ s >> signature;
+ if( signature == 0x3842494D )
+ {
+ while (signature == 0x3842494D )
+ {
+ s >> signature;
+ s >> addRes;
+ s.device()->at( s.device()->at() + addRes );
+ s >> signature;
+ }
+ s.device()->at( s.device()->at() - 4 );
+ }
+ else
+ s.device()->at( s.device()->at() - 6 );
+ }
+ }
+ bool firstLayer = true;
+ for (int layer = 0; layer < numLayers; layer++)
+ {
+ loadLayerChannels( s, header, m_imageInfoRecord.layerInfo, layer, &firstLayer );
+ }
+ }
+ else
+ {
+ s >> numLayers;
+ loadLayer( s, header);
+ }
+ return true;
+}
+
+bool ScImgDataLoader_PSD::loadChannel( QDataStream & s, const PSDHeader & header, QValueList<PSDLayer> &layerInfo, uint layer, int channel, int component, QImage &tmpImg)
+{
+ uint base = s.device()->at();
+ uchar cbyte;
+ ushort compression;
+ s >> compression;
+ if( compression > 1 )
+ return false;
+ if (compression == 0)
+ {
+ int count = layerInfo[layer].channelLen[channel]-2;
+ for (int i = 0; i < tmpImg.height(); i++)
+ {
+ uchar *ptr = tmpImg.scanLine(i);
+ for (int j = 0; j < tmpImg.width(); j++)
+ {
+ s >> cbyte;
+ count--;
+ if (header.color_mode == CM_CMYK)
+ cbyte = 255 - cbyte;
+ if ((header.color_mode == CM_GRAYSCALE) && (component != 3))
+ {
+ ptr[0] = cbyte;
+ ptr[1] = cbyte;
+ ptr[2] = cbyte;
+ }
+ else if ((header.color_mode == CM_INDEXED) && (component != 3))
+ {
+ int ccol = colorTable[cbyte];
+ ptr[2] = qRed(ccol);
+ ptr[1] = qGreen(ccol);
+ ptr[0] = qBlue(ccol);
+ }
+ else
+ {
+ if (channel < 4)
+ ptr[component] = cbyte;
+ }
+ if (count == 0)
+ break;
+ ptr += 4;
+ }
+ if (count == 0)
+ break;
+ }
+ }
+ else
+ {
+ s.device()->at( s.device()->at() + tmpImg.height() * 2 );
+ uint pixel_count = tmpImg.width();
+ for (int hh = 0; hh < tmpImg.height(); hh++)
+ {
+ uint count = 0;
+ uchar *ptr = tmpImg.scanLine(hh);
+ uchar *ptr2 = ptr+tmpImg.width() * 4;
+ ptr += component;
+ while( count < pixel_count )
+ {
+ uchar c;
+ if(s.atEnd())
+ return false;
+ s >> c;
+ uint len = c;
+ if( len < 128 )
+ {
+ // Copy next len+1 bytes literally.
+ len++;
+ count += len;
+ while( len != 0 )
+ {
+ s >> cbyte;
+ if (ptr < ptr2)
+ {
+ if (header.color_mode == CM_CMYK)
+ cbyte = 255 - cbyte;
+ if ((header.color_mode == CM_GRAYSCALE) && (component != 3))
+ {
+ ptr -= component;
+ ptr[0] = cbyte;
+ ptr[1] = cbyte;
+ ptr[2] = cbyte;
+ ptr += component;
+ }
+ else if ((header.color_mode == CM_INDEXED) && (component != 3))
+ {
+ ptr -= component;
+ int ccol = colorTable[cbyte];
+ ptr[2] = qRed(ccol);
+ ptr[1] = qGreen(ccol);
+ ptr[0] = qBlue(ccol);
+ ptr += component;
+ }
+ else
+ {
+ *ptr = cbyte;
+ }
+ }
+ ptr += 4;
+ len--;
+ }
+ }
+ else if( len > 128 )
+ {
+ // Next -len+1 bytes in the dest are replicated from next source byte.
+ // (Interpret len as a negative 8-bit int.)
+ len ^= 0xFF;
+ len += 2;
+ count += len;
+ uchar val;
+ s >> val;
+ if (header.color_mode == CM_CMYK)
+ val = 255 - val;
+ while( len != 0 )
+ {
+ if (ptr < ptr2)
+ {
+ if ((header.color_mode == CM_GRAYSCALE) && (component != 3))
+ {
+ ptr -= component;
+ ptr[0] = val;
+ ptr[1] = val;
+ ptr[2] = val;
+ ptr += component;
+ }
+ else if ((header.color_mode == CM_INDEXED) && (component != 3))
+ {
+ ptr -= component;
+ int ccol = colorTable[val];
+ ptr[2] = qRed(ccol);
+ ptr[1] = qGreen(ccol);
+ ptr[0] = qBlue(ccol);
+ ptr += component;
+ }
+ else
+ *ptr = val;
+ }
+ ptr += 4;
+ len--;
+ }
+ }
+ else if( len == 128 )
+ {
+ // No-op.
+ }
+ }
+ }
+ }
+ s.device()->at( base+layerInfo[layer].channelLen[channel] );
+ return true;
+}
+
+bool ScImgDataLoader_PSD::loadLayerChannels( QDataStream & s, const PSDHeader & header, QValueList<PSDLayer> &layerInfo, uint layer, bool* firstLayer)
+{
+ // Find out if the data is compressed.
+ // Known values:
+ // 0: no compression
+ // 1: RLE compressed
+ uint base = s.device()->at();
+ uint base2 = base;
+ uint channel_num = layerInfo[layer].channelLen.count();
+ QImage tmpImg = QImage();
+ QImage mask = QImage();
+ if( !tmpImg.create( layerInfo[layer].width, layerInfo[layer].height, 32 ))
+ {
+ for(uint channel = 0; channel < channel_num; channel++)
+ {
+ base2 += layerInfo[layer].channelLen[channel];
+ }
+ s.device()->at( base2 );
+ return false;
+ }
+ tmpImg.fill(qRgba(255, 255, 255, 0));
+ tmpImg.setAlphaBuffer( true );
+ channel_num = QMIN(channel_num, 39);
+ uint components[40];
+ for(uint channel = 0; channel < channel_num; channel++)
+ {
+ switch(layerInfo[layer].channelType[channel])
+ {
+ case 0:
+ components[channel] = 2;
+ break;
+ case 1:
+ components[channel] = 1;
+ break;
+ case 2:
+ components[channel] = 0;
+ break;
+ case 3:
+ components[channel] = 3;
+ break;
+ case -1:
+ case -2:
+ components[channel] = 3;
+ break;
+ }
+ }
+ if (channel_num < 4)
+ {
+ for (int i = 0; i < tmpImg.height(); i++)
+ {
+ QRgb * s = (QRgb*)(tmpImg.scanLine( i ));
+ for (int j = 0; j < tmpImg.width(); j++)
+ {
+ *s++ = qRgba(255, 255, 255, 255);
+ }
+ }
+ }
+ for(uint channel = 0; channel < channel_num; channel++)
+ {
+ if ((layerInfo[layer].channelType[channel] < 0) && (header.color_mode == CM_CMYK))
+ {
+ s.device()->at( base+layerInfo[layer].channelLen[channel] );
+ base = base+layerInfo[layer].channelLen[channel];
+ continue;
+ }
+// if ((layerInfo[layer].channelType[channel] == -2) || (layerInfo[layer].channelType[channel] == -1))
+ if (layerInfo[layer].channelType[channel] == -2)
+ {
+ if (!mask.create( layerInfo[layer].maskWidth, layerInfo[layer].maskHeight, 32 ))
+// {
+// if (!mask.create(layerInfo[layer].width, layerInfo[layer].height, 32 ))
+ break;
+// }
+ mask.fill(qRgba(255, 255, 255, 0));
+ mask.setAlphaBuffer( true );
+ if (!loadChannel(s, header, layerInfo, layer, channel, components[channel], mask))
+ break;
+ }
+ else
+ {
+ if (!loadChannel(s, header, layerInfo, layer, channel, components[channel], tmpImg))
+ break;
+ }
+ }
+ for(uint channel = 0; channel < channel_num; channel++)
+ {
+ base2 += layerInfo[layer].channelLen[channel];
+ }
+ s.device()->at( base2 );
+ QImage tmpImg2 = tmpImg.copy();
+ if (header.color_mode == CM_CMYK)
+ {
+ for (int i = 0; i < tmpImg.height(); i++)
+ {
+ unsigned int *ptr = (unsigned int *) tmpImg.scanLine(i);
+ unsigned int *ptr2 = (unsigned int *) tmpImg2.scanLine(i);
+ unsigned char r, g, b;
+ for (int j = 0; j < tmpImg.width(); j++)
+ {
+ unsigned char *p = (unsigned char *) ptr;
+ unsigned char *p2 = (unsigned char *) ptr2;
+ r = 255 - QMIN(255, p[0] + p[3]);
+ g = 255 - QMIN(255, p[1] + p[3]);
+ b = 255 - QMIN(255, p[2] + p[3]);
+ p2[0] = r;
+ p2[1] = g;
+ p2[2] = b;
+ p2[3] = 255;
+ ptr++;
+ ptr2++;
+ }
+ }
+ }
+ QImage imt;
+ double sx = tmpImg.width() / 40.0;
+ double sy = tmpImg.height() / 40.0;
+ imt = sy < sx ? tmpImg2.smoothScale(qRound(tmpImg.width() / sx), qRound(tmpImg.height() / sx)) :
+ tmpImg2.smoothScale(qRound(tmpImg.width() / sy), qRound(tmpImg.height() / sy));
+ layerInfo[layer].thumb = imt.copy();
+ bool visible = !(layerInfo[layer].flags & 2);
+ if ((m_imageInfoRecord.isRequest) && (m_imageInfoRecord.RequestProps.contains(layer)))
+ visible = m_imageInfoRecord.RequestProps[layer].visible;
+ if (visible)
+ {
+ unsigned int startSrcY, startSrcX, startDstY, startDstX;
+ if (layerInfo[layer].ypos < 0)
+ {
+ startSrcY = abs(layerInfo[layer].ypos);
+ startDstY = 0;
+ }
+ else
+ {
+ startSrcY = 0;
+ startDstY = layerInfo[layer].ypos;
+ }
+ if (layerInfo[layer].xpos < 0)
+ {
+ startSrcX = abs(layerInfo[layer].xpos);
+ startDstX = 0;
+ }
+ else
+ {
+ startSrcX = 0;
+ startDstX = layerInfo[layer].xpos;
+ }
+ unsigned int startSrcYm, startSrcXm, startDstYm, startDstXm;
+ if (layerInfo[layer].maskYpos < 0)
+ {
+ startSrcYm = abs(layerInfo[layer].maskYpos);
+ startDstYm = 0;
+ }
+ else
+ {
+ startSrcYm = 0;
+ startDstYm = layerInfo[layer].maskYpos;
+ }
+ if (layerInfo[layer].maskXpos < 0)
+ {
+ startSrcXm = abs(layerInfo[layer].maskXpos);
+ startDstXm = 0;
+ }
+ else
+ {
+ startSrcXm = 0;
+ startDstXm = layerInfo[layer].maskXpos;
+ }
+ QString layBlend2 = layerInfo[layer].blend;
+ if ((m_imageInfoRecord.isRequest) && (m_imageInfoRecord.RequestProps.contains(layer)))
+ layBlend2 = m_imageInfoRecord.RequestProps[layer].blend;
+ if ((layBlend2 == "diss") && (header.color_mode != CM_CMYK))
+ {
+ for (int l = 0; l < tmpImg.height(); l++)
+ {
+ srand(random_table[ l % 4096]);
+ for (int k = 0; k < tmpImg.width(); k++)
+ {
+ int rand_val = rand() & 0xff;
+ QRgb pixel = tmpImg.pixel(k, l);
+ if (rand_val > 128)
+ tmpImg.setPixel(k, l, qRgba(qRed(pixel), qGreen(pixel), qBlue(pixel), 0));
+ }
+ }
+ }
+ if (*firstLayer)
+ {
+ for( int yi=static_cast<int>(startSrcY); yi < QMIN(tmpImg.height(), m_image.height()); ++yi )
+ {
+ QRgb *s = (QRgb*)(tmpImg.scanLine( yi ));
+ QRgb *d = (QRgb*)( m_image.scanLine( QMIN(static_cast<int>(startDstY), m_image.height()-1) ));
+ d += QMIN(static_cast<int>(startDstX), m_image.width()-1);
+ s += QMIN(static_cast<int>(startSrcX), tmpImg.width()-1);
+/* unsigned int *srcm;
+ if (!mask.isNull())
+ {
+ srcm = (unsigned int *)mask.scanLine(QMIN(yi, mask.height()-1));
+ srcm += QMIN(static_cast<int>(startSrcXm), mask.width()-1);
+ } */
+ for(int xi=static_cast<int>(startSrcX); xi < QMIN(tmpImg.width(), m_image.width()); ++xi )
+ {
+ (*d) = (*s);
+/* unsigned char *sm = (unsigned char *) srcm;
+ unsigned char *sc = (unsigned char *) d;
+ unsigned char *ss = (unsigned char *) s;
+ if (!mask.isNull())
+ {
+ if (header.color_mode == CM_CMYK)
+ {
+ sc[0] = (sc[0] * (255 - sm[3]) + ss[0] * sm[3]) / 255;
+ sc[1] = (sc[1] * (255 - sm[3]) + ss[1] * sm[3]) / 255;
+ sc[2] = (sc[2] * (255 - sm[3]) + ss[2] * sm[3]) / 255;
+ sc[3] = (sc[3] * (255 - sm[3]) + ss[3] * sm[3]) / 255;
+ }
+ else
+ sc[3] = sm[3];
+ }
+ srcm++; */
+ s++;
+ d++;
+ }
+ startDstY++;
+ }
+ }
+ else
+ {
+ for (int i = static_cast<int>(startSrcY); i < layerInfo[layer].height; i++)
+ {
+ unsigned int *dst = (unsigned int *)m_image.scanLine(QMIN(static_cast<int>(startDstY), m_image.height()-1));
+ unsigned int *src = (unsigned int *)tmpImg.scanLine(QMIN(i, tmpImg.height()-1));
+ dst += QMIN(static_cast<int>(startDstX), m_image.width()-1);
+ src += QMIN(static_cast<int>(startSrcX), tmpImg.width()-1);
+ unsigned int *srcm = 0;
+ if (!mask.isNull())
+ {
+ srcm = (unsigned int *)mask.scanLine(QMIN(i, mask.height()-1));
+ srcm += QMIN(static_cast<int>(startSrcXm), mask.width()-1);
+ }
+ startDstY++;
+ unsigned char r, g, b, a, src_r, src_g, src_b, src_a, mask_a;
+ //<<#3356
+ unsigned int maxDestX = m_image.width() - startDstX + startSrcX - 1;
+ for (unsigned int j = startSrcX; j < QMIN(maxDestX, static_cast<unsigned int>(layerInfo[layer].width)); j++)
+ //for (unsigned int j = startSrcX; j < static_cast<unsigned int>(layerInfo[layer].width); j++)
+ //>>#3356
+ {
+ unsigned char *d = (unsigned char *) dst;
+ unsigned char *s = (unsigned char *) src;
+ unsigned char *sm = (unsigned char *) srcm;
+ src_r = s[0];
+ src_g = s[1];
+ src_b = s[2];
+ src_a = s[3];
+ if (!mask.isNull())
+ mask_a = sm[3];
+ QString layBlend = layerInfo[layer].blend;
+ if ((m_imageInfoRecord.isRequest) && (m_imageInfoRecord.RequestProps.contains(layer)))
+ layBlend = m_imageInfoRecord.RequestProps[layer].blend;
+ if (layBlend == "mul ")
+ {
+ if (header.color_mode == CM_CMYK)
+ {
+ src_r = INT_MULT(src_r, d[0]);
+ src_g = INT_MULT(src_g, d[1]);
+ src_b = INT_MULT(src_b, d[2]);
+ src_a = INT_MULT(src_a, d[3]);
+ }
+ else
+ {
+ if (d[3] > 0)
+ {
+ src_r = INT_MULT(src_r, d[0]);
+ src_g = INT_MULT(src_g, d[1]);
+ src_b = INT_MULT(src_b, d[2]);
+ }
+ }
+ }
+ else if (layBlend == "scrn")
+ {
+ if (header.color_mode == CM_CMYK)
+ {
+ src_r = 255 - ((255-src_r) * (255-d[0]) / 128);
+ src_g = 255 - ((255-src_g) * (255-d[1]) / 128);
+ src_b = 255 - ((255-src_b) * (255-d[2]) / 128);
+ src_a = 255 - ((255-src_a) * (255-d[3]) / 128);
+/* src_r = 255 - INT_MULT(255 - d[0], 255 - src_r);
+ src_g = 255 - INT_MULT(255 - d[1], 255 - src_g);
+ src_b = 255 - INT_MULT(255 - d[2], 255 - src_b);
+ src_a = 255 - INT_MULT(255 - d[3], 255 - src_a); */
+ }
+ else
+ {
+ if (d[3] > 0)
+ {
+ src_r = 255 - ((255-src_r) * (255-d[0]) / 128);
+ src_g = 255 - ((255-src_g) * (255-d[1]) / 128);
+ src_b = 255 - ((255-src_b) * (255-d[2]) / 128);
+/* src_r = 255 - INT_MULT(255 - d[0], 255 - src_r);
+ src_g = 255 - INT_MULT(255 - d[1], 255 - src_g);
+ src_b = 255 - INT_MULT(255 - d[2], 255 - src_b); */
+ }
+ }
+ }
+ else if (layBlend == "over")
+ {
+ if (header.color_mode == CM_CMYK)
+ {
+ src_r = d[0] < 128 ? src_r * d[0] / 128 : 255 - ((255-src_r) * (255-d[0]) / 128);
+ src_g = d[1] < 128 ? src_g * d[1] / 128 : 255 - ((255-src_g) * (255-d[1]) / 128);
+ src_b = d[2] < 128 ? src_b * d[2] / 128 : 255 - ((255-src_b) * (255-d[2]) / 128);
+ src_a = d[3] < 128 ? src_a * d[3] / 128 : 255 - ((255-src_a) * (255-d[3]) / 128);
+/* src_r = INT_MULT(d[0], d[0] + INT_MULT(2 * src_r, 255 - d[0]));
+ src_g = INT_MULT(d[1], d[1] + INT_MULT(2 * src_g, 255 - d[1]));
+ src_b = INT_MULT(d[2], d[2] + INT_MULT(2 * src_b, 255 - d[2]));
+ src_a = INT_MULT(d[3], d[3] + INT_MULT(2 * src_a, 255 - d[3])); */
+ }
+ else
+ {
+ if (d[3] > 0)
+ {
+ src_r = d[0] < 128 ? src_r * d[0] / 128 : 255 - ((255-src_r) * (255-d[0]) / 128);
+ src_g = d[1] < 128 ? src_g * d[1] / 128 : 255 - ((255-src_g) * (255-d[1]) / 128);
+ src_b = d[2] < 128 ? src_b * d[2] / 128 : 255 - ((255-src_b) * (255-d[2]) / 128);
+/* src_r = INT_MULT(d[0], d[0] + INT_MULT(2 * src_r, 255 - d[0]));
+ src_g = INT_MULT(d[1], d[1] + INT_MULT(2 * src_g, 255 - d[1]));
+ src_b = INT_MULT(d[2], d[2] + INT_MULT(2 * src_b, 255 - d[2])); */
+ }
+ }
+ }
+ else if (layBlend == "diff")
+ {
+ if (header.color_mode == CM_CMYK)
+ {
+ src_r = d[0] > src_r ? d[0] - src_r : src_r - d[0];
+ src_g = d[1] > src_g ? d[1] - src_g : src_g - d[1];
+ src_b = d[2] > src_b ? d[2] - src_b : src_b - d[2];
+ src_a = d[3] > src_a ? d[3] - src_a : src_a - d[3];
+ }
+ else
+ {
+ if (d[3] > 0)
+ {
+ src_r = d[0] > src_r ? d[0] - src_r : src_r - d[0];
+ src_g = d[1] > src_g ? d[1] - src_g : src_g - d[1];
+ src_b = d[2] > src_b ? d[2] - src_b : src_b - d[2];
+ }
+ }
+ }
+ else if (layBlend == "dark")
+ {
+ if (header.color_mode == CM_CMYK)
+ {
+ src_r = d[0] < src_r ? d[0] : src_r;
+ src_g = d[1] < src_g ? d[1] : src_g;
+ src_b = d[2] < src_b ? d[2] : src_b;
+ src_a = d[3] < src_a ? d[3] : src_a;
+ }
+ else
+ {
+ if (d[3] > 0)
+ {
+ src_r = d[0] < src_r ? d[0] : src_r;
+ src_g = d[1] < src_g ? d[1] : src_g;
+ src_b = d[2] < src_b ? d[2] : src_b;
+ }
+ }
+ }
+ else if (layBlend == "hLit")
+ {
+ if (header.color_mode == CM_CMYK)
+ {
+ src_r = src_r < 128 ? src_r * d[0] / 128 : 255 - ((255-src_r) * (255-d[0]) / 128);
+ src_g = src_g < 128 ? src_g * d[1] / 128 : 255 - ((255-src_g) * (255-d[1]) / 128);
+ src_b = src_b < 128 ? src_b * d[2] / 128 : 255 - ((255-src_b) * (255-d[2]) / 128);
+ src_a = src_a < 128 ? src_a * d[3] / 128 : 255 - ((255-src_a) * (255-d[3]) / 128);
+ }
+ else
+ {
+ if (d[3] > 0)
+ {
+ src_r = src_r < 128 ? src_r * d[0] / 128 : 255 - ((255-src_r) * (255-d[0]) / 128);
+ src_g = src_g < 128 ? src_g * d[1] / 128 : 255 - ((255-src_g) * (255-d[1]) / 128);
+ src_b = src_b < 128 ? src_b * d[2] / 128 : 255 - ((255-src_b) * (255-d[2]) / 128);
+ }
+ }
+ }
+ else if (layBlend == "sLit")
+ {
+ if (header.color_mode == CM_CMYK)
+ {
+ src_r = src_r * d[0] / 256 + src_r * (255 - ((255-src_r)*(255-d[0]) / 256) - src_r * d[0] / 256) / 256;
+ src_g = src_g * d[1] / 256 + src_g * (255 - ((255-src_g)*(255-d[1]) / 256) - src_g * d[1] / 256) / 256;
+ src_b = src_b * d[2] / 256 + src_b * (255 - ((255-src_b)*(255-d[2]) / 256) - src_b * d[2] / 256) / 256;
+ src_a = src_a * d[3] / 256 + src_a * (255 - ((255-src_a)*(255-d[3]) / 256) - src_a * d[3] / 256) / 256;
+ }
+ else
+ {
+ if (d[3] > 0)
+ {
+ src_r = src_r * d[0] / 256 + src_r * (255 - ((255-src_r)*(255-d[0]) / 256) - src_r * d[0] / 256) / 256;
+ src_g = src_g * d[1] / 256 + src_g * (255 - ((255-src_g)*(255-d[1]) / 256) - src_g * d[1] / 256) / 256;
+ src_b = src_b * d[2] / 256 + src_b * (255 - ((255-src_b)*(255-d[2]) / 256) - src_b * d[2] / 256) / 256;
+ }
+ }
+ }
+ else if (layBlend == "lite")
+ {
+ if (header.color_mode == CM_CMYK)
+ {
+ src_r = d[0] < src_r ? src_r : d[0];
+ src_g = d[1] < src_g ? src_g : d[1];
+ src_b = d[2] < src_b ? src_b : d[2];
+ src_a = d[3] < src_a ? src_a : d[3];
+ }
+ else
+ {
+ if (d[3] > 0)
+ {
+ src_r = d[0] < src_r ? src_r : d[0];
+ src_g = d[1] < src_g ? src_g : d[1];
+ src_b = d[2] < src_b ? src_b : d[2];
+ }
+ }
+ }
+ else if (layBlend == "smud")
+ {
+ if (header.color_mode == CM_CMYK)
+ {
+ src_r = d[0] + src_r - src_r * d[0] / 128;
+ src_g = d[1] + src_g - src_g * d[1] / 128;
+ src_b = d[2] + src_b - src_b * d[2] / 128;
+ src_a = d[3] + src_a - src_a * d[3] / 128;
+ }
+ else
+ {
+ if (d[3] > 0)
+ {
+ src_r = d[0] + src_r - src_r * d[0] / 128;
+ src_g = d[1] + src_g - src_g * d[1] / 128;
+ src_b = d[2] + src_b - src_b * d[2] / 128;
+ }
+ }
+ }
+ else if (layBlend == "div ")
+ {
+ if (header.color_mode == CM_CMYK)
+ {
+ src_r = src_r == 255 ? 255 : ((d[0] * 256) / (255-src_r)) > 255 ? 255 : (d[0] * 256) / (255-src_r);
+ src_g = src_g == 255 ? 255 : ((d[1] * 256) / (255-src_g)) > 255 ? 255 : (d[1] * 256) / (255-src_g);
+ src_b = src_b == 255 ? 255 : ((d[2] * 256) / (255-src_b)) > 255 ? 255 : (d[2] * 256) / (255-src_b);
+ src_a = src_a == 255 ? 255 : ((d[3] * 256) / (255-src_a)) > 255 ? 255 : (d[3] * 256) / (255-src_a);
+ }
+ else
+ {
+ if (d[3] > 0)
+ {
+ src_r = src_r == 255 ? 255 : ((d[0] * 256) / (255-src_r)) > 255 ? 255 : (d[0] * 256) / (255-src_r);
+ src_g = src_g == 255 ? 255 : ((d[1] * 256) / (255-src_g)) > 255 ? 255 : (d[1] * 256) / (255-src_g);
+ src_b = src_b == 255 ? 255 : ((d[2] * 256) / (255-src_b)) > 255 ? 255 : (d[2] * 256) / (255-src_b);
+ }
+ }
+ }
+ else if (layBlend == "idiv")
+ {
+ if (header.color_mode == CM_CMYK)
+ {
+ src_r = src_r == 0 ? 0 : (255 - (((255-d[0]) * 256) / src_r)) < 0 ? 0 : 255 - (((255-d[0]) * 256) / src_r);
+ src_g = src_g == 0 ? 0 : (255 - (((255-d[1]) * 256) / src_g)) < 0 ? 0 : 255 - (((255-d[1]) * 256) / src_g);
+ src_b = src_b == 0 ? 0 : (255 - (((255-d[2]) * 256) / src_b)) < 0 ? 0 : 255 - (((255-d[2]) * 256) / src_b);
+ src_a = src_a == 0 ? 0 : (255 - (((255-d[3]) * 256) / src_a)) < 0 ? 0 : 255 - (((255-d[3]) * 256) / src_a);
+ }
+ else
+ {
+ if (d[3] > 0)
+ {
+ src_r = src_r == 0 ? 0 : (255 - (((255-d[0]) * 256) / src_r)) < 0 ? 0 : 255 - (((255-d[0]) * 256) / src_r);
+ src_g = src_g == 0 ? 0 : (255 - (((255-d[1]) * 256) / src_g)) < 0 ? 0 : 255 - (((255-d[1]) * 256) / src_g);
+ src_b = src_b == 0 ? 0 : (255 - (((255-d[2]) * 256) / src_b)) < 0 ? 0 : 255 - (((255-d[2]) * 256) / src_b);
+ }
+ }
+ }
+ else if (layBlend == "hue ")
+ {
+ if (header.color_mode != CM_CMYK)
+ {
+ if (d[3] > 0)
+ {
+ uchar new_r = d[0];
+ uchar new_g = d[1];
+ uchar new_b = d[2];
+ RGBTOHSV(src_r, src_g, src_b);
+ RGBTOHSV(new_r, new_g, new_b);
+ new_r = src_r;
+ HSVTORGB(new_r, new_g, new_b);
+ src_r = new_r;
+ src_g = new_g;
+ src_b = new_b;
+ }
+ }
+ }
+ else if (layBlend == "sat ")
+ {
+ if (header.color_mode != CM_CMYK)
+ {
+ if (d[3] > 0)
+ {
+ uchar new_r = d[0];
+ uchar new_g = d[1];
+ uchar new_b = d[2];
+ RGBTOHSV(src_r, src_g, src_b);
+ RGBTOHSV(new_r, new_g, new_b);
+ new_g = src_g;
+ HSVTORGB(new_r, new_g, new_b);
+ src_r = new_r;
+ src_g = new_g;
+ src_b = new_b;
+ }
+ }
+ }
+ else if (layBlend == "lum ")
+ {
+ if (header.color_mode != CM_CMYK)
+ {
+ if (d[3] > 0)
+ {
+ uchar new_r = d[0];
+ uchar new_g = d[1];
+ uchar new_b = d[2];
+ RGBTOHSV(src_r, src_g, src_b);
+ RGBTOHSV(new_r, new_g, new_b);
+ new_b = src_b;
+ HSVTORGB(new_r, new_g, new_b);
+ src_r = new_r;
+ src_g = new_g;
+ src_b = new_b;
+ }
+ }
+ }
+ else if (layBlend == "colr")
+ {
+ if (header.color_mode != CM_CMYK)
+ {
+ if (d[3] > 0)
+ {
+ uchar new_r = d[0];
+ uchar new_g = d[1];
+ uchar new_b = d[2];
+ RGBTOHLS(src_r, src_g, src_b);
+ RGBTOHLS(new_r, new_g, new_b);
+ new_r = src_r;
+ new_b = src_b;
+ HLSTORGB(new_r, new_g, new_b);
+ src_r = new_r;
+ src_g = new_g;
+ src_b = new_b;
+ }
+ }
+ }
+
+ int layOpa = layerInfo[layer].opacity;
+ if ((m_imageInfoRecord.isRequest) && (m_imageInfoRecord.RequestProps.contains(layer)))
+ layOpa = m_imageInfoRecord.RequestProps[layer].opacity;
+ if (!mask.isNull())
+ layOpa = INT_MULT(mask_a, layOpa);
+ if (header.color_mode != CM_CMYK)
+ src_a = INT_MULT(src_a, layOpa);
+ if (d[3] > 0)
+ {
+ r = (d[0] * (255 - layOpa) + src_r * layOpa) / 255;
+ g = (d[1] * (255 - layOpa) + src_g * layOpa) / 255;
+ b = (d[2] * (255 - layOpa) + src_b * layOpa) / 255;
+ if (header.color_mode == CM_CMYK)
+ a = (d[3] * (255 - layOpa) + src_a * layOpa) / 255;
+ else
+ {
+ a = d[3] + INT_MULT(255 - d[3], src_a);
+ r = (d[0] * (255 - src_a) + src_r * src_a) / 255;
+ g = (d[1] * (255 - src_a) + src_g * src_a) / 255;
+ b = (d[2] * (255 - src_a) + src_b * src_a) / 255;
+ }
+ }
+ else
+ {
+ r = src_r;
+ g = src_g;
+ b = src_b;
+ a = src_a;
+ }
+ if (header.color_mode == CM_CMYK)
+ {
+ d[0] = r;
+ d[1] = g;
+ d[2] = b;
+ d[3] = a;
+ }
+ else
+ {
+ if (src_a > 0)
+ {
+ d[0] = r;
+ d[1] = g;
+ d[2] = b;
+ d[3] = a;
+ }
+ }
+ dst++;
+ src++;
+ if (!mask.isNull())
+ srcm++;
+ }
+ }
+ }
+ }
+ *firstLayer = false;
+ return true;
+}
+
+bool ScImgDataLoader_PSD::loadLayer( QDataStream & s, const PSDHeader & header )
+{
+ // Find out if the data is compressed.
+ // Known values:
+ // 0: no compression
+ // 1: RLE compressed
+ ushort compression;
+ uchar cbyte;
+ s >> compression;
+ if( compression > 1 )
+ {
+ // Unknown compression type.
+ return false;
+ }
+ uint channel_num = header.channel_count;
+ if (channel_num < 4)
+ {
+ for (int i = 0; i < m_image.height(); i++)
+ {
+ QRgb * s = (QRgb*)( m_image.scanLine( i ));
+ for (int j = 0; j < m_image.width(); j++)
+ {
+ *s++ = qRgba(0, 0, 0, 255);
+ }
+ }
+ }
+// channel_num = 4;
+ const uint pixel_count = header.height * header.width;
+ static const uint components[4] = {2, 1, 0, 3};
+ if( compression )
+ {
+ // Skip row lengths.
+ ushort w;
+ for(uint i = 0; i < header.height * header.channel_count; i++)
+ {
+ s >> w;
+ }
+ // Read RLE data.
+ for(uint channel = 0; channel < channel_num; channel++)
+ {
+ uchar * ptr = m_image.bits() + components[channel];
+ uint count = 0;
+ while( count < pixel_count )
+ {
+ uchar c;
+ if(s.atEnd())
+ return false;
+ s >> c;
+ uint len = c;
+ if( len < 128 )
+ {
+ // Copy next len+1 bytes literally.
+ len++;
+ count += len;
+ if ( count > pixel_count )
+ return false;
+ while( len != 0 )
+ {
+ s >> cbyte;
+ if (header.color_mode == CM_CMYK)
+ cbyte = 255 - cbyte;
+ if ((header.color_mode == CM_GRAYSCALE) && (components[channel] != 3))
+ {
+ ptr -= components[channel];
+ ptr[0] = cbyte;
+ ptr[1] = cbyte;
+ ptr[2] = cbyte;
+ ptr += components[channel];
+ }
+ else if ((header.color_mode == CM_INDEXED) && (components[channel] != 3))
+ {
+ ptr -= components[channel];
+ int ccol = colorTable[cbyte];
+ ptr[2] = qRed(ccol);
+ ptr[1] = qGreen(ccol);
+ ptr[0] = qBlue(ccol);
+ ptr += components[channel];
+ }
+ else
+ *ptr = cbyte;
+ ptr += 4;
+ len--;
+ }
+ }
+ else if( len > 128 )
+ {
+ // Next -len+1 bytes in the dest are replicated from next source byte.
+ // (Interpret len as a negative 8-bit int.)
+ len ^= 0xFF;
+ len += 2;
+ count += len;
+ if(s.atEnd() || count > pixel_count)
+ return false;
+ uchar val;
+ s >> val;
+ if (header.color_mode == CM_CMYK)
+ val = 255 - val;
+ while( len != 0 )
+ {
+ if ((header.color_mode == CM_GRAYSCALE) && (components[channel] != 3))
+ {
+ ptr -= components[channel];
+ ptr[0] = val;
+ ptr[1] = val;
+ ptr[2] = val;
+ ptr += components[channel];
+ }
+ else if ((header.color_mode == CM_INDEXED) && (components[channel] != 3))
+ {
+ ptr -= components[channel];
+ int ccol = colorTable[val];
+ ptr[2] = qRed(ccol);
+ ptr[1] = qGreen(ccol);
+ ptr[0] = qBlue(ccol);
+ ptr += components[channel];
+ }
+ else
+ *ptr = val;
+ ptr += 4;
+ len--;
+ }
+ }
+ else if( len == 128 )
+ {
+ // No-op.
+ }
+ }
+ }
+ }
+ else
+ {
+ // We're at the raw image data. It's each channel in order (Red, Green, Blue, Alpha, ...)
+ // where each channel consists of an 8-bit value for each pixel in the image.
+ // Read the data by channel.
+ for(uint channel = 0; channel < channel_num; channel++)
+ {
+ uchar * ptr = m_image.bits() + components[channel];
+ // Read the data.
+ uint count = pixel_count;
+ while( count != 0 )
+ {
+ s >> cbyte;
+ if (header.color_mode == CM_CMYK)
+ cbyte = 255 - cbyte;
+ if ((header.color_mode == CM_GRAYSCALE) && (components[channel] != 3))
+ {
+ ptr -= components[channel];
+ ptr[0] = cbyte;
+ ptr[1] = cbyte;
+ ptr[2] = cbyte;
+ ptr += components[channel];
+ }
+ else if ((header.color_mode == CM_INDEXED) && (components[channel] != 3))
+ {
+ ptr -= components[channel];
+ int ccol = colorTable[cbyte];
+ ptr[2] = qRed(ccol);
+ ptr[1] = qGreen(ccol);
+ ptr[0] = qBlue(ccol);
+ ptr += components[channel];
+ }
+ else
+ *ptr = cbyte;
+ ptr += 4;
+ count--;
+ }
+ }
+ }
+ return true;
+}
+
+QString ScImgDataLoader_PSD::getLayerString(QDataStream & s)
+{
+ uchar len, tmp;
+ uint adj;
+ QString ret = "";
+ s >> len;
+ if (len == 0)
+ {
+ s >> tmp;
+ s >> tmp;
+ s >> tmp;
+ return ret;
+ }
+ for( int i = 0; i < len; i++ )
+ {
+ s >> tmp;
+ ret += QChar(tmp);
+ }
+ adj = 0;
+ if (((ret.length()+1) % 4) != 0)
+ adj = 4 - ((ret.length()+1) % 4);
+ s.device()->at( s.device()->at() + adj );
+ return ret;
+}
+
+bool ScImgDataLoader_PSD::IsValid( const PSDHeader & header )
+{
+ if( header.signature != 0x38425053 )
+ return false;
+ return true;
+}
+
+// Check that the header is supported.
+bool ScImgDataLoader_PSD::IsSupported( const PSDHeader & header )
+{
+ if ( header.version != 1 )
+ return false;
+ if ( header.channel_count > 16 )
+ return false;
+ if ( header.depth != 8 )
+ return false;
+ if ((header.color_mode == CM_RGB) || (header.color_mode == CM_CMYK)
+ || (header.color_mode == CM_GRAYSCALE) || (header.color_mode == CM_INDEXED))
+ return true;
+ return false;
+}
/branches/Version13x/Scribus/scribus/scimgdataloader_psd.cpp
Property changes:
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+Author Date Id Revision
\ No newline at end of property
Index: branches/Version13x/Scribus/scribus/extimageprops.cpp
===================================================================
--- branches/Version13x/Scribus/scribus/extimageprops.cpp (revision 5936)
+++ branches/Version13x/Scribus/scribus/extimageprops.cpp (revision 5937)
@@ -27,7 +27,7 @@
#include "scribusview.h"
#include "util.h"
-ExtImageProps::ExtImageProps( QWidget* parent, ScImage::ImageInfoRecord *info, PageItem *item, ScribusView *view ) : QDialog( parent, "ExtImageProps", true, 0 )
+ExtImageProps::ExtImageProps( QWidget* parent, ImageInfoRecord *info, PageItem *item, ScribusView *view ) : QDialog( parent, "ExtImageProps", true, 0 )
{
setIcon(loadIcon("AppIcon.png"));
setCaption( tr( "Extended Image Properties" ) );
@@ -147,7 +147,7 @@
opacitySpinBox->setEnabled(true);
blendMode->setEnabled(true);
QString tmp;
- QValueList<ScImage::PSDLayer>::iterator it2;
+ QValueList<PSDLayer>::iterator it2;
layerTable->setNumRows(info->layerInfo.count());
uint counter = 0;
for (it2 = info->layerInfo.begin(); it2 != info->layerInfo.end(); ++it2)
@@ -255,7 +255,7 @@
void ExtImageProps::changedLayer()
{
- struct ScImage::LoadRequest loadingInfo;
+ struct ImageLoadRequest loadingInfo;
currentItem->pixm.imgInfo.isRequest = true;
for (int r = 0; r < layerTable->numRows(); ++r)
{
/branches/Version13x/Scribus/scribus/scimgdataloader_ps.h
0,0 → 1,20
#ifndef SCIMGDATALOADER_PS_H
#define SCIMGDATALOADER_PS_H
 
#include "scimgdataloader.h"
 
class ScImgDataLoader_PS : public ScImgDataLoader
{
protected:
 
void initSupportedFormatList();
 
public:
ScImgDataLoader_PS(void);
 
virtual void preloadAlphaChannel(const QString& fn, int res);
virtual void loadEmbeddedProfile(const QString& fn);
virtual bool loadPicture(const QString& fn, int res, bool thumbnail);
};
 
#endif
Property changes:
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+Author Date Id Revision
\ No newline at end of property
Index: branches/Version13x/Scribus/scribus/scimage.h
===================================================================
--- branches/Version13x/Scribus/scribus/scimage.h (revision 5936)
+++ branches/Version13x/Scribus/scribus/scimage.h (revision 5937)
@@ -9,6 +9,7 @@
#include "scconfig.h"
#include "scribusapi.h"
+#include "scimagestructs.h"
#include <setjmp.h>
#include <cstdlib>
@@ -43,9 +44,6 @@
# undef const // remove crazy C hackery in jconfig.h
#endif
}
-#ifdef HAVE_TIFF
- #include <tiffio.h>
-#endif
class SCRIBUS_API ScImage : private QImage
{
@@ -65,18 +63,6 @@
Thumbnail = 4,
};
- enum PSDColorMode
- {
- CM_BITMAP = 0,
- CM_GRAYSCALE = 1,
- CM_INDEXED = 2,
- CM_RGB = 3,
- CM_CMYK = 4,
- CM_MULTICHANNEL = 7,
- CM_DUOTONE = 8,
- CM_LABCOLOR = 9
- };
-
enum ImageEffectCode
{
EF_INVERT = 0,
@@ -103,7 +89,6 @@
int width() const { return QImage::width(); }
bool hasAlpha() const { return QImage::hasAlphaBuffer(); }
-
// Routines for PDF/PS output of images
QByteArray ImageToArray();
QByteArray ImageToGray();
@@ -133,83 +118,8 @@
// TODO: document params, split into smaller functions
bool LoadPicture(const QString & fn, const CMSettings& cmSettings, int rend, bool useEmbedded, bool useProf, RequestType requestType, int gsRes, bool *realCMYK = 0);
- struct PSDLayer
- {
- QValueList<uint> channelLen;
- QValueList<int> channelType;
- int xpos;
- int ypos;
- int width;
- int height;
- ushort opacity;
- uchar clipping;
- uchar flags;
- int maskXpos;
- int maskYpos;
- int maskWidth;
- int maskHeight;
- QString layerName;
- QString blend;
- QImage thumb;
- };
+ ImageInfoRecord imgInfo;
- struct PSDHeader
- {
- uint signature;
- ushort version;
- uchar reserved[6];
- ushort channel_count;
- uint height;
- uint width;
- ushort depth;
- ushort color_mode;
- };
-
- struct LoadRequest
- {
- bool visible;
- ushort opacity;
- QString blend;
- };
-
- struct ExifValues
- {
- int width;
- int height;
- QString cameraName;
- QString cameraVendor;
- QString comment;
- QString userComment;
- QString artist;
- QString copyright;
- QString dateTime;
- QImage thumbnail;
- };
-
- struct ImageInfoRecord
- {
- int typ; /* 0 = jpg, 1 = tiff, 2 = psd, 3 = eps/ps, 4 = pdf, 5 = jpg2000, 6 = other */
- int xres;
- int yres;
- int BBoxX;
- int BBoxH;
- int colorspace; /* 0 = RGB 1 = CMYK 2 = Grayscale */
- bool valid;
- bool isRequest;
- bool progressive;
- bool isEmbedded;
- bool exifDataValid;
- int lowResType; /* 0 = full Resolution, 1 = 72 dpi, 2 = 36 dpi */
- double lowResScale;
- QMap<QString, FPointArray> PDSpathData;
- QMap<int, LoadRequest> RequestProps;
- QString clipPath;
- QString usedPath;
- QString profileName;
- QValueList<PSDLayer> layerInfo;
- ExifValues exifInfo;
- } imgInfo;
-
private:
// Image effects
void solarize(double factor, bool cmyk);
@@ -229,19 +139,6 @@
bool convolveImage(QImage *dest, const unsigned int order, const double *kernel);
int getOptimalKernelWidth(double radius, double sigma);
void applyCurve(bool cmyk);
- bool IsValid( const PSDHeader & header );
- bool IsSupported( const PSDHeader & header );
- bool loadChannel( QDataStream & s, const PSDHeader & header, QValueList<PSDLayer> &layerInfo, uint layer, int channel, int component, QImage &tmpImg);
- bool loadLayerChannels( QDataStream & s, const PSDHeader & header, QValueList<PSDLayer> &layerInfo, uint layer, bool* firstLayer);
- bool loadLayer( QDataStream & s, const PSDHeader & header);
- QString getLayerString(QDataStream & s);
- QString getPascalString(QDataStream & s);
- void parseRessourceData( QDataStream & s, const PSDHeader & header, uint size);
- bool parseLayer( QDataStream & s, const PSDHeader & header);
- bool LoadPSD( QDataStream & s, const PSDHeader & header);
- bool marker_is_icc (jpeg_saved_marker_ptr marker);
- bool marker_is_photoshop (jpeg_saved_marker_ptr marker);
- bool read_jpeg_marker (UINT8 requestmarker, j_decompress_ptr cinfo, JOCTET **icc_data_ptr, unsigned int *icc_data_len);
char* iccbuf;
uint icclen;
//std::valarray<int> curveTable;
/branches/Version13x/Scribus/scribus/scimgdataloader_ps.cpp
0,0 → 1,222
#include <qfile.h>
#include <qfileinfo.h>
#include "gsutil.h"
#include "scpaths.h"
#include "scribuscore.h"
#include "scimgdataloader_ps.h"
 
ScImgDataLoader_PS::ScImgDataLoader_PS(void) : ScImgDataLoader()
{
initSupportedFormatList();
}
 
void ScImgDataLoader_PS::initSupportedFormatList(void)
{
m_supportedFormats.clear();
m_supportedFormats.append( "ps" );
m_supportedFormats.append( "eps" );
}
 
void ScImgDataLoader_PS::loadEmbeddedProfile(const QString& fn)
{
m_embeddedProfile.resize(0);
m_profileComponents = 0;
}
 
bool ScImgDataLoader_PS::loadPicture(const QString& fn, int gsRes, bool /*thumbnail*/)
{
QStringList args;
double x, y, b, h;
bool found = false;
QString tmp, dummy, cmd1, cmd2, BBox, tmp2;
QFileInfo fi = QFileInfo(fn);
if (!fi.exists())
return false;
QChar tc;
QString ext = fi.extension(false).lower();
QString tmpFile = QDir::convertSeparators(ScPaths::getTempFileDir() + "sc.png");
QString picFile = QDir::convertSeparators(fn);
float xres = gsRes;
float yres = gsRes;
 
initialize();
m_imageInfoRecord.type = 3;
m_imageInfoRecord.exifDataValid = false;
QFile f(fn);
if (f.open(IO_ReadOnly))
{
QTextStream ts(&f);
while (!ts.atEnd())
{
tc = ' ';
tmp = "";
while ((tc != '\n') && (tc != '\r'))
{
ts >> tc;
if ((tc != '\n') && (tc != '\r'))
tmp += tc;
}
if (tmp.startsWith("%%BoundingBox:"))
{
found = true;
BBox = tmp.remove("%%BoundingBox:");
}
if (!found)
{
if (tmp.startsWith("%%BoundingBox"))
{
found = true;
BBox = tmp.remove("%%BoundingBox");
}
}
if (tmp.startsWith("%%EndComments"))
break;
}
}
f.close();
if (found)
{
QTextStream ts2(&BBox, IO_ReadOnly);
ts2 >> x >> y >> b >> h;
h = h * gsRes / 72.0;
QStringList args;
xres = gsRes;
yres = gsRes;
if (ext == "eps")
args.append("-dEPSCrop");
args.append("-r"+QString::number(gsRes));
args.append("-sOutputFile="+tmpFile);
args.append(picFile);
int retg = callGS(args);
if (retg == 0)
{
m_image.load(tmpFile);
m_image.setAlphaBuffer(true);
if (ScCore->havePNGAlpha() != 0)
{
int wi = m_image.width();
int hi = m_image.height();
for( int yi=0; yi < hi; ++yi )
{
QRgb *s = (QRgb*)(m_image.scanLine( yi ));
QRgb alphaFF = qRgba(255,255,255,255);
QRgb alpha00 = qRgba(255,255,255, 0);
for(int xi=0; xi < wi; ++xi )
{
if((*s) == alphaFF)
(*s) &= alpha00;
s++;
}
}
}
unlink(tmpFile);
if (ext == "eps")
{
m_imageInfoRecord.BBoxX = static_cast<int>(x);
m_imageInfoRecord.BBoxH = static_cast<int>(h);
}
else
{
m_imageInfoRecord.BBoxX = 0;
m_imageInfoRecord.BBoxH = m_image.height();
}
m_imageInfoRecord.xres = qRound(gsRes);
m_imageInfoRecord.yres = qRound(gsRes);
m_imageInfoRecord.colorspace = 0;
m_image.setDotsPerMeterX ((int) (xres / 0.0254));
m_image.setDotsPerMeterY ((int) (yres / 0.0254));
return true;
}
}
return false;
}
 
void ScImgDataLoader_PS::preloadAlphaChannel(const QString& fn, int gsRes)
{
float xres, yres;
short resolutionunit = 0;
initialize();
QFileInfo fi = QFileInfo(fn);
if (!fi.exists())
return;
QString tmp, BBox, tmp2;
QString ext = fi.extension(false).lower();
QString tmpFile = QDir::convertSeparators(ScPaths::getTempFileDir() + "sc.png");
QString picFile = QDir::convertSeparators(fn);
double x, y, b, h;
bool found = false;
int retg = -1;
QChar tc;
QFile f(fn);
if (f.open(IO_ReadOnly))
{
QTextStream ts(&f);
while (!ts.atEnd())
{
tc = ' ';
tmp = "";
while ((tc != '\n') && (tc != '\r'))
{
ts >> tc;
if ((tc != '\n') && (tc != '\r'))
tmp += tc;
}
if (tmp.startsWith("%%BoundingBox:"))
{
found = true;
BBox = tmp.remove("%%BoundingBox:");
}
if (!found)
{
if (tmp.startsWith("%%BoundingBox"))
{
found = true;
BBox = tmp.remove("%%BoundingBox");
}
}
if (tmp.startsWith("%%EndComments"))
break;
}
}
f.close();
if (found)
{
QTextStream ts2(&BBox, IO_ReadOnly);
ts2 >> x >> y >> b >> h;
h = h * gsRes / 72.0;
QStringList args;
xres = gsRes;
yres = gsRes;
if (ext == "eps")
args.append("-dEPSCrop");
args.append("-r"+QString::number(gsRes));
args.append("-sOutputFile="+tmpFile);
args.append(picFile);
int retg = callGS(args);
if (retg == 0)
{
m_image.load(tmpFile);
m_image.setAlphaBuffer(true);
if (ScCore->havePNGAlpha() != 0)
{
int wi = m_image.width();
int hi = m_image.height();
for( int yi=0; yi < hi; ++yi )
{
QRgb *s = (QRgb*)(m_image.scanLine( yi ));
QRgb alphaFF = qRgba(255,255,255,255);
QRgb alpha00 = qRgba(255,255,255, 0);
for(int xi=0; xi < wi; ++xi )
{
if((*s) == alphaFF)
(*s) &= alpha00;
s++;
}
}
}
m_image.setAlphaBuffer(true);
unlink(tmpFile);
}
}
}
Property changes:
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+Author Date Id Revision
\ No newline at end of property
Index: branches/Version13x/Scribus/scribus/scimgdataloader_qt.h
===================================================================
--- branches/Version13x/Scribus/scribus/scimgdataloader_qt.h (nonexistent)
+++ branches/Version13x/Scribus/scribus/scimgdataloader_qt.h (revision 5937)
@@ -0,0 +1,20 @@
+#ifndef SCIMGDATALOADER_QT_H
+#define SCIMGDATALOADER_QT_H
+
+#include "scimgdataloader.h"
+
+class ScImgDataLoader_QT : public ScImgDataLoader
+{
+protected:
+
+ void initSupportedFormatList();
+
+public:
+ ScImgDataLoader_QT(void);
+
+ virtual void preloadAlphaChannel(const QString& fn, int res);
+ virtual void loadEmbeddedProfile(const QString& fn);
+ virtual bool loadPicture(const QString& fn, int res, bool thumbnail);
+};
+
+#endif
/branches/Version13x/Scribus/scribus/scimgdataloader_qt.h
Property changes:
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+Author Date Id Revision
\ No newline at end of property
Index: branches/Version13x/Scribus/scribus/scimgdataloader_jpeg.h
===================================================================
--- branches/Version13x/Scribus/scribus/scimgdataloader_jpeg.h (nonexistent)
+++ branches/Version13x/Scribus/scribus/scimgdataloader_jpeg.h (revision 5937)
@@ -0,0 +1,38 @@
+#ifndef SCIMGDATALOADER_JPEG_H
+#define SCIMGDATALOADER_JPEG_H
+
+#include "scimgdataloader.h"
+
+extern "C"
+{
+#define XMD_H // shut JPEGlib up
+#if defined(Q_OS_UNIXWARE)
+# define HAVE_BOOLEAN // libjpeg under Unixware seems to need this
+#endif
+#include <jpeglib.h>
+#include <jerror.h>
+#undef HAVE_STDLIB_H
+#ifdef const
+# undef const // remove crazy C hackery in jconfig.h
+#endif
+}
+
+class ScImgDataLoader_JPEG : public ScImgDataLoader
+{
+protected:
+
+ void initSupportedFormatList();
+
+ bool marker_is_icc (jpeg_saved_marker_ptr marker);
+ bool marker_is_photoshop (jpeg_saved_marker_ptr marker);
+ bool read_jpeg_marker (UINT8 requestmarker, j_decompress_ptr cinfo, JOCTET **icc_data_ptr, unsigned int *icc_data_len);
+
+public:
+ ScImgDataLoader_JPEG(void);
+
+ virtual void preloadAlphaChannel(const QString& fn, int res);
+ virtual void loadEmbeddedProfile(const QString& fn);
+ virtual bool loadPicture(const QString& fn, int res, bool thumbnail);
+};
+
+#endif
/branches/Version13x/Scribus/scribus/scimgdataloader_jpeg.h
Property changes:
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+Author Date Id Revision
\ No newline at end of property
Index: branches/Version13x/Scribus/scribus/imageinfodialog.cpp
===================================================================
--- branches/Version13x/Scribus/scribus/imageinfodialog.cpp (revision 5936)
+++ branches/Version13x/Scribus/scribus/imageinfodialog.cpp (revision 5937)
@@ -10,7 +10,7 @@
extern QPixmap loadIcon(QString nam);
-ImageInfoDialog::ImageInfoDialog( QWidget* parent, ScImage::ImageInfoRecord *info ) : QDialog( parent, "ImageInfo", true, 0 )
+ImageInfoDialog::ImageInfoDialog( QWidget* parent, ImageInfoRecord *info ) : QDialog( parent, "ImageInfo", true, 0 )
{
setCaption( tr( "Image Info" ) );
setIcon(loadIcon("AppIcon.png"));
@@ -71,7 +71,7 @@
UserComment = new QLabel(info->exifInfo.userComment, ExGroup, "UserComment" );
layout2->addWidget( UserComment, 1, 1 );
int a = 2;
- if (info->typ == 1)
+ if (info->type == 1)
{
Text5 = new QLabel( tr("Artist:"), ExGroup, "Text5" );
layout2->addWidget( Text5, 2, 0 );
@@ -88,7 +88,7 @@
Manufact = new QLabel(info->exifInfo.cameraVendor, ExGroup, "Manufact" );
layout2->addWidget( Manufact, a+1, 1 );
ImageInfoDialogLayout->addWidget(ExGroup);
- switch (info->typ)
+ switch (info->type)
{
case 0:
Text1->setText( tr( "Comment:" ));
/branches/Version13x/Scribus/scribus/scimgdataloader_pdf.h
0,0 → 1,20
#ifndef SCIMGDATALOADER_PDF_H
#define SCIMGDATALOADER_PDF_H
 
#include "scimgdataloader.h"
 
class ScImgDataLoader_PDF : public ScImgDataLoader
{
protected:
 
void initSupportedFormatList();
 
public:
ScImgDataLoader_PDF(void);
 
virtual void preloadAlphaChannel(const QString& fn, int res);
virtual void loadEmbeddedProfile(const QString& fn);
virtual bool loadPicture(const QString& fn, int res, bool thumbnail);
};
 
#endif
Property changes:
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+Author Date Id Revision
\ No newline at end of property
Index: branches/Version13x/Scribus/scribus/Makefile.am
===================================================================
--- branches/Version13x/Scribus/scribus/Makefile.am (revision 5936)
+++ branches/Version13x/Scribus/scribus/Makefile.am (revision 5937)
@@ -180,6 +180,14 @@
scfonts_ttf.cpp \
scfontmetrics.cpp \
scimage.cpp \
+ scimagestructs.cpp \
+ scimgdataloader.cpp \
+ scimgdataloader_jpeg.cpp \
+ scimgdataloader_pdf.cpp \
+ scimgdataloader_ps.cpp \
+ scimgdataloader_psd.cpp \
+ scimgdataloader_qt.cpp \
+ scimgdataloader_tiff.cpp \
scmenu.cpp \
scmessagebox.cpp \
scgtplugin.cpp \
Index: branches/Version13x/Scribus/scribus/scimgdataloader_tiff.cpp
===================================================================
--- branches/Version13x/Scribus/scribus/scimgdataloader_tiff.cpp (nonexistent)
+++ branches/Version13x/Scribus/scribus/scimgdataloader_tiff.cpp (revision 5937)
@@ -0,0 +1,294 @@
+#include <qfile.h>
+#include <qfileinfo.h>
+#include "scconfig.h"
+#include "scimgdataloader_tiff.h"
+
+#ifdef HAVE_TIFF
+ #include <tiffio.h>
+#endif
+
+#ifdef HAVE_CMS
+ #include CMS_INC
+#endif
+
+ScImgDataLoader_TIFF::ScImgDataLoader_TIFF(void) : ScImgDataLoader()
+{
+ initSupportedFormatList();
+}
+
+void ScImgDataLoader_TIFF::initSupportedFormatList(void)
+{
+ m_supportedFormats.clear();
+ m_supportedFormats.append( "tif" );
+ m_supportedFormats.append( "tiff" );
+}
+
+void ScImgDataLoader_TIFF::loadEmbeddedProfile(const QString& fn)
+{
+ m_embeddedProfile.resize(0);
+ m_profileComponents = 0;
+#ifdef HAVE_CMS
+ if ( !QFile::exists(fn) )
+ return;
+ TIFF* tif = TIFFOpen(fn.local8Bit(), "r");
+ if(tif)
+ {
+ DWORD EmbedLen = 0;
+ LPBYTE EmbedBuffer;
+ if (TIFFGetField(tif, TIFFTAG_ICCPROFILE, &EmbedLen, &EmbedBuffer))
+ {
+ cmsHPROFILE tiffProf = cmsOpenProfileFromMem(EmbedBuffer, EmbedLen);
+ if (tiffProf)
+ {
+ if (static_cast<int>(cmsGetColorSpace(tiffProf)) == icSigRgbData)
+ m_profileComponents = 3;
+ if (static_cast<int>(cmsGetColorSpace(tiffProf)) == icSigCmykData)
+ m_profileComponents = 4;
+ m_embeddedProfile.duplicate((const char*) EmbedBuffer, EmbedLen);
+ }
+ cmsCloseProfile(tiffProf);
+ }
+ TIFFClose(tif);
+ }
+#endif
+}
+
+void ScImgDataLoader_TIFF::preloadAlphaChannel(const QString& fn, int res)
+{
+ float xres, yres;
+ short resolutionunit = 0;
+ initialize();
+ QFileInfo fi = QFileInfo(fn);
+ if (!fi.exists())
+ return;
+ QString tmp, BBox, tmp2;
+#ifdef HAVE_TIFF
+ TIFF* tif = TIFFOpen(fn.local8Bit(), "r");
+ if(tif)
+ {
+ unsigned width, height, size;
+ TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &width);
+ TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &height);
+ TIFFGetField(tif, TIFFTAG_XRESOLUTION, &xres);
+ TIFFGetField(tif, TIFFTAG_YRESOLUTION, &yres);
+ TIFFGetField(tif, TIFFTAG_RESOLUTIONUNIT , &resolutionunit);
+ size = width * height;
+ uint16 photometric, bitspersample, samplesperpixel, fillorder;
+ TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &photometric);
+ TIFFGetField(tif, TIFFTAG_BITSPERSAMPLE, &bitspersample);
+ TIFFGetField(tif, TIFFTAG_SAMPLESPERPIXEL, &samplesperpixel);
+ TIFFGetField(tif, TIFFTAG_FILLORDER, &fillorder);
+ uint32 *bits = 0;
+ if (photometric == PHOTOMETRIC_SEPARATED)
+ {
+ TIFFClose(tif);
+ return;
+ }
+ else
+ {
+ m_image.create(width,height,32);
+ m_image.setAlphaBuffer(true);
+ bits = (uint32 *) _TIFFmalloc(size * sizeof(uint32));
+ if(bits)
+ {
+ if (TIFFReadRGBAImage(tif, width, height, bits, 0))
+ {
+ for(unsigned int y = 0; y < height; y++)
+ memcpy(m_image.scanLine(height - 1 - y), bits + y * width, width * 4);
+ }
+ _TIFFfree(bits);
+ }
+ else
+ m_image.reset();
+ TIFFClose(tif);
+ }
+ }
+#else
+ qDebug("TIFF Support not available");
+#endif // HAVE_TIFF
+}
+
+bool ScImgDataLoader_TIFF::loadPicture(const QString& fn, int /*gsRes*/, bool /*thumbnail*/)
+{
+ bool bilevel = false;
+ short resolutionunit = 0;
+ float xres = 72.0, yres = 72.0;
+ if (!QFile::exists(fn))
+ return false;
+
+ initialize();
+ m_imageInfoRecord.type = 1;
+ TIFF* tif = TIFFOpen(fn.local8Bit(), "r");
+ if(tif)
+ {
+ bool isCMYK = false;
+ unsigned widtht, heightt, size;
+ char *description=0, *copyright=0, *datetime=0, *artist=0, *scannerMake=0, *scannerModel=0;
+
+ TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &widtht);
+ TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &heightt);
+ TIFFGetField(tif, TIFFTAG_XRESOLUTION, &xres);
+ TIFFGetField(tif, TIFFTAG_YRESOLUTION, &yres);
+ TIFFGetField(tif, TIFFTAG_RESOLUTIONUNIT , &resolutionunit);
+ size = widtht * heightt;
+ uint16 photometric, bitspersample, samplesperpixel, fillorder;
+ TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &photometric);
+ TIFFGetField(tif, TIFFTAG_BITSPERSAMPLE, &bitspersample);
+ TIFFGetField(tif, TIFFTAG_SAMPLESPERPIXEL, &samplesperpixel);
+ TIFFGetField(tif, TIFFTAG_FILLORDER, &fillorder);
+
+ TIFFGetField(tif, TIFFTAG_MAKE, &scannerMake);
+ TIFFGetField(tif, TIFFTAG_MODEL, &scannerModel);
+ TIFFGetField(tif, TIFFTAG_IMAGEDESCRIPTION, &description);
+ TIFFGetField(tif, TIFFTAG_COPYRIGHT, &copyright);
+ TIFFGetField(tif, TIFFTAG_DATETIME, &datetime);
+ TIFFGetField(tif, TIFFTAG_ARTIST, &artist);
+ m_imageInfoRecord.exifInfo.cameraName = QString(scannerModel);
+ m_imageInfoRecord.exifInfo.cameraVendor = QString(scannerMake);
+ m_imageInfoRecord.exifInfo.comment = QString(description);
+ m_imageInfoRecord.exifInfo.userComment = QString(copyright);
+ m_imageInfoRecord.exifInfo.width = widtht;
+ m_imageInfoRecord.exifInfo.height = heightt;
+ m_imageInfoRecord.exifInfo.dateTime = QString(datetime);
+ m_imageInfoRecord.exifInfo.artist = QString(artist);
+ m_imageInfoRecord.exifInfo.thumbnail = QImage();
+ m_imageInfoRecord.exifDataValid = true;
+
+ if (!m_image.create(widtht,heightt,32))
+ {
+ TIFFClose(tif);
+ return false;
+ }
+ m_image.setAlphaBuffer(true);
+ uint32 *bits = 0;
+ if (photometric == PHOTOMETRIC_SEPARATED)
+ {
+ if (TIFFIsTiled(tif))
+ {
+ uint32 columns, rows;
+ uint32 *tile_buf;
+ uint32 xt, yt;
+ TIFFGetField(tif, TIFFTAG_TILEWIDTH, &columns);
+ TIFFGetField(tif, TIFFTAG_TILELENGTH, &rows);
+ tile_buf = (uint32*) _TIFFmalloc(columns*rows*sizeof(uint32));
+ if (tile_buf == NULL)
+ {
+ TIFFClose(tif);
+ return false;
+ }
+ uint32 tileW = columns, tileH = rows;
+ for (yt = 0; yt < (uint32) m_image.height(); yt += rows)
+ {
+ if (yt > (uint) m_image.height())
+ break;
+ if (m_image.height()-yt < rows)
+ tileH = m_image.height()-yt;
+ tileW = columns;
+ register uint32 yi;
+ for (xt = 0; xt < (uint) m_image.width(); xt += columns)
+ {
+ TIFFReadTile(tif, tile_buf, xt, yt, 0, 0);
+ for (yi = 0; yi < tileH; yi++)
+ _TIFFmemcpy(m_image.scanLine(yt+(tileH-1-yi))+xt, tile_buf+tileW*yi, tileW*4);
+ }
+ }
+ _TIFFfree(tile_buf);
+ }
+ else
+ {
+ tsize_t bytesperrow = TIFFScanlineSize(tif);
+ bits = (uint32 *) _TIFFmalloc(bytesperrow);
+ if (bits)
+ {
+ for (unsigned int y = 0; y < heightt; y++)
+ {
+ if (TIFFReadScanline(tif, bits, y, 0))
+ {
+ memcpy(m_image.scanLine(y), bits, widtht * 4);
+ }
+ }
+ _TIFFfree(bits);
+ }
+ }
+ isCMYK = true;
+ }
+ else
+ {
+ bits = (uint32 *) _TIFFmalloc(size * sizeof(uint32));
+ if(bits)
+ {
+ if (TIFFReadRGBAImage(tif, widtht, heightt, bits, 0))
+ {
+ for(unsigned int y = 0; y < heightt; y++)
+ memcpy(m_image.scanLine(heightt - 1 - y), bits + y * widtht, widtht * 4);
+ }
+ _TIFFfree(bits);
+ if (bitspersample == 1)
+ bilevel = true;
+ }
+ }
+ swapRGBA();
+#ifdef HAVE_CMS
+ DWORD EmbedLen = 0;
+ LPBYTE EmbedBuffer;
+ if (TIFFGetField(tif, TIFFTAG_ICCPROFILE, &EmbedLen, &EmbedBuffer))
+ {
+ const char *Descriptor;
+ cmsHPROFILE tiffProf = cmsOpenProfileFromMem(EmbedBuffer, EmbedLen);
+ Descriptor = cmsTakeProductDesc(tiffProf);
+ m_embeddedProfile.duplicate((const char*) EmbedBuffer, EmbedLen);
+ m_imageInfoRecord.profileName = QString(Descriptor);
+ m_imageInfoRecord.isEmbedded = true;
+ cmsCloseProfile(tiffProf);
+ }
+ else
+ {
+ m_imageInfoRecord.isEmbedded = false;
+ m_imageInfoRecord.profileName = "";
+ }
+#endif // HAVE_CMS
+ unsigned int PhotoshopLen = 0;
+ unsigned char* PhotoshopBuffer;
+ if (TIFFGetField(tif, TIFFTAG_PHOTOSHOP, &PhotoshopLen, &PhotoshopBuffer) )
+ {
+ if (PhotoshopLen != 0)
+ {
+ QByteArray arrayPhot(PhotoshopLen);
+ arrayPhot.duplicate((const char*)PhotoshopBuffer,PhotoshopLen);
+ QDataStream strPhot(arrayPhot,IO_ReadOnly);
+ strPhot.setByteOrder( QDataStream::BigEndian );
+ PSDHeader fakeHeader;
+ fakeHeader.width = m_image.width();
+ fakeHeader.height = m_image.height();
+ parseRessourceData(strPhot, fakeHeader, PhotoshopLen);
+ m_imageInfoRecord.valid = (m_imageInfoRecord.PDSpathData.size())>0?true:false;
+ }
+ }
+ TIFFClose(tif);
+ if (resolutionunit == RESUNIT_INCH)
+ {
+ m_image.setDotsPerMeterX ((int) (xres / 0.0254));
+ m_image.setDotsPerMeterY ((int) (yres / 0.0254));
+ m_imageInfoRecord.xres = qRound(xres);
+ m_imageInfoRecord.yres = qRound(yres);
+ }
+ else if (resolutionunit == RESUNIT_CENTIMETER)
+ {
+ m_image.setDotsPerMeterX ((int) (xres * 100.0));
+ m_image.setDotsPerMeterY ((int) (yres * 100.0));
+ m_imageInfoRecord.xres = qRound(xres*2.54);
+ m_imageInfoRecord.yres = qRound(yres*2.54);
+ }
+ if (isCMYK)
+ m_imageInfoRecord.colorspace = 1;
+ else if (bilevel)
+ m_imageInfoRecord.colorspace = 2;
+ else
+ m_imageInfoRecord.colorspace = 0;
+ m_imageInfoRecord.layerInfo.clear();
+ m_imageInfoRecord.BBoxX = 0;
+ m_imageInfoRecord.BBoxH = m_image.height();
+ return true;
+ }
+ return false;
+}
/branches/Version13x/Scribus/scribus/scimgdataloader_tiff.cpp
Property changes:
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+Author Date Id Revision
\ No newline at end of property
Index: branches/Version13x/Scribus/scribus/scimgdataloader_qt.cpp
===================================================================
--- branches/Version13x/Scribus/scribus/scimgdataloader_qt.cpp (nonexistent)
+++ branches/Version13x/Scribus/scribus/scimgdataloader_qt.cpp (revision 5937)
@@ -0,0 +1,66 @@
+#include <qfile.h>
+#include <qfileinfo.h>
+#include "scimgdataloader_qt.h"
+
+ScImgDataLoader_QT::ScImgDataLoader_QT(void) : ScImgDataLoader()
+{
+ initSupportedFormatList();
+}
+
+void ScImgDataLoader_QT::initSupportedFormatList(void)
+{
+ m_supportedFormats.clear();
+ QStringList fmtList = QImage::inputFormatList();
+ for (uint i = 0; i < fmtList.count(); i++)
+ m_supportedFormats.append( fmtList[i].lower() );
+}
+
+void ScImgDataLoader_QT::loadEmbeddedProfile(const QString& fn)
+{
+ m_embeddedProfile.resize(0);
+ m_profileComponents = 0;
+}
+
+bool ScImgDataLoader_QT::loadPicture(const QString& fn, int /*res*/, bool /*thumbnail*/)
+{
+ if (!QFile::exists(fn))
+ return false;
+ initialize();
+ if (m_image.load(fn))
+ {
+ m_imageInfoRecord.type = 6;
+ m_imageInfoRecord.exifDataValid = false;
+ float xres = m_image.dotsPerMeterX() * 0.0254;
+ float yres = m_image.dotsPerMeterY() * 0.0254;
+ int resInf = m_imageInfoRecord.lowResType;
+ m_image = m_image.convertDepth(32);
+ m_image.setAlphaBuffer(true);
+ m_image.setDotsPerMeterX (QMAX(2834, (int) (xres / 0.0254)));
+ m_image.setDotsPerMeterY (QMAX(2834, (int) (yres / 0.0254)));
+ m_imageInfoRecord.colorspace = 0;
+ m_imageInfoRecord.xres = QMAX(72, qRound(xres));
+ m_imageInfoRecord.yres = QMAX(72, qRound(yres));
+ m_imageInfoRecord.lowResType = resInf;
+ m_imageInfoRecord.BBoxX = 0;
+ m_imageInfoRecord.BBoxH = m_image.height();
+ return true;
+ }
+ return true;
+}
+
+void ScImgDataLoader_QT::preloadAlphaChannel(const QString& fn, int res)
+{
+ initialize();
+ QFileInfo fi = QFileInfo(fn);
+ if (!fi.exists())
+ return;
+ QString ext = fi.extension(false).lower();
+ if ((ext == "jpg") || (ext == "jpeg"))
+ return;
+ if (m_image.load(fn))
+ {
+ m_image = m_image.convertDepth(32);
+ if (m_image.hasAlphaBuffer())
+ m_image.setAlphaBuffer(true);
+ }
+}
/branches/Version13x/Scribus/scribus/scimgdataloader_qt.cpp
Property changes:
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+Author Date Id Revision
\ No newline at end of property
Index: branches/Version13x/Scribus/scribus/scimagestructs.cpp
===================================================================
--- branches/Version13x/Scribus/scribus/scimagestructs.cpp (nonexistent)
+++ branches/Version13x/Scribus/scribus/scimagestructs.cpp (revision 5937)
@@ -0,0 +1,49 @@
+#include "scimagestructs.h"
+
+ExifValues::ExifValues(void)
+{
+ init();
+}
+
+void ExifValues::init(void)
+{
+ width = 0;
+ height = 0;
+ cameraName.setLength(0);
+ cameraVendor.setLength(0);
+ comment.setLength(0);
+ userComment.setLength(0);
+ artist.setLength(0);
+ copyright.setLength(0);
+ dateTime.setLength(0);
+ thumbnail = QImage();
+}
+
+ImageInfoRecord::ImageInfoRecord(void)
+{
+ init();
+}
+
+void ImageInfoRecord::init(void)
+{
+ type = 0; /* 0 = jpg, 1 = tiff, 2 = psd, 3 = eps/ps, 4 = pdf, 5 = jpg2000, 6 = other */
+ xres = 72;
+ yres = 72;
+ BBoxX = 0;
+ BBoxH = 0;
+ colorspace = 0; /* 0 = RGB 1 = CMYK 2 = Grayscale */
+ valid = false;
+ isRequest = false;
+ progressive = false;
+ isEmbedded = false;
+ exifDataValid = false;
+ lowResType = 1; /* 0 = full Resolution, 1 = 72 dpi, 2 = 36 dpi */
+ lowResScale = 1.0;
+ PDSpathData.clear();
+ RequestProps.clear();
+ clipPath.setLength(0);
+ usedPath.setLength(0);
+ profileName.setLength(0);
+ layerInfo.clear();
+ exifInfo.init();
+}
/branches/Version13x/Scribus/scribus/scimagestructs.cpp
Property changes:
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+Author Date Id Revision
\ No newline at end of property
Index: branches/Version13x/Scribus/scribus/imageinfodialog.h
===================================================================
--- branches/Version13x/Scribus/scribus/imageinfodialog.h (revision 5936)
+++ branches/Version13x/Scribus/scribus/imageinfodialog.h (revision 5937)
@@ -24,7 +24,7 @@
Q_OBJECT
public:
- ImageInfoDialog( QWidget* parent, ScImage::ImageInfoRecord *info );
+ ImageInfoDialog( QWidget* parent, ImageInfoRecord *info );
~ImageInfoDialog() {};
protected:
/branches/Version13x/Scribus/scribus/scimage.cpp
8,7 → 8,15
#include "scribus.h"
#include "scpaths.h"
#include "scribuscore.h"
#include "scimgdataloader_jpeg.h"
#include "scimgdataloader_pdf.h"
#include "scimgdataloader_ps.h"
#include "scimgdataloader_psd.h"
#include "scimgdataloader_pdf.h"
#include "scimgdataloader_qt.h"
#include "scimgdataloader_tiff.h"
#include <qtextstream.h>
#include <memory>
#include <cassert>
#ifdef HAVE_CMS
#include CMS_INC
18,6 → 26,8
#include "commonstrings.h"
#include "util.h"
 
using namespace std;
 
typedef struct my_error_mgr
{
struct jpeg_error_mgr pub; /* "public" fields */
32,23 → 42,6
longjmp (myerr->setjmp_buffer, 1);
}
 
static QDataStream & operator>> ( QDataStream & s, ScImage::PSDHeader & header )
{
s >> header.signature;
s >> header.version;
for( int i = 0; i < 6; i++ )
{
s >> header.reserved[i];
}
s >> header.channel_count;
s >> header.height;
s >> header.width;
s >> header.depth;
s >> header.color_mode;
return s;
}
 
 
ScImage::ScImage(const QImage & image) : QImage(image)
{
initialize();
409,8 → 402,8
q = (unsigned int *)dest.scanLine(y);
blurScanLine(kernel, widthk, p, q, width());
}
unsigned int **srcTable = (unsigned int **)jumpTable();
unsigned int **destTable = (unsigned int **)dest.jumpTable();
unsigned int **srcTable = (unsigned int **) jumpTable();
unsigned int **destTable = (unsigned int **) dest.jumpTable();
for(x=0; x < width(); ++x)
{
for(y=0; y < height(); ++y)
1039,1391 → 1032,6
return imgArray;
}
 
// Check that the header is a valid PSD.
bool ScImage::IsValid( const PSDHeader & header )
{
if( header.signature != 0x38425053 )
return false;
return true;
}
 
// Check that the header is supported.
bool ScImage::IsSupported( const PSDHeader & header )
{
if ( header.version != 1 )
return false;
if ( header.channel_count > 16 )
return false;
if ( header.depth != 8 )
return false;
if ((header.color_mode == CM_RGB) || (header.color_mode == CM_CMYK)
|| (header.color_mode == CM_GRAYSCALE) || (header.color_mode == CM_INDEXED))
return true;
return false;
}
 
bool ScImage::loadChannel( QDataStream & s, const PSDHeader & header, QValueList<PSDLayer> &layerInfo, uint layer, int channel, int component, QImage &tmpImg)
{
uint base = s.device()->at();
uchar cbyte;
ushort compression;
s >> compression;
if( compression > 1 )
return false;
if (compression == 0)
{
int count = layerInfo[layer].channelLen[channel]-2;
for (int i = 0; i < tmpImg.height(); i++)
{
uchar *ptr = tmpImg.scanLine(i);
for (int j = 0; j < tmpImg.width(); j++)
{
s >> cbyte;
count--;
if (header.color_mode == CM_CMYK)
cbyte = 255 - cbyte;
if ((header.color_mode == CM_GRAYSCALE) && (component != 3))
{
ptr[0] = cbyte;
ptr[1] = cbyte;
ptr[2] = cbyte;
}
else if ((header.color_mode == CM_INDEXED) && (component != 3))
{
int ccol = colorTable[cbyte];
ptr[2] = qRed(ccol);
ptr[1] = qGreen(ccol);
ptr[0] = qBlue(ccol);
}
else
{
if (channel < 4)
ptr[component] = cbyte;
}
if (count == 0)
break;
ptr += 4;
}
if (count == 0)
break;
}
}
else
{
s.device()->at( s.device()->at() + tmpImg.height() * 2 );
uint pixel_count = tmpImg.width();
for (int hh = 0; hh < tmpImg.height(); hh++)
{
uint count = 0;
uchar *ptr = tmpImg.scanLine(hh);
uchar *ptr2 = ptr+tmpImg.width() * 4;
ptr += component;
while( count < pixel_count )
{
uchar c;
if(s.atEnd())
return false;
s >> c;
uint len = c;
if( len < 128 )
{
// Copy next len+1 bytes literally.
len++;
count += len;
while( len != 0 )
{
s >> cbyte;
if (ptr < ptr2)
{
if (header.color_mode == CM_CMYK)
cbyte = 255 - cbyte;
if ((header.color_mode == CM_GRAYSCALE) && (component != 3))
{
ptr -= component;
ptr[0] = cbyte;
ptr[1] = cbyte;
ptr[2] = cbyte;
ptr += component;
}
else if ((header.color_mode == CM_INDEXED) && (component != 3))
{
ptr -= component;
int ccol = colorTable[cbyte];
ptr[2] = qRed(ccol);
ptr[1] = qGreen(ccol);
ptr[0] = qBlue(ccol);
ptr += component;
}
else
{
*ptr = cbyte;
}
}
ptr += 4;
len--;
}
}
else if( len > 128 )
{
// Next -len+1 bytes in the dest are replicated from next source byte.
// (Interpret len as a negative 8-bit int.)
len ^= 0xFF;
len += 2;
count += len;
uchar val;
s >> val;
if (header.color_mode == CM_CMYK)
val = 255 - val;
while( len != 0 )
{
if (ptr < ptr2)
{
if ((header.color_mode == CM_GRAYSCALE) && (component != 3))
{
ptr -= component;
ptr[0] = val;
ptr[1] = val;
ptr[2] = val;
ptr += component;
}
else if ((header.color_mode == CM_INDEXED) && (component != 3))
{
ptr -= component;
int ccol = colorTable[val];
ptr[2] = qRed(ccol);
ptr[1] = qGreen(ccol);
ptr[0] = qBlue(ccol);
ptr += component;
}
else
*ptr = val;
}
ptr += 4;
len--;
}
}
else if( len == 128 )
{
// No-op.
}
}
}
}
s.device()->at( base+layerInfo[layer].channelLen[channel] );
return true;
}
 
bool ScImage::loadLayerChannels( QDataStream & s, const PSDHeader & header, QValueList<PSDLayer> &layerInfo, uint layer, bool* firstLayer)
{
// Find out if the data is compressed.
// Known values:
// 0: no compression
// 1: RLE compressed
uint base = s.device()->at();
uint base2 = base;
uint channel_num = layerInfo[layer].channelLen.count();
QImage tmpImg = QImage();
QImage mask = QImage();
if( !tmpImg.create( layerInfo[layer].width, layerInfo[layer].height, 32 ))
{
for(uint channel = 0; channel < channel_num; channel++)
{
base2 += layerInfo[layer].channelLen[channel];
}
s.device()->at( base2 );
return false;
}
tmpImg.fill(qRgba(255, 255, 255, 0));
tmpImg.setAlphaBuffer( true );
channel_num = QMIN(channel_num, 39);
uint components[40];
for(uint channel = 0; channel < channel_num; channel++)
{
switch(layerInfo[layer].channelType[channel])
{
case 0:
components[channel] = 2;
break;
case 1:
components[channel] = 1;
break;
case 2:
components[channel] = 0;
break;
case 3:
components[channel] = 3;
break;
case -1:
case -2:
components[channel] = 3;
break;
}
}
if (channel_num < 4)
{
for (int i = 0; i < tmpImg.height(); i++)
{
QRgb * s = (QRgb*)(tmpImg.scanLine( i ));
for (int j = 0; j < tmpImg.width(); j++)
{
*s++ = qRgba(255, 255, 255, 255);
}
}
}
for(uint channel = 0; channel < channel_num; channel++)
{
if ((layerInfo[layer].channelType[channel] < 0) && (header.color_mode == CM_CMYK))
{
s.device()->at( base+layerInfo[layer].channelLen[channel] );
base = base+layerInfo[layer].channelLen[channel];
continue;
}
// if ((layerInfo[layer].channelType[channel] == -2) || (layerInfo[layer].channelType[channel] == -1))
if (layerInfo[layer].channelType[channel] == -2)
{
if (!mask.create( layerInfo[layer].maskWidth, layerInfo[layer].maskHeight, 32 ))
// {
// if (!mask.create(layerInfo[layer].width, layerInfo[layer].height, 32 ))
break;
// }
mask.fill(qRgba(255, 255, 255, 0));
mask.setAlphaBuffer( true );
if (!loadChannel(s, header, layerInfo, layer, channel, components[channel], mask))
break;
}
else
{
if (!loadChannel(s, header, layerInfo, layer, channel, components[channel], tmpImg))
break;
}
}
for(uint channel = 0; channel < channel_num; channel++)
{
base2 += layerInfo[layer].channelLen[channel];
}
s.device()->at( base2 );
QImage tmpImg2 = tmpImg.copy();
if (header.color_mode == CM_CMYK)
{
for (int i = 0; i < tmpImg.height(); i++)
{
unsigned int *ptr = (unsigned int *) tmpImg.scanLine(i);
unsigned int *ptr2 = (unsigned int *) tmpImg2.scanLine(i);
unsigned char r, g, b;
for (int j = 0; j < tmpImg.width(); j++)
{
unsigned char *p = (unsigned char *) ptr;
unsigned char *p2 = (unsigned char *) ptr2;
r = 255 - QMIN(255, p[0] + p[3]);
g = 255 - QMIN(255, p[1] + p[3]);
b = 255 - QMIN(255, p[2] + p[3]);
p2[0] = r;
p2[1] = g;
p2[2] = b;
p2[3] = 255;
ptr++;
ptr2++;
}
}
}
QImage imt;
double sx = tmpImg.width() / 40.0;
double sy = tmpImg.height() / 40.0;
imt = sy < sx ? tmpImg2.smoothScale(qRound(tmpImg.width() / sx), qRound(tmpImg.height() / sx)) :
tmpImg2.smoothScale(qRound(tmpImg.width() / sy), qRound(tmpImg.height() / sy));
layerInfo[layer].thumb = imt.copy();
bool visible = !(layerInfo[layer].flags & 2);
if ((imgInfo.isRequest) && (imgInfo.RequestProps.contains(layer)))
visible = imgInfo.RequestProps[layer].visible;
if (visible)
{
unsigned int startSrcY, startSrcX, startDstY, startDstX;
if (layerInfo[layer].ypos < 0)
{
startSrcY = abs(layerInfo[layer].ypos);
startDstY = 0;
}
else
{
startSrcY = 0;
startDstY = layerInfo[layer].ypos;
}
if (layerInfo[layer].xpos < 0)
{
startSrcX = abs(layerInfo[layer].xpos);
startDstX = 0;
}
else
{
startSrcX = 0;
startDstX = layerInfo[layer].xpos;
}
unsigned int startSrcYm, startSrcXm, startDstYm, startDstXm;
if (layerInfo[layer].maskYpos < 0)
{
startSrcYm = abs(layerInfo[layer].maskYpos);
startDstYm = 0;
}
else
{
startSrcYm = 0;
startDstYm = layerInfo[layer].maskYpos;
}
if (layerInfo[layer].maskXpos < 0)
{
startSrcXm = abs(layerInfo[layer].maskXpos);
startDstXm = 0;
}
else
{
startSrcXm = 0;
startDstXm = layerInfo[layer].maskXpos;
}
QString layBlend2 = layerInfo[layer].blend;
if ((imgInfo.isRequest) && (imgInfo.RequestProps.contains(layer)))
layBlend2 = imgInfo.RequestProps[layer].blend;
if ((layBlend2 == "diss") && (header.color_mode != CM_CMYK))
{
for (int l = 0; l < tmpImg.height(); l++)
{
srand(random_table[ l % 4096]);
for (int k = 0; k < tmpImg.width(); k++)
{
int rand_val = rand() & 0xff;
QRgb pixel = tmpImg.pixel(k, l);
if (rand_val > 128)
tmpImg.setPixel(k, l, qRgba(qRed(pixel), qGreen(pixel), qBlue(pixel), 0));
}
}
}
if (*firstLayer)
{
for( int yi=static_cast<int>(startSrcY); yi < QMIN(tmpImg.height(), height()); ++yi )
{
QRgb *s = (QRgb*)(tmpImg.scanLine( yi ));
QRgb *d = (QRgb*)(scanLine( QMIN(static_cast<int>(startDstY), height()-1) ));
d += QMIN(static_cast<int>(startDstX), width()-1);
s += QMIN(static_cast<int>(startSrcX), tmpImg.width()-1);
/* unsigned int *srcm;
if (!mask.isNull())
{
srcm = (unsigned int *)mask.scanLine(QMIN(yi, mask.height()-1));
srcm += QMIN(static_cast<int>(startSrcXm), mask.width()-1);
} */
for(int xi=static_cast<int>(startSrcX); xi < QMIN(tmpImg.width(), width()); ++xi )
{
(*d) = (*s);
/* unsigned char *sm = (unsigned char *) srcm;
unsigned char *sc = (unsigned char *) d;
unsigned char *ss = (unsigned char *) s;
if (!mask.isNull())
{
if (header.color_mode == CM_CMYK)
{
sc[0] = (sc[0] * (255 - sm[3]) + ss[0] * sm[3]) / 255;
sc[1] = (sc[1] * (255 - sm[3]) + ss[1] * sm[3]) / 255;
sc[2] = (sc[2] * (255 - sm[3]) + ss[2] * sm[3]) / 255;
sc[3] = (sc[3] * (255 - sm[3]) + ss[3] * sm[3]) / 255;
}
else
sc[3] = sm[3];
}
srcm++; */
s++;
d++;
}
startDstY++;
}
}
else
{
for (int i = static_cast<int>(startSrcY); i < layerInfo[layer].height; i++)
{
unsigned int *dst = (unsigned int *)scanLine(QMIN(static_cast<int>(startDstY), height()-1));
unsigned int *src = (unsigned int *)tmpImg.scanLine(QMIN(i, tmpImg.height()-1));
dst += QMIN(static_cast<int>(startDstX), width()-1);
src += QMIN(static_cast<int>(startSrcX), tmpImg.width()-1);
unsigned int *srcm = 0;
if (!mask.isNull())
{
srcm = (unsigned int *)mask.scanLine(QMIN(i, mask.height()-1));
srcm += QMIN(static_cast<int>(startSrcXm), mask.width()-1);
}
startDstY++;
unsigned char r, g, b, a, src_r, src_g, src_b, src_a, mask_a;
//<<#3356
unsigned int maxDestX = width() - startDstX + startSrcX - 1;
for (unsigned int j = startSrcX; j < QMIN(maxDestX, static_cast<unsigned int>(layerInfo[layer].width)); j++)
//for (unsigned int j = startSrcX; j < static_cast<unsigned int>(layerInfo[layer].width); j++)
//>>#3356
{
unsigned char *d = (unsigned char *) dst;
unsigned char *s = (unsigned char *) src;
unsigned char *sm = (unsigned char *) srcm;
src_r = s[0];
src_g = s[1];
src_b = s[2];
src_a = s[3];
if (!mask.isNull())
mask_a = sm[3];
QString layBlend = layerInfo[layer].blend;
if ((imgInfo.isRequest) && (imgInfo.RequestProps.contains(layer)))
layBlend = imgInfo.RequestProps[layer].blend;
if (layBlend == "mul ")
{
if (header.color_mode == CM_CMYK)
{
src_r = INT_MULT(src_r, d[0]);
src_g = INT_MULT(src_g, d[1]);
src_b = INT_MULT(src_b, d[2]);
src_a = INT_MULT(src_a, d[3]);
}
else
{
if (d[3] > 0)
{
src_r = INT_MULT(src_r, d[0]);
src_g = INT_MULT(src_g, d[1]);
src_b = INT_MULT(src_b, d[2]);
}
}
}
else if (layBlend == "scrn")
{
if (header.color_mode == CM_CMYK)
{
src_r = 255 - ((255-src_r) * (255-d[0]) / 128);
src_g = 255 - ((255-src_g) * (255-d[1]) / 128);
src_b = 255 - ((255-src_b) * (255-d[2]) / 128);
src_a = 255 - ((255-src_a) * (255-d[3]) / 128);
/* src_r = 255 - INT_MULT(255 - d[0], 255 - src_r);
src_g = 255 - INT_MULT(255 - d[1], 255 - src_g);
src_b = 255 - INT_MULT(255 - d[2], 255 - src_b);
src_a = 255 - INT_MULT(255 - d[3], 255 - src_a); */
}
else
{
if (d[3] > 0)
{
src_r = 255 - ((255-src_r) * (255-d[0]) / 128);
src_g = 255 - ((255-src_g) * (255-d[1]) / 128);
src_b = 255 - ((255-src_b) * (255-d[2]) / 128);
/* src_r = 255 - INT_MULT(255 - d[0], 255 - src_r);
src_g = 255 - INT_MULT(255 - d[1], 255 - src_g);
src_b = 255 - INT_MULT(255 - d[2], 255 - src_b); */
}
}
}
else if (layBlend == "over")
{
if (header.color_mode == CM_CMYK)
{
src_r = d[0] < 128 ? src_r * d[0] / 128 : 255 - ((255-src_r) * (255-d[0]) / 128);
src_g = d[1] < 128 ? src_g * d[1] / 128 : 255 - ((255-src_g) * (255-d[1]) / 128);
src_b = d[2] < 128 ? src_b * d[2] / 128 : 255 - ((255-src_b) * (255-d[2]) / 128);
src_a = d[3] < 128 ? src_a * d[3] / 128 : 255 - ((255-src_a) * (255-d[3]) / 128);
/* src_r = INT_MULT(d[0], d[0] + INT_MULT(2 * src_r, 255 - d[0]));
src_g = INT_MULT(d[1], d[1] + INT_MULT(2 * src_g, 255 - d[1]));
src_b = INT_MULT(d[2], d[2] + INT_MULT(2 * src_b, 255 - d[2]));
src_a = INT_MULT(d[3], d[3] + INT_MULT(2 * src_a, 255 - d[3])); */
}
else
{
if (d[3] > 0)
{
src_r = d[0] < 128 ? src_r * d[0] / 128 : 255 - ((255-src_r) * (255-d[0]) / 128);
src_g = d[1] < 128 ? src_g * d[1] / 128 : 255 - ((255-src_g) * (255-d[1]) / 128);
src_b = d[2] < 128 ? src_b * d[2] / 128 : 255 - ((255-src_b) * (255-d[2]) / 128);
/* src_r = INT_MULT(d[0], d[0] + INT_MULT(2 * src_r, 255 - d[0]));
src_g = INT_MULT(d[1], d[1] + INT_MULT(2 * src_g, 255 - d[1]));
src_b = INT_MULT(d[2], d[2] + INT_MULT(2 * src_b, 255 - d[2])); */
}
}
}
else if (layBlend == "diff")
{
if (header.color_mode == CM_CMYK)
{
src_r = d[0] > src_r ? d[0] - src_r : src_r - d[0];
src_g = d[1] > src_g ? d[1] - src_g : src_g - d[1];
src_b = d[2] > src_b ? d[2] - src_b : src_b - d[2];
src_a = d[3] > src_a ? d[3] - src_a : src_a - d[3];
}
else
{
if (d[3] > 0)
{
src_r = d[0] > src_r ? d[0] - src_r : src_r - d[0];
src_g = d[1] > src_g ? d[1] - src_g : src_g - d[1];
src_b = d[2] > src_b ? d[2] - src_b : src_b - d[2];
}
}
}
else if (layBlend == "dark")
{
if (header.color_mode == CM_CMYK)
{
src_r = d[0] < src_r ? d[0] : src_r;
src_g = d[1] < src_g ? d[1] : src_g;
src_b = d[2] < src_b ? d[2] : src_b;
src_a = d[3] < src_a ? d[3] : src_a;
}
else
{
if (d[3] > 0)
{
src_r = d[0] < src_r ? d[0] : src_r;
src_g = d[1] < src_g ? d[1] : src_g;
src_b = d[2] < src_b ? d[2] : src_b;
}
}
}
else if (layBlend == "hLit")
{
if (header.color_mode == CM_CMYK)
{
src_r = src_r < 128 ? src_r * d[0] / 128 : 255 - ((255-src_r) * (255-d[0]) / 128);
src_g = src_g < 128 ? src_g * d[1] / 128 : 255 - ((255-src_g) * (255-d[1]) / 128);
src_b = src_b < 128 ? src_b * d[2] / 128 : 255 - ((255-src_b) * (255-d[2]) / 128);
src_a = src_a < 128 ? src_a * d[3] / 128 : 255 - ((255-src_a) * (255-d[3]) / 128);
}
else
{
if (d[3] > 0)
{
src_r = src_r < 128 ? src_r * d[0] / 128 : 255 - ((255-src_r) * (255-d[0]) / 128);
src_g = src_g < 128 ? src_g * d[1] / 128 : 255 - ((255-src_g) * (255-d[1]) / 128);
src_b = src_b < 128 ? src_b * d[2] / 128 : 255 - ((255-src_b) * (255-d[2]) / 128);
}
}
}
else if (layBlend == "sLit")
{
if (header.color_mode == CM_CMYK)
{
src_r = src_r * d[0] / 256 + src_r * (255 - ((255-src_r)*(255-d[0]) / 256) - src_r * d[0] / 256) / 256;
src_g = src_g * d[1] / 256 + src_g * (255 - ((255-src_g)*(255-d[1]) / 256) - src_g * d[1] / 256) / 256;
src_b = src_b * d[2] / 256 + src_b * (255 - ((255-src_b)*(255-d[2]) / 256) - src_b * d[2] / 256) / 256;
src_a = src_a * d[3] / 256 + src_a * (255 - ((255-src_a)*(255-d[3]) / 256) - src_a * d[3] / 256) / 256;
}
else
{
if (d[3] > 0)
{
src_r = src_r * d[0] / 256 + src_r * (255 - ((255-src_r)*(255-d[0]) / 256) - src_r * d[0] / 256) / 256;
src_g = src_g * d[1] / 256 + src_g * (255 - ((255-src_g)*(255-d[1]) / 256) - src_g * d[1] / 256) / 256;
src_b = src_b * d[2] / 256 + src_b * (255 - ((255-src_b)*(255-d[2]) / 256) - src_b * d[2] / 256) / 256;
}
}
}
else if (layBlend == "lite")
{
if (header.color_mode == CM_CMYK)
{
src_r = d[0] < src_r ? src_r : d[0];
src_g = d[1] < src_g ? src_g : d[1];
src_b = d[2] < src_b ? src_b : d[2];
src_a = d[3] < src_a ? src_a : d[3];
}
else
{
if (d[3] > 0)
{
src_r = d[0] < src_r ? src_r : d[0];
src_g = d[1] < src_g ? src_g : d[1];
src_b = d[2] < src_b ? src_b : d[2];
}
}
}
else if (layBlend == "smud")
{
if (header.color_mode == CM_CMYK)
{
src_r = d[0] + src_r - src_r * d[0] / 128;
src_g = d[1] + src_g - src_g * d[1] / 128;
src_b = d[2] + src_b - src_b * d[2] / 128;
src_a = d[3] + src_a - src_a * d[3] / 128;
}
else
{
if (d[3] > 0)
{
src_r = d[0] + src_r - src_r * d[0] / 128;
src_g = d[1] + src_g - src_g * d[1] / 128;
src_b = d[2] + src_b - src_b * d[2] / 128;
}
}
}
else if (layBlend == "div ")
{
if (header.color_mode == CM_CMYK)
{
src_r = src_r == 255 ? 255 : ((d[0] * 256) / (255-src_r)) > 255 ? 255 : (d[0] * 256) / (255-src_r);
src_g = src_g == 255 ? 255 : ((d[1] * 256) / (255-src_g)) > 255 ? 255 : (d[1] * 256) / (255-src_g);
src_b = src_b == 255 ? 255 : ((d[2] * 256) / (255-src_b)) > 255 ? 255 : (d[2] * 256) / (255-src_b);
src_a = src_a == 255 ? 255 : ((d[3] * 256) / (255-src_a)) > 255 ? 255 : (d[3] * 256) / (255-src_a);
}
else
{
if (d[3] > 0)
{
src_r = src_r == 255 ? 255 : ((d[0] * 256) / (255-src_r)) > 255 ? 255 : (d[0] * 256) / (255-src_r);
src_g = src_g == 255 ? 255 : ((d[1] * 256) / (255-src_g)) > 255 ? 255 : (d[1] * 256) / (255-src_g);
src_b = src_b == 255 ? 255 : ((d[2] * 256) / (255-src_b)) > 255 ? 255 : (d[2] * 256) / (255-src_b);
}
}
}
else if (layBlend == "idiv")
{
if (header.color_mode == CM_CMYK)
{
src_r = src_r == 0 ? 0 : (255 - (((255-d[0]) * 256) / src_r)) < 0 ? 0 : 255 - (((255-d[0]) * 256) / src_r);
src_g = src_g == 0 ? 0 : (255 - (((255-d[1]) * 256) / src_g)) < 0 ? 0 : 255 - (((255-d[1]) * 256) / src_g);
src_b = src_b == 0 ? 0 : (255 - (((255-d[2]) * 256) / src_b)) < 0 ? 0 : 255 - (((255-d[2]) * 256) / src_b);
src_a = src_a == 0 ? 0 : (255 - (((255-d[3]) * 256) / src_a)) < 0 ? 0 : 255 - (((255-d[3]) * 256) / src_a);
}
else
{
if (d[3] > 0)
{
src_r = src_r == 0 ? 0 : (255 - (((255-d[0]) * 256) / src_r)) < 0 ? 0 : 255 - (((255-d[0]) * 256) / src_r);
src_g = src_g == 0 ? 0 : (255 - (((255-d[1]) * 256) / src_g)) < 0 ? 0 : 255 - (((255-d[1]) * 256) / src_g);
src_b = src_b == 0 ? 0 : (255 - (((255-d[2]) * 256) / src_b)) < 0 ? 0 : 255 - (((255-d[2]) * 256) / src_b);
}
}
}
else if (layBlend == "hue ")
{
if (header.color_mode != CM_CMYK)
{
if (d[3] > 0)
{
uchar new_r = d[0];
uchar new_g = d[1];
uchar new_b = d[2];
RGBTOHSV(src_r, src_g, src_b);
RGBTOHSV(new_r, new_g, new_b);
new_r = src_r;
HSVTORGB(new_r, new_g, new_b);
src_r = new_r;
src_g = new_g;
src_b = new_b;
}
}
}
else if (layBlend == "sat ")
{
if (header.color_mode != CM_CMYK)
{
if (d[3] > 0)
{
uchar new_r = d[0];
uchar new_g = d[1];
uchar new_b = d[2];
RGBTOHSV(src_r, src_g, src_b);
RGBTOHSV(new_r, new_g, new_b);
new_g = src_g;
HSVTORGB(new_r, new_g, new_b);
src_r = new_r;
src_g = new_g;
src_b = new_b;
}
}
}
else if (layBlend == "lum ")
{
if (header.color_mode != CM_CMYK)
{
if (d[3] > 0)
{
uchar new_r = d[0];
uchar new_g = d[1];
uchar new_b = d[2];
RGBTOHSV(src_r, src_g, src_b);
RGBTOHSV(new_r, new_g, new_b);
new_b = src_b;
HSVTORGB(new_r, new_g, new_b);
src_r = new_r;
src_g = new_g;
src_b = new_b;
}
}
}
else if (layBlend == "colr")
{
if (header.color_mode != CM_CMYK)
{
if (d[3] > 0)
{
uchar new_r = d[0];
uchar new_g = d[1];
uchar new_b = d[2];
RGBTOHLS(src_r, src_g, src_b);
RGBTOHLS(new_r, new_g, new_b);
new_r = src_r;
new_b = src_b;
HLSTORGB(new_r, new_g, new_b);
src_r = new_r;
src_g = new_g;
src_b = new_b;
}
}
}
int layOpa = layerInfo[layer].opacity;
if ((imgInfo.isRequest) && (imgInfo.RequestProps.contains(layer)))
layOpa = imgInfo.RequestProps[layer].opacity;
if (!mask.isNull())
layOpa = INT_MULT(mask_a, layOpa);
if (header.color_mode != CM_CMYK)
src_a = INT_MULT(src_a, layOpa);
if (d[3] > 0)
{
r = (d[0] * (255 - layOpa) + src_r * layOpa) / 255;
g = (d[1] * (255 - layOpa) + src_g * layOpa) / 255;
b = (d[2] * (255 - layOpa) + src_b * layOpa) / 255;
if (header.color_mode == CM_CMYK)
a = (d[3] * (255 - layOpa) + src_a * layOpa) / 255;
else
{
a = d[3] + INT_MULT(255 - d[3], src_a);
r = (d[0] * (255 - src_a) + src_r * src_a) / 255;
g = (d[1] * (255 - src_a) + src_g * src_a) / 255;
b = (d[2] * (255 - src_a) + src_b * src_a) / 255;
}
}
else
{
r = src_r;
g = src_g;
b = src_b;
a = src_a;
}
if (header.color_mode == CM_CMYK)
{
d[0] = r;
d[1] = g;
d[2] = b;
d[3] = a;
}
else
{
if (src_a > 0)
{
d[0] = r;
d[1] = g;
d[2] = b;
d[3] = a;
}
}
dst++;
src++;
if (!mask.isNull())
srcm++;
}
}
}
}
*firstLayer = false;
return true;
}
 
bool ScImage::loadLayer( QDataStream & s, const PSDHeader & header )
{
// Find out if the data is compressed.
// Known values:
// 0: no compression
// 1: RLE compressed
ushort compression;
uchar cbyte;
s >> compression;
if( compression > 1 )
{
// Unknown compression type.
return false;
}
uint channel_num = header.channel_count;
if (channel_num < 4)
{
for (int i = 0; i < height(); i++)
{
QRgb * s = (QRgb*)(scanLine( i ));
for (int j = 0; j < width(); j++)
{
*s++ = qRgba(0, 0, 0, 255);
}
}
}
// channel_num = 4;
const uint pixel_count = header.height * header.width;
static const uint components[4] = {2, 1, 0, 3};
if( compression )
{
// Skip row lengths.
ushort w;
for(uint i = 0; i < header.height * header.channel_count; i++)
{
s >> w;
}
// Read RLE data.
for(uint channel = 0; channel < channel_num; channel++)
{
uchar * ptr = bits() + components[channel];
uint count = 0;
while( count < pixel_count )
{
uchar c;
if(s.atEnd())
return false;
s >> c;
uint len = c;
if( len < 128 )
{
// Copy next len+1 bytes literally.
len++;
count += len;
if ( count > pixel_count )
return false;
while( len != 0 )
{
s >> cbyte;
if (header.color_mode == CM_CMYK)
cbyte = 255 - cbyte;
if ((header.color_mode == CM_GRAYSCALE) && (components[channel] != 3))
{
ptr -= components[channel];
ptr[0] = cbyte;
ptr[1] = cbyte;
ptr[2] = cbyte;
ptr += components[channel];
}
else if ((header.color_mode == CM_INDEXED) && (components[channel] != 3))
{
ptr -= components[channel];
int ccol = colorTable[cbyte];
ptr[2] = qRed(ccol);
ptr[1] = qGreen(ccol);
ptr[0] = qBlue(ccol);
ptr += components[channel];
}
else
*ptr = cbyte;
ptr += 4;
len--;
}
}
else if( len > 128 )
{
// Next -len+1 bytes in the dest are replicated from next source byte.
// (Interpret len as a negative 8-bit int.)
len ^= 0xFF;
len += 2;
count += len;
if(s.atEnd() || count > pixel_count)
return false;
uchar val;
s >> val;
if (header.color_mode == CM_CMYK)
val = 255 - val;
while( len != 0 )
{
if ((header.color_mode == CM_GRAYSCALE) && (components[channel] != 3))
{
ptr -= components[channel];
ptr[0] = val;
ptr[1] = val;
ptr[2] = val;
ptr += components[channel];
}
else if ((header.color_mode == CM_INDEXED) && (components[channel] != 3))
{
ptr -= components[channel];
int ccol = colorTable[val];
ptr[2] = qRed(ccol);
ptr[1] = qGreen(ccol);
ptr[0] = qBlue(ccol);
ptr += components[channel];
}
else
*ptr = val;
ptr += 4;
len--;
}
}
else if( len == 128 )
{
// No-op.
}
}
}
}
else
{
// We're at the raw image data. It's each channel in order (Red, Green, Blue, Alpha, ...)
// where each channel consists of an 8-bit value for each pixel in the image.
// Read the data by channel.
for(uint channel = 0; channel < channel_num; channel++)
{
uchar * ptr = bits() + components[channel];
// Read the data.
uint count = pixel_count;
while( count != 0 )
{
s >> cbyte;
if (header.color_mode == CM_CMYK)
cbyte = 255 - cbyte;
if ((header.color_mode == CM_GRAYSCALE) && (components[channel] != 3))
{
ptr -= components[channel];
ptr[0] = cbyte;
ptr[1] = cbyte;
ptr[2] = cbyte;
ptr += components[channel];
}
else if ((header.color_mode == CM_INDEXED) && (components[channel] != 3))
{
ptr -= components[channel];
int ccol = colorTable[cbyte];
ptr[2] = qRed(ccol);
ptr[1] = qGreen(ccol);
ptr[0] = qBlue(ccol);
ptr += components[channel];
}
else
*ptr = cbyte;
ptr += 4;
count--;
}
}
}
return true;
}
 
QString ScImage::getLayerString(QDataStream & s)
{
uchar len, tmp;
uint adj;
QString ret = "";
s >> len;
if (len == 0)
{
s >> tmp;
s >> tmp;
s >> tmp;
return ret;
}
for( int i = 0; i < len; i++ )
{
s >> tmp;
ret += QChar(tmp);
}
adj = 0;
if (((ret.length()+1) % 4) != 0)
adj = 4 - ((ret.length()+1) % 4);
s.device()->at( s.device()->at() + adj );
return ret;
}
 
QString ScImage::getPascalString(QDataStream & s)
{
uchar len, tmp;
uint adj;
QString ret = "";
s >> len;
if (len == 0)
{
s >> tmp;
return ret;
}
for( int i = 0; i < len; i++ )
{
s >> tmp;
ret += QChar(tmp);
}
adj = (ret.length()+1) % 2;
s.device()->at( s.device()->at() + adj );
return ret;
}
 
void ScImage::parseRessourceData( QDataStream & s, const PSDHeader & header, uint size )
{
uint signature, resSize, offset, resBase, vRes, hRes, adj;
ushort resID, hResUnit, vResUnit, dummyW;
QString resName;
uchar filler;
offset = 0;
bool first = false;
bool pathOpen = false;
FPoint firstPoint, firstControl;
FPointArray clip2;
while ((offset + 6)< size)
{
s >> signature;
offset += 4;
if(((signature >> 24)&0xff) != '8' ||
((signature >> 16)&0xff) != 'B' ||
((signature >> 8)&0xff) != 'I' ||
((signature )&0xff) != 'M' )
break;
s >> resID;
offset += 2;
adj = s.device()->at();
resName = getPascalString(s);
offset += s.device()->at() - adj;
s >> resSize;
if(offset + resSize > size)
break;
resBase = s.device()->at();
if ( (resID >= 0x07d0) && (resID <= 0x0bb6) )
{
QString db1, db2;
short type;
uint data1, data2, data3, data4, data5, data6;
double frac1, frac2, frac3, frac4, frac5, frac6;
ushort man1, man2, man3, man4, man5, man6;
uint offset2;
offset2 = 0;
first = false;
pathOpen = false;
clip2.resize(0);
while (offset2 < resSize)
{
s >> type;
s >> data1;
frac1 = (data1 & 0x00FFFFFF) / 16777215.0;
man1 = (data1 & 0x0F000000) >> 24;
frac1 = (frac1 + man1) * header.height;
s >> data2;
frac2 = (data2 & 0x00FFFFFF) / 16777215.0;
man2 = (data2 & 0x0F000000) >> 24;
frac2 = (frac2 + man2) * header.width;
s >> data3;
frac3 = (data3 & 0x00FFFFFF) / 16777215.0;
man3 = (data3 & 0x0F000000) >> 24;
frac3 = (frac3 + man3) * header.height;
s >> data4;
frac4 = (data4 & 0x00FFFFFF) / 16777215.0;
man4 = (data4 & 0x0F000000) >> 24;
frac4 = (frac4 + man4) * header.width;
s >> data5;
frac5 = (data5 & 0x00FFFFFF) / 16777215.0;
man5 = (data5 & 0x0F000000) >> 24;
frac5 = (frac5 + man5) * header.height;
s >> data6;
frac6 = (data6 & 0x00FFFFFF) / 16777215.0;
man6 = (data6 & 0x0F000000) >> 24;
frac6 = (frac6 + man6) * header.width;
switch (type)
{
case 0:
case 3:
if (pathOpen)
{
clip2.addPoint(firstPoint);
clip2.addPoint(firstControl);
clip2.setMarker();
}
pathOpen = false;
first = true;
break;
case 1:
case 2:
case 4:
case 5:
if (first)
{
firstControl = FPoint(frac2, frac1);
firstPoint = FPoint(frac4, frac3);
clip2.addPoint(FPoint(frac4, frac3));
clip2.addPoint(FPoint(frac6, frac5));
}
else
{
clip2.addPoint(frac4, frac3);
clip2.addPoint(frac2, frac1);
clip2.addPoint(frac4, frac3);
clip2.addPoint(frac6, frac5);
}
pathOpen = true;
first = false;
break;
case 6:
first = true;
break;
default:
break;
}
offset2 += 26;
}
clip2.addPoint(firstPoint);
clip2.addPoint(firstControl);
imgInfo.PDSpathData.insert(resName, clip2.copy());
}
else
{
switch (resID)
{
case 0x0bb7:
adj = s.device()->at();
imgInfo.clipPath = getPascalString(s);
offset += s.device()->at() - adj;
break;
case 0x03ed:
s >> hRes;
s >> hResUnit;
s >> dummyW;
s >> vRes;
s >> vResUnit;
s >> dummyW;
imgInfo.xres = qRound(hRes / 65536.0);
imgInfo.yres = qRound(vRes / 65536.0);
break;
case 0x040f:
{
icclen = resSize;
char* buffer = (char*)malloc(resSize);
iccbuf = buffer;
s.readRawBytes(buffer, resSize);
}
break;
case 0x0409:
case 0x040C:
{
uint thdummy, thsize;
s >> thdummy;
s >> thdummy;
s >> thdummy;
s >> thdummy;
s >> thdummy;
s >> thsize;
s >> thdummy;
char* buffer = (char*)malloc(thsize);
s.readRawBytes(buffer, thsize);
QImage imth;
imth.loadFromData((const uchar*)buffer, thsize, "JPEG");
imth.convertDepth(32);
if (resID == 0x0409)
imgInfo.exifInfo.thumbnail = imth.swapRGB();
else
imgInfo.exifInfo.thumbnail = imth;
imgInfo.exifDataValid = true;
free(buffer);
}
default:
break;
}
}
if (resBase + resSize <= size) {
s.device()->at( resBase + resSize );
offset += resSize;
}
if (resSize & 1)
{
s >> filler;
offset += 1;
}
}
if(offset<size)
s.device()->at( size );
}
 
bool ScImage::parseLayer( QDataStream & s, const PSDHeader & header )
{
uint addRes, layerinfo, channelLen, signature, extradata, layermasksize, layerRange, dummy;
int top, left, bottom, right;
short numLayers, numChannels;
short channelType;
uchar blendKey[4];
uchar opacity, clipping, flags, filler;
QString layerName, blend;
struct PSDLayer lay;
s >> layerinfo;
s >> numLayers;
if (numLayers < 0)
numLayers = -numLayers;
if (numLayers != 0)
{
for (int layer = 0; layer < numLayers; layer++)
{
s >> top;
lay.ypos = top;
s >> left;
lay.xpos = left;
s >> bottom;
lay.height = bottom - top;
s >> right;
lay.width = right - left;
s >> numChannels;
lay.channelType.clear();
lay.channelLen.clear();
for (int channels = 0; channels < numChannels; channels++)
{
s >> channelType;
s >> channelLen;
lay.channelType.append(channelType);
lay.channelLen.append(channelLen);
}
s >> signature;
blend = "";
for( int i = 0; i < 4; i++ )
{
s >> blendKey[i];
blend += QChar(blendKey[i]);
}
lay.blend = blend;
s >> opacity;
lay.opacity = opacity;
s >> clipping;
lay.clipping = clipping;
s >> flags;
lay.flags = flags;
s >> filler;
s >> extradata;
s >> layermasksize;
lay.maskYpos = 0;
lay.maskXpos = 0;
lay.maskHeight = 0;
lay.maskWidth = 0;
if (layermasksize != 0)
{
s >> lay.maskYpos;
s >> lay.maskXpos;
s >> dummy;
lay.maskHeight = dummy - lay.maskYpos;
s >> dummy;
lay.maskWidth = dummy - lay.maskXpos;
s >> dummy;
}
s >> layerRange;
s.device()->at( s.device()->at() + layerRange );
lay.layerName = getLayerString(s);
imgInfo.layerInfo.append(lay);
s >> signature;
if( signature == 0x3842494D )
{
while (signature == 0x3842494D )
{
s >> signature;
s >> addRes;
s.device()->at( s.device()->at() + addRes );
s >> signature;
}
s.device()->at( s.device()->at() - 4 );
}
else
{
s.device()->at( s.device()->at() - 2 );
s >> signature;
if( signature == 0x3842494D )
{
while (signature == 0x3842494D )
{
s >> signature;
s >> addRes;
s.device()->at( s.device()->at() + addRes );
s >> signature;
}
s.device()->at( s.device()->at() - 4 );
}
else
s.device()->at( s.device()->at() - 6 );
}
}
bool firstLayer = true;
for (int layer = 0; layer < numLayers; layer++)
{
loadLayerChannels( s, header, imgInfo.layerInfo, layer, &firstLayer );
}
}
else
{
s >> numLayers;
loadLayer( s, header);
}
return true;
}
 
// Load the PSD image.
bool ScImage::LoadPSD( QDataStream & s, const PSDHeader & header)
{
// Create dst image.
if( !create( header.width, header.height, 32 ))
return false;
setAlphaBuffer( true );
uint tmp;
uint cdataStart;
uint ressourceDataLen;
uint startRessource;
uint layerDataLen;
uint startLayers;
 
srand(314159265);
for (int i = 0; i < 4096; i++)
random_table[i] = rand();
for (int i = 0; i < 4096; i++)
{
int tmp;
int swap = i + rand() % (4096 - i);
tmp = random_table[i];
random_table[i] = random_table[swap];
random_table[swap] = tmp;
}
 
// Skip mode data. FIX: this is incorrect, it's the Colormap Data for indexed Images
s >> tmp;
cdataStart = s.device()->at();
if (tmp != 0)
{
QValueList<uchar> colorTableR;
QValueList<uchar> colorTableG;
QValueList<uchar> colorTableB;
colorTableR.clear();
colorTableG.clear();
colorTableB.clear();
colorTable.clear();
uchar r;
for (uint cc = 0; cc < 256; cc++)
{
s >> r;
colorTableR.append(r);
}
for (uint cc = 0; cc < 256; cc++)
{
s >> r;
colorTableG.append(r);
}
for (uint cc = 0; cc < 256; cc++)
{
s >> r;
colorTableB.append(r);
}
for (uint cc = 0; cc < 256; cc++)
{
colorTable.append(qRgb(colorTableR[cc], colorTableG[cc], colorTableB[cc]));
}
}
s.device()->at( cdataStart + tmp );
s >> ressourceDataLen;
startRessource = s.device()->at();
if (ressourceDataLen != 0)
parseRessourceData(s, header, ressourceDataLen);
if ((!imgInfo.exifInfo.thumbnail.isNull()) && (header.reserved[0] == 't'))
return true;
s.device()->at( startRessource + ressourceDataLen );
// Skip the reserved data. FIX: Also incorrect, this is the actual Layer Data for Images with Layers
s >> layerDataLen;
startLayers = s.device()->at();
if (layerDataLen != 0)
return parseLayer( s, header);
else
{
// Decoding simple psd file, no layers
s.device()->at( s.device()->at() + layerDataLen );
loadLayer( s, header);
}
return true;
}
 
void ScImage::scaleImage(int nwidth, int nheight)
{
QImage dst;
2636,7 → 1244,7
QByteArray ScImage::getAlpha(QString fn, bool PDF, bool pdf14, int gsRes)
{
QByteArray retArray;
float xres, yres;
ScImgDataLoader* pDataLoader = NULL;
short resolutionunit = 0;
imgInfo.valid = false;
imgInfo.clipPath = "";
2647,521 → 1255,122
return retArray;
QString tmp, BBox, tmp2;
QString ext = fi.extension(false).lower();
QString tmpFile = QDir::convertSeparators(ScPaths::getTempFileDir() + "sc.png");
QString picFile = QDir::convertSeparators(fn);
if ((ext == "jpg") || (ext == "jpeg"))
return retArray;
double x, y, b, h;
bool found = false;
int retg = -1;
QChar tc;
 
if (ext == "pdf")
{
QStringList args;
xres = gsRes;
yres = gsRes;
args.append("-r"+QString::number(gsRes));
args.append("-sOutputFile=\""+tmpFile + "\"");
args.append("-dFirstPage=1");
args.append("-dLastPage=1");
args.append("\""+picFile+"\"");
retg = callGS(args);
if (retg == 0)
{
load(tmpFile);
unlink(tmpFile);
setAlphaBuffer(true);
if (ScCore->havePNGAlpha() != 0)
{
for( int yi=0; yi < height(); ++yi )
{
QRgb *s = (QRgb*)(scanLine( yi ));
for(int xi=0; xi < width(); ++xi )
{
if((*s) == 0xffffffff)
(*s) &= 0x00ffffff;
s++;
}
}
}
}
}
pDataLoader = new ScImgDataLoader_PDF();
else if ((ext == "eps") || (ext == "ps"))
pDataLoader = new ScImgDataLoader_PS();
#ifdef HAVE_TIFF
else if ((ext == "tif") || (ext == "tiff"))
pDataLoader = new ScImgDataLoader_TIFF();
#endif // HAVE_TIFF
else if (ext == "psd")
pDataLoader = new ScImgDataLoader_PSD();
else
pDataLoader = new ScImgDataLoader_QT();
 
if (pDataLoader)
{
QFile f(fn);
if (f.open(IO_ReadOnly))
pDataLoader->preloadAlphaChannel(fn, gsRes);
QImage& rImage = pDataLoader->image();
if (rImage.isNull())
{
QTextStream ts(&f);
while (!ts.atEnd())
{
tc = ' ';
tmp = "";
while ((tc != '\n') && (tc != '\r'))
{
ts >> tc;
if ((tc != '\n') && (tc != '\r'))
tmp += tc;
}
if (tmp.startsWith("%%BoundingBox:"))
{
found = true;
BBox = tmp.remove("%%BoundingBox:");
}
if (!found)
{
if (tmp.startsWith("%%BoundingBox"))
{
found = true;
BBox = tmp.remove("%%BoundingBox");
}
}
if (tmp.startsWith("%%EndComments"))
break;
}
delete pDataLoader;
return retArray;
}
f.close();
if (found)
int i = 0;
unsigned char u;
int hm = rImage.height();
int wm = rImage.width();
int w2;
if (pdf14)
{
QTextStream ts2(&BBox, IO_ReadOnly);
ts2 >> x >> y >> b >> h;
h = h * gsRes / 72.0;
QStringList args;
xres = gsRes;
yres = gsRes;
if (ext == "eps")
args.append("-dEPSCrop");
args.append("-r"+QString::number(gsRes));
args.append("-sOutputFile="+tmpFile);
args.append(picFile);
retg = callGS(args);
if (retg == 0)
retArray.resize(hm * wm);
for( int yi=0; yi < hm; ++yi )
{
QImage image;
image.load(tmpFile);
image.setAlphaBuffer(true);
if (ScCore->havePNGAlpha() != 0)
QRgb * s = (QRgb*)(rImage.scanLine( yi ));
for( int xi=0; xi < wm; ++xi )
{
int wi = image.width();
int hi = image.height();
for( int yi=0; yi < hi; ++yi )
{
QRgb *s = (QRgb*)(image.scanLine( yi ));
QRgb alphaFF = qRgba(255,255,255,255);
QRgb alpha00 = qRgba(255,255,255, 0);
for(int xi=0; xi < wi; ++xi )
{
if((*s) == alphaFF)
(*s) &= alpha00;
s++;
}
}
QRgb r=*s++;
u=qAlpha(r);
retArray[i++] = u;
}
*this = static_cast<ScImage>(image.copy());
setAlphaBuffer(true);
unlink(tmpFile);
}
}
}
else if ((ext == "tif") || (ext == "tiff"))
{
#ifdef HAVE_TIFF
TIFF* tif = TIFFOpen(fn.local8Bit(), "r");
if(tif)
else
{
unsigned width, height, size;
TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &width);
TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &height);
TIFFGetField(tif, TIFFTAG_XRESOLUTION, &xres);
TIFFGetField(tif, TIFFTAG_YRESOLUTION, &yres);
TIFFGetField(tif, TIFFTAG_RESOLUTIONUNIT , &resolutionunit);
size = width * height;
uint16 photometric, bitspersample, samplesperpixel, fillorder;
TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &photometric);
TIFFGetField(tif, TIFFTAG_BITSPERSAMPLE, &bitspersample);
TIFFGetField(tif, TIFFTAG_SAMPLESPERPIXEL, &samplesperpixel);
TIFFGetField(tif, TIFFTAG_FILLORDER, &fillorder);
uint32 *bits = 0;
if (photometric == PHOTOMETRIC_SEPARATED)
QImage iMask = rImage.createAlphaMask();
hm = iMask.height();
wm = iMask.width();
w2 = wm / 8;
if ((wm % 8) != 0)
w2++;
retArray.resize(hm * w2);
for( int yi=0; yi < hm; ++yi )
{
TIFFClose(tif);
return retArray;
}
else
{
create(width,height,32);
setAlphaBuffer(true);
bits = (uint32 *) _TIFFmalloc(size * sizeof(uint32));
if(bits)
uchar * s = iMask.scanLine( yi );
for( int xi=0; xi < w2; ++xi )
{
if (TIFFReadRGBAImage(tif, width, height, bits, 0))
{
for(unsigned int y = 0; y < height; y++)
memcpy(scanLine(height - 1 - y), bits + y * width, width * 4);
}
_TIFFfree(bits);
u = *(s+xi);
if(PDF) u = ~u;
retArray[i++] = u;
}
TIFFClose(tif);
}
}
#else
qDebug("TIFF Support not available");
#endif // HAVE_TIFF
 
delete pDataLoader;
}
else if (ext == "psd")
{
QFile f(fn);
if (f.open(IO_ReadOnly))
{
xres = 72.0;
yres = 72.0;
QDataStream s( &f );
s.setByteOrder( QDataStream::BigEndian );
PSDHeader header;
s >> header;
// Check image file format.
if( s.atEnd() || !IsValid( header ) )
return retArray;
// Check if it's a supported format.
if( !IsSupported( header ) )
return retArray;
if (header.color_mode == CM_CMYK)
return retArray;
if( !LoadPSD(s, header) )
return retArray;
f.close();
}
else
return retArray;
}
else
{
if (load(fn))
{
*this = convertDepth(32);
if (hasAlphaBuffer())
setAlphaBuffer(true);
else
return retArray;
}
else
return retArray;
}
if (isNull())
return retArray;
int i = 0;
unsigned char u;
int hm = height();
int wm = width();
int w2;
if (pdf14)
{
retArray.resize(hm * wm);
for( int yi=0; yi < hm; ++yi )
{
QRgb * s = (QRgb*)(scanLine( yi ));
for( int xi=0; xi < wm; ++xi )
{
QRgb r=*s++;
u=qAlpha(r);
retArray[i++] = u;
}
}
}
else
{
QImage iMask = createAlphaMask();
hm = iMask.height();
wm = iMask.width();
w2 = wm / 8;
if ((wm % 8) != 0)
w2++;
retArray.resize(hm * w2);
for( int yi=0; yi < hm; ++yi )
{
uchar * s = iMask.scanLine( yi );
for( int xi=0; xi < w2; ++xi )
{
u = *(s+xi);
if(PDF) u = ~u;
retArray[i++] = u;
}
}
}
return retArray;
}
 
#define ICC_MARKER (JPEG_APP0 + 2) /* JPEG marker code for ICC */
#define PHOTOSHOP_MARKER (JPEG_APP0 + 13) /* JPEG marker code for PHOTOSHOP */
#define ICC_OVERHEAD_LEN 14 /* size of non-profile data in APP2 */
#define MAX_BYTES_IN_MARKER 65533 /* maximum data len of a JPEG marker */
#define MAX_DATA_BYTES_IN_MARKER (MAX_BYTES_IN_MARKER - ICC_OVERHEAD_LEN)
 
bool ScImage::marker_is_icc (jpeg_saved_marker_ptr marker)
{
return
marker->marker == ICC_MARKER &&
marker->data_length >= ICC_OVERHEAD_LEN &&
/* verify the identifying string */
GETJOCTET(marker->data[0]) == 0x49 &&
GETJOCTET(marker->data[1]) == 0x43 &&
GETJOCTET(marker->data[2]) == 0x43 &&
GETJOCTET(marker->data[3]) == 0x5F &&
GETJOCTET(marker->data[4]) == 0x50 &&
GETJOCTET(marker->data[5]) == 0x52 &&
GETJOCTET(marker->data[6]) == 0x4F &&
GETJOCTET(marker->data[7]) == 0x46 &&
GETJOCTET(marker->data[8]) == 0x49 &&
GETJOCTET(marker->data[9]) == 0x4C &&
GETJOCTET(marker->data[10]) == 0x45 &&
GETJOCTET(marker->data[11]) == 0x0;
}
 
bool ScImage::marker_is_photoshop (jpeg_saved_marker_ptr marker)
{
return
marker->marker == PHOTOSHOP_MARKER &&
marker->data_length >= ICC_OVERHEAD_LEN &&
/* verify the identifying string */
GETJOCTET(marker->data[0]) == 0x50 &&
GETJOCTET(marker->data[1]) == 0x68 &&
GETJOCTET(marker->data[2]) == 0x6F &&
GETJOCTET(marker->data[3]) == 0x74 &&
GETJOCTET(marker->data[4]) == 0x6F &&
GETJOCTET(marker->data[5]) == 0x73 &&
GETJOCTET(marker->data[6]) == 0x68 &&
GETJOCTET(marker->data[7]) == 0x6F &&
GETJOCTET(marker->data[8]) == 0x70 &&
GETJOCTET(marker->data[9]) == 0x20 &&
GETJOCTET(marker->data[10]) == 0x33 &&
GETJOCTET(marker->data[11]) == 0x2E &&
GETJOCTET(marker->data[12]) == 0x30 &&
GETJOCTET(marker->data[13]) == 0x0;
}
/* Small modification of original read_icc_profile method from jpegicc of lcms project
* to enable read of Photoshop marker
*/
bool ScImage::read_jpeg_marker (UINT8 requestmarker, j_decompress_ptr cinfo, JOCTET **icc_data_ptr, unsigned int *icc_data_len)
{
jpeg_saved_marker_ptr marker;
int num_markers = 0;
int seq_no;
JOCTET *icc_data;
unsigned int total_length;
#define MAX_SEQ_NO 255 /* sufficient since marker numbers are bytes */
char marker_present[MAX_SEQ_NO+1]; /* 1 if marker found */
unsigned int data_length[MAX_SEQ_NO+1]; /* size of profile data in marker */
unsigned int data_offset[MAX_SEQ_NO+1]; /* offset for data in marker */
 
*icc_data_ptr = NULL; /* avoid confusion if false return */
*icc_data_len = 0;
 
/* This first pass over the saved markers discovers whether there are
* any ICC markers and verifies the consistency of the marker numbering.
*/
 
for (seq_no = 1; seq_no <= MAX_SEQ_NO; seq_no++)
marker_present[seq_no] = 0;
seq_no = 0;
for (marker = cinfo->marker_list; marker != NULL; marker = marker->next)
{
if (requestmarker == ICC_MARKER && marker_is_icc(marker))
{
if (num_markers == 0)
num_markers = GETJOCTET(marker->data[13]);
else if (num_markers != GETJOCTET(marker->data[13]))
return false; /* inconsistent num_markers fields */
seq_no = GETJOCTET(marker->data[12]);
if (seq_no <= 0 || seq_no > num_markers)
return false; /* bogus sequence number */
if (marker_present[seq_no])
return false; /* duplicate sequence numbers */
marker_present[seq_no] = 1;
data_length[seq_no] = marker->data_length - ICC_OVERHEAD_LEN;
}
else if(requestmarker == PHOTOSHOP_MARKER && marker_is_photoshop(marker))
{
num_markers = ++seq_no;
marker_present[seq_no] = 1;
data_length[seq_no] = marker->data_length - ICC_OVERHEAD_LEN;
}
}
 
if (num_markers == 0)
return false;
 
/* Check for missing markers, count total space needed,
* compute offset of each marker's part of the data.
*/
 
total_length = 0;
for (seq_no = 1; seq_no <= num_markers; seq_no++)
{
if (marker_present[seq_no] == 0)
return false; /* missing sequence number */
data_offset[seq_no] = total_length;
total_length += data_length[seq_no];
}
 
if (total_length <= 0)
return false; /* found only empty markers? */
 
/* Allocate space for assembled data */
icc_data = (JOCTET *) malloc(total_length * sizeof(JOCTET));
if (icc_data == NULL)
return false; /* oops, out of memory */
seq_no=0;
/* and fill it in */
for (marker = cinfo->marker_list; marker != NULL; marker = marker->next)
{
if ( (requestmarker == ICC_MARKER && marker_is_icc(marker)) ||
(requestmarker == PHOTOSHOP_MARKER && marker_is_photoshop(marker)) || (requestmarker == 0xE1))
{
JOCTET FAR *src_ptr;
JOCTET *dst_ptr;
unsigned int length;
if(requestmarker == ICC_MARKER)
seq_no = GETJOCTET(marker->data[12]);
else if(requestmarker == PHOTOSHOP_MARKER)
seq_no++;
dst_ptr = icc_data + data_offset[seq_no];
src_ptr = marker->data + ICC_OVERHEAD_LEN;
length = data_length[seq_no];
while (length--)
{
*dst_ptr++ = *src_ptr++;
}
}
}
 
*icc_data_ptr = icc_data;
*icc_data_len = total_length;
 
return true;
}
 
void ScImage::getEmbeddedProfile(const QString & fn, QString *profile, int *components)
{
Q_ASSERT(profile);
Q_ASSERT(components);
ScImgDataLoader* pDataLoader = NULL;
#ifdef HAVE_CMS
cmsHPROFILE tiffProf = 0;
cmsHPROFILE prof = 0;
 
profile->setLength(0);
*components = 0;
QFileInfo fi = QFileInfo(fn);
if (!fi.exists())
return;
QString ext = fi.extension(false).lower();
iccbuf = 0;
icclen = 0;
 
if (ext == "psd")
{
QFile f(fn);
if (f.open(IO_ReadOnly))
{
imgInfo.xres = 72;
imgInfo.yres = 72;
QDataStream s( &f );
s.setByteOrder( QDataStream::BigEndian );
PSDHeader header;
s >> header;
// Check image file format.
if( s.atEnd() || !IsValid( header ) )
return;
// Check if it's a supported format.
if( !IsSupported( header ) )
return;
if( !LoadPSD(s, header) )
return;
if (icclen > 0)
{
tiffProf = cmsOpenProfileFromMem(iccbuf, icclen);
if (tiffProf)
{
if (static_cast<int>(cmsGetColorSpace(tiffProf)) == icSigRgbData)
*components = 3;
if (static_cast<int>(cmsGetColorSpace(tiffProf)) == icSigCmykData)
*components = 4;
for (uint el = 0; el < icclen; ++el)
*profile += iccbuf[el];
}
cmsCloseProfile(tiffProf);
free(iccbuf);
}
f.close();
}
else
return;
}
pDataLoader = new ScImgDataLoader_PSD();
#ifdef HAVE_TIFF
else if ((ext == "tif") || (ext == "tiff"))
{
TIFF* tif = TIFFOpen(fn.local8Bit(), "r");
if(tif)
{
DWORD EmbedLen = 0;
LPBYTE EmbedBuffer;
if (TIFFGetField(tif, TIFFTAG_ICCPROFILE, &EmbedLen, &EmbedBuffer))
{
tiffProf = cmsOpenProfileFromMem(EmbedBuffer, EmbedLen);
if (tiffProf)
{
if (static_cast<int>(cmsGetColorSpace(tiffProf)) == icSigRgbData)
*components = 3;
if (static_cast<int>(cmsGetColorSpace(tiffProf)) == icSigCmykData)
*components = 4;
for (uint el = 0; el < EmbedLen; ++el)
*profile += EmbedBuffer[el];
}
cmsCloseProfile(tiffProf);
}
TIFFClose(tif);
}
}
#endif // HAVE_TIFF
pDataLoader = new ScImgDataLoader_TIFF();
#endif
else if ((ext == "jpg") || (ext == "jpeg"))
pDataLoader = new ScImgDataLoader_JPEG();
 
if (pDataLoader)
{
struct jpeg_decompress_struct cinfo;
struct my_error_mgr jerr;
FILE *infile;
cinfo.err = jpeg_std_error (&jerr.pub);
jerr.pub.error_exit = my_error_exit;
infile = NULL;
if (setjmp (jerr.setjmp_buffer))
pDataLoader->loadEmbeddedProfile(fn);
QByteArray embeddedProfile = pDataLoader->embeddedProfile();
if (embeddedProfile.size())
{
jpeg_destroy_decompress (&cinfo);
if (infile)
fclose (infile);
return;
}
jpeg_create_decompress (&cinfo);
if ((infile = fopen (fn.local8Bit(), "rb")) == NULL)
return;
jpeg_stdio_src(&cinfo, infile);
jpeg_save_markers(&cinfo, ICC_MARKER, 0xFFFF);
jpeg_read_header(&cinfo, true);
jpeg_start_decompress(&cinfo);
unsigned int EmbedLen = 0;
unsigned char* EmbedBuffer;
if (read_jpeg_marker(ICC_MARKER,&cinfo, &EmbedBuffer, &EmbedLen))
{
tiffProf = cmsOpenProfileFromMem(EmbedBuffer, EmbedLen);
if (tiffProf)
prof = cmsOpenProfileFromMem(embeddedProfile.data(), embeddedProfile.size());
if (prof)
{
if (static_cast<int>(cmsGetColorSpace(tiffProf)) == icSigRgbData)
if (static_cast<int>(cmsGetColorSpace(prof)) == icSigRgbData)
*components = 3;
if (static_cast<int>(cmsGetColorSpace(tiffProf)) == icSigCmykData)
if (static_cast<int>(cmsGetColorSpace(prof)) == icSigCmykData)
*components = 4;
for (uint el = 0; el < EmbedLen; ++el)
*profile += EmbedBuffer[el];
for (uint el = 0; el < embeddedProfile.size(); ++el)
*profile += embeddedProfile[el];
}
cmsCloseProfile(tiffProf);
free(EmbedBuffer);
cmsCloseProfile(prof);
}
(void) jpeg_finish_decompress(&cinfo);
fclose (infile);
jpeg_destroy_decompress (&cinfo);
delete pDataLoader;
}
else
return;
#endif // HAVE_CMS
}
 
3169,127 → 1378,45
{
Q_ASSERT(profile);
Q_ASSERT(components);
ScImgDataLoader* pDataLoader = NULL;
#ifdef HAVE_CMS
cmsHPROFILE tiffProf = 0;
cmsHPROFILE prof = 0;
 
profile->resize(0);
*components = 0;
QFileInfo fi = QFileInfo(fn);
if (!fi.exists())
return;
QString ext = fi.extension(false).lower();
iccbuf = 0;
icclen = 0;
 
if (ext == "psd")
{
QFile f(fn);
if (f.open(IO_ReadOnly))
{
imgInfo.xres = 72;
imgInfo.yres = 72;
QDataStream s( &f );
s.setByteOrder( QDataStream::BigEndian );
PSDHeader header;
s >> header;
// Check image file format.
if( s.atEnd() || !IsValid( header ) )
return;
// Check if it's a supported format.
if( !IsSupported( header ) )
return;
if( !LoadPSD(s, header) )
return;
if (icclen > 0)
{
tiffProf = cmsOpenProfileFromMem(iccbuf, icclen);
if (tiffProf)
{
if (static_cast<int>(cmsGetColorSpace(tiffProf)) == icSigRgbData)
*components = 3;
if (static_cast<int>(cmsGetColorSpace(tiffProf)) == icSigCmykData)
*components = 4;
profile->resize(icclen);
for (uint el = 0; el < icclen; ++el)
(*profile)[el] = iccbuf[el];
}
cmsCloseProfile(tiffProf);
free(iccbuf);
}
f.close();
}
else
return;
}
pDataLoader = new ScImgDataLoader_PSD();
#ifdef HAVE_TIFF
else if ((ext == "tif") || (ext == "tiff"))
{
TIFF* tif = TIFFOpen(fn.local8Bit(), "r");
if(tif)
{
DWORD EmbedLen = 0;
LPBYTE EmbedBuffer;
if (TIFFGetField(tif, TIFFTAG_ICCPROFILE, &EmbedLen, &EmbedBuffer))
{
tiffProf = cmsOpenProfileFromMem(EmbedBuffer, EmbedLen);
if (tiffProf)
{
if (static_cast<int>(cmsGetColorSpace(tiffProf)) == icSigRgbData)
*components = 3;
if (static_cast<int>(cmsGetColorSpace(tiffProf)) == icSigCmykData)
*components = 4;
profile->resize(EmbedLen);
for (uint el = 0; el < EmbedLen; ++el)
(*profile)[el] = EmbedBuffer[el];
}
cmsCloseProfile(tiffProf);
}
TIFFClose(tif);
}
}
#endif // HAVE_TIFF
pDataLoader = new ScImgDataLoader_TIFF();
#endif
else if ((ext == "jpg") || (ext == "jpeg"))
pDataLoader = new ScImgDataLoader_JPEG();
 
if (pDataLoader)
{
struct jpeg_decompress_struct cinfo;
struct my_error_mgr jerr;
FILE *infile;
cinfo.err = jpeg_std_error (&jerr.pub);
jerr.pub.error_exit = my_error_exit;
infile = NULL;
if (setjmp (jerr.setjmp_buffer))
pDataLoader->loadEmbeddedProfile(fn);
QByteArray embeddedProfile = pDataLoader->embeddedProfile();
if (embeddedProfile.size())
{
jpeg_destroy_decompress (&cinfo);
if (infile)
fclose (infile);
return;
}
jpeg_create_decompress (&cinfo);
if ((infile = fopen (fn.local8Bit(), "rb")) == NULL)
return;
jpeg_stdio_src(&cinfo, infile);
jpeg_save_markers(&cinfo, ICC_MARKER, 0xFFFF);
jpeg_read_header(&cinfo, true);
jpeg_start_decompress(&cinfo);
unsigned int EmbedLen = 0;
unsigned char* EmbedBuffer;
if (read_jpeg_marker(ICC_MARKER,&cinfo, &EmbedBuffer, &EmbedLen))
{
tiffProf = cmsOpenProfileFromMem(EmbedBuffer, EmbedLen);
if (tiffProf)
prof = cmsOpenProfileFromMem(embeddedProfile.data(), embeddedProfile.size());
if (prof)
{
if (static_cast<int>(cmsGetColorSpace(tiffProf)) == icSigRgbData)
if (static_cast<int>(cmsGetColorSpace(prof)) == icSigRgbData)
*components = 3;
if (static_cast<int>(cmsGetColorSpace(tiffProf)) == icSigCmykData)
if (static_cast<int>(cmsGetColorSpace(prof)) == icSigCmykData)
*components = 4;
profile->resize(EmbedLen);
for (uint el = 0; el < EmbedLen; ++el)
(*profile)[el] = EmbedBuffer[el];
*profile = embeddedProfile;
}
cmsCloseProfile(tiffProf);
free(EmbedBuffer);
cmsCloseProfile(prof);
}
(void) jpeg_finish_decompress(&cinfo);
fclose (infile);
jpeg_destroy_decompress (&cinfo);
delete pDataLoader;
}
else
return;
#endif // HAVE_CMS
}
 
3304,15 → 1431,14
if (realCMYK != 0)
*realCMYK = false;
bool bilevel = false;
float xres, yres;
short resolutionunit = 0;
RequestType reqType = requestType;
#ifdef HAVE_CMS
cmsHTRANSFORM xform = 0;
cmsHPROFILE inputProf = 0;
cmsHPROFILE tiffProf = 0;
int cmsFlags = 0;
#endif
auto_ptr<ScImgDataLoader> pDataLoader;
QFileInfo fi = QFileInfo(fn);
if (!fi.exists())
return ret;
3319,713 → 1445,56
QString ext = fi.extension(false).lower();
QString tmp, dummy, cmd1, cmd2, BBox, tmp2;
QChar tc;
double x, y, b, h;
bool found = false;
int retg = -1;
QString tmpFile = QDir::convertSeparators(ScPaths::getTempFileDir() + "sc.png");
QString picFile = QDir::convertSeparators(fn);
 
if (ext == "pdf")
{
imgInfo.typ = 4;
imgInfo.exifDataValid = false;
if (reqType == Thumbnail)
reqType = RGBData;
QStringList args;
xres = gsRes;
yres = gsRes;
args.append("-r"+QString::number(gsRes));
args.append("-sOutputFile="+tmpFile);
args.append("-dFirstPage=1");
args.append("-dLastPage=1");
args.append(picFile);
retg = callGS(args);
if (retg == 0)
{
QImage image;
load(tmpFile);
unlink(tmpFile);
setAlphaBuffer(true);
if (ScCore->havePNGAlpha() != 0)
{
for( int yi=0; yi < height(); ++yi )
{
QRgb *s = (QRgb*)(scanLine( yi ));
for(int xi=0; xi < width(); ++xi )
{
if((*s) == 0xffffffff)
(*s) &= 0x00ffffff;
s++;
}
}
}
imgInfo.BBoxX = 0;
imgInfo.BBoxH = height();
imgInfo.xres = qRound(gsRes);
imgInfo.yres = qRound(gsRes);
imgInfo.colorspace = 0;
setDotsPerMeterX ((int) (xres / 0.0254));
setDotsPerMeterY ((int) (yres / 0.0254));
}
}
if ((ext == "eps") || (ext == "ps"))
{
imgInfo.typ = 3;
imgInfo.exifDataValid = false;
if (reqType == Thumbnail)
reqType = RGBData;
QFile f(fn);
if (f.open(IO_ReadOnly))
{
QTextStream ts(&f);
while (!ts.atEnd())
{
tc = ' ';
tmp = "";
while ((tc != '\n') && (tc != '\r'))
{
ts >> tc;
if ((tc != '\n') && (tc != '\r'))
tmp += tc;
}
if (tmp.startsWith("%%BoundingBox:"))
{
found = true;
BBox = tmp.remove("%%BoundingBox:");
}
if (!found)
{
if (tmp.startsWith("%%BoundingBox"))
{
found = true;
BBox = tmp.remove("%%BoundingBox");
}
}
if (tmp.startsWith("%%EndComments"))
break;
}
}
f.close();
if (found)
{
QTextStream ts2(&BBox, IO_ReadOnly);
ts2 >> x >> y >> b >> h;
/* x = x * gsRes / 72.0;
y = y * gsRes / 72.0;
b = b * gsRes / 72.0; */
h = h * gsRes / 72.0;
QStringList args;
xres = gsRes;
yres = gsRes;
if (ext == "eps")
args.append("-dEPSCrop");
args.append("-r"+QString::number(gsRes));
args.append("-sOutputFile="+tmpFile);
// args.append("-g"+tmp.setNum(qRound(b))+"x"+tmp2.setNum(qRound(h)));
args.append(picFile);
retg = callGS(args);
if (retg == 0)
{
QImage image;
image.load(tmpFile);
image.setAlphaBuffer(true);
if (ScCore->havePNGAlpha() != 0)
{
int wi = image.width();
int hi = image.height();
for( int yi=0; yi < hi; ++yi )
{
QRgb *s = (QRgb*)(image.scanLine( yi ));
QRgb alphaFF = qRgba(255,255,255,255);
QRgb alpha00 = qRgba(255,255,255, 0);
for(int xi=0; xi < wi; ++xi )
{
if((*s) == alphaFF)
(*s) &= alpha00;
s++;
}
}
}
// *this = static_cast<ScImage>(image.copy(static_cast<int>(x), 0, static_cast<int>(b-x), static_cast<int>(h-y)));
*this = static_cast<ScImage>(image.copy());
unlink(tmpFile);
if (ext == "eps")
{
imgInfo.BBoxX = static_cast<int>(x);
imgInfo.BBoxH = static_cast<int>(h);
}
else
{
imgInfo.BBoxX = 0;
imgInfo.BBoxH = height();
}
imgInfo.xres = qRound(gsRes);
imgInfo.yres = qRound(gsRes);
imgInfo.colorspace = 0;
setDotsPerMeterX ((int) (xres / 0.0254));
setDotsPerMeterY ((int) (yres / 0.0254));
}
}
}
pDataLoader.reset( new ScImgDataLoader_PDF() );
else if ((ext == "eps") || (ext == "ps"))
pDataLoader.reset( new ScImgDataLoader_PS() );
#ifdef HAVE_TIFF
else if ((ext == "tif") || (ext == "tiff"))
{
imgInfo.typ = 1;
if (reqType == Thumbnail)
reqType = RGBData;
QImage img2;
TIFF* tif = TIFFOpen(fn.local8Bit(), "r");
if(tif)
{
unsigned widtht, heightt, size;
char *description=0, *copyright=0, *datetime=0, *artist=0, *scannerMake=0, *scannerModel=0;
 
TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &widtht);
TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &heightt);
TIFFGetField(tif, TIFFTAG_XRESOLUTION, &xres);
TIFFGetField(tif, TIFFTAG_YRESOLUTION, &yres);
TIFFGetField(tif, TIFFTAG_RESOLUTIONUNIT , &resolutionunit);
size = widtht * heightt;
uint16 photometric, bitspersample, samplesperpixel, fillorder;
TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &photometric);
TIFFGetField(tif, TIFFTAG_BITSPERSAMPLE, &bitspersample);
TIFFGetField(tif, TIFFTAG_SAMPLESPERPIXEL, &samplesperpixel);
TIFFGetField(tif, TIFFTAG_FILLORDER, &fillorder);
 
TIFFGetField(tif, TIFFTAG_MAKE, &scannerMake);
TIFFGetField(tif, TIFFTAG_MODEL, &scannerModel);
TIFFGetField(tif, TIFFTAG_IMAGEDESCRIPTION, &description);
TIFFGetField(tif, TIFFTAG_COPYRIGHT, &copyright);
TIFFGetField(tif, TIFFTAG_DATETIME, &datetime);
TIFFGetField(tif, TIFFTAG_ARTIST, &artist);
imgInfo.exifInfo.cameraName = QString(scannerModel);
imgInfo.exifInfo.cameraVendor = QString(scannerMake);
imgInfo.exifInfo.comment = QString(description);
imgInfo.exifInfo.userComment = QString(copyright);
imgInfo.exifInfo.width = widtht;
imgInfo.exifInfo.height = heightt;
imgInfo.exifInfo.dateTime = QString(datetime);
imgInfo.exifInfo.artist = QString(artist);
imgInfo.exifInfo.thumbnail = QImage();
imgInfo.exifDataValid = true;
 
if (!create(widtht,heightt,32))
{
TIFFClose(tif);
return ret;
}
setAlphaBuffer(true);
uint32 *bits = 0;
if (photometric == PHOTOMETRIC_SEPARATED)
{
if (TIFFIsTiled(tif))
{
uint32 columns, rows;
uint32 *tile_buf;
uint32 xt, yt;
TIFFGetField(tif, TIFFTAG_TILEWIDTH, &columns);
TIFFGetField(tif, TIFFTAG_TILELENGTH, &rows);
tile_buf = (uint32*) _TIFFmalloc(columns*rows*sizeof(uint32));
if (tile_buf == NULL)
{
TIFFClose(tif);
return ret;
}
uint32 tileW = columns, tileH = rows;
for (yt = 0; yt < (uint32)height(); yt += rows)
{
if (yt > (uint)height())
break;
if (height()-yt < rows)
tileH = height()-yt;
tileW = columns;
register uint32 yi;
for (xt = 0; xt < (uint)width(); xt += columns)
{
TIFFReadTile(tif, tile_buf, xt, yt, 0, 0);
for (yi = 0; yi < tileH; yi++)
_TIFFmemcpy(scanLine(yt+(tileH-1-yi))+xt, tile_buf+tileW*yi, tileW*4);
}
}
_TIFFfree(tile_buf);
}
else
{
tsize_t bytesperrow = TIFFScanlineSize(tif);
bits = (uint32 *) _TIFFmalloc(bytesperrow);
if (bits)
{
for (unsigned int y = 0; y < heightt; y++)
{
if (TIFFReadScanline(tif, bits, y, 0))
{
memcpy(scanLine(y), bits, widtht * 4);
}
}
_TIFFfree(bits);
}
}
isCMYK = true;
if (realCMYK != 0)
*realCMYK = true;
}
else
{
bits = (uint32 *) _TIFFmalloc(size * sizeof(uint32));
if(bits)
{
if (TIFFReadRGBAImage(tif, widtht, heightt, bits, 0))
{
for(unsigned int y = 0; y < heightt; y++)
memcpy(scanLine(heightt - 1 - y), bits + y * widtht, widtht * 4);
}
_TIFFfree(bits);
if (bitspersample == 1)
bilevel = true;
}
}
swapRGBA();
#ifdef HAVE_CMS
DWORD EmbedLen = 0;
LPBYTE EmbedBuffer;
if (TIFFGetField(tif, TIFFTAG_ICCPROFILE, &EmbedLen, &EmbedBuffer) && useEmbedded && cmSettings.useColorManagement() && useProf)
{
const char *Descriptor;
tiffProf = cmsOpenProfileFromMem(EmbedBuffer, EmbedLen);
Descriptor = cmsTakeProductDesc(tiffProf);
imgInfo.profileName = QString(Descriptor);
imgInfo.isEmbedded = true;
}
else
{
imgInfo.isEmbedded = false;
imgInfo.profileName = "";
}
#endif // HAVE_CMS
unsigned int PhotoshopLen = 0;
unsigned char* PhotoshopBuffer;
if (TIFFGetField(tif, TIFFTAG_PHOTOSHOP, &PhotoshopLen, &PhotoshopBuffer) )
{
if (PhotoshopLen != 0)
{
QByteArray arrayPhot(PhotoshopLen);
arrayPhot.duplicate((const char*)PhotoshopBuffer,PhotoshopLen);
QDataStream strPhot(arrayPhot,IO_ReadOnly);
strPhot.setByteOrder( QDataStream::BigEndian );
PSDHeader fakeHeader;
fakeHeader.width = width();
fakeHeader.height = height();
parseRessourceData(strPhot, fakeHeader, PhotoshopLen);
imgInfo.valid = (imgInfo.PDSpathData.size())>0?true:false;
}
}
// uint32 ClipLen = 0;
// uint8 ClipBuffer;
// QString db;
// if (TIFFGetField(tif, TIFFTAG_CLIPPATH, &ClipLen, &ClipBuffer))
// qDebug("%s", db.setNum(ClipLen).ascii());
TIFFClose(tif);
if (resolutionunit == RESUNIT_INCH)
{
setDotsPerMeterX ((int) (xres / 0.0254));
setDotsPerMeterY ((int) (yres / 0.0254));
imgInfo.xres = qRound(xres);
imgInfo.yres = qRound(yres);
}
else if (resolutionunit == RESUNIT_CENTIMETER)
{
setDotsPerMeterX ((int) (xres * 100.0));
setDotsPerMeterY ((int) (yres * 100.0));
imgInfo.xres = qRound(xres*2.54);
imgInfo.yres = qRound(yres*2.54);
}
if (isCMYK)
imgInfo.colorspace = 1;
else if (bilevel)
imgInfo.colorspace = 2;
else
imgInfo.colorspace = 0;
imgInfo.layerInfo.clear();
imgInfo.BBoxX = 0;
imgInfo.BBoxH = height();
}
}
pDataLoader.reset( new ScImgDataLoader_TIFF() );
#endif // HAVE_TIFF
else if (ext == "psd")
{
imgInfo.typ = 2;
imgInfo.exifDataValid = false;
QFile f(fn);
if (f.open(IO_ReadOnly))
{
imgInfo.xres = 72;
imgInfo.yres = 72;
QDataStream s( &f );
s.setByteOrder( QDataStream::BigEndian );
PSDHeader header;
s >> header;
// Check image file format.
if( s.atEnd() || !IsValid( header ) )
return ret;
// Check if it's a supported format.
if( !IsSupported( header ) )
return ret;
iccbuf = 0;
icclen = 0;
if (reqType == Thumbnail)
header.reserved[0] = 't';
if( !LoadPSD(s, header) )
return ret;
#ifdef HAVE_CMS
if (icclen>0)
{
if (useEmbedded && cmSettings.useColorManagement() && useProf)
{
tiffProf = cmsOpenProfileFromMem(iccbuf, icclen);
const char *Descriptor;
Descriptor = cmsTakeProductDesc(tiffProf);
imgInfo.profileName = QString(Descriptor);
imgInfo.isEmbedded = true;
}
else
{
imgInfo.isEmbedded = false;
imgInfo.profileName = "";
}
free(iccbuf);
}
#endif // HAVE_CMS
if (header.color_mode == CM_CMYK)
isCMYK = true;
else
isCMYK = false;
if (realCMYK != 0)
*realCMYK = isCMYK;
if (header.color_mode == CM_CMYK)
imgInfo.colorspace = 1;
else if (header.color_mode == CM_RGB)
imgInfo.colorspace = 0;
else if (header.color_mode == CM_GRAYSCALE)
imgInfo.colorspace = 2;
imgInfo.valid = true;
setDotsPerMeterX ((int) (imgInfo.xres / 0.0254));
setDotsPerMeterY ((int) (imgInfo.yres / 0.0254));
xres = imgInfo.xres;
yres = imgInfo.yres;
f.close();
if (reqType == Thumbnail)
{
if (!imgInfo.exifInfo.thumbnail.isNull())
{
create(imgInfo.exifInfo.thumbnail.width(), imgInfo.exifInfo.thumbnail.height(), 32);
for( int yit=0; yit < imgInfo.exifInfo.thumbnail.height(); ++yit )
{
QRgb *s = (QRgb*)(imgInfo.exifInfo.thumbnail.scanLine( yit ));
QRgb *d = (QRgb*)(scanLine( yit ));
for(int xit=0; xit < imgInfo.exifInfo.thumbnail.width(); ++xit )
{
(*d) = (*s);
s++;
d++;
}
}
imgInfo.exifInfo.width = header.width;
imgInfo.exifInfo.height = header.height;
return true;
}
else
reqType = RGBData;
}
imgInfo.exifInfo.width = header.width;
imgInfo.exifInfo.height = header.height;
imgInfo.BBoxX = 0;
imgInfo.BBoxH = height();
}
else
return ret;
}
pDataLoader.reset( new ScImgDataLoader_PSD() );
else if ((ext == "jpg") || (ext == "jpeg"))
pDataLoader.reset( new ScImgDataLoader_JPEG() );
else
pDataLoader.reset( new ScImgDataLoader_QT() );
 
if (pDataLoader->loadPicture(fn, gsRes, (requestType == Thumbnail)))
{
imgInfo.typ = 0;
ExifData ExifInf;
imgInfo.exifInfo.thumbnail = QImage();
struct jpeg_decompress_struct cinfo;
struct my_error_mgr jerr;
FILE *infile;
cinfo.err = jpeg_std_error (&jerr.pub);
jerr.pub.error_exit = my_error_exit;
infile = NULL;
if (setjmp (jerr.setjmp_buffer))
*this = pDataLoader->image();
imgInfo = pDataLoader->imageInfoRecord();
if (requestType == Thumbnail)
requestType = RGBData;
if (!cmSettings.useColorManagement() || !useProf)
{
jpeg_destroy_decompress (&cinfo);
if (infile)
fclose (infile);
return ret;
}
jpeg_create_decompress (&cinfo);
if ((infile = fopen (fn.local8Bit(), "rb")) == NULL)
return ret;
jpeg_stdio_src(&cinfo, infile);
jpeg_save_markers(&cinfo, ICC_MARKER, 0xFFFF);
jpeg_save_markers(&cinfo, PHOTOSHOP_MARKER, 0xFFFF);
jpeg_read_header(&cinfo, true);
jpeg_start_decompress(&cinfo);
bool exi = ExifInf.scan(fn);
if ((exi) && (ExifInf.exifDataValid))
{
if ((!ExifInf.isNullThumbnail()) && (reqType == Thumbnail))
*this = ExifInf.getThumbnail();
imgInfo.exifInfo.cameraName = ExifInf.getCameraModel();
imgInfo.exifInfo.cameraVendor = ExifInf.getCameraMake();
imgInfo.exifInfo.thumbnail = ExifInf.getThumbnail();
imgInfo.exifInfo.comment = ExifInf.getComment();
imgInfo.exifInfo.width = ExifInf.getWidth();
imgInfo.exifInfo.height = ExifInf.getHeight();
imgInfo.exifInfo.userComment = ExifInf.getUserComment();
imgInfo.exifInfo.dateTime = ExifInf.getDateTime();
imgInfo.exifDataValid = true;
if (cinfo.density_unit == 0)
{
xres = 72;
yres = 72;
}
else if ( cinfo.density_unit == 1 )
{
xres = cinfo.X_density;
yres = cinfo.Y_density;
}
else if ( cinfo.density_unit == 2 )
{
xres = cinfo.X_density * 2.54;
yres = cinfo.Y_density * 2.54;
}
imgInfo.xres = qRound(xres);
imgInfo.yres = qRound(yres);
if (cinfo.output_components == 4)
imgInfo.colorspace = 1;
else if (cinfo.output_components == 3)
imgInfo.colorspace = 0;
else if (cinfo.output_components == 1)
imgInfo.colorspace = 2;
imgInfo.progressive = jpeg_has_multiple_scans(&cinfo);
if ((!ExifInf.isNullThumbnail()) && (reqType == Thumbnail))
{
jpeg_destroy_decompress(&cinfo);
fclose(infile);
return true;
}
else
{
if (reqType == Thumbnail)
reqType = RGBData;
}
}
else
imgInfo.exifDataValid = false;
if (reqType == Thumbnail)
reqType = RGBData;
#ifdef HAVE_CMS
unsigned int EmbedLen = 0;
unsigned char* EmbedBuffer;
if (read_jpeg_marker(ICC_MARKER,&cinfo, &EmbedBuffer, &EmbedLen) && useEmbedded && cmSettings.useColorManagement() && useProf)
{
const char *Descriptor;
tiffProf = cmsOpenProfileFromMem(EmbedBuffer, EmbedLen);
Descriptor = cmsTakeProductDesc(tiffProf);
imgInfo.profileName = QString(Descriptor);
imgInfo.isEmbedded = true;
free(EmbedBuffer);
}
else
{
imgInfo.isEmbedded = false;
imgInfo.profileName = "";
}
#endif // HAVE_CMS
unsigned int PhotoshopLen = 0;
unsigned char * PhotoshopBuffer;
if (cinfo.density_unit == 0)
if (imgInfo.colorspace == 1)
{
xres = 72;
yres = 72;
setDotsPerMeterX(2834);
setDotsPerMeterY(2834);
}
else if ( cinfo.density_unit == 1 )
{
xres = cinfo.X_density;
yres = cinfo.Y_density;
setDotsPerMeterX( int(100. * cinfo.X_density / 2.54) );
setDotsPerMeterY( int(100. * cinfo.Y_density / 2.54) );
}
else if ( cinfo.density_unit == 2 )
{
xres = cinfo.X_density * 2.54;
yres = cinfo.Y_density * 2.54;
setDotsPerMeterX( int(100. * cinfo.X_density) );
setDotsPerMeterY( int(100. * cinfo.Y_density) );
}
imgInfo.xres = qRound(xres);
imgInfo.yres = qRound(yres);
if (cinfo.output_components == 4)
{
isCMYK = true;
imgInfo.colorspace = 1;
if(realCMYK)
*realCMYK = true;
}
else if (cinfo.output_components == 3)
imgInfo.colorspace = 0;
else if (cinfo.output_components == 1)
imgInfo.colorspace = 2;
imgInfo.progressive = jpeg_has_multiple_scans(&cinfo);
 
if (read_jpeg_marker(PHOTOSHOP_MARKER,&cinfo, &PhotoshopBuffer, &PhotoshopLen) )
{
if (PhotoshopLen != 0)
{
bool savEx = imgInfo.exifDataValid;
QByteArray arrayPhot(PhotoshopLen);
arrayPhot.setRawData((const char*)PhotoshopBuffer,PhotoshopLen);
QDataStream strPhot(arrayPhot,IO_ReadOnly);
strPhot.setByteOrder( QDataStream::BigEndian );
PSDHeader fakeHeader;
fakeHeader.width = cinfo.output_width;
fakeHeader.height = cinfo.output_height;
if (cinfo.output_components == 4)
imgInfo.colorspace = 1;
else if (cinfo.output_components == 3)
imgInfo.colorspace = 0;
else if (cinfo.output_components == 1)
imgInfo.colorspace = 2;
imgInfo.progressive = jpeg_has_multiple_scans(&cinfo);
parseRessourceData(strPhot, fakeHeader, PhotoshopLen);
// Photoshop resolution is more accurate than jpeg header resolution
xres = imgInfo.xres;
yres = imgInfo.yres;
setDotsPerMeterX( int(100. * imgInfo.xres / 2.54) );
setDotsPerMeterY( int(100. * imgInfo.yres / 2.54) );
imgInfo.valid = (imgInfo.PDSpathData.size())>0?true:false; // The only interest is vectormask
arrayPhot.resetRawData((const char*)PhotoshopBuffer,PhotoshopLen);
free( PhotoshopBuffer );
imgInfo.exifDataValid = savEx;
}
}
if ( cinfo.output_components == 3 || cinfo.output_components == 4)
create( cinfo.output_width, cinfo.output_height, 32 );
else if ( cinfo.output_components == 1 )
{
create( cinfo.output_width, cinfo.output_height, 8, 256 );
for (int i=0; i<256; i++)
setColor(i, qRgb(i,i,i));
}
if (!isNull())
{
uchar** lines = jumpTable();
while (cinfo.output_scanline < cinfo.output_height)
(void) jpeg_read_scanlines(&cinfo, lines + cinfo.output_scanline, cinfo.output_height);
if ( cinfo.output_components == 3 )
{
for (uint j=0; j<cinfo.output_height; j++)
{
uchar *in = scanLine(j) + cinfo.output_width * 3;
QRgb *out = (QRgb*)scanLine(j);
for (uint i=cinfo.output_width; i--; )
{
in -= 3;
out[i] = qRgb(in[0], in[1], in[2]);
}
}
}
if ( cinfo.output_components == 4 )
{
for (int i = 0; i < height(); i++)
{
QRgb *ptr = (QRgb*) scanLine(i);
unsigned char c, m, y ,k;
if ((cinfo.jpeg_color_space == JCS_YCCK) || ((cinfo.jpeg_color_space == JCS_CMYK) && (cinfo.saw_Adobe_marker)))
{
for (int j = 0; j < width(); j++)
{
unsigned char *p = (unsigned char *) ptr;
c = p[0];
m = p[1];
y = p[2];
k = p[3];
*ptr = qRgba(255 - c, 255 - m, 255 - y, 255 - k);
ptr++;
}
}
else
{
for (int j = 0; j < width(); j++)
{
unsigned char *p = (unsigned char *) ptr;
c = p[0];
m = p[1];
y = p[2];
k = p[3];
*ptr = qRgba(y, m, c, k);
ptr++;
}
}
}
isCMYK = true;
if (realCMYK != 0)
*realCMYK = true;
}
else
isCMYK = false;
if ( cinfo.output_components == 1 )
{
QImage tmpImg = convertDepth(32);
create( cinfo.output_width, cinfo.output_height, 32 );
for( int yi=0; yi < tmpImg.height(); ++yi )
{
QRgb *s = (QRgb*)(tmpImg.scanLine( yi ));
QRgb *d = (QRgb*)(scanLine( yi ));
for(int xi=0; xi < tmpImg.width(); ++xi )
{
(*d) = (*s);
s++;
d++;
}
}
}
setAlphaBuffer(true);
}
(void) jpeg_finish_decompress(&cinfo);
fclose (infile);
jpeg_destroy_decompress (&cinfo);
imgInfo.layerInfo.clear();
imgInfo.BBoxX = 0;
imgInfo.BBoxH = height();
pDataLoader->image() = QImage();
}
else
{
if (load(fn))
{
imgInfo.typ = 6;
imgInfo.exifDataValid = false;
xres = dotsPerMeterX() * 0.0254;
yres = dotsPerMeterY() * 0.0254;
int resInf = imgInfo.lowResType;
*this = convertDepth(32);
setAlphaBuffer(true);
imgInfo.colorspace = 0;
setDotsPerMeterX (QMAX(2834, (int) (xres / 0.0254)));
setDotsPerMeterY (QMAX(2834, (int) (yres / 0.0254)));
imgInfo.xres = QMAX(72, qRound(xres));
imgInfo.yres = QMAX(72, qRound(yres));
imgInfo.lowResType = resInf;
imgInfo.BBoxX = 0;
imgInfo.BBoxH = height();
}
}
return false;
 
if (isNull())
return ret;
 
#ifdef HAVE_CMS
QByteArray embeddedProfile = pDataLoader->embeddedProfile();
if (cmSettings.useColorManagement() && useProf)
{
if (tiffProf)
inputProf = tiffProf;
if (embeddedProfile.size() > 0 )
{
inputProf = cmsOpenProfileFromMem(embeddedProfile.data(), embeddedProfile.size());
}
else
{
QCString profilePath;
/branches/Version13x/Scribus/scribus/scimgdataloader_jpeg.cpp
0,0 → 1,495
#include <qfile.h>
#include <setjmp.h>
#include "scconfig.h"
#include "scimgdataloader_jpeg.h"
#include "exif.h"
 
#ifdef HAVE_CMS
#include CMS_INC
#endif
 
typedef struct my_error_mgr
{
struct jpeg_error_mgr pub; /* "public" fields */
jmp_buf setjmp_buffer; /* for return to caller */
} *my_error_ptr;
 
static void my_error_exit (j_common_ptr cinfo)
{
my_error_ptr myerr = (my_error_ptr) cinfo->err;
(*cinfo->err->output_message) (cinfo);
longjmp (myerr->setjmp_buffer, 1);
}
 
#define ICC_MARKER (JPEG_APP0 + 2) /* JPEG marker code for ICC */
#define PHOTOSHOP_MARKER (JPEG_APP0 + 13) /* JPEG marker code for PHOTOSHOP */
#define ICC_OVERHEAD_LEN 14 /* size of non-profile data in APP2 */
#define MAX_BYTES_IN_MARKER 65533 /* maximum data len of a JPEG marker */
#define MAX_DATA_BYTES_IN_MARKER (MAX_BYTES_IN_MARKER - ICC_OVERHEAD_LEN)
 
 
ScImgDataLoader_JPEG::ScImgDataLoader_JPEG(void)
{
initSupportedFormatList();
}
 
void ScImgDataLoader_JPEG::initSupportedFormatList(void)
{
m_supportedFormats.clear();
m_supportedFormats.append( "jpg" );
m_supportedFormats.append( "jpeg" );
}
 
void ScImgDataLoader_JPEG::loadEmbeddedProfile(const QString& fn)
{
m_embeddedProfile.resize(0);
m_profileComponents = 0;
#ifdef HAVE_CMS
if (!QFile::exists(fn))
return;
struct jpeg_decompress_struct cinfo;
struct my_error_mgr jerr;
FILE *infile;
cinfo.err = jpeg_std_error (&jerr.pub);
jerr.pub.error_exit = my_error_exit;
infile = NULL;
if (setjmp (jerr.setjmp_buffer))
{
jpeg_destroy_decompress (&cinfo);
if (infile)
fclose (infile);
return;
}
jpeg_create_decompress (&cinfo);
if ((infile = fopen (fn.local8Bit(), "rb")) == NULL)
return;
jpeg_stdio_src(&cinfo, infile);
jpeg_save_markers(&cinfo, ICC_MARKER, 0xFFFF);
jpeg_read_header(&cinfo, true);
jpeg_start_decompress(&cinfo);
unsigned int EmbedLen = 0;
unsigned char* EmbedBuffer;
if (read_jpeg_marker(ICC_MARKER,&cinfo, &EmbedBuffer, &EmbedLen))
{
cmsHPROFILE prof = cmsOpenProfileFromMem(EmbedBuffer, EmbedLen);
if (prof)
{
if (static_cast<int>(cmsGetColorSpace(prof)) == icSigRgbData)
m_profileComponents = 3;
if (static_cast<int>(cmsGetColorSpace(prof)) == icSigCmykData)
m_profileComponents = 4;
m_embeddedProfile.duplicate((const char*) EmbedBuffer, EmbedLen);
}
cmsCloseProfile(prof);
free(EmbedBuffer);
}
(void) jpeg_finish_decompress(&cinfo);
fclose (infile);
jpeg_destroy_decompress (&cinfo);
#endif
}
 
void ScImgDataLoader_JPEG::preloadAlphaChannel(const QString& fn, int res)
{
// No support for aplha in jpeg pictures
initialize();
}
 
bool ScImgDataLoader_JPEG::loadPicture(const QString& fn, int res, bool thumbnail)
{
bool isCMYK = false;
float xres = 72.0, yres = 72.0;
if (!QFile::exists(fn))
return false;
ExifData ExifInf;
struct jpeg_decompress_struct cinfo;
struct my_error_mgr jerr;
FILE *infile;
cinfo.err = jpeg_std_error (&jerr.pub);
jerr.pub.error_exit = my_error_exit;
infile = NULL;
 
initialize();
m_imageInfoRecord.type = 0;
m_imageInfoRecord.exifInfo.thumbnail = QImage();
if (setjmp (jerr.setjmp_buffer))
{
jpeg_destroy_decompress (&cinfo);
if (infile)
fclose (infile);
return false;
}
jpeg_create_decompress (&cinfo);
if ((infile = fopen (fn.local8Bit(), "rb")) == NULL)
return false;
jpeg_stdio_src(&cinfo, infile);
jpeg_save_markers(&cinfo, ICC_MARKER, 0xFFFF);
jpeg_save_markers(&cinfo, PHOTOSHOP_MARKER, 0xFFFF);
jpeg_read_header(&cinfo, true);
jpeg_start_decompress(&cinfo);
bool exi = ExifInf.scan(fn);
if ((exi) && (ExifInf.exifDataValid))
{
if ((!ExifInf.isNullThumbnail()) && thumbnail)
m_image = ExifInf.getThumbnail();
m_imageInfoRecord.exifInfo.cameraName = ExifInf.getCameraModel();
m_imageInfoRecord.exifInfo.cameraVendor = ExifInf.getCameraMake();
m_imageInfoRecord.exifInfo.thumbnail = ExifInf.getThumbnail();
m_imageInfoRecord.exifInfo.comment = ExifInf.getComment();
m_imageInfoRecord.exifInfo.width = ExifInf.getWidth();
m_imageInfoRecord.exifInfo.height = ExifInf.getHeight();
m_imageInfoRecord.exifInfo.userComment = ExifInf.getUserComment();
m_imageInfoRecord.exifInfo.dateTime = ExifInf.getDateTime();
m_imageInfoRecord.exifDataValid = true;
if (cinfo.density_unit == 0)
{
xres = 72;
yres = 72;
}
else if ( cinfo.density_unit == 1 )
{
xres = cinfo.X_density;
yres = cinfo.Y_density;
}
else if ( cinfo.density_unit == 2 )
{
xres = cinfo.X_density * 2.54;
yres = cinfo.Y_density * 2.54;
}
m_imageInfoRecord.xres = qRound(xres);
m_imageInfoRecord.yres = qRound(yres);
if (cinfo.output_components == 4)
m_imageInfoRecord.colorspace = 1;
else if (cinfo.output_components == 3)
m_imageInfoRecord.colorspace = 0;
else if (cinfo.output_components == 1)
m_imageInfoRecord.colorspace = 2;
m_imageInfoRecord.progressive = jpeg_has_multiple_scans(&cinfo);
if ((!ExifInf.isNullThumbnail()) && thumbnail)
{
jpeg_destroy_decompress(&cinfo);
fclose(infile);
return true;
}
}
else
m_imageInfoRecord.exifDataValid = false;
#ifdef HAVE_CMS
unsigned int EmbedLen = 0;
unsigned char* EmbedBuffer;
if (read_jpeg_marker(ICC_MARKER,&cinfo, &EmbedBuffer, &EmbedLen))
{
const char *Descriptor;
cmsHPROFILE prof = cmsOpenProfileFromMem(EmbedBuffer, EmbedLen);
Descriptor = cmsTakeProductDesc(prof);
m_embeddedProfile.duplicate((const char*) EmbedBuffer, EmbedLen);
m_imageInfoRecord.profileName = QString(Descriptor);
m_imageInfoRecord.isEmbedded = true;
free(EmbedBuffer);
}
else
{
m_imageInfoRecord.isEmbedded = false;
m_imageInfoRecord.profileName = "";
}
#endif // HAVE_CMS
unsigned int PhotoshopLen = 0;
unsigned char * PhotoshopBuffer;
if (cinfo.density_unit == 0)
{
xres = 72;
yres = 72;
m_image.setDotsPerMeterX(2834);
m_image.setDotsPerMeterY(2834);
}
else if ( cinfo.density_unit == 1 )
{
xres = cinfo.X_density;
yres = cinfo.Y_density;
m_image.setDotsPerMeterX( int(100. * cinfo.X_density / 2.54) );
m_image.setDotsPerMeterY( int(100. * cinfo.Y_density / 2.54) );
}
else if ( cinfo.density_unit == 2 )
{
xres = cinfo.X_density * 2.54;
yres = cinfo.Y_density * 2.54;
m_image.setDotsPerMeterX( int(100. * cinfo.X_density) );
m_image.setDotsPerMeterY( int(100. * cinfo.Y_density) );
}
m_imageInfoRecord.xres = qRound(xres);
m_imageInfoRecord.yres = qRound(yres);
if (cinfo.output_components == 4)
{
isCMYK = true;
m_imageInfoRecord.colorspace = 1;
}
else if (cinfo.output_components == 3)
m_imageInfoRecord.colorspace = 0;
else if (cinfo.output_components == 1)
m_imageInfoRecord.colorspace = 2;
m_imageInfoRecord.progressive = jpeg_has_multiple_scans(&cinfo);
 
if (read_jpeg_marker(PHOTOSHOP_MARKER,&cinfo, &PhotoshopBuffer, &PhotoshopLen) )
{
if (PhotoshopLen != 0)
{
bool savEx = m_imageInfoRecord.exifDataValid;
QByteArray arrayPhot(PhotoshopLen);
arrayPhot.setRawData((const char*)PhotoshopBuffer,PhotoshopLen);
QDataStream strPhot(arrayPhot,IO_ReadOnly);
strPhot.setByteOrder( QDataStream::BigEndian );
PSDHeader fakeHeader;
fakeHeader.width = cinfo.output_width;
fakeHeader.height = cinfo.output_height;
if (cinfo.output_components == 4)
m_imageInfoRecord.colorspace = 1;
else if (cinfo.output_components == 3)
m_imageInfoRecord.colorspace = 0;
else if (cinfo.output_components == 1)
m_imageInfoRecord.colorspace = 2;
m_imageInfoRecord.progressive = jpeg_has_multiple_scans(&cinfo);
parseRessourceData(strPhot, fakeHeader, PhotoshopLen);
// Photoshop resolution is more accurate than jpeg header resolution
xres = m_imageInfoRecord.xres;
yres = m_imageInfoRecord.yres;
m_image.setDotsPerMeterX( int(100. * m_imageInfoRecord.xres / 2.54) );
m_image.setDotsPerMeterY( int(100. * m_imageInfoRecord.yres / 2.54) );
m_imageInfoRecord.valid = (m_imageInfoRecord.PDSpathData.size())>0?true:false; // The only interest is vectormask
arrayPhot.resetRawData((const char*)PhotoshopBuffer,PhotoshopLen);
free( PhotoshopBuffer );
m_imageInfoRecord.exifDataValid = savEx;
}
}
if ( cinfo.output_components == 3 || cinfo.output_components == 4)
m_image.create( cinfo.output_width, cinfo.output_height, 32 );
else if ( cinfo.output_components == 1 )
{
m_image.create( cinfo.output_width, cinfo.output_height, 8, 256 );
for (int i=0; i<256; i++)
m_image.setColor(i, qRgb(i,i,i));
}
if (!m_image.isNull())
{
uchar** lines = m_image.jumpTable();
while (cinfo.output_scanline < cinfo.output_height)
(void) jpeg_read_scanlines(&cinfo, lines + cinfo.output_scanline, cinfo.output_height);
if ( cinfo.output_components == 3 )
{
for (uint j=0; j<cinfo.output_height; j++)
{
uchar *in = m_image.scanLine(j) + cinfo.output_width * 3;
QRgb *out = (QRgb*) m_image.scanLine(j);
for (uint i=cinfo.output_width; i--; )
{
in -= 3;
out[i] = qRgb(in[0], in[1], in[2]);
}
}
}
if ( cinfo.output_components == 4 )
{
for (int i = 0; i < m_image.height(); i++)
{
QRgb *ptr = (QRgb*) m_image.scanLine(i);
unsigned char c, m, y ,k;
if ((cinfo.jpeg_color_space == JCS_YCCK) || ((cinfo.jpeg_color_space == JCS_CMYK) && (cinfo.saw_Adobe_marker)))
{
for (int j = 0; j < m_image.width(); j++)
{
unsigned char *p = (unsigned char *) ptr;
c = p[0];
m = p[1];
y = p[2];
k = p[3];
*ptr = qRgba(255 - c, 255 - m, 255 - y, 255 - k);
ptr++;
}
}
else
{
for (int j = 0; j < m_image.width(); j++)
{
unsigned char *p = (unsigned char *) ptr;
c = p[0];
m = p[1];
y = p[2];
k = p[3];
*ptr = qRgba(y, m, c, k);
ptr++;
}
}
}
isCMYK = true;
}
else
isCMYK = false;
if ( cinfo.output_components == 1 )
{
QImage tmpImg = m_image.convertDepth(32);
m_image.create( cinfo.output_width, cinfo.output_height, 32 );
for( int yi=0; yi < tmpImg.height(); ++yi )
{
QRgb *s = (QRgb*)(tmpImg.scanLine( yi ));
QRgb *d = (QRgb*)(m_image.scanLine( yi ));
for(int xi=0; xi < tmpImg.width(); ++xi )
{
(*d) = (*s);
s++;
d++;
}
}
}
m_image.setAlphaBuffer(true);
}
(void) jpeg_finish_decompress(&cinfo);
fclose (infile);
jpeg_destroy_decompress (&cinfo);
m_imageInfoRecord.layerInfo.clear();
m_imageInfoRecord.BBoxX = 0;
m_imageInfoRecord.BBoxH = m_image.height();
return (!m_image.isNull());
}
 
bool ScImgDataLoader_JPEG::marker_is_icc (jpeg_saved_marker_ptr marker)
{
return
marker->marker == ICC_MARKER &&
marker->data_length >= ICC_OVERHEAD_LEN &&
/* verify the identifying string */
GETJOCTET(marker->data[0]) == 0x49 &&
GETJOCTET(marker->data[1]) == 0x43 &&
GETJOCTET(marker->data[2]) == 0x43 &&
GETJOCTET(marker->data[3]) == 0x5F &&
GETJOCTET(marker->data[4]) == 0x50 &&
GETJOCTET(marker->data[5]) == 0x52 &&
GETJOCTET(marker->data[6]) == 0x4F &&
GETJOCTET(marker->data[7]) == 0x46 &&
GETJOCTET(marker->data[8]) == 0x49 &&
GETJOCTET(marker->data[9]) == 0x4C &&
GETJOCTET(marker->data[10]) == 0x45 &&
GETJOCTET(marker->data[11]) == 0x0;
}
 
bool ScImgDataLoader_JPEG::marker_is_photoshop (jpeg_saved_marker_ptr marker)
{
return
marker->marker == PHOTOSHOP_MARKER &&
marker->data_length >= ICC_OVERHEAD_LEN &&
/* verify the identifying string */
GETJOCTET(marker->data[0]) == 0x50 &&
GETJOCTET(marker->data[1]) == 0x68 &&
GETJOCTET(marker->data[2]) == 0x6F &&
GETJOCTET(marker->data[3]) == 0x74 &&
GETJOCTET(marker->data[4]) == 0x6F &&
GETJOCTET(marker->data[5]) == 0x73 &&
GETJOCTET(marker->data[6]) == 0x68 &&
GETJOCTET(marker->data[7]) == 0x6F &&
GETJOCTET(marker->data[8]) == 0x70 &&
GETJOCTET(marker->data[9]) == 0x20 &&
GETJOCTET(marker->data[10]) == 0x33 &&
GETJOCTET(marker->data[11]) == 0x2E &&
GETJOCTET(marker->data[12]) == 0x30 &&
GETJOCTET(marker->data[13]) == 0x0;
}
 
/* Small modification of original read_icc_profile method from jpegicc of lcms project
* to enable read of Photoshop marker
*/
bool ScImgDataLoader_JPEG::read_jpeg_marker (UINT8 requestmarker, j_decompress_ptr cinfo, JOCTET **icc_data_ptr, unsigned int *icc_data_len)
{
jpeg_saved_marker_ptr marker;
int num_markers = 0;
int seq_no;
JOCTET *icc_data;
unsigned int total_length;
#define MAX_SEQ_NO 255 /* sufficient since marker numbers are bytes */
char marker_present[MAX_SEQ_NO+1]; /* 1 if marker found */
unsigned int data_length[MAX_SEQ_NO+1]; /* size of profile data in marker */
unsigned int data_offset[MAX_SEQ_NO+1]; /* offset for data in marker */
 
*icc_data_ptr = NULL; /* avoid confusion if false return */
*icc_data_len = 0;
 
/* This first pass over the saved markers discovers whether there are
* any ICC markers and verifies the consistency of the marker numbering.
*/
 
for (seq_no = 1; seq_no <= MAX_SEQ_NO; seq_no++)
marker_present[seq_no] = 0;
seq_no = 0;
for (marker = cinfo->marker_list; marker != NULL; marker = marker->next)
{
if (requestmarker == ICC_MARKER && marker_is_icc(marker))
{
if (num_markers == 0)
num_markers = GETJOCTET(marker->data[13]);
else if (num_markers != GETJOCTET(marker->data[13]))
return false; /* inconsistent num_markers fields */
seq_no = GETJOCTET(marker->data[12]);
if (seq_no <= 0 || seq_no > num_markers)
return false; /* bogus sequence number */
if (marker_present[seq_no])
return false; /* duplicate sequence numbers */
marker_present[seq_no] = 1;
data_length[seq_no] = marker->data_length - ICC_OVERHEAD_LEN;
}
else if(requestmarker == PHOTOSHOP_MARKER && marker_is_photoshop(marker))
{
num_markers = ++seq_no;
marker_present[seq_no] = 1;
data_length[seq_no] = marker->data_length - ICC_OVERHEAD_LEN;
}
}
 
if (num_markers == 0)
return false;
 
/* Check for missing markers, count total space needed,
* compute offset of each marker's part of the data.
*/
 
total_length = 0;
for (seq_no = 1; seq_no <= num_markers; seq_no++)
{
if (marker_present[seq_no] == 0)
return false; /* missing sequence number */
data_offset[seq_no] = total_length;
total_length += data_length[seq_no];
}
 
if (total_length <= 0)
return false; /* found only empty markers? */
 
/* Allocate space for assembled data */
icc_data = (JOCTET *) malloc(total_length * sizeof(JOCTET));
if (icc_data == NULL)
return false; /* oops, out of memory */
seq_no=0;
/* and fill it in */
for (marker = cinfo->marker_list; marker != NULL; marker = marker->next)
{
if ( (requestmarker == ICC_MARKER && marker_is_icc(marker)) ||
(requestmarker == PHOTOSHOP_MARKER && marker_is_photoshop(marker)) || (requestmarker == 0xE1))
{
JOCTET FAR *src_ptr;
JOCTET *dst_ptr;
unsigned int length;
if(requestmarker == ICC_MARKER)
seq_no = GETJOCTET(marker->data[12]);
else if(requestmarker == PHOTOSHOP_MARKER)
seq_no++;
dst_ptr = icc_data + data_offset[seq_no];
src_ptr = marker->data + ICC_OVERHEAD_LEN;
length = data_length[seq_no];
while (length--)
{
*dst_ptr++ = *src_ptr++;
}
}
}
 
*icc_data_ptr = icc_data;
*icc_data_len = total_length;
 
return true;
}
Property changes:
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+Author Date Id Revision
\ No newline at end of property
Index: branches/Version13x/Scribus/scribus/scimgdataloader_psd.h
===================================================================
--- branches/Version13x/Scribus/scribus/scimgdataloader_psd.h (nonexistent)
+++ branches/Version13x/Scribus/scribus/scimgdataloader_psd.h (revision 5937)
@@ -0,0 +1,47 @@
+#ifndef SCIMGDATALOADER_PSD_H
+#define SCIMGDATALOADER_PSD_H
+
+#include <qvaluelist.h>
+#include "scimgdataloader.h"
+
+class ScImgDataLoader_PSD : public ScImgDataLoader
+{
+public:
+
+ enum PSDColorMode
+ {
+ CM_BITMAP = 0,
+ CM_GRAYSCALE = 1,
+ CM_INDEXED = 2,
+ CM_RGB = 3,
+ CM_CMYK = 4,
+ CM_MULTICHANNEL = 7,
+ CM_DUOTONE = 8,
+ CM_LABCOLOR = 9
+ };
+
+ ScImgDataLoader_PSD(void);
+
+ virtual void preloadAlphaChannel(const QString& fn, int res);
+ virtual void loadEmbeddedProfile(const QString& fn);
+ virtual bool loadPicture(const QString& fn, int res, bool thumbnail);
+
+protected:
+
+ QValueList<unsigned int> colorTable;
+ int random_table[4096];
+
+ void initSupportedFormatList();
+
+ bool IsValid( const PSDHeader & header );
+ bool IsSupported( const PSDHeader & header );
+
+ bool LoadPSD( QDataStream & s, const PSDHeader & header);
+ bool loadChannel( QDataStream & s, const PSDHeader & header, QValueList<PSDLayer> &layerInfo, uint layer, int channel, int component, QImage &tmpImg);
+ bool loadLayerChannels( QDataStream & s, const PSDHeader & header, QValueList<PSDLayer> &layerInfo, uint layer, bool* firstLayer);
+ bool loadLayer( QDataStream & s, const PSDHeader & header);
+ bool parseLayer( QDataStream & s, const PSDHeader & header);
+ QString getLayerString(QDataStream & s);
+};
+
+#endif
/branches/Version13x/Scribus/scribus/scimgdataloader_psd.h
Property changes:
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+Author Date Id Revision
\ No newline at end of property
Index: branches/Version13x/Scribus/scribus/plugins/fileloader/scribus13format/scribus13format.cpp
===================================================================
--- branches/Version13x/Scribus/scribus/plugins/fileloader/scribus13format/scribus13format.cpp (revision 5936)
+++ branches/Version13x/Scribus/scribus/plugins/fileloader/scribus13format/scribus13format.cpp (revision 5937)
@@ -1981,7 +1981,7 @@
PageItem* Scribus13Format::PasteItem(QDomElement *obj, ScribusDoc *doc)
{
- struct ScImage::LoadRequest loadingInfo;
+ struct ImageLoadRequest loadingInfo;
int z = 0;
PageItem::ItemType pt = static_cast<PageItem::ItemType>(obj->attribute("PTYPE").toInt());
double x = obj->attribute("XPOS").toDouble();
@@ -3294,7 +3294,7 @@
}
if (((item->asImageFrame()) || (item->asTextFrame())) && (!item->Pfile.isEmpty()) && (item->pixm.imgInfo.layerInfo.count() != 0) && (item->pixm.imgInfo.isRequest))
{
- QMap<int, ScImage::LoadRequest>::iterator it2;
+ QMap<int, ImageLoadRequest>::iterator it2;
for (it2 = item->pixm.imgInfo.RequestProps.begin(); it2 != item->pixm.imgInfo.RequestProps.end(); ++it2)
{
QDomElement psd = docu->createElement("PSDLayer");
/branches/Version13x/Scribus/scribus/plugins/fileloader/scribus134format/scribus134format.cpp
1969,7 → 1969,7
 
PageItem* Scribus134Format::PasteItem(QDomElement *obj, ScribusDoc *doc)
{
struct ScImage::LoadRequest loadingInfo;
struct ImageLoadRequest loadingInfo;
int z = 0;
PageItem::ItemType pt = static_cast<PageItem::ItemType>(obj->attribute("PTYPE").toInt());
double x = obj->attribute("XPOS").toDouble();
3283,7 → 3283,7
}
if (((item->asImageFrame()) || (item->asTextFrame())) && (!item->Pfile.isEmpty()) && (item->pixm.imgInfo.layerInfo.count() != 0) && (item->pixm.imgInfo.isRequest))
{
QMap<int, ScImage::LoadRequest>::iterator it2;
QMap<int, ImageLoadRequest>::iterator it2;
for (it2 = item->pixm.imgInfo.RequestProps.begin(); it2 != item->pixm.imgInfo.RequestProps.end(); ++it2)
{
QDomElement psd = docu->createElement("PSDLayer");
/branches/Version13x/Scribus/scribus/CMakeLists.txt
363,6 → 363,14
scfonts_ttf.cpp
scfontmetrics.cpp
scimage.cpp
scimagestructs.cpp
scimgdataloader.cpp
scimgdataloader_jpeg.cpp
scimgdataloader_pdf.cpp
scimgdataloader_ps.cpp
scimgdataloader_psd.cpp
scimgdataloader_qt.cpp
scimgdataloader_tiff.cpp
scgtplugin.cpp
scpainter.cpp
scpaths.cpp
/branches/Version13x/Scribus/scribus/scimagestructs.h
0,0 → 1,95
#ifndef SCIMAGESTRUCTS_H
#define SCIMAGESTRUCTS_H
 
#include <qstring.h>
#include <qvaluelist.h>
#include <qimage.h>
#include <qmap.h>
#include "fpointarray.h"
 
struct ImageLoadRequest
{
bool visible;
ushort opacity;
QString blend;
};
 
struct PSDHeader
{
uint signature;
ushort version;
uchar reserved[6];
ushort channel_count;
uint height;
uint width;
ushort depth;
ushort color_mode;
};
 
struct PSDLayer
{
QValueList<uint> channelLen;
QValueList<int> channelType;
int xpos;
int ypos;
int width;
int height;
ushort opacity;
uchar clipping;
uchar flags;
int maskXpos;
int maskYpos;
int maskWidth;
int maskHeight;
QString layerName;
QString blend;
QImage thumb;
};
 
class ExifValues
{
public:
ExifValues(void);
void init(void);
 
int width;
int height;
QString cameraName;
QString cameraVendor;
QString comment;
QString userComment;
QString artist;
QString copyright;
QString dateTime;
QImage thumbnail;
};
 
class ImageInfoRecord
{
public:
ImageInfoRecord(void);
void init(void);
 
int type; /* 0 = jpg, 1 = tiff, 2 = psd, 3 = eps/ps, 4 = pdf, 5 = jpg2000, 6 = other */
int xres;
int yres;
int BBoxX;
int BBoxH;
int colorspace; /* 0 = RGB 1 = CMYK 2 = Grayscale */
bool valid;
bool isRequest;
bool progressive;
bool isEmbedded;
bool exifDataValid;
int lowResType; /* 0 = full Resolution, 1 = 72 dpi, 2 = 36 dpi */
double lowResScale;
QMap<QString, FPointArray> PDSpathData;
QMap<int, ImageLoadRequest> RequestProps;
QString clipPath;
QString usedPath;
QString profileName;
QValueList<PSDLayer> layerInfo;
ExifValues exifInfo;
};
 
#endif
Property changes:
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+Author Date Id Revision
\ No newline at end of property