Back to index

scribus-ng  1.3.4.dfsg+svn20071115
scimgdataloader_ps.cpp
Go to the documentation of this file.
00001 /*
00002 For general Scribus (>=1.3.2) copyright and licensing information please refer
00003 to the COPYING file provided with the program. Following this notice may exist
00004 a copyright and/or license notice that predates the release of Scribus 1.3.2
00005 for which a new license (GPL+exception) is in place.
00006 */
00007 #include <qfile.h>
00008 #include <qfileinfo.h>
00009 #include <qregexp.h>
00010 #include "gsutil.h"
00011 #include "scpaths.h"
00012 #include "scribuscore.h"
00013 #include "scimgdataloader_ps.h"
00014 #include "prefsmanager.h"
00015 #include "util.h"
00016 #include "cmsettings.h"
00017 #include "scimage.h"
00018 
00019 extern "C"
00020 {
00021 #define XMD_H           // shut JPEGlib up
00022 #if defined(Q_OS_UNIXWARE)
00023 #  define HAVE_BOOLEAN  // libjpeg under Unixware seems to need this
00024 #endif
00025 #include <jpeglib.h>
00026 #include <jerror.h>
00027 #undef HAVE_STDLIB_H
00028 #ifdef const
00029 #  undef const          // remove crazy C hackery in jconfig.h
00030 #endif
00031 }
00032 
00033 ScImgDataLoader_PS::ScImgDataLoader_PS(void) : ScImgDataLoader()
00034 {
00035        initSupportedFormatList();
00036 }
00037 
00038 void ScImgDataLoader_PS::initSupportedFormatList(void)
00039 {
00040        m_supportedFormats.clear();
00041        m_supportedFormats.append( "ps" );
00042        m_supportedFormats.append( "eps" );
00043        m_supportedFormats.append( "epsi" );
00044 }
00045 
00046 void ScImgDataLoader_PS::loadEmbeddedProfile(const QString& fn)
00047 {
00048        QChar tc;
00049        QString tmp;
00050        m_embeddedProfile.resize(0);
00051        m_profileComponents = 0;
00052        if ( !QFile::exists(fn) )
00053               return;
00054        QFile f(fn);
00055        if (f.open(IO_ReadOnly))
00056        {
00057               QTextStream ts(&f);
00058               while (!ts.atEnd())
00059               {
00060                      tmp = ts.readLine();
00061                      if (tmp.startsWith("%%BeginICCProfile:"))
00062                      {
00063                             QByteArray psdata;
00064                             while (!ts.atEnd())
00065                             {
00066                                    tmp = ts.readLine();
00067                                    for (uint a = 2; a < tmp.length(); a += 2)
00068                                    {
00069                                           bool ok;
00070                                           ushort data = tmp.mid(a, 2).toUShort(&ok, 16);
00071                                           psdata.resize(psdata.size()+1);
00072                                           psdata[psdata.size()-1] = data;
00073                                    }
00074                                    if (tmp.startsWith("%%EndICCProfile"))
00075                                    {
00076                                           cmsHPROFILE prof = cmsOpenProfileFromMem(psdata.data(), psdata.size());
00077                                           if (prof)
00078                                           {
00079                                                  if (static_cast<int>(cmsGetColorSpace(prof)) == icSigRgbData)
00080                                                         m_profileComponents = 3;
00081                                                  if (static_cast<int>(cmsGetColorSpace(prof)) == icSigCmykData)
00082                                                         m_profileComponents = 4;
00083                                                  const char *Descriptor;
00084                                                  Descriptor = cmsTakeProductDesc(prof);
00085                                                  m_imageInfoRecord.profileName = QString(Descriptor);
00086                                                  m_imageInfoRecord.isEmbedded = true;
00087                                                  m_embeddedProfile.duplicate((const char*)psdata.data(), psdata.size());
00088                                           }
00089                                           cmsCloseProfile(prof);
00090                                           break;
00091                                    }
00092                             }
00093                      }
00094               }
00095        }
00096 }
00097 
00098 void ScImgDataLoader_PS::scanForFonts(QString fn)
00099 {
00100        QString tmp;
00101        QFile f(fn);
00102        if (f.open(IO_ReadOnly))
00103        {
00104               QTextStream ts(&f);
00105               while (!ts.atEnd())
00106               {
00107                      tmp = ts.readLine();
00108                      if (tmp.startsWith("%%BeginFont:"))
00109                      {
00110                             tmp = tmp.remove("%%BeginFont:");
00111                             QTextStream ts2(&tmp, IO_ReadOnly);
00112                             QString tmp2;
00113                             ts2 >> tmp2;
00114                             FontListe.remove(tmp2);
00115                      }
00116               }
00117        }
00118 }
00119 
00120 bool ScImgDataLoader_PS::parseData(QString fn)
00121 {
00122        QChar tc;
00123        QString tmp, FarNam;
00124        ScColor cc;
00125        double x, y, b, h, c, m, k;
00126        bool found = false;
00127        isDCS1 = false;
00128        isDCS2 = false;
00129        isDCS2multi = false;
00130        isPhotoshop = false;
00131        hasPhotoshopImageData = false;
00132        hasThumbnail = false;
00133        int plateCount = 0;
00134        uint startPos = 0;
00135        FontListe.clear();
00136        QFile f(fn);
00137        if (f.open(IO_ReadOnly))
00138        {
00139               QCString tempBuf(9);
00140               f.readBlock(tempBuf.data(), 8);
00141               if (getDouble(QString(tempBuf.mid(0, 4)), true) == 0xC5D0D3C6)
00142               {
00143                      startPos = getDouble(tempBuf.mid(4, 4), false);
00144                      if (doThumbnail)
00145                      {
00146                             f.at(0);
00147                             QByteArray tmp2buf(29);
00148                             f.readBlock(tmp2buf.data(), 28);
00149                             uint thumbStart = 0;
00150                             thumbStart = tmp2buf[20] & 0xff;
00151                             thumbStart |= (tmp2buf[21] << 8) & 0xff00;
00152                             thumbStart |= (tmp2buf[22] << 16) & 0xff0000;
00153                             thumbStart |= (tmp2buf[23] << 24) & 0xff000000;
00154                             uint thumbLen = 0;
00155                             thumbLen = tmp2buf[24] & 0xff;
00156                             thumbLen |= (tmp2buf[25] << 8) & 0xff00;
00157                             thumbLen |= (tmp2buf[26] << 16) & 0xff0000;
00158                             thumbLen |= (tmp2buf[27] << 24) & 0xff000000;
00159                             if (thumbLen != 0)
00160                             {
00161                                    QByteArray imgc(thumbLen);
00162                                    f.at(thumbStart);
00163                                    uint readB = f.readBlock(imgc.data(), thumbLen);
00164                                    readB = 0;
00165                                    QString tmpFile = QDir::convertSeparators(ScPaths::getTempFileDir() + "preview.tiff");
00166                                    QFile f2(tmpFile);
00167                                    if (f2.open(IO_WriteOnly))
00168                                           f2.writeBlock(imgc.data(), thumbLen);
00169                                    f2.close();
00170                                    imgc.resize(0);
00171                                    ScImage thum;
00172                                    CMSettings cms(0, "", 0);
00173                                    bool mode = true;
00174                                    if (thum.LoadPicture(tmpFile, cms, false, false, ScImage::RGBData, 72, &mode))
00175                                    {
00176                                           m_imageInfoRecord.exifDataValid = true;
00177                                           m_imageInfoRecord.exifInfo.thumbnail = thum.qImage().copy();
00178                                    }
00179                                    unlink(tmpFile);
00180                                    hasThumbnail = true;
00181                             }
00182                      }
00183               }
00184               bool psFound = false;
00185               QTextStream ts(&f);
00186               ts.device()->at(startPos);
00187               while (!ts.atEnd())
00188               {
00189                      tmp = ts.readLine();
00190                      if (tmp.startsWith("%%Creator: "))
00191                             Creator = tmp.remove("%%Creator: ");
00192                      if (tmp.startsWith("%%BoundingBox:"))
00193                      {
00194                             found = true;
00195                             BBox = tmp.remove("%%BoundingBox:");
00196                             if (BBox.contains("(atend)"))
00197                                    found = false;
00198                      }
00199                      if (!found)
00200                      {
00201                             if (tmp.startsWith("%%BoundingBox"))
00202                             {
00203                                    found = true;
00204                                    BBox = tmp.remove("%%BoundingBox");
00205                                    if (BBox.contains("(atend)"))
00206                                           found = false;
00207                             }
00208                      }
00209                      if (tmp.startsWith("%%CyanPlate:"))
00210                      {
00211                             colorPlates.insert("Cyan", tmp.remove("%%CyanPlate: "));
00212                             isDCS1 = true;
00213                      }
00214                      if (tmp.startsWith("%%MagentaPlate:"))
00215                      {
00216                             colorPlates.insert("Magenta", tmp.remove("%%MagentaPlate: "));
00217                             isDCS1 = true;
00218                      }
00219                      if (tmp.startsWith("%%YellowPlate:"))
00220                      {
00221                             colorPlates.insert("Yellow", tmp.remove("%%YellowPlate: "));
00222                             isDCS1 = true;
00223                      }
00224                      if (tmp.startsWith("%%BlackPlate:"))
00225                      {
00226                             colorPlates.insert("Black", tmp.remove("%%BlackPlate: "));
00227                             isDCS1 = true;
00228                      }
00229                      if (tmp.startsWith("%%PlateFile: ("))
00230                      {
00231                             tmp = tmp.remove("%%PlateFile: (");
00232                             int endNam = tmp.find(")");
00233                             QString plateNam = tmp.left(endNam);
00234                             tmp = tmp.remove(plateNam+")");
00235                             QTextStream ts2(&tmp, IO_ReadOnly);
00236                             QString posStr, dummy, lenStr;
00237                             ts2 >> dummy >> posStr >> lenStr;
00238                             if (dummy == "EPS")
00239                             {
00240                                    if (posStr.startsWith("#"))
00241                                    {
00242                                           posStr = posStr.remove(0, 1);
00243                                           uint pos = posStr.toUInt();
00244                                           uint len = lenStr.toUInt();
00245                                           struct plateOffsets offs;
00246                                           if (Creator.contains("Photoshop Version 9"))     // This is very strange, it seems that there is a bug in PS 9 which writes weired entries
00247                                           {
00248                                                  pos -= (191 + plateCount * 83);
00249                                                  len -= 83;
00250                                           }
00251                                           offs.pos = pos;
00252                                           offs.len = len;
00253                                           colorPlates2.insert(plateNam, offs);
00254                                           isDCS2 = true;
00255                                           plateCount++;
00256                                    }
00257                                    else
00258                                    {
00259                                           colorPlates.insert(plateNam, lenStr);
00260                                           isDCS2 = true;
00261                                           isDCS2multi = true;
00262                                    }
00263                             }
00264                      }
00265                      if (tmp.startsWith("%%DocumentFonts:"))
00266                      {
00267                             tmp = tmp.remove("%%DocumentFonts:");
00268                             QTextStream ts2(&tmp, IO_ReadOnly);
00269                             QString tmp2;
00270                             ts2 >> tmp2;
00271                             if (!tmp2.isEmpty())
00272                                    FontListe.append(tmp2);
00273                             while (!ts.atEnd())
00274                             {
00275                                    uint oldPos = ts.device()->at();
00276                                    tmp = ts.readLine();
00277                                    if (!tmp.startsWith("%%+"))
00278                                    {
00279                                           ts.device()->at(oldPos);
00280                                           break;
00281                                    }
00282                                    tmp = tmp.remove(0,3);
00283                                    QTextStream ts2(&tmp, IO_ReadOnly);
00284                                    QString tmp2;
00285                                    ts2 >> tmp2;
00286                                    if (!tmp2.isEmpty())
00287                                           FontListe.append(tmp2);
00288                             }
00289                      }
00290                      if (tmp.startsWith("%%CMYKCustomColor"))
00291                      {
00292                             tmp = tmp.remove(0,18);
00293                             QTextStream ts2(&tmp, IO_ReadOnly);
00294                             ts2 >> c >> m >> y >> k;
00295                             FarNam = ts2.read();
00296                             FarNam = FarNam.stripWhiteSpace();
00297                             FarNam = FarNam.remove(0,1);
00298                             FarNam = FarNam.remove(FarNam.length()-1,1);
00299                             cc = ScColor(static_cast<int>(255 * c), static_cast<int>(255 * m), static_cast<int>(255 * y), static_cast<int>(255 * k));
00300                             cc.setSpotColor(true);
00301                             CustColors.insert(FarNam, cc);
00302                             while (!ts.atEnd())
00303                             {
00304                                    uint oldPos = ts.device()->at();
00305                                    tmp = ts.readLine();
00306                                    if (!tmp.startsWith("%%+"))
00307                                    {
00308                                           ts.device()->at(oldPos);
00309                                           break;
00310                                    }
00311                                    tmp = tmp.remove(0,3);
00312                                    QTextStream ts2(&tmp, IO_ReadOnly);
00313                                    ts2 >> c >> m >> y >> k;
00314                                    FarNam = ts2.read();
00315                                    FarNam = FarNam.stripWhiteSpace();
00316                                    FarNam = FarNam.remove(0,1);
00317                                    FarNam = FarNam.remove(FarNam.length()-1,1);
00318                                    cc = ScColor(static_cast<int>(255 * c), static_cast<int>(255 * m), static_cast<int>(255 * y), static_cast<int>(255 * k));
00319                                    cc.setSpotColor(true);
00320                                    CustColors.insert(FarNam, cc);
00321                             }
00322                      }
00323                      if (tmp.startsWith("%%EndComments"))
00324                      {
00325                             while (!ts.atEnd())
00326                             {
00327                                    tmp = ts.readLine();
00328                                    if ((!tmp.isEmpty()) && (!tmp.startsWith("%")) && (found))
00329                                    {
00330                                           psFound = true;
00331                                           break;
00332                                    }
00333                                    if (tmp.startsWith("%%BoundingBox:"))
00334                                    {
00335                                           found = true;
00336                                           BBox = tmp.remove("%%BoundingBox:");
00337                                           if (BBox.contains("(atend)"))
00338                                                  found = false;
00339                                    }
00340                                    if (!found)
00341                                    {
00342                                           if (tmp.startsWith("%%BoundingBox"))
00343                                           {
00344                                                  found = true;
00345                                                  BBox = tmp.remove("%%BoundingBox");
00346                                                  if (BBox.contains("(atend)"))
00347                                                         found = false;
00348                                           }
00349                                    }
00350                                    if (tmp.startsWith("%ImageData: "))
00351                                    {
00352                                           hasPhotoshopImageData = true;
00353                                           tmp.remove("%ImageData: ");
00354                                           QTextStream ts2(&tmp, IO_ReadOnly);
00355                                           ts2 >> psXSize >> psYSize >> psDepth >> psMode >> psChannel >> psBlock >> psDataType >> psCommand;
00356                                           psCommand = psCommand.remove(0,1);
00357                                           psCommand = psCommand.remove(psCommand.length()-1,1);
00358                                    }
00359                                    if (tmp.startsWith("%BeginPhotoshop"))
00360                                    {
00361                                           QByteArray psdata;
00362                                           while (!ts.atEnd())
00363                                           {
00364                                                  tmp = ts.readLine();
00365                                                  if (tmp.startsWith("%EndPhotoshop"))
00366                                                  {
00367                                                         QDataStream strPhot(psdata,IO_ReadOnly);
00368                                                         strPhot.setByteOrder( QDataStream::BigEndian );
00369                                                         PSDHeader fakeHeader;
00370                                                         QTextStream ts2(&BBox, IO_ReadOnly);
00371                                                         ts2 >> x >> y >> b >> h;
00372                                                         fakeHeader.width = qRound(b);
00373                                                         fakeHeader.height = qRound(h);
00374                                                         parseRessourceData(strPhot, fakeHeader, psdata.size());
00375                                                         m_imageInfoRecord.valid = (m_imageInfoRecord.PDSpathData.size()) > 0 ? true : false;
00376                                                         isPhotoshop = true;
00377                                                         break;
00378                                                  }
00379                                                  for (uint a = 2; a < tmp.length(); a += 2)
00380                                                  {
00381                                                         bool ok;
00382                                                         ushort data = tmp.mid(a, 2).toUShort(&ok, 16);
00383                                                         psdata.resize(psdata.size()+1);
00384                                                         psdata[psdata.size()-1] = data;
00385                                                  }
00386                                           }
00387                                           if ((doThumbnail) && ((hasThumbnail) || (!m_imageInfoRecord.exifInfo.thumbnail.isNull())))
00388                                                  return true;
00389                                    }
00390                                    if (tmp.startsWith("%%BeginICCProfile:"))
00391                                    {
00392                                           QByteArray psdata;
00393                                           while (!ts.atEnd())
00394                                           {
00395                                                  tmp = ts.readLine();
00396                                                  for (uint a = 2; a < tmp.length(); a += 2)
00397                                                  {
00398                                                         bool ok;
00399                                                         ushort data = tmp.mid(a, 2).toUShort(&ok, 16);
00400                                                         psdata.resize(psdata.size()+1);
00401                                                         psdata[psdata.size()-1] = data;
00402                                                  }
00403                                                  if (tmp.startsWith("%%EndICCProfile"))
00404                                                  {
00405                                                         cmsHPROFILE prof = cmsOpenProfileFromMem(psdata.data(), psdata.size());
00406                                                         if (prof)
00407                                                         {
00408                                                                if (static_cast<int>(cmsGetColorSpace(prof)) == icSigRgbData)
00409                                                                       m_profileComponents = 3;
00410                                                                if (static_cast<int>(cmsGetColorSpace(prof)) == icSigCmykData)
00411                                                                       m_profileComponents = 4;
00412                                                                const char *Descriptor;
00413                                                                Descriptor = cmsTakeProductDesc(prof);
00414                                                                m_imageInfoRecord.profileName = QString(Descriptor);
00415                                                                m_imageInfoRecord.isEmbedded = true;
00416                                                                m_embeddedProfile.duplicate((const char*)psdata.data(), psdata.size());
00417                                                         }
00418                                                         cmsCloseProfile(prof);
00419                                                         break;
00420                                                  }
00421                                           }
00422                                    }
00423                                    if (psFound)
00424                                           break;
00425                             }
00426                      }
00427                      if (psFound)
00428                             break;
00429               }
00430        }
00431        f.close();
00432        return found;
00433 }
00434 
00435 bool ScImgDataLoader_PS::loadPicture(const QString& fn, int gsRes, bool thumbnail)
00436 {
00437        QStringList args;
00438        double x, y, b, h;
00439        bool found = false;
00440        QString tmp, dummy, cmd1, cmd2, tmp2;
00441        QFileInfo fi = QFileInfo(fn);
00442        if (!fi.exists())
00443               return false;
00444        QString ext = fi.extension(false).lower();
00445        if (ext.isEmpty())
00446               ext = getImageType(fn);
00447        QString tmpFile = QDir::convertSeparators(ScPaths::getTempFileDir() + "sc.png");
00448        QString picFile = QDir::convertSeparators(fn);
00449        float xres = gsRes;
00450        float yres = gsRes;
00451 
00452        initialize();
00453        m_imageInfoRecord.type = 3;
00454        m_imageInfoRecord.exifDataValid = false;
00455        doThumbnail = thumbnail;
00456        colorPlates2.clear();
00457        colorPlates.clear();
00458        CustColors.clear();
00459        CustColors.insert("Cyan", ScColor(255, 0, 0, 0));
00460        CustColors.insert("Magenta", ScColor(0, 255, 0, 0));
00461        CustColors.insert("Yellow", ScColor(0, 0, 255, 0));
00462        CustColors.insert("Black", ScColor(0, 0, 0, 255));
00463        found = parseData(fn);
00464        if (FontListe.count() != 0)
00465        {
00466               scanForFonts(fn);
00467               if (FontListe.count() != 0)
00468               {
00469                      bool missing = false;
00470                      QString missingF = "";
00471                      for (uint fo = 0; fo < FontListe.count(); fo++)
00472                      {
00473                             if (!PrefsManager::instance()->appPrefs.AvailFonts.contains(FontListe[fo]))
00474                             {
00475                                    missing = true;
00476                                    missingF += FontListe[fo]+"\n";
00477                             }
00478                      }
00479                      if (missing)
00480                      {
00481                             m_message = QObject::tr("The Font(s):\n%1 are not available.\nThey have been replaced by \"Courier\"\nTherefore the image may be not correct").arg(missingF);
00482                             m_msgType = warningMsg;
00483                      }
00484               }
00485        }
00486        if ((thumbnail) && (m_imageInfoRecord.exifDataValid) && (!m_imageInfoRecord.exifInfo.thumbnail.isNull()))
00487        {
00488               QTextStream ts2(&BBox, IO_ReadOnly);
00489               ts2 >> x >> y >> b >> h;
00490               m_imageInfoRecord.exifInfo.width = qRound(b);
00491               m_imageInfoRecord.exifInfo.height = qRound(h);
00492               m_image = m_imageInfoRecord.exifInfo.thumbnail;
00493               if ((isPhotoshop) && (hasPhotoshopImageData))
00494               {
00495                      m_imageInfoRecord.exifInfo.width = qRound(psXSize);
00496                      m_imageInfoRecord.exifInfo.height = qRound(psYSize);
00497                      m_imageInfoRecord.type = 7;
00498                      if (psMode == 4)
00499                      {
00500                             m_imageInfoRecord.colorspace = 1;
00501                             QRgb *s;
00502                             unsigned char cc, cm, cy, ck;
00503                             for( int yit=0; yit < m_image.height(); ++yit )
00504                             {
00505                                    s = (QRgb*)(m_image.scanLine( yit ));
00506                                    for(int xit=0; xit < m_image.width(); ++xit )
00507                                    {
00508                                           cc = 255 - qRed(*s);
00509                                           cm = 255 - qGreen(*s);
00510                                           cy = 255 - qBlue(*s);
00511                                           ck = QMIN(QMIN(cc, cm), cy);
00512                                           *s = qRgba(cc-ck,cm-ck,cy-ck,ck);
00513                                           s++;
00514                                    }
00515                             }
00516                      }
00517                      else
00518                             m_imageInfoRecord.colorspace = 0;
00519               }
00520               else
00521                      m_imageInfoRecord.colorspace = 0;
00522               return true;
00523        }
00524        if (found)
00525        {
00526               if (isDCS1)
00527                      loadDCS1(fn, gsRes);
00528               else if (isDCS2)
00529                      loadDCS2(fn, gsRes);
00530               else if ((isPhotoshop) && (hasPhotoshopImageData))
00531                      loadPhotoshop(fn, gsRes);
00532               else if ((!m_imageInfoRecord.isEmbedded) || ((m_imageInfoRecord.isEmbedded) && (m_profileComponents == 3)))
00533               {
00534                      QTextStream ts2(&BBox, IO_ReadOnly);
00535                      ts2 >> x >> y >> b >> h;
00536                      h = h * gsRes / 72.0;
00537                      QStringList args;
00538                      xres = gsRes;
00539                      yres = gsRes;
00540                      if ((ext == "eps") || (ext == "epsi"))
00541                             args.append("-dEPSCrop");
00542                      args.append("-r"+QString::number(gsRes));
00543                      args.append("-sOutputFile="+tmpFile);
00544                      args.append(picFile);
00545                      int retg = callGS(args);
00546                      if (retg == 0)
00547                      {
00548                             m_image.load(tmpFile);
00549                             m_image.setAlphaBuffer(true);
00550                             if (ScCore->havePNGAlpha() != 0)
00551                             {
00552                                    int wi = m_image.width();
00553                                    int hi = m_image.height();
00554                                    QRgb alphaFF = qRgba(255,255,255,255);
00555                                    QRgb alpha00 = qRgba(255,255,255,  0);
00556                                    QRgb *s;
00557                                    for( int yi=0; yi < hi; ++yi )
00558                                    {
00559                                           s = (QRgb*)(m_image.scanLine( yi ));
00560                                           for(int xi=0; xi < wi; ++xi )
00561                                           {
00562                                                  if((*s) == alphaFF)
00563                                                         (*s) &= alpha00;
00564                                                  s++;
00565                                           }
00566                                    }
00567                             }
00568                             unlink(tmpFile);
00569                             if ((ext == "eps") || (ext == "epsi"))
00570                             {
00571                                    m_imageInfoRecord.BBoxX = static_cast<int>(x);
00572                                    m_imageInfoRecord.BBoxH = static_cast<int>(h);
00573                                    x = x * gsRes / 72.0;
00574                                    y = y * gsRes / 72.0;
00575                                    b = b * gsRes / 72.0;
00576                                    if (((b - x) < m_image.width()) || ((h - y) < m_image.height()))
00577                                    {
00578                                           int yc = qRound(m_image.height() - y - (h-y));
00579                                           m_image = m_image.copy(qRound(x), yc, qRound(b - x), qRound(h - y));
00580                                    }
00581                             }
00582                             else
00583                             {
00584                                    m_imageInfoRecord.BBoxX = 0;
00585                                    m_imageInfoRecord.BBoxH = m_image.height();
00586                             }
00587                             m_imageInfoRecord.xres = qRound(gsRes);
00588                             m_imageInfoRecord.yres = qRound(gsRes);
00589                             if ((m_imageInfoRecord.isEmbedded) && (m_profileComponents == 3))
00590                                    m_imageInfoRecord.type = 7;
00591                             m_imageInfoRecord.colorspace = 0;
00592                             m_image.setDotsPerMeterX ((int) (xres / 0.0254));
00593                             m_image.setDotsPerMeterY ((int) (yres / 0.0254));
00594                      }
00595               }
00596               else
00597               {
00598                      QTextStream ts2(&BBox, IO_ReadOnly);
00599                      ts2 >> x >> y >> b >> h;
00600                      h = h * gsRes / 72.0;
00601                      QStringList args;
00602                      xres = gsRes;
00603                      yres = gsRes;
00604                      if ((ext == "eps") || (ext == "epsi"))
00605                             args.append("-dEPSCrop");
00606                      args.append("-dGrayValues=256");
00607                      args.append("-r"+QString::number(gsRes));
00608                      args.append("-sOutputFile="+tmpFile);
00609                      args.append(picFile);
00610                      int retg = callGS(args, "bitcmyk");
00611                      if (retg == 0)
00612                      {
00613                             m_image.create( qRound(b * gsRes / 72.0), qRound(h * gsRes / 72.0), 32 );
00614                             m_image.fill(qRgba(0, 0, 0, 0));
00615                             int w = qRound(b * gsRes / 72.0);
00616                             int w2 = 4*w;
00617                             int h2 = qRound(h * gsRes / 72.0);
00618                             uint *p;
00619                             int cyan, magenta, yellow, black;
00620                             QByteArray imgc(w2);
00621                             QFile f(tmpFile);
00622                             if (f.open(IO_ReadOnly))
00623                             {
00624                                    for (int y=0; y < h2; ++y )
00625                                    {
00626                                           p = (uint *)m_image.scanLine( y );
00627                                           f.readBlock(imgc.data(), w2);
00628                                           for (int x=0; x < w2; x += 4 )
00629                                           {
00630                                                  cyan = uchar(imgc[x]);
00631                                                  magenta = uchar(imgc[x + 1]);
00632                                                  yellow = uchar(imgc[x + 2]);
00633                                                  black = uchar(imgc[x + 3]);
00634                                                  *p = qRgba(cyan, magenta, yellow, black);
00635                                                  p++;
00636                                           }
00637                                    }
00638                                    f.close();
00639                             }
00640                             unlink(tmpFile);
00641                             if ((ext == "eps") || (ext == "epsi"))
00642                             {
00643                                    m_imageInfoRecord.BBoxX = static_cast<int>(x);
00644                                    m_imageInfoRecord.BBoxH = static_cast<int>(h);
00645                                    x = x * gsRes / 72.0;
00646                                    y = y * gsRes / 72.0;
00647                                    b = b * gsRes / 72.0;
00648                                    if (((b - x) < m_image.width()) || ((h - y) < m_image.height()))
00649                                    {
00650                                           int yc = qRound(m_image.height() - y - (h-y));
00651                                           m_image = m_image.copy(qRound(x), yc, qRound(b - x), qRound(h - y));
00652                                    }
00653                             }
00654                             else
00655                             {
00656                                    m_imageInfoRecord.BBoxX = 0;
00657                                    m_imageInfoRecord.BBoxH = m_image.height();
00658                             }
00659                             m_imageInfoRecord.xres = qRound(gsRes);
00660                             m_imageInfoRecord.yres = qRound(gsRes);
00661                             m_imageInfoRecord.colorspace = 1;
00662                             m_imageInfoRecord.type = 7;
00663                             m_image.setDotsPerMeterX ((int) (xres / 0.0254));
00664                             m_image.setDotsPerMeterY ((int) (yres / 0.0254));
00665                      }
00666               }
00667               return true;
00668        }
00669        return false;
00670 }
00671 
00672 void ScImgDataLoader_PS::loadPhotoshop(QString fn, int gsRes)
00673 {
00674        if ((psDataType >= 1) && (psDataType <= 6) && ((psMode == 3) || (psMode == 4)))
00675        {
00676               loadPhotoshopBinary(fn);
00677               return;
00678        }
00679        QStringList args;
00680        double x, y, b, h;
00681        QFileInfo fi = QFileInfo(fn);
00682        QString ext = fi.extension(false).lower();
00683        QString tmpFile = QDir::convertSeparators(ScPaths::getTempFileDir() + "sc.png");
00684        int retg;
00685        int GsMajor;
00686        int GsMinor;
00687        getNumericGSVersion(GsMajor, GsMinor);
00688        QTextStream ts2(&BBox, IO_ReadOnly);
00689        ts2 >> x >> y >> b >> h;
00690        h = h * gsRes / 72.0;
00691        if ((ext == "eps") || (ext == "epsi"))
00692               args.append("-dEPSCrop");
00693        if (psMode == 4)
00694               args.append("-dGrayValues=256");
00695        if ((GsMajor >= 8) && (GsMinor >= 53))
00696               args.append("-dNOPSICC");          // prevent GS from applying an embedded ICC profile as it will be applied later on in ScImage.
00697        args.append("-r"+QString::number(gsRes));
00698        args.append("-sOutputFile="+tmpFile);
00699        args.append(QDir::convertSeparators(fn));
00700        if (psMode == 4)
00701               retg = callGS(args, "bitcmyk");
00702        else
00703               retg = callGS(args);
00704        if (retg == 0)
00705        {
00706               if (psMode == 4)
00707               {
00708                      m_image.create( qRound(b * gsRes / 72.0), qRound(h * gsRes / 72.0), 32 );
00709                      m_image.fill(qRgba(0, 0, 0, 0));
00710                      int w = qRound(b * gsRes / 72.0);
00711                      int w2 = 4*w;
00712                      int h2 = qRound(h * gsRes / 72.0);
00713                      uint *p;
00714                      int cyan, magenta, yellow, black;
00715                      QByteArray imgc(w2);
00716                      QFile f(tmpFile);
00717                      if (f.open(IO_ReadOnly))
00718                      {
00719                             for (int y=0; y < h2; ++y )
00720                             {
00721                                    p = (uint *)m_image.scanLine( y );
00722                                    f.readBlock(imgc.data(), w2);
00723                                    for (int x=0; x < w2; x += 4 )
00724                                    {
00725                                           cyan = uchar(imgc[x]);
00726                                           magenta = uchar(imgc[x + 1]);
00727                                           yellow = uchar(imgc[x + 2]);
00728                                           black = uchar(imgc[x + 3]);
00729                                           *p = qRgba(cyan, magenta, yellow, black);
00730                                           p++;
00731                                    }
00732                             }
00733                             f.close();
00734                      }
00735                      m_imageInfoRecord.colorspace = 1;
00736                      m_imageInfoRecord.type = 7;
00737               }
00738               else
00739               {
00740                      m_image.load(tmpFile);
00741                      m_image.setAlphaBuffer(true);
00742                      if (ScCore->havePNGAlpha() != 0)
00743                      {
00744                             int wi = m_image.width();
00745                             int hi = m_image.height();
00746                             QRgb alphaFF = qRgba(255,255,255,255);
00747                             QRgb alpha00 = qRgba(255,255,255,  0);
00748                             QRgb *s;
00749                             for( int yi=0; yi < hi; ++yi )
00750                             {
00751                                    s = (QRgb*)(m_image.scanLine( yi ));
00752                                    for(int xi=0; xi < wi; ++xi )
00753                                    {
00754                                           if((*s) == alphaFF)
00755                                                  (*s) &= alpha00;
00756                                           s++;
00757                                    }
00758                             }
00759                      }
00760                      m_imageInfoRecord.type = 7;
00761                      m_imageInfoRecord.colorspace = 0;
00762               }
00763               unlink(tmpFile);
00764               if ((ext == "eps") || (ext == "epsi"))
00765               {
00766                      m_imageInfoRecord.BBoxX = static_cast<int>(x);
00767                      m_imageInfoRecord.BBoxH = static_cast<int>(h);
00768                      x = x * gsRes / 72.0;
00769                      y = y * gsRes / 72.0;
00770                      b = b * gsRes / 72.0;
00771                      if (((b - x) < m_image.width()) || ((h - y) < m_image.height()))
00772                      {
00773                             int yc = qRound(m_image.height() - y - (h-y));
00774                             m_image = m_image.copy(qRound(x), yc, qRound(b - x), qRound(h - y));
00775                      }
00776               }
00777               else
00778               {
00779                      m_imageInfoRecord.BBoxX = 0;
00780                      m_imageInfoRecord.BBoxH = m_image.height();
00781               }
00782               m_image.setDotsPerMeterX ((int) (m_imageInfoRecord.xres / 0.0254));
00783               m_image.setDotsPerMeterY ((int) (m_imageInfoRecord.yres / 0.0254));
00784        }
00785 }
00786 
00787 void ScImgDataLoader_PS::decodeA85(QByteArray &psdata, QString tmp)
00788 {
00789        uchar byte;
00790        ushort data;
00791        unsigned long sum = 0;
00792     int quintet = 0;
00793        for (uint c = 0; c < tmp.length(); c++)
00794        {
00795               byte = uchar(QChar(tmp.at(c)));
00796               if (byte >= '!' && byte <= 'u')
00797               {
00798                      sum = sum * 85 + ((unsigned long)byte - '!');
00799                      quintet++;
00800                      if (quintet == 5)
00801                      {
00802                             psdata.resize(psdata.size()+4);
00803                             data = sum >> 24;
00804                             psdata[psdata.size()-4] = data;
00805                             data = (sum >> 16) & 0xFF;
00806                             psdata[psdata.size()-3] = data;
00807                             data = (sum >> 8) & 0xFF;
00808                             psdata[psdata.size()-2] = data;
00809                             data = sum & 0xFF;
00810                             psdata[psdata.size()-1] = data;
00811                             quintet = 0;
00812                             sum = 0;
00813               }
00814               }
00815               else if (byte == 'z')
00816               {
00817                      psdata.resize(psdata.size()+4);
00818                      psdata[psdata.size()-4] = 0;
00819                      psdata[psdata.size()-3] = 0;
00820                      psdata[psdata.size()-2] = 0;
00821                      psdata[psdata.size()-1] = 0;
00822               }
00823               else if (byte == '~')
00824               {
00825                      if (quintet)
00826                      {
00827                             int i;
00828                             for (i = 0; i < 5 - quintet; i++)
00829                                    sum *= 85;
00830                             if (quintet > 1)
00831                                    sum += (0xFFFFFF >> ((quintet - 2) * 8));
00832                             for (i = 0; i < quintet - 1; i++)
00833                             {
00834                                    data = (sum >> (24 - 8 * i)) & 0xFF;
00835                                    psdata.resize(psdata.size()+1);
00836                                    psdata[psdata.size()-1] = data;
00837                             }
00838                             quintet = 0;
00839                      }
00840                      break;
00841               }
00842        }
00843 }
00844 
00845 typedef struct my_error_mgr
00846 {
00847        struct jpeg_error_mgr pub;            /* "public" fields */
00848        jmp_buf setjmp_buffer;  /* for return to caller */
00849 } *my_error_ptr;
00850 
00851 static void my_error_exit (j_common_ptr cinfo)
00852 {
00853        my_error_ptr myerr = (my_error_ptr) cinfo->err;
00854        (*cinfo->err->output_message) (cinfo);
00855        longjmp (myerr->setjmp_buffer, 1);
00856 }
00857 
00858 bool ScImgDataLoader_PS::loadPSjpeg(QString fn)
00859 {
00860        if (!QFile::exists(fn))
00861               return false;
00862        struct jpeg_decompress_struct cinfo;
00863        struct my_error_mgr         jerr;
00864        FILE     *infile;
00865        cinfo.err = jpeg_std_error (&jerr.pub);
00866        jerr.pub.error_exit = my_error_exit;
00867        infile = NULL;
00868        if (setjmp (jerr.setjmp_buffer))
00869        {
00870               jpeg_destroy_decompress (&cinfo);
00871               if (infile)
00872                      fclose (infile);
00873               return false;
00874        }
00875        jpeg_create_decompress (&cinfo);
00876        if ((infile = fopen (fn.local8Bit(), "rb")) == NULL)
00877               return false;
00878        jpeg_stdio_src(&cinfo, infile);
00879        jpeg_read_header(&cinfo, true);
00880        jpeg_start_decompress(&cinfo);
00881        if ( cinfo.output_components == 3 || cinfo.output_components == 4)
00882               m_image.create( cinfo.output_width, cinfo.output_height, 32 );
00883        else if ( cinfo.output_components == 1 )
00884        {
00885               m_image.create( cinfo.output_width, cinfo.output_height, 8, 256 );
00886               for (int i=0; i<256; i++)
00887                      m_image.setColor(i, qRgb(i,i,i));
00888        }
00889        if (!m_image.isNull())
00890        {
00891               uchar** lines = m_image.jumpTable();
00892               while (cinfo.output_scanline < cinfo.output_height)
00893                      (void) jpeg_read_scanlines(&cinfo, lines + cinfo.output_scanline, cinfo.output_height);
00894               if ( cinfo.output_components == 3 )
00895               {
00896                      uchar *in;
00897                      QRgb *out;
00898                      for (uint j=0; j<cinfo.output_height; j++)
00899                      {
00900                             in = m_image.scanLine(j) + cinfo.output_width * 3;
00901                             out = (QRgb*) m_image.scanLine(j);
00902                             for (uint i=cinfo.output_width; i--; )
00903                             {
00904                                    in -= 3;
00905                                    out[i] = qRgb(in[0], in[1], in[2]);
00906                             }
00907                      }
00908               }
00909               if ( cinfo.output_components == 4 )
00910               {
00911                      QRgb *ptr;
00912                      unsigned char c, m, y ,k;
00913                      unsigned char *p;
00914                      for (int i = 0; i < m_image.height(); i++)
00915                      {
00916                             ptr = (QRgb*)  m_image.scanLine(i);
00917                             if ((cinfo.jpeg_color_space == JCS_YCCK) || ((cinfo.jpeg_color_space == JCS_CMYK) && (cinfo.saw_Adobe_marker)))
00918                             {
00919                                    for (int j = 0; j <  m_image.width(); j++)
00920                                    {
00921                                           p = (unsigned char *) ptr;
00922                                           c = p[0];
00923                                           m = p[1];
00924                                           y =  p[2];
00925                                           k =  p[3];
00926                                           *ptr = qRgba(c, m, y, k);
00927                                           ptr++;
00928                                    }
00929                             }
00930                             else
00931                             {
00932                                    for (int j = 0; j <  m_image.width(); j++)
00933                                    {
00934                                           p = (unsigned char *) ptr;
00935                                           c = p[0];
00936                                           m = p[1];
00937                                           y =  p[2];
00938                                           k =  p[3];
00939                                           *ptr = qRgba(y, m, c, k);
00940                                           ptr++;
00941                                    }
00942                             }
00943                      }
00944               }
00945               if ( cinfo.output_components == 1 )
00946               {
00947                      QImage tmpImg = m_image.convertDepth(32);
00948                      m_image.create( cinfo.output_width, cinfo.output_height, 32 );
00949                      QRgb *s;
00950                      QRgb *d;
00951                      for( int yi=0; yi < tmpImg.height(); ++yi )
00952                      {
00953                             s = (QRgb*)(tmpImg.scanLine( yi ));
00954                             d = (QRgb*)(m_image.scanLine( yi ));
00955                             for(int xi=0; xi < tmpImg.width(); ++xi )
00956                             {
00957                                    (*d) = (*s);
00958                                    s++;
00959                                    d++;
00960                             }
00961                      }
00962               }
00963               m_image.setAlphaBuffer(true);
00964        }
00965        (void) jpeg_finish_decompress(&cinfo);
00966        fclose (infile);
00967        jpeg_destroy_decompress (&cinfo);
00968        return (!m_image.isNull());
00969 }
00970 
00971 bool ScImgDataLoader_PS::loadPSjpeg(QString fn, QImage &tmpImg)
00972 {
00973        if (!QFile::exists(fn))
00974               return false;
00975        struct jpeg_decompress_struct cinfo;
00976        struct my_error_mgr         jerr;
00977        FILE     *infile;
00978        cinfo.err = jpeg_std_error (&jerr.pub);
00979        jerr.pub.error_exit = my_error_exit;
00980        infile = NULL;
00981        if (setjmp (jerr.setjmp_buffer))
00982        {
00983               jpeg_destroy_decompress (&cinfo);
00984               if (infile)
00985                      fclose (infile);
00986               return false;
00987        }
00988        jpeg_create_decompress (&cinfo);
00989        if ((infile = fopen (fn.local8Bit(), "rb")) == NULL)
00990               return false;
00991        jpeg_stdio_src(&cinfo, infile);
00992        jpeg_read_header(&cinfo, true);
00993        jpeg_start_decompress(&cinfo);
00994        if ( cinfo.output_components == 3 || cinfo.output_components == 4)
00995               tmpImg.create( cinfo.output_width, cinfo.output_height, 32 );
00996        else if ( cinfo.output_components == 1 )
00997        {
00998               tmpImg.create( cinfo.output_width, cinfo.output_height, 8, 256 );
00999               for (int i=0; i<256; i++)
01000                      tmpImg.setColor(i, qRgb(i,i,i));
01001        }
01002        if (!tmpImg.isNull())
01003        {
01004               uchar** lines = tmpImg.jumpTable();
01005               while (cinfo.output_scanline < cinfo.output_height)
01006                      (void) jpeg_read_scanlines(&cinfo, lines + cinfo.output_scanline, cinfo.output_height);
01007               if ( cinfo.output_components == 3 )
01008               {
01009                      uchar *in;
01010                      QRgb *out;
01011                      for (uint j=0; j<cinfo.output_height; j++)
01012                      {
01013                             in = tmpImg.scanLine(j) + cinfo.output_width * 3;
01014                             out = (QRgb*) tmpImg.scanLine(j);
01015                             for (uint i=cinfo.output_width; i--; )
01016                             {
01017                                    in -= 3;
01018                                    out[i] = qRgb(in[0], in[1], in[2]);
01019                             }
01020                      }
01021               }
01022               if ( cinfo.output_components == 4 )
01023               {
01024                      QRgb *ptr;
01025                      unsigned char c, m, y ,k;
01026                      unsigned char *p;
01027                      for (int i = 0; i < tmpImg.height(); i++)
01028                      {
01029                             ptr = (QRgb*)  tmpImg.scanLine(i);
01030                             if ((cinfo.jpeg_color_space == JCS_YCCK) || ((cinfo.jpeg_color_space == JCS_CMYK) && (cinfo.saw_Adobe_marker)))
01031                             {
01032                                    for (int j = 0; j <  tmpImg.width(); j++)
01033                                    {
01034                                           p = (unsigned char *) ptr;
01035                                           c = p[0];
01036                                           m = p[1];
01037                                           y =  p[2];
01038                                           k =  p[3];
01039                                           *ptr = qRgba(c, m, y, k);
01040                                           ptr++;
01041                                    }
01042                             }
01043                             else
01044                             {
01045                                    for (int j = 0; j <  tmpImg.width(); j++)
01046                                    {
01047                                           p = (unsigned char *) ptr;
01048                                           c = p[0];
01049                                           m = p[1];
01050                                           y =  p[2];
01051                                           k =  p[3];
01052                                           *ptr = qRgba(y, m, c, k);
01053                                           ptr++;
01054                                    }
01055                             }
01056                      }
01057               }
01058               if ( cinfo.output_components == 1 )
01059               {
01060                      QImage tmpImg2 = tmpImg.convertDepth(32);
01061                      tmpImg.create( cinfo.output_width, cinfo.output_height, 32 );
01062                      QRgb *s;
01063                      QRgb *d;
01064                      for( int yi=0; yi < tmpImg2.height(); ++yi )
01065                      {
01066                             s = (QRgb*)(tmpImg2.scanLine( yi ));
01067                             d = (QRgb*)(tmpImg.scanLine( yi ));
01068                             for(int xi=0; xi < tmpImg2.width(); ++xi )
01069                             {
01070                                    (*d) = (*s);
01071                                    s++;
01072                                    d++;
01073                             }
01074                      }
01075               }
01076               tmpImg.setAlphaBuffer(true);
01077        }
01078        (void) jpeg_finish_decompress(&cinfo);
01079        fclose (infile);
01080        jpeg_destroy_decompress (&cinfo);
01081        return (!tmpImg.isNull());
01082 }
01083 
01084 void ScImgDataLoader_PS::loadPhotoshopBinary(QString fn)
01085 {
01086        double x, y, b, h;
01087        QTextStream ts2(&BBox, IO_ReadOnly);
01088        ts2 >> x >> y >> b >> h;
01089        QFileInfo fi = QFileInfo(fn);
01090        QString ext = fi.extension(false).lower();
01091        QString tmpFile = QDir::convertSeparators(ScPaths::getTempFileDir() + "sc.jpg");
01092        QFile f2(tmpFile);
01093        QString tmp;
01094        m_image.create(psXSize, psYSize, 32);
01095        m_image.fill(qRgba(0, 0, 0, 0));
01096        m_imageInfoRecord.xres = qRound(psXSize / b * 72.0);
01097        m_imageInfoRecord.yres = qRound(psYSize / h * 72.0);
01098        QByteArray psdata;
01099        QFile f(fn);
01100        int yCount = 0;
01101        if (f.open(IO_ReadOnly))
01102        {
01103               if (psDataType > 2)
01104               {
01105                      f2.open(IO_WriteOnly);
01106               }
01107               QTextStream ts(&f);
01108               while (!ts.atEnd())
01109               {
01110                      tmp = ts.readLine();
01111                      if (tmp == psCommand)
01112                      {
01113                             if (psDataType == 1)
01114                             {
01115                                    QRgb *p;
01116                                    uchar cc, cm, cy, ck;
01117                                    for (int yh = 0; yh < m_image.height(); ++yh )
01118                                    {
01119                                           if (psMode == 4)
01120                                                  psdata.resize(psXSize * (4 + psChannel));
01121                                           else
01122                                                  psdata.resize(psXSize * (3 + psChannel));
01123                                           f.readBlock(psdata.data(), psdata.size());
01124                                           p = (QRgb *)m_image.scanLine( yh );
01125                                           for (int xh = 0; xh < m_image.width(); ++xh )
01126                                           {
01127                                                  cc = psdata[xh];
01128                                                  cm = psdata[psXSize+xh];
01129                                                  cy = psdata[psXSize*2+xh];
01130                                                  ck = psdata[psXSize*3+xh];
01131                                                  if (psMode == 4)
01132                                                         *p = qRgba(cc, cm, cy, ck);
01133                                                  else
01134                                                         *p = qRgba(cc, cm, cy, 255);
01135                                                  p++;
01136                                           }
01137                                    }
01138                             }
01139                             else if (psDataType > 1)
01140                             {
01141                                    while (!ts.atEnd())
01142                                    {
01143                                           tmp = ts.readLine();
01144                                           if ((tmp.isEmpty()) || (tmp.startsWith("%%EndBinary")))
01145                                                  break;
01146                                           if (psDataType == 2)
01147                                           {
01148                                                  for (uint a = 0; a < tmp.length(); a += 2)
01149                                                  {
01150                                                         bool ok;
01151                                                         ushort data = tmp.mid(a, 2).toUShort(&ok, 16);
01152                                                         psdata.resize(psdata.size()+1);
01153                                                         psdata[psdata.size()-1] = data;
01154                                                  }
01155                                           }
01156                                           else
01157                                           {
01158                                                  decodeA85(psdata, tmp);
01159                                                  f2.writeBlock(psdata.data(), psdata.size());
01160                                                  psdata.resize(0);
01161                                           }
01162                                    }
01163                                    if (psDataType > 2)
01164                                    {
01165                                           f2.close();
01166                                           loadPSjpeg(tmpFile);
01167                                           unlink(tmpFile);
01168                                    }
01169                                    else
01170                                    {
01171                                           QRgb *p;
01172                                           uchar cc, cm, cy, ck;
01173                                           for (int yh = 0; yh < m_image.height(); ++yh )
01174                                           {
01175                                                  p = (QRgb *)m_image.scanLine( yh );
01176                                                  for (int xh = 0; xh < m_image.width(); ++xh )
01177                                                  {
01178                                                         cc = psdata[yCount+xh];
01179                                                         cm = psdata[yCount+psXSize+xh];
01180                                                         cy = psdata[yCount+psXSize*2+xh];
01181                                                         if (psMode == 4)
01182                                                         {
01183                                                                ck = psdata[yCount+psXSize*3+xh];
01184                                                                *p = qRgba(cc, cm, cy, ck);
01185                                                         }
01186                                                         else
01187                                                                *p = qRgba(cc, cm, cy, 255);
01188                                                         p++;
01189                                                  }
01190                                                  if (psMode == 4)
01191                                                         yCount += psXSize * (4 + psChannel);
01192                                                  else
01193                                                         yCount += psXSize * (3 + psChannel);
01194                                           }
01195                                    }
01196                             }
01197                             if (psMode == 4)
01198                                    m_imageInfoRecord.colorspace = 1;
01199                             else
01200                                    m_imageInfoRecord.colorspace = 0;
01201                             m_imageInfoRecord.type = 7;
01202                             m_imageInfoRecord.BBoxX = 0;
01203                             m_imageInfoRecord.BBoxH = m_image.height();
01204                             m_image.setDotsPerMeterX ((int) (m_imageInfoRecord.xres / 0.0254));
01205                             m_image.setDotsPerMeterY ((int) (m_imageInfoRecord.yres / 0.0254));
01206                             f.close();
01207                             return;
01208                      }
01209               }
01210               f.close();
01211        }
01212 }
01213 
01214 void ScImgDataLoader_PS::loadPhotoshopBinary(QString fn, QImage &tmpImg)
01215 {
01216        double x, y, b, h;
01217        QTextStream ts2(&BBox, IO_ReadOnly);
01218        ts2 >> x >> y >> b >> h;
01219        QFileInfo fi = QFileInfo(fn);
01220        QString ext = fi.extension(false).lower();
01221        QString tmpFile = QDir::convertSeparators(ScPaths::getTempFileDir() + "sc.jpg");
01222        QFile f2(tmpFile);
01223        QString tmp;
01224        tmpImg.create(psXSize, psYSize, 32);
01225        tmpImg.fill(qRgba(0, 0, 0, 0));
01226        QByteArray psdata;
01227        QFile f(fn);
01228        int yCount = 0;
01229        if (f.open(IO_ReadOnly))
01230        {
01231               if (psDataType > 2)
01232               {
01233                      f2.open(IO_WriteOnly);
01234               }
01235               QTextStream ts(&f);
01236               while (!ts.atEnd())
01237               {
01238                      tmp = ts.readLine();
01239                      if (tmp == psCommand)
01240                      {
01241                             if (psDataType == 1)
01242                             {
01243                                    QRgb *p;
01244                                    uchar cc, cm, cy, ck;
01245                                    for (int yh = 0; yh < tmpImg.height(); ++yh )
01246                                    {
01247                                           if (psMode == 4)
01248                                                  psdata.resize(psXSize * (4 + psChannel));
01249                                           else
01250                                                  psdata.resize(psXSize * (3 + psChannel));
01251                                           f.readBlock(psdata.data(), psdata.size());
01252                                           p = (QRgb *)tmpImg.scanLine( yh );
01253                                           for (int xh = 0; xh < tmpImg.width(); ++xh )
01254                                           {
01255                                                  cc = psdata[xh];
01256                                                  cm = psdata[psXSize+xh];
01257                                                  cy = psdata[psXSize*2+xh];
01258                                                  if (psMode == 4)
01259                                                  {
01260                                                         ck = psdata[psXSize*3+xh];
01261                                                         *p = qRgba(cc, cm, cy, ck);
01262                                                  }
01263                                                  else
01264                                                         *p = qRgba(cc, cm, cy, 255);
01265                                                  p++;
01266                                           }
01267                                    }
01268                             }
01269                             else if (psDataType > 1)
01270                             {
01271                                    while (!ts.atEnd())
01272                                    {
01273                                           tmp = ts.readLine();
01274                                           if ((tmp.isEmpty()) || (tmp.startsWith("%%EndBinary")))
01275                                                  break;
01276                                           if (psDataType == 2)
01277                                           {
01278                                                  for (uint a = 0; a < tmp.length(); a += 2)
01279                                                  {
01280                                                         bool ok;
01281                                                         ushort data = tmp.mid(a, 2).toUShort(&ok, 16);
01282                                                         psdata.resize(psdata.size()+1);
01283                                                         psdata[psdata.size()-1] = data;
01284                                                  }
01285                                           }
01286                                           else
01287                                           {
01288                                                  decodeA85(psdata, tmp);
01289                                                  f2.writeBlock(psdata.data(), psdata.size());
01290                                                  psdata.resize(0);
01291                                           }
01292                                    }
01293                                    if (psDataType > 2)
01294                                    {
01295                                           f2.close();
01296                                           loadPSjpeg(tmpFile, tmpImg);
01297                                           unlink(tmpFile);
01298                                    }
01299                                    else
01300                                    {
01301                                           QRgb *p;
01302                                           uchar cc, cm, cy, ck;
01303                                           for (int yh = 0; yh < tmpImg.height(); ++yh )
01304                                           {
01305                                                  p = (QRgb *)tmpImg.scanLine( yh );
01306                                                  for (int xh = 0; xh < tmpImg.width(); ++xh )
01307                                                  {
01308                                                         cc = psdata[yCount+xh];
01309                                                         cm = psdata[yCount+psXSize+xh];
01310                                                         cy = psdata[yCount+psXSize*2+xh];
01311                                                         if (psMode == 4)
01312                                                         {
01313                                                                ck = psdata[yCount+psXSize*3+xh];
01314                                                                *p = qRgba(cc, cm, cy, ck);
01315                                                         }
01316                                                         else
01317                                                                *p = qRgba(cc, cm, cy, 255);
01318                                                         p++;
01319                                                  }
01320                                                  if (psMode == 4)
01321                                                         yCount += psXSize * (4 + psChannel);
01322                                                  else
01323                                                         yCount += psXSize * (3 + psChannel);
01324                                           }
01325                                    }
01326                             }
01327                             f.close();
01328                             return;
01329                      }
01330               }
01331               f.close();
01332        }
01333 }
01334 
01335 void ScImgDataLoader_PS::loadDCS2(QString fn, int gsRes)
01336 {
01337        QStringList args;
01338        double x, y, b, h;
01339        QFileInfo fi = QFileInfo(fn);
01340        QString ext = fi.extension(false).lower();
01341        QString tmpFile = QDir::convertSeparators(ScPaths::getTempFileDir() + "sc.png");
01342        QString tmpFile2 = QDir::convertSeparators(ScPaths::getTempFileDir() + "tmp.eps");
01343        QString baseFile = fi.dirPath(true);
01344        QString picFile = QDir::convertSeparators(fn);
01345        float xres = gsRes;
01346        float yres = gsRes;
01347        QTextStream ts2(&BBox, IO_ReadOnly);
01348        ts2 >> x >> y >> b >> h;
01349        xres = gsRes;
01350        yres = gsRes;
01351        if ((isPhotoshop) && (hasPhotoshopImageData))
01352        {
01353               m_image.create(psXSize, psYSize, 32);
01354               xres = psXSize / b * 72.0;
01355               yres = psYSize / h * 72.0;
01356        }
01357        else
01358               m_image.create( qRound(b * gsRes / 72.0), qRound(h * gsRes / 72.0), 32 );
01359        m_image.fill(qRgba(0, 0, 0, 0));
01360        if (!isDCS2multi)
01361        {
01362               for (QMap<QString, plateOffsets>::Iterator it = colorPlates2.begin(); it != colorPlates2.end(); ++it)
01363               {
01364                      QByteArray imgc(it.data().len);
01365                      QFile f(picFile);
01366                      if (f.open(IO_ReadOnly))
01367                      {
01368                             f.at(it.data().pos);
01369                             uint readB = f.readBlock(imgc.data(), it.data().len);
01370                             readB = 0;
01371                      }
01372                      f.close();
01373                      QFile f2(tmpFile2);
01374                      if (f2.open(IO_WriteOnly))
01375                             f2.writeBlock(imgc.data(), it.data().len);
01376                      f2.close();
01377                      imgc.resize(0);
01378                      if ((isPhotoshop) && (hasPhotoshopImageData))
01379                      {
01380                             QImage tmpImg;
01381                             loadPhotoshopBinary(tmpFile2, tmpImg);
01382                             blendImages(tmpImg, CustColors[it.key()]);
01383                      }
01384                      else
01385                      {
01386                             args.append("-dEPSCrop");
01387                             args.append("-r"+QString::number(gsRes));
01388                             args.append("-sOutputFile="+tmpFile);
01389                             args.append(tmpFile2);
01390                             int retg = callGS(args);
01391                             if (retg == 0)
01392                             {
01393                                    QImage tmpImg;
01394                                    tmpImg.load(tmpFile);
01395                                    blendImages(tmpImg, CustColors[it.key()]);
01396                                    unlink(tmpFile);
01397                             }
01398                      }
01399                      unlink(tmpFile2);
01400               }
01401        }
01402        else
01403        {
01404               for (QMap<QString, QString>::Iterator it = colorPlates.begin(); it != colorPlates.end(); ++it)
01405               {
01406                      tmpFile2 = QDir::convertSeparators(baseFile+"/"+it.data());
01407                      if ((isPhotoshop) && (hasPhotoshopImageData))
01408                      {
01409                             QImage tmpImg;
01410                             loadPhotoshopBinary(tmpFile2, tmpImg);
01411                             blendImages(tmpImg, CustColors[it.key()]);
01412                      }
01413                      else
01414                      {
01415                             args.append("-dEPSCrop");
01416                             args.append("-r"+QString::number(gsRes));
01417                             args.append("-sOutputFile="+tmpFile);
01418                             args.append(tmpFile2);
01419                             int retg = callGS(args);
01420                             if (retg == 0)
01421                             {
01422                                    QImage tmpImg;
01423                                    tmpImg.load(tmpFile);
01424                                    blendImages(tmpImg, CustColors[it.key()]);
01425                                    unlink(tmpFile);
01426                             }
01427                             args.clear();
01428                      }
01429               }
01430        }
01431        if ((ext == "eps") || (ext == "epsi"))
01432        {
01433               m_imageInfoRecord.BBoxX = static_cast<int>(x);
01434               m_imageInfoRecord.BBoxH = static_cast<int>(h);
01435               x = x * gsRes / 72.0;
01436               y = y * gsRes / 72.0;
01437               b = b * gsRes / 72.0;
01438               if (((b - x) < m_image.width()) || ((h - y) < m_image.height()))
01439               {
01440                      int yc = qRound(m_image.height() - y - (h-y));
01441                      m_image = m_image.copy(qRound(x), yc, qRound(b - x), qRound(h - y));
01442               }
01443        }
01444        else
01445        {
01446               m_imageInfoRecord.BBoxX = 0;
01447               m_imageInfoRecord.BBoxH = m_image.height();
01448        }
01449        m_imageInfoRecord.xres = qRound(xres);
01450        m_imageInfoRecord.yres = qRound(yres);
01451        m_imageInfoRecord.colorspace = 1;
01452        m_imageInfoRecord.type = 7;
01453        m_image.setDotsPerMeterX ((int) (xres / 0.0254));
01454        m_image.setDotsPerMeterY ((int) (yres / 0.0254));
01455 }
01456 
01457 void ScImgDataLoader_PS::loadDCS1(QString fn, int gsRes)
01458 {
01459        QStringList args;
01460        double x, y, b, h;
01461        QFileInfo fi = QFileInfo(fn);
01462        QString ext = fi.extension(false).lower();
01463        QString tmpFile = QDir::convertSeparators(ScPaths::getTempFileDir() + "sc.png");
01464        QString baseFile = fi.dirPath(true);
01465        QString picFile;
01466        float xres = gsRes;
01467        float yres = gsRes;
01468        QTextStream ts2(&BBox, IO_ReadOnly);
01469        ts2 >> x >> y >> b >> h;
01470        xres = gsRes;
01471        yres = gsRes;
01472        m_image.create( qRound(b * gsRes / 72.0), qRound(h * gsRes / 72.0), 32 );
01473        m_image.fill(qRgba(0, 0, 0, 0));
01474        if ((ext == "eps") || (ext == "epsi"))
01475               args.append("-dEPSCrop");
01476        args.append("-r"+QString::number(gsRes));
01477        args.append("-sOutputFile="+tmpFile);
01478        picFile = QDir::convertSeparators(baseFile+"/"+colorPlates["Cyan"]);
01479        args.append(picFile);
01480        int retg = callGS(args);
01481        if (retg == 0)
01482        {
01483               QImage tmpImg;
01484               tmpImg.load(tmpFile);
01485               blendImages(tmpImg, ScColor(255, 0, 0, 0));
01486               unlink(tmpFile);
01487        }
01488        args.clear();
01489 
01490        if ((ext == "eps") || (ext == "epsi"))
01491               args.append("-dEPSCrop");
01492        args.append("-r"+QString::number(gsRes));
01493        args.append("-sOutputFile="+tmpFile);
01494        picFile = QDir::convertSeparators(baseFile+"/"+colorPlates["Magenta"]);
01495        args.append(picFile);
01496        retg = callGS(args);
01497        if (retg == 0)
01498        {
01499               QImage tmpImg;
01500               tmpImg.load(tmpFile);
01501               blendImages(tmpImg, ScColor(0, 255, 0, 0));
01502               unlink(tmpFile);
01503        }
01504        args.clear();
01505 
01506        if ((ext == "eps") || (ext == "epsi"))
01507               args.append("-dEPSCrop");
01508        args.append("-r"+QString::number(gsRes));
01509        args.append("-sOutputFile="+tmpFile);
01510        picFile = QDir::convertSeparators(baseFile+"/"+colorPlates["Yellow"]);
01511        args.append(picFile);
01512        retg = callGS(args);
01513        if (retg == 0)
01514        {
01515               QImage tmpImg;
01516               tmpImg.load(tmpFile);
01517               blendImages(tmpImg, ScColor(0, 0, 255, 0));
01518               unlink(tmpFile);
01519        }
01520        args.clear();
01521 
01522        if ((ext == "eps") || (ext == "epsi"))
01523               args.append("-dEPSCrop");
01524        args.append("-r"+QString::number(gsRes));
01525        args.append("-sOutputFile="+tmpFile);
01526        picFile = QDir::convertSeparators(baseFile+"/"+colorPlates["Black"]);
01527        args.append(picFile);
01528        retg = callGS(args);
01529        if (retg == 0)
01530        {
01531               QImage tmpImg;
01532               tmpImg.load(tmpFile);
01533               blendImages(tmpImg, ScColor(0, 0, 0, 255));
01534               unlink(tmpFile);
01535        }
01536        args.clear();
01537 
01538        if ((ext == "eps") || (ext == "epsi"))
01539        {
01540               m_imageInfoRecord.BBoxX = static_cast<int>(x);
01541               m_imageInfoRecord.BBoxH = static_cast<int>(h);
01542               x = x * gsRes / 72.0;
01543               y = y * gsRes / 72.0;
01544               b = b * gsRes / 72.0;
01545               if (((b - x) < m_image.width()) || ((h - y) < m_image.height()))
01546               {
01547                      int yc = qRound(m_image.height() - y - (h-y));
01548                      m_image = m_image.copy(qRound(x), yc, qRound(b - x), qRound(h - y));
01549               }
01550        }
01551        else
01552        {
01553               m_imageInfoRecord.BBoxX = 0;
01554               m_imageInfoRecord.BBoxH = m_image.height();
01555        }
01556        m_imageInfoRecord.xres = qRound(gsRes);
01557        m_imageInfoRecord.yres = qRound(gsRes);
01558        m_imageInfoRecord.colorspace = 1;
01559        m_imageInfoRecord.type = 7;
01560        m_image.setDotsPerMeterX ((int) (xres / 0.0254));
01561        m_image.setDotsPerMeterY ((int) (yres / 0.0254));
01562 }
01563 
01564 void ScImgDataLoader_PS::blendImages(QImage &source, ScColor col)
01565 {
01566        int h = source.height();
01567        int w = source.width();
01568        int cyan, c, m, yc, k, cc, mm, yy, kk;
01569        col.getCMYK(&c, &m, &yc, &k);
01570        QRgb *p;
01571        QRgb *pq;
01572        for (int y=0; y < h; ++y )
01573        {
01574               p = (QRgb *)m_image.scanLine( y );
01575               pq = (QRgb *)source.scanLine( y );
01576               for (int x=0; x < w; ++x )
01577               {
01578                      cyan = 255 - qRed(*pq);
01579                      if (cyan != 0)
01580                      {
01581                             (c == 0) ? cc = qRed(*p) : cc = QMIN(c * cyan / 255 + qRed(*p), 255);
01582                             (m == 0) ? mm = qGreen(*p) : mm = QMIN(m * cyan / 255 + qGreen(*p), 255);
01583                             (yc == 0) ? yy = qBlue(*p) : yy = QMIN(yc * cyan / 255 + qBlue(*p), 255);
01584                             (k == 0) ? kk = qAlpha(*p) : kk = QMIN(k * cyan / 255 + qAlpha(*p), 255);
01585                             *p = qRgba(cc, mm, yy, kk);
01586                      }
01587                      p++;
01588                      pq++;
01589               }
01590        }
01591 }
01592 
01593 void ScImgDataLoader_PS::preloadAlphaChannel(const QString& fn, int gsRes)
01594 {
01595        float xres, yres;
01596 //     short resolutionunit = 0;
01597        initialize();
01598        QFileInfo fi = QFileInfo(fn);
01599        if (!fi.exists())
01600               return;
01601        QString tmp, BBox, tmp2;
01602        QString ext = fi.extension(false).lower();
01603        QString tmpFile = QDir::convertSeparators(ScPaths::getTempFileDir() + "sc.png");
01604        QString picFile = QDir::convertSeparators(fn);
01605        double x, y, b, h;
01606        bool found = false;
01607 //     int retg = -1;
01608        QChar tc;
01609        
01610        QFile f(fn);
01611        if (f.open(IO_ReadOnly))
01612        {
01613               QTextStream ts(&f);
01614               while (!ts.atEnd())
01615               {
01616                      tc = ' ';
01617                      tmp = "";
01618                      while ((tc != '\n') && (tc != '\r'))
01619                      {
01620                             ts >> tc;
01621                             if ((tc != '\n') && (tc != '\r'))
01622                                    tmp += tc;
01623                      }
01624                      if (tmp.startsWith("%%BoundingBox:"))
01625                      {
01626                             found = true;
01627                             BBox = tmp.remove("%%BoundingBox:");
01628                             if (BBox.contains("(atend)"))
01629                                    found = false;
01630                      }
01631                      if (!found)
01632                      {
01633                             if (tmp.startsWith("%%BoundingBox"))
01634                             {
01635                                    found = true;
01636                                    BBox = tmp.remove("%%BoundingBox");
01637                                    if (BBox.contains("(atend)"))
01638                                           found = false;
01639                             }
01640                      }
01641                      if ((tmp.startsWith("%%EndComments")) && (found))
01642                             break;
01643               }
01644        }
01645        f.close();
01646        if (found)
01647        {
01648               QTextStream ts2(&BBox, IO_ReadOnly);
01649               ts2 >> x >> y >> b >> h;
01650               h = h * gsRes / 72.0;
01651               QStringList args;
01652               xres = gsRes;
01653               yres = gsRes;
01654               if ((ext == "eps") || (ext == "epsi"))
01655                      args.append("-dEPSCrop");
01656               args.append("-r"+QString::number(gsRes));
01657               args.append("-sOutputFile="+tmpFile);
01658               args.append(picFile);
01659               int retg = callGS(args);
01660               if (retg == 0)
01661               {
01662                      m_image.load(tmpFile);
01663                      m_image.setAlphaBuffer(true);
01664                      if (ScCore->havePNGAlpha() != 0)
01665                      {
01666                             int wi = m_image.width();
01667                             int hi = m_image.height();
01668                             QRgb alphaFF = qRgba(255,255,255,255);
01669                             QRgb alpha00 = qRgba(255,255,255,  0);
01670                             QRgb *s;
01671                             for( int yi=0; yi < hi; ++yi )
01672                             {
01673                                    s = (QRgb*)(m_image.scanLine( yi ));
01674                                    for(int xi=0; xi < wi; ++xi )
01675                                    {
01676                                           if((*s) == alphaFF)
01677                                                  (*s) &= alpha00;
01678                                           s++;
01679                                    }
01680                             }
01681                      }
01682                      if ((ext == "eps") || (ext == "epsi"))
01683                      {
01684                             x = x * gsRes / 72.0;
01685                             y = y * gsRes / 72.0;
01686                             b = b * gsRes / 72.0;
01687                             if (((b - x) < m_image.width()) || ((h - y) < m_image.height()))
01688                             {
01689                                    int yc = qRound(m_image.height() - y - (h-y));
01690                                    m_image = m_image.copy(qRound(x), yc, qRound(b - x), qRound(h - y));
01691                             }
01692                      }
01693                      m_image.setAlphaBuffer(true);
01694                      unlink(tmpFile);
01695               }
01696        }
01697 }