Back to index

scribus-ng  1.3.4.dfsg+svn20071115
scimgdataloader.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 "scimgdataloader.h"
00008 
00009 ScImgDataLoader::ScImgDataLoader(void)
00010 {
00011        initialize();
00012 }
00013 
00014 void ScImgDataLoader::initialize(void)
00015 {
00016        m_msgType = noMsg;
00017        m_message.setLength(0);
00018        m_image = QImage();
00019        m_imageInfoRecord.init();
00020        m_embeddedProfile.resize(0);
00021        m_profileComponents = 0;
00022 }
00023 
00024 void ScImgDataLoader::setRequest(bool valid, QMap<int, ImageLoadRequest> req)
00025 {
00026        m_imageInfoRecord.RequestProps = req;
00027        m_imageInfoRecord.isRequest = valid;
00028 }
00029 
00030 bool ScImgDataLoader::supportFormat(const QString& fmt) 
00031 {
00032        QString format = fmt.lower();
00033        return (m_supportedFormats.contains(format));
00034 }
00035 
00036 QString ScImgDataLoader::getPascalString(QDataStream & s)
00037 {
00038        uchar len, tmp;
00039        uint adj;
00040        QString ret = "";
00041        s >> len;
00042        if (len == 0)
00043        {
00044               s >> tmp;
00045               return ret;
00046        }
00047        for( int i = 0; i < len; i++ )
00048        {
00049               s >> tmp;
00050               ret += QChar(tmp);
00051        }
00052        adj = (ret.length()+1) % 2;
00053        s.device()->at( s.device()->at() + adj );
00054        return ret;
00055 }
00056 
00057 void ScImgDataLoader::swapRGBA()
00058 {
00059        for (int i = 0; i < m_image.height(); ++i)
00060        {
00061               unsigned int *ptr = (unsigned int *) m_image.scanLine(i);
00062               unsigned char r, b;
00063               for (int j = 0; j < m_image.width(); ++j)
00064               {
00065                      unsigned char *p = (unsigned char *) ptr;
00066                      r = p[0];
00067                      b = p[2];
00068                      p[2] = r;
00069                      p[0] = b;
00070                      ptr++;
00071               }
00072        }
00073 }
00074 
00075 void ScImgDataLoader::swapRGBA(QImage *img)
00076 {
00077        for (int i = 0; i < img->height(); ++i)
00078        {
00079               unsigned int *ptr = (unsigned int *) img->scanLine(i);
00080               unsigned char r, b;
00081               for (int j = 0; j < img->width(); ++j)
00082               {
00083                      unsigned char *p = (unsigned char *) ptr;
00084                      r = p[0];
00085                      b = p[2];
00086                      p[2] = r;
00087                      p[0] = b;
00088                      ptr++;
00089               }
00090        }
00091 }
00092 
00093 void ScImgDataLoader::parseRessourceData( QDataStream & s, const PSDHeader & header, uint size )
00094 {
00095        uint signature, resSize, offset, resBase, vRes, hRes, adj;
00096        ushort resID, hResUnit, vResUnit, dummyW;
00097        QString resName;
00098        uchar filler;
00099        offset = 0;
00100        bool first = false;
00101        bool pathOpen = false;
00102        FPoint firstPoint, firstControl;
00103        FPointArray clip2;
00104        while ((offset + 6)< size)
00105        {
00106               s >> signature;
00107               offset += 4;
00108               if(((signature >> 24)&0xff) != '8' ||
00109                       ((signature >> 16)&0xff) != 'B' ||
00110                       ((signature >> 8)&0xff) != 'I' ||
00111                       ((signature )&0xff) != 'M' )
00112                      break;
00113               s >> resID;
00114               offset += 2;
00115               adj = s.device()->at();
00116               resName = getPascalString(s);
00117               offset += s.device()->at() - adj;
00118               s >> resSize;
00119               if(offset + resSize > size)
00120                      break;
00121               resBase = s.device()->at();
00122               if ( (resID >= 0x07d0) && (resID <= 0x0bb6) )
00123               {
00124                      QString db1, db2;
00125                      short type;
00126                      uint data1, data2, data3, data4, data5, data6;
00127                      double frac1, frac2, frac3, frac4, frac5, frac6;
00128                      ushort man1, man2, man3, man4, man5, man6;
00129                      uint offset2;
00130                      offset2 = 0;
00131                      first = false;
00132                      pathOpen = false;
00133                      clip2.resize(0);
00134                      while (offset2 < resSize)
00135                      {
00136                             s >> type;
00137                             s >> data1;
00138                             frac1 = (data1 & 0x00FFFFFF) / 16777215.0;
00139                             man1 = (data1 & 0x0F000000) >> 24;
00140                             frac1 = (frac1 + man1) * header.height;
00141                             s >> data2;
00142                             frac2 = (data2 & 0x00FFFFFF) / 16777215.0;
00143                             man2 = (data2 & 0x0F000000) >> 24;
00144                             frac2 = (frac2 + man2) * header.width;
00145                             s >> data3;
00146                             frac3 = (data3 & 0x00FFFFFF) / 16777215.0;
00147                             man3 = (data3 & 0x0F000000) >> 24;
00148                             frac3 = (frac3 + man3) * header.height;
00149                             s >> data4;
00150                             frac4 = (data4 & 0x00FFFFFF) / 16777215.0;
00151                             man4 = (data4 & 0x0F000000) >> 24;
00152                             frac4 = (frac4 + man4) * header.width;
00153                             s >> data5;
00154                             frac5 = (data5 & 0x00FFFFFF) / 16777215.0;
00155                             man5 = (data5 & 0x0F000000) >> 24;
00156                             frac5 = (frac5 + man5) * header.height;
00157                             s >> data6;
00158                             frac6 = (data6 & 0x00FFFFFF) / 16777215.0;
00159                             man6 = (data6 & 0x0F000000) >> 24;
00160                             frac6 = (frac6 + man6) * header.width;
00161                             switch (type)
00162                             {
00163                             case 0:
00164                             case 3:
00165                                    if (pathOpen)
00166                                    {
00167                                           clip2.addPoint(firstPoint);
00168                                           clip2.addPoint(firstControl);
00169                                           clip2.setMarker();
00170                                    }
00171                                    pathOpen = false;
00172                                    first = true;
00173                                    break;
00174                             case 1:
00175                             case 2:
00176                             case 4:
00177                             case 5:
00178                                    if (first)
00179                                    {
00180                                           firstControl = FPoint(frac2, frac1);
00181                                           firstPoint = FPoint(frac4, frac3);
00182                                           clip2.addPoint(FPoint(frac4, frac3));
00183                                           clip2.addPoint(FPoint(frac6, frac5));
00184                                    }
00185                                    else
00186                                    {
00187                                           clip2.addPoint(frac4, frac3);
00188                                           clip2.addPoint(frac2, frac1);
00189                                           clip2.addPoint(frac4, frac3);
00190                                           clip2.addPoint(frac6, frac5);
00191                                    }
00192                                    pathOpen = true;
00193                                    first = false;
00194                                    break;
00195                             case 6:
00196                                    first = true;
00197                                    break;
00198                             default:
00199                                    break;
00200                             }
00201                             offset2 += 26;
00202                      }
00203                      clip2.addPoint(firstPoint);
00204                      clip2.addPoint(firstControl);
00205                      m_imageInfoRecord.PDSpathData.insert(resName, clip2.copy());
00206                      m_imageInfoRecord.valid = true;
00207               }
00208               else
00209               {
00210                      switch (resID)
00211                      {
00212                      case 0x0bb7:
00213                             adj = s.device()->at();
00214                             m_imageInfoRecord.clipPath = getPascalString(s);
00215                             offset += s.device()->at() - adj;
00216                             break;
00217                      case 0x03ed:
00218                             s >> hRes;
00219                             s >> hResUnit;
00220                             s >> dummyW;
00221                             s >> vRes;
00222                             s >> vResUnit;
00223                             s >> dummyW;
00224                             m_imageInfoRecord.xres = qRound(hRes / 65536.0);
00225                             m_imageInfoRecord.yres = qRound(vRes / 65536.0);
00226                             break;
00227                      case 0x040f:
00228                             m_embeddedProfile.resize(resSize);
00229                             s.readRawBytes(m_embeddedProfile.data(), resSize);
00230                             break;
00231                      case 0x0409:
00232                      case 0x040C:
00233                             {
00234                                    uint thdummy, thsize;
00235                                    s >> thdummy;
00236                                    s >> thdummy;
00237                                    s >> thdummy;
00238                                    s >> thdummy;
00239                                    s >> thdummy;
00240                                    s >> thsize;
00241                                    s >> thdummy;
00242                                    char* buffer = (char*)malloc(thsize);
00243                                    s.readRawBytes(buffer, thsize);
00244                                    QImage imth;
00245                                    imth.loadFromData((const uchar*)buffer, thsize, "JPEG");
00246                                    imth.convertDepth(32);
00247                                    if (resID == 0x0409)
00248                                           m_imageInfoRecord.exifInfo.thumbnail = imth.swapRGB();
00249                                    else
00250                                           m_imageInfoRecord.exifInfo.thumbnail = imth;
00251                                    m_imageInfoRecord.exifInfo.width = imth.width();
00252                                    m_imageInfoRecord.exifInfo.height = imth.height();
00253                                    m_imageInfoRecord.exifDataValid = true;
00254                                    free(buffer);
00255                             }
00256                      default:
00257                             break;
00258                      }
00259               }
00260               if (resBase + resSize <= size) {
00261                      s.device()->at( resBase + resSize );
00262                      offset += resSize;
00263               }
00264               if (resSize & 1)
00265               {
00266                      s >> filler;
00267                      offset += 1;
00268               }
00269        }
00270        if(offset<size)
00271               s.device()->at( size );
00272 }