Back to index

scribus-ng  1.3.4.dfsg+svn20071115
scimgdataloader_tiff.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 <qobject.h>
00010 #include "scconfig.h"
00011 #include "scimgdataloader_tiff.h"
00012 #include "colorutil.h"
00013 #include CMS_INC
00014 
00015 static void TagExtender(TIFF *tiff)
00016 {
00017        static const TIFFFieldInfo xtiffFieldInfo[] =
00018        {
00019               { 37724, -3, -3, TIFF_UNDEFINED, FIELD_CUSTOM, TRUE, TRUE,   const_cast<char*>("PhotoshopLayerData") }
00020        };
00021        TIFFMergeFieldInfo(tiff, xtiffFieldInfo, sizeof (xtiffFieldInfo) / sizeof (xtiffFieldInfo[0]));
00022 }
00023 
00024 ScImgDataLoader_TIFF::ScImgDataLoader_TIFF(void) : ScImgDataLoader()
00025 {
00026        initSupportedFormatList();
00027 }
00028 
00029 void ScImgDataLoader_TIFF::initSupportedFormatList(void)
00030 {
00031        m_supportedFormats.clear();
00032        m_supportedFormats.append( "tif" );
00033        m_supportedFormats.append( "tiff" );
00034 }
00035 
00036 void ScImgDataLoader_TIFF::loadEmbeddedProfile(const QString& fn)
00037 {
00038        m_embeddedProfile.resize(0);
00039        m_profileComponents = 0;
00040        if ( !QFile::exists(fn) )
00041               return;
00042        TIFFSetTagExtender(TagExtender);
00043        TIFF* tif = TIFFOpen(fn.local8Bit(), "r");
00044        if(tif)
00045        {
00046               DWORD EmbedLen = 0;
00047               LPBYTE EmbedBuffer;
00048               if (TIFFGetField(tif, TIFFTAG_ICCPROFILE, &EmbedLen, &EmbedBuffer))
00049               {
00050                      cmsHPROFILE tiffProf = cmsOpenProfileFromMem(EmbedBuffer, EmbedLen);
00051                      if (tiffProf)
00052                      {
00053                             if (static_cast<int>(cmsGetColorSpace(tiffProf)) == icSigRgbData)
00054                                    m_profileComponents = 3;
00055                             if (static_cast<int>(cmsGetColorSpace(tiffProf)) == icSigCmykData)
00056                                    m_profileComponents = 4;
00057                             m_embeddedProfile.duplicate((const char*) EmbedBuffer, EmbedLen);
00058                      }
00059                      cmsCloseProfile(tiffProf);
00060               }
00061               TIFFClose(tif);
00062        }
00063 }
00064 
00065 void ScImgDataLoader_TIFF::preloadAlphaChannel(const QString& fn, int res)
00066 {
00067        bool valid = m_imageInfoRecord.isRequest;
00068        QMap<int, ImageLoadRequest> req = m_imageInfoRecord.RequestProps;
00069        initialize();
00070        m_imageInfoRecord.RequestProps = req;
00071        m_imageInfoRecord.isRequest = valid;
00072        QFileInfo fi = QFileInfo(fn);
00073        if (!fi.exists())
00074               return;
00075        if( !loadPicture(fn, res, false))
00076               r_image.resize(0);
00077        else
00078        {
00079               m_imageInfoRecord.valid = true;
00080               if (photometric == PHOTOMETRIC_SEPARATED)
00081               {
00082                      if (samplesperpixel == 4)
00083                             m_imageInfoRecord.valid = false;
00084               }
00085               else
00086               {
00087                      if (samplesperpixel == 3)
00088                             m_imageInfoRecord.valid = false;
00089               }
00090        }
00091 }
00092 
00093 int ScImgDataLoader_TIFF::getLayers(const QString& fn)
00094 {
00095        int layerNum = 1;
00096        int test;
00097        struct PSDLayer lay;
00098        TIFFSetTagExtender(TagExtender);
00099        TIFF* tif = TIFFOpen(fn.local8Bit(), "r");
00100        if(tif)
00101        {
00102               do
00103               {
00104                      char *layerName=0;
00105                      TIFFGetField(tif, TIFFTAG_PAGENAME, &layerName);
00106                      QString name = QString(layerName);
00107                      if (name.isEmpty())
00108                             lay.layerName = QString("Layer #%1").arg(layerNum);
00109                      else
00110                             lay.layerName = name;
00111                      lay.blend = "norm";
00112                      lay.opacity = 255;
00113                      lay.flags = 0;
00114                      m_imageInfoRecord.layerInfo.append(lay);
00115                      m_imageInfoRecord.valid = true;
00116                      layerNum++;
00117                      test = TIFFReadDirectory(tif);
00118               }
00119               while (test == 1);
00120               TIFFClose(tif);
00121        }
00122        return layerNum;
00123 }
00124 
00125 bool ScImgDataLoader_TIFF::getImageData(TIFF* tif, RawImage *image, uint widtht, uint heightt, uint size, uint16 photometric, uint16 bitspersample, uint16 samplesperpixel, bool &bilevel, bool &isCMYK)
00126 {
00127        bool endian;
00128        int wordsize;
00129        qSysInfo(&wordsize, &endian);
00130        uint32 *bits = 0;
00131        if (photometric == PHOTOMETRIC_SEPARATED)
00132        {
00133               if (samplesperpixel > 5)
00134               {
00135                      bits = (uint32 *) _TIFFmalloc(size * sizeof(uint32));
00136                      if(bits)
00137                      {
00138                             if (TIFFReadRGBAImage(tif, widtht, heightt, bits, 0))
00139                             {
00140                                    for(unsigned int y = 0; y < heightt; y++)
00141                                    {
00142                                           memcpy(image->scanLine(heightt - 1 - y), bits + y * widtht, widtht * image->channels());
00143                                           if (endian)
00144                                           {
00145                                                  unsigned char *s = image->scanLine( heightt - 1 - y );
00146                                                  unsigned char r, g, b, a;
00147                                                  for(uint xi=0; xi < widtht; ++xi )
00148                                                  {
00149                                                         r = s[0];
00150                                                         g = s[1];
00151                                                         b = s[2];
00152                                                         a = s[3];
00153                                                         s[0] = a;
00154                                                         s[1] = b;
00155                                                         s[2] = g;
00156                                                         s[3] = r;
00157                                                         s += image->channels();
00158                                                  }
00159                                           }
00160                                    }
00161                             }
00162                             _TIFFfree(bits);
00163                             if (bitspersample == 1)
00164                                    bilevel = true;
00165                             isCMYK = false;
00166                      }
00167               }
00168               else
00169               {
00170                      if (TIFFIsTiled(tif))
00171                      {
00172                             uint32 columns, rows;
00173                             uint32 *tile_buf;
00174                             uint32 xt, yt;
00175                             TIFFGetField(tif, TIFFTAG_TILEWIDTH,  &columns);
00176                             TIFFGetField(tif, TIFFTAG_TILELENGTH, &rows);
00177                             tile_buf = (uint32*) _TIFFmalloc(columns*rows*sizeof(uint32));
00178                             if (tile_buf == NULL)
00179                             {
00180                                    TIFFClose(tif);
00181                                    return false;
00182                             }
00183                             uint32 tileW = columns, tileH = rows;
00184                             for (yt = 0; yt < (uint32) image->height(); yt += rows)
00185                             {
00186                                    if (yt > (uint) image->height())
00187                                           break;
00188                                    if (image->height()-yt < rows)
00189                                           tileH = image->height()-yt;
00190                                    tileW = columns;
00191                                    register uint32 yi;
00192                                    int chans = image->channels();
00193                                    for (xt = 0; xt < (uint) image->width(); xt += columns)
00194                                    {
00195                                           TIFFReadTile(tif, tile_buf, xt, yt, 0, 0);
00196                                           for (yi = 0; yi < tileH; yi++)
00197                                           {
00198                                                  _TIFFmemcpy(image->scanLine(yt+(tileH-1-yi))+xt, tile_buf+tileW*yi, tileW*chans);
00199                                           }
00200                                    }
00201                             }
00202                             _TIFFfree(tile_buf);
00203                      }
00204                      else
00205                      {
00206                             tsize_t bytesperrow = TIFFScanlineSize(tif);
00207                             bits = (uint32 *) _TIFFmalloc(bytesperrow);
00208                             int chans = image->channels();
00209                             if (bits)
00210                             {
00211                                    for (unsigned int y = 0; y < heightt; y++)
00212                                    {
00213                                           if (TIFFReadScanline(tif, bits, y, 0))
00214                                           {
00215                                                  memcpy(image->scanLine(y), bits, chans * widtht);
00216                                           }
00217                                    }
00218                                    _TIFFfree(bits);
00219                             }
00220                      }
00221                      isCMYK = true;
00222               }
00223        }
00224        else
00225        {
00226               bits = (uint32 *) _TIFFmalloc(size * sizeof(uint32));
00227               if(bits)
00228               {
00229                      if (TIFFReadRGBAImage(tif, widtht, heightt, bits, 0))
00230                      {
00231                             for(unsigned int y = 0; y < heightt; y++)
00232                             {
00233                                    memcpy(image->scanLine(heightt - 1 - y), bits + y * widtht, widtht * image->channels());
00234                                    if (endian)
00235                                    {
00236                                           unsigned char *s = image->scanLine( heightt - 1 - y );
00237                                           unsigned char r, g, b, a;
00238                                           for(uint xi=0; xi < widtht; ++xi )
00239                                           {
00240                                                  r = s[0];
00241                                                  g = s[1];
00242                                                  b = s[2];
00243                                                  a = s[3];
00244                                                  s[0] = a;
00245                                                  s[1] = b;
00246                                                  s[2] = g;
00247                                                  s[3] = r;
00248                                                  s += image->channels();
00249                                           }
00250                                    }
00251                             }
00252                      }
00253                      _TIFFfree(bits);
00254                      if (bitspersample == 1)
00255                             bilevel = true;
00256               }
00257        }
00258        return true;
00259 }
00260 
00261 void ScImgDataLoader_TIFF::blendOntoTarget(RawImage *tmp, int layOpa, QString layBlend, bool cmyk, bool useMask)
00262 {
00263        if (layBlend == "diss")
00264        {
00265               for (int l = 0; l < tmp->height(); l++)
00266               {
00267                      srand(random_table[ l  % 4096]);
00268                      for (int k = 0; k < tmp->width(); k++)
00269                      {
00270                             int rand_val = rand() & 0xff;
00271                             if (rand_val > layOpa)
00272                                    tmp->setAlpha(k, l, 0);
00273                      }
00274               }
00275        }
00276        int w = r_image.width();
00277        int h = r_image.height();
00278        for( int yi=0; yi < h; ++yi )
00279        {
00280               unsigned char *s = tmp->scanLine( yi );
00281               unsigned char *d = r_image.scanLine( yi );
00282               unsigned char r, g, b, src_r, src_g, src_b, src_a, src_alpha, dst_alpha;
00283               unsigned char a = 0;
00284               for(int xi=0; xi < w; ++xi )
00285               {
00286                      src_r = s[0];
00287                      src_g = s[1];
00288                      src_b = s[2];
00289                      src_a = s[3];
00290                      if (r_image.channels() == 5)
00291                      {
00292                             dst_alpha = d[4];
00293                             if (useMask)
00294                                    src_alpha = s[4];
00295                             else
00296                                    src_alpha = 255;
00297                      }
00298                      else
00299                      {
00300                             if (cmyk)
00301                             {
00302                                    dst_alpha = 255;
00303                                    src_alpha = 255;
00304                             }
00305                             else
00306                             {
00307                                    dst_alpha = d[3];
00308                                    src_alpha = s[3];
00309                             }
00310                      }
00311                      if (layBlend != "diss")
00312                             src_alpha = INT_MULT(src_alpha, layOpa);
00313                      if ((dst_alpha > 0) && (src_alpha > 0))
00314                      {
00315                             if (layBlend == "mul ")
00316                             {
00317                                    src_r = INT_MULT(src_r, d[0]);
00318                                    src_g = INT_MULT(src_g, d[1]);
00319                                    src_b = INT_MULT(src_b, d[2]);
00320                                    if (cmyk)
00321                                           src_a = INT_MULT(src_a, d[3]);
00322                             }
00323                             else if (layBlend == "scrn")
00324                             {
00325                                    src_r = 255 - ((255-src_r) * (255-d[0]) / 128);
00326                                    src_g = 255 - ((255-src_g) * (255-d[1]) / 128);
00327                                    src_b = 255 - ((255-src_b) * (255-d[2]) / 128);
00328                                    if (cmyk)
00329                                           src_a = 255 - ((255-src_a) * (255-d[3]) / 128);
00330                             }
00331                             else if (layBlend == "over")
00332                             {
00333                                    src_r = d[0] < 128 ? src_r * d[0] / 128 : 255 - ((255-src_r) * (255-d[0]) / 128);
00334                                    src_g = d[1] < 128 ? src_g * d[1] / 128 : 255 - ((255-src_g) * (255-d[1]) / 128);
00335                                    src_b = d[2] < 128 ? src_b * d[2] / 128 : 255 - ((255-src_b) * (255-d[2]) / 128);
00336                                    if (cmyk)
00337                                           src_a = d[3] < 128 ? src_a * d[3] / 128 : 255 - ((255-src_a) * (255-d[3]) / 128);
00338                             }
00339                             else if (layBlend == "diff")
00340                             {
00341                                    src_r = d[0] > src_r ? d[0] - src_r : src_r - d[0];
00342                                    src_g = d[1] > src_g ? d[1] - src_g : src_g - d[1];
00343                                    src_b = d[2] > src_b ? d[2] - src_b : src_b - d[2];
00344                                    if (cmyk)
00345                                           src_a = d[3] > src_a ? d[3] - src_a : src_a - d[3];
00346                             }
00347                             else if (layBlend == "dark")
00348                             {
00349                                    src_r = d[0]  < src_r ? d[0]  : src_r;
00350                                    src_g = d[1] < src_g ? d[1] : src_g;
00351                                    src_b = d[2] < src_b ? d[2] : src_b;
00352                                    if (cmyk)
00353                                           src_a = d[3] < src_a ? d[3] : src_a;
00354                             }
00355                             else if (layBlend == "hLit")
00356                             {
00357                                    src_r = src_r < 128 ? src_r * d[0] / 128 : 255 - ((255-src_r) * (255-d[0]) / 128);
00358                                    src_g = src_g < 128 ? src_g * d[1] / 128 : 255 - ((255-src_g) * (255-d[1]) / 128);
00359                                    src_b = src_b < 128 ? src_b * d[2] / 128 : 255 - ((255-src_b) * (255-d[2]) / 128);
00360                                    if (cmyk)
00361                                           src_a = src_a < 128 ? src_a * d[3] / 128 : 255 - ((255-src_a) * (255-d[3]) / 128);
00362                             }
00363                             else if (layBlend == "sLit")
00364                             {
00365                                    src_r = src_r * d[0] / 256 + src_r * (255 - ((255-src_r)*(255-d[0]) / 256) - src_r * d[0] / 256) / 256;
00366                                    src_g = src_g * d[1] / 256 + src_g * (255 - ((255-src_g)*(255-d[1]) / 256) - src_g * d[1] / 256) / 256;
00367                                    src_b = src_b * d[2] / 256 + src_b * (255 - ((255-src_b)*(255-d[2]) / 256) - src_b * d[2] / 256) / 256;
00368                                    if (cmyk)
00369                                           src_a = src_a * d[3] / 256 + src_a * (255 - ((255-src_a)*(255-d[3]) / 256) - src_a * d[3] / 256) / 256;
00370                             }
00371                             else if (layBlend == "lite")
00372                             {
00373                                    src_r = d[0] < src_r ? src_r : d[0];
00374                                    src_g = d[1] < src_g ? src_g : d[1];
00375                                    src_b = d[2] < src_b ? src_b : d[2];
00376                                    if (cmyk)
00377                                           src_a = d[3] < src_a ? src_a : d[3];
00378                             }
00379                             else if (layBlend == "smud")
00380                             {
00381                                    src_r = d[0] + src_r - src_r * d[0] / 128;
00382                                    src_g = d[1] + src_g - src_g * d[1] / 128;
00383                                    src_b = d[2] + src_b - src_b * d[2] / 128;
00384                                    if (cmyk)
00385                                           src_a = d[3] + src_a - src_a * d[3] / 128;
00386                             }
00387                             else if (layBlend == "div ")
00388                             {
00389                                    src_r = src_r == 255 ? 255 : ((d[0] * 256) / (255-src_r)) > 255 ? 255 : (d[0] * 256) / (255-src_r);
00390                                    src_g = src_g == 255 ? 255 : ((d[1] * 256) / (255-src_g)) > 255 ? 255 : (d[1] * 256) / (255-src_g);
00391                                    src_b = src_b == 255 ? 255 : ((d[2] * 256) / (255-src_b)) > 255 ? 255 : (d[2] * 256) / (255-src_b);
00392                                    if (cmyk)
00393                                           src_a = src_a == 255 ? 255 : ((d[3] * 256) / (255-src_a)) > 255 ? 255 : (d[3] * 256) / (255-src_a);
00394                             }
00395                             else if (layBlend == "idiv")
00396                             {
00397                                    src_r = src_r == 0 ? 0 : (255 - (((255-d[0]) * 256) / src_r)) < 0 ? 0 : 255 - (((255-d[0]) * 256) / src_r);
00398                                    src_g = src_g == 0 ? 0 : (255 - (((255-d[1]) * 256) / src_g)) < 0 ? 0 : 255 - (((255-d[1]) * 256) / src_g);
00399                                    src_b = src_b == 0 ? 0 : (255 - (((255-d[2]) * 256) / src_b)) < 0 ? 0 : 255 - (((255-d[2]) * 256) / src_b);
00400                                    if (cmyk)
00401                                           src_a = src_a == 0 ? 0 : (255 - (((255-d[3]) * 256) / src_a)) < 0 ? 0 : 255 - (((255-d[3]) * 256) / src_a);
00402                             }
00403                             else if (layBlend == "hue ")
00404                             {
00405                                    if (!cmyk)
00406                                    {
00407                                           uchar new_r = d[0];
00408                                           uchar new_g = d[1];
00409                                           uchar new_b = d[2];
00410                                           RGBTOHSV(src_r, src_g, src_b);
00411                                           RGBTOHSV(new_r, new_g, new_b);
00412                                           new_r = src_r;
00413                                           HSVTORGB(new_r, new_g, new_b);
00414                                           src_r = new_r;
00415                                           src_g = new_g;
00416                                           src_b = new_b;
00417                                    }
00418                             }
00419                             else if (layBlend == "sat ")
00420                             {
00421                                    if (!cmyk)
00422                                    {
00423                                           uchar new_r = d[0];
00424                                           uchar new_g = d[1];
00425                                           uchar new_b = d[2];
00426                                           RGBTOHSV(src_r, src_g, src_b);
00427                                           RGBTOHSV(new_r, new_g, new_b);
00428                                           new_g = src_g;
00429                                           HSVTORGB(new_r, new_g, new_b);
00430                                           src_r = new_r;
00431                                           src_g = new_g;
00432                                           src_b = new_b;
00433                                    }
00434                             }
00435                             else if (layBlend == "lum ")
00436                             {
00437                                    if (!cmyk)
00438                                    {
00439                                           uchar new_r = d[0];
00440                                           uchar new_g = d[1];
00441                                           uchar new_b = d[2];
00442                                           RGBTOHSV(src_r, src_g, src_b);
00443                                           RGBTOHSV(new_r, new_g, new_b);
00444                                           new_b = src_b;
00445                                           HSVTORGB(new_r, new_g, new_b);
00446                                           src_r = new_r;
00447                                           src_g = new_g;
00448                                           src_b = new_b;
00449                                    }
00450                             }
00451                             else if (layBlend == "colr")
00452                             {
00453                                    if (!cmyk)
00454                                    {
00455                                           uchar new_r = d[0];
00456                                           uchar new_g = d[1];
00457                                           uchar new_b = d[2];
00458                                           RGBTOHLS(src_r, src_g, src_b);
00459                                           RGBTOHLS(new_r, new_g, new_b);
00460                                           new_r = src_r;
00461                                           new_b = src_b;
00462                                           HLSTORGB(new_r, new_g, new_b);
00463                                           src_r = new_r;
00464                                           src_g = new_g;
00465                                           src_b = new_b;
00466                                    }
00467                             }
00468                      }
00469                      if (dst_alpha == 0)
00470                      {
00471                             r = src_r;
00472                             g = src_g;
00473                             b = src_b;
00474                             a = src_a;
00475                      }
00476                      else
00477                      {
00478                             if (src_alpha > 0)
00479                             {
00480                                    r = (d[0] * (255 - src_alpha) + src_r * src_alpha) / 255;
00481                                    g = (d[1] * (255 - src_alpha) + src_g * src_alpha) / 255;
00482                                    b = (d[2] * (255 - src_alpha) + src_b * src_alpha) / 255;
00483                                    if (cmyk)
00484                                           a = (d[3] * (255 - src_alpha) + src_a * src_alpha) / 255;
00485                                    if (layBlend != "diss")
00486                                           src_alpha = dst_alpha + INT_MULT(255 - dst_alpha, src_alpha);
00487                             }
00488                      }
00489                      if (src_alpha > 0)
00490                      {
00491                             d[0] = r;
00492                             d[1] = g;
00493                             d[2] = b;
00494                             if (r_image.channels() == 5)
00495                             {
00496                                    d[3] = a;
00497                                    d[4] = src_alpha;
00498                             }
00499                             else
00500                             {
00501                                    if (cmyk)
00502                                           d[3] = a;
00503                                    else
00504                                           d[3] = src_alpha;
00505                             }
00506                      }
00507                      d += r_image.channels();
00508                      s += tmp->channels();
00509               }
00510        }
00511 }
00512 
00513 bool ScImgDataLoader_TIFF::loadPicture(const QString& fn, int res, bool thumbnail)
00514 {
00515        bool bilevel = false;
00516        bool failedPS = false;
00517        bool foundPS = false;
00518        short resolutionunit = 0;
00519        float xres = 72.0, yres = 72.0;
00520        if (!QFile::exists(fn))
00521               return false;
00522        QByteArray byteOrder(2);
00523        QFile fo(fn);
00524        if (fo.open(IO_ReadOnly))
00525        {
00526               fo.readBlock(byteOrder.data(), 1);
00527               fo.close();
00528        }
00529        srand(314159265);
00530        for (int i = 0; i < 4096; i++)
00531               random_table[i] = rand();
00532        for (int i = 0; i < 4096; i++)
00533        {
00534               int tmp;
00535               int swap = i + rand() % (4096 - i);
00536               tmp = random_table[i];
00537               random_table[i] = random_table[swap];
00538               random_table[swap] = tmp;
00539        }
00540        int test;
00541        int layerNum = 0;
00542        bool valid = m_imageInfoRecord.isRequest;
00543        QMap<int, ImageLoadRequest> req = m_imageInfoRecord.RequestProps;
00544        initialize();
00545        m_imageInfoRecord.RequestProps = req;
00546        m_imageInfoRecord.isRequest = valid;
00547        m_imageInfoRecord.type = 1;
00548        getLayers(fn);
00549        TIFFSetTagExtender(TagExtender);
00550        TIFF* tif = TIFFOpen(fn.local8Bit(), "r");
00551        if(tif)
00552        {
00553               bool isCMYK = false;
00554               unsigned int widtht, heightt, size;
00555               char *description=0, *copyright=0, *datetime=0, *artist=0, *scannerMake=0, *scannerModel=0;
00556               uint16 bitspersample, fillorder, planar;
00557 
00558               TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &widtht);
00559               TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &heightt);
00560               TIFFGetField(tif, TIFFTAG_XRESOLUTION, &xres);
00561               TIFFGetField(tif, TIFFTAG_YRESOLUTION, &yres);
00562               TIFFGetField(tif, TIFFTAG_RESOLUTIONUNIT , &resolutionunit);
00563               size = widtht * heightt;
00564               TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &photometric);
00565               TIFFGetField(tif, TIFFTAG_PLANARCONFIG, &planar);
00566               TIFFGetField(tif, TIFFTAG_BITSPERSAMPLE, &bitspersample);
00567               TIFFGetField(tif, TIFFTAG_SAMPLESPERPIXEL, &samplesperpixel);
00568               TIFFGetField(tif, TIFFTAG_FILLORDER, &fillorder);
00569 
00570               TIFFGetField(tif, TIFFTAG_MAKE, &scannerMake);
00571               TIFFGetField(tif, TIFFTAG_MODEL, &scannerModel);
00572               TIFFGetField(tif, TIFFTAG_IMAGEDESCRIPTION, &description);
00573               TIFFGetField(tif, TIFFTAG_COPYRIGHT, &copyright);
00574               TIFFGetField(tif, TIFFTAG_DATETIME, &datetime);
00575               TIFFGetField(tif, TIFFTAG_ARTIST, &artist);
00576               m_imageInfoRecord.exifInfo.cameraName = QString(scannerModel);
00577               m_imageInfoRecord.exifInfo.cameraVendor = QString(scannerMake);
00578               m_imageInfoRecord.exifInfo.comment = QString(description);
00579               m_imageInfoRecord.exifInfo.userComment = QString(copyright);
00580               m_imageInfoRecord.exifInfo.width = widtht;
00581               m_imageInfoRecord.exifInfo.height = heightt;
00582               m_imageInfoRecord.exifInfo.dateTime = QString(datetime);
00583               m_imageInfoRecord.exifInfo.artist = QString(artist);
00584               m_imageInfoRecord.exifInfo.thumbnail = QImage();
00585               m_imageInfoRecord.exifDataValid = true;
00586               DWORD EmbedLen = 0;
00587               LPBYTE EmbedBuffer;
00588               if (TIFFGetField(tif, TIFFTAG_ICCPROFILE, &EmbedLen, &EmbedBuffer))
00589               {
00590                      const char *Descriptor;
00591                      cmsHPROFILE tiffProf = cmsOpenProfileFromMem(EmbedBuffer, EmbedLen);
00592                      Descriptor = cmsTakeProductDesc(tiffProf);
00593                      m_embeddedProfile.duplicate((const char*) EmbedBuffer, EmbedLen);
00594                      m_imageInfoRecord.profileName = QString(Descriptor);
00595                      m_imageInfoRecord.isEmbedded = true;
00596                      cmsCloseProfile(tiffProf);
00597               }
00598               else
00599               {
00600                      m_imageInfoRecord.isEmbedded = false;
00601                      m_imageInfoRecord.profileName = "";
00602               }
00603               unsigned int PhotoshopLen = 0;
00604               unsigned char* PhotoshopBuffer;
00605               if (TIFFGetField(tif, TIFFTAG_PHOTOSHOP, &PhotoshopLen, &PhotoshopBuffer) )
00606               {
00607                      if (PhotoshopLen != 0)
00608                      {
00609                             QByteArray arrayPhot(PhotoshopLen);
00610                             arrayPhot.duplicate((const char*)PhotoshopBuffer,PhotoshopLen);
00611                             QDataStream strPhot(arrayPhot,IO_ReadOnly);
00612                             strPhot.setByteOrder( QDataStream::BigEndian );
00613                             PSDHeader fakeHeader;
00614                             fakeHeader.width = widtht;
00615                             fakeHeader.height = heightt;
00616                             parseRessourceData(strPhot, fakeHeader, PhotoshopLen);
00617                             m_imageInfoRecord.exifInfo.width = widtht;
00618                             m_imageInfoRecord.exifInfo.height = heightt;
00619                             if (!m_imageInfoRecord.valid)
00620                                    m_imageInfoRecord.valid = (m_imageInfoRecord.PDSpathData.size())>0?true:false;
00621                             if (thumbnail)
00622                             {
00623                                    if (photometric == PHOTOMETRIC_SEPARATED)
00624                                    {
00625                                           isCMYK = true;
00626                                           m_imageInfoRecord.colorspace = 1;
00627                                    }
00628                                    else
00629                                           m_imageInfoRecord.colorspace = 0;
00630                                    if (bitspersample == 1)
00631                                           bilevel = true;
00632                                    if (!m_imageInfoRecord.exifInfo.thumbnail.isNull())
00633                                    {
00634                                           if (isCMYK)
00635                                                  r_image.create(m_imageInfoRecord.exifInfo.thumbnail.width(), m_imageInfoRecord.exifInfo.thumbnail.height(), 5);
00636                                           else
00637                                                  r_image.create(m_imageInfoRecord.exifInfo.thumbnail.width(), m_imageInfoRecord.exifInfo.thumbnail.height(), 4);
00638                                           r_image.fill(0);
00639                                           QRgb *s;
00640                                           uchar *d;
00641                                           unsigned char cc, cm, cy, ck;
00642                                           for( int yit=0; yit < m_imageInfoRecord.exifInfo.thumbnail.height(); ++yit )
00643                                           {
00644                                                  s = (QRgb*)(m_imageInfoRecord.exifInfo.thumbnail.scanLine( yit ));
00645                                                  d = r_image.scanLine( yit );
00646                                                  for(int xit=0; xit < m_imageInfoRecord.exifInfo.thumbnail.width(); ++xit )
00647                                                  {
00648                                                         if (isCMYK)
00649                                                         {
00650                                                                cc = 255 - qRed(*s);
00651                                                                cm = 255 - qGreen(*s);
00652                                                                cy = 255 - qBlue(*s);
00653                                                                ck = QMIN(QMIN(cc, cm), cy);
00654                                                                d[0] = cc-ck;
00655                                                                d[1] = cm-ck;
00656                                                                d[2] = cy-ck;
00657                                                                d[3] = ck;
00658                                                                d[4] = 255;
00659                                                         }
00660                                                         else
00661                                                         {
00662                                                                d[0] = qRed(*s);
00663                                                                d[1] = qGreen(*s);
00664                                                                d[2] = qBlue(*s);
00665                                                                d[3] = 255;
00666                                                         }
00667                                                         s++;
00668                                                         d += r_image.channels();
00669                                                  }
00670                                           }
00671                                           TIFFClose(tif);
00672                                           return true;
00673                                    }
00674                             }
00675                      }
00676               }
00677               unsigned int PhotoshopLen2 = 0;
00678               unsigned char* PhotoshopBuffer2;
00679               if (TIFFGetField(tif, 37724, &PhotoshopLen2, &PhotoshopBuffer2) )
00680               {
00681                      if (PhotoshopLen2 > 40)
00682                      {
00683                             m_imageInfoRecord.layerInfo.clear();
00684                             QByteArray arrayPhot;
00685                             arrayPhot.setRawData((const char*)PhotoshopBuffer2, PhotoshopLen2);
00686                             QDataStream s(arrayPhot,IO_ReadOnly);
00687                             if (byteOrder[0] == QChar('M'))
00688                                    s.setByteOrder( QDataStream::BigEndian );
00689                             else
00690                                    s.setByteOrder( QDataStream::LittleEndian );
00691                             uint addRes, layerinfo, channelLen, signature, extradata, layermasksize, layerRange, dummy;
00692                             int top, left, bottom, right;
00693                             short numLayers, numChannels;
00694                             short channelType;
00695                             uchar blendKey[4];
00696                             uchar opacity, clipping, flags, filler;
00697                             QString layerName, blend;
00698                             struct PSDLayer lay;
00699                             do
00700                             {
00701                                    if(s.atEnd())
00702                                    {
00703                                           m_imageInfoRecord.layerInfo.clear();
00704                                           failedPS = true;
00705                                           break;
00706                                    }
00707                                    s >> signature;
00708                             }
00709                             while (signature != 0x4c617972);
00710                             if (!failedPS)
00711                             {
00712                                    s >> layerinfo;
00713                                    s >> numLayers;
00714                                    if (numLayers < 0)
00715                                           numLayers = -numLayers;
00716                                    if (numLayers != 0)
00717                                    {
00718                                           for (int layer = 0; layer < numLayers; layer++)
00719                                           {
00720                                                  s >> top;
00721                                                  lay.ypos = top;
00722                                                  s >> left;
00723                                                  lay.xpos = left;
00724                                                  s >> bottom;
00725                                                  lay.height = bottom - top;
00726                                                  s >> right;
00727                                                  lay.width = right - left;
00728                                                  s >> numChannels;
00729                                                  if (numChannels > 6) // we don't support images with more than 6 channels yet
00730                                                  {
00731                                                         m_imageInfoRecord.layerInfo.clear();
00732                                                         failedPS = true;
00733                                                         break;
00734                                                  }
00735                                                  lay.channelType.clear();
00736                                                  lay.channelLen.clear();
00737                                                  for (int channels = 0; channels < numChannels; channels++)
00738                                                  {
00739                                                         s >> channelType;
00740                                                         s >> channelLen;
00741                                                         lay.channelType.append(channelType);
00742                                                         lay.channelLen.append(channelLen);
00743                                                  }
00744                                                  s >> signature;
00745                                                  blend = "";
00746                                                  for( int i = 0; i < 4; i++ )
00747                                                  {
00748                                                         s >> blendKey[i];
00749                                                         if (byteOrder[0] == QChar('M'))
00750                                                                blend.append(QChar(blendKey[i]));
00751                                                         else
00752                                                                blend.prepend(QChar(blendKey[i]));
00753                                                  }
00754                                                  lay.blend = blend;
00755                                                  s >> opacity;
00756                                                  lay.opacity = opacity;
00757                                                  s >> clipping;
00758                                                  lay.clipping = clipping;
00759                                                  s >> flags;
00760                                                  if (flags & 8)
00761                                                  {
00762                                                         if (flags & 16)      // Unknown combination of layer flags, probably an adjustment or effects layer
00763                                                         {
00764                                                                m_imageInfoRecord.layerInfo.clear();
00765                                                                failedPS = true;
00766                                                                break;
00767                                                         }
00768                                                  }
00769                                                  lay.flags = flags;
00770                                                  s >> filler;
00771                                                  s >> extradata;
00772                                                  s >> layermasksize;
00773                                                  lay.maskYpos = 0;
00774                                                  lay.maskXpos = 0;
00775                                                  lay.maskHeight = 0;
00776                                                  lay.maskWidth = 0;
00777                                                  if (layermasksize != 0)
00778                                                  {
00779                                                         s >> lay.maskYpos;
00780                                                         s >> lay.maskXpos;
00781                                                         s >> dummy;
00782                                                         lay.maskHeight = dummy - lay.maskYpos;
00783                                                         s >> dummy;
00784                                                         lay.maskWidth = dummy - lay.maskXpos;
00785                                                         s >> dummy;
00786                                                  }
00787                                                  s >> layerRange;
00788                                                  s.device()->at( s.device()->at() + layerRange );
00789                                                  lay.layerName = getLayerString(s);
00790                                                  m_imageInfoRecord.layerInfo.append(lay);
00791                                                  s >> signature;
00792                                                  if( signature == 0x3842494D )
00793                                                  {
00794                                                         while (signature == 0x3842494D )
00795                                                         {
00796                                                                s >> signature;
00797                                                                s >> addRes;
00798                                                                s.device()->at( s.device()->at() + addRes );
00799                                                                s >> signature;
00800                                                         }
00801                                                         s.device()->at( s.device()->at() - 4 );
00802                                                  }
00803                                                  else
00804                                                  {
00805                                                         s.device()->at( s.device()->at() - 2 );
00806                                                         s >> signature;
00807                                                         if( signature == 0x3842494D )
00808                                                         {
00809                                                                while (signature == 0x3842494D )
00810                                                                {
00811                                                                       s >> signature;
00812                                                                       s >> addRes;
00813                                                                       s.device()->at( s.device()->at() + addRes );
00814                                                                       s >> signature;
00815                                                                }
00816                                                                s.device()->at( s.device()->at() - 4 );
00817                                                         }
00818                                                         else
00819                                                                s.device()->at( s.device()->at() - 6 );
00820                                                  }
00821                                           }
00822                                    }
00823                             }
00824                             if (!failedPS)
00825                             {
00826                                    int chans = 4;
00827                                    bilevel = false;
00828                                    PSDHeader fakeHeader;
00829                                    fakeHeader.width = widtht;
00830                                    fakeHeader.height = heightt;
00831                                    fakeHeader.channel_count = numChannels;
00832                                    fakeHeader.depth = 8;
00833                                    if (photometric == PHOTOMETRIC_SEPARATED)
00834                                    {
00835                                           isCMYK = true;
00836                                           fakeHeader.color_mode = CM_CMYK;
00837                                           chans = 5;
00838                                    }
00839                                    else
00840                                    {
00841                                           fakeHeader.color_mode = CM_RGB;
00842                                           isCMYK = false;
00843                                           chans = 5;
00844                                    }
00845                                    if( !r_image.create( widtht, heightt, chans ))
00846                                           return false;
00847                                    r_image.fill(0);
00848                                    bool firstLayer = true;
00849                                    for (int layer = 0; layer < numLayers; layer++)
00850                                    {
00851                                           loadLayerChannels( s, fakeHeader, m_imageInfoRecord.layerInfo, layer, &firstLayer );
00852                                    }
00853                                    arrayPhot.resetRawData((const char*)PhotoshopBuffer2, PhotoshopLen2);
00854                                    TIFFClose(tif);
00855                                    foundPS = true;
00856                                    if (m_imageInfoRecord.layerInfo.count() == 1)
00857                                           m_imageInfoRecord.layerInfo.clear();
00858                             }
00859                             else
00860                             {
00861                                    arrayPhot.resetRawData((const char*)PhotoshopBuffer2, PhotoshopLen2);
00862                                    getLayers(fn);
00863                             }
00864                      }
00865               }
00866               if( xres <= 1.0 || yres <= 1.0 )
00867               {
00868                      xres = yres = 72.0;
00869                      QFileInfo qfi(fn);
00870                      m_message = QObject::tr("%1 may be corrupted : missing resolution tags").arg(qfi.fileName());
00871                      m_msgType = warningMsg;
00872               }
00873               if ((!foundPS) || (failedPS))
00874               {
00875                      int chans = 4;
00876                      if (photometric == PHOTOMETRIC_SEPARATED)
00877                      {
00878                             if (samplesperpixel > 5) 
00879                                    chans = 4;
00880                             else
00881                                    chans = samplesperpixel;
00882                      }
00883                      else
00884                             chans = 4;
00885                      if (!r_image.create(widtht, heightt, chans))
00886                      {
00887                             TIFFClose(tif);
00888                             return false;
00889                      }
00890                      r_image.fill(0);
00891                      do
00892                      {
00893                             RawImage tmpImg;
00894                             if( !tmpImg.create(widtht, heightt, chans))
00895                             {
00896                                    TIFFClose(tif);
00897                                    return false;
00898                             }
00899                             else
00900                             {
00901                                    tmpImg.fill(0);
00902                                    if (!getImageData(tif, &tmpImg, widtht, heightt, size, photometric, bitspersample, samplesperpixel, bilevel, isCMYK))
00903                                    {
00904                                           TIFFClose(tif);
00905                                           return false;
00906                                    }
00907                                    bool visible = true;
00908                                    bool useMask = true;
00909                                    if ((m_imageInfoRecord.isRequest) && (m_imageInfoRecord.RequestProps.contains(layerNum)))
00910                                           visible = m_imageInfoRecord.RequestProps[layerNum].visible;
00911                                    QString layBlend = "norm";
00912                                    if ((m_imageInfoRecord.isRequest) && (m_imageInfoRecord.RequestProps.contains(layerNum)))
00913                                           layBlend = m_imageInfoRecord.RequestProps[layerNum].blend;
00914                                    if ((m_imageInfoRecord.isRequest) && (m_imageInfoRecord.RequestProps.contains(layerNum)))
00915                                           useMask = m_imageInfoRecord.RequestProps[layerNum].useMask;
00916                                    int layOpa = 255;
00917                                    if ((m_imageInfoRecord.isRequest) && (m_imageInfoRecord.RequestProps.contains(layerNum)))
00918                                           layOpa = m_imageInfoRecord.RequestProps[layerNum].opacity;
00919                                    if (visible)
00920                                           blendOntoTarget(&tmpImg, layOpa, layBlend, isCMYK, useMask);
00921                                    QImage imt = tmpImg.copy();
00922                                    if (chans > 4)
00923                                           imt = tmpImg.convertToQImage(true);
00924                                    else
00925                                           imt = tmpImg.convertToQImage(false);
00926                                    double sx = tmpImg.width() / 40.0;
00927                                    double sy = tmpImg.height() / 40.0;
00928                                    imt = sy < sx ?      imt.smoothScale(qRound(imt.width() / sx), qRound(imt.height() / sx)) :
00929                                                                                     imt.smoothScale(qRound(imt.width() / sy), qRound(imt.height() / sy));
00930                                    m_imageInfoRecord.layerInfo[layerNum].thumb = imt.copy();
00931                                    if (chans > 4)
00932                                    {
00933                                           QImage imt2 = imt.createAlphaMask();
00934                                           imt2.invertPixels();
00935                                           m_imageInfoRecord.layerInfo[layerNum].thumb_mask = imt2.copy();
00936                                    }
00937                                    else
00938                                           m_imageInfoRecord.layerInfo[layerNum].thumb_mask = QImage();
00939                                    layerNum++;
00940                             }
00941                             if ((m_imageInfoRecord.layerInfo.count() == 1) && (chans < 5))
00942                                    m_imageInfoRecord.layerInfo.clear();
00943                             test = TIFFReadDirectory(tif);
00944                      }
00945                      while (test == 1);
00946                      TIFFClose(tif);
00947               }
00948               if (resolutionunit == RESUNIT_INCH)
00949               {
00950                      m_image.setDotsPerMeterX ((int) (xres / 0.0254));
00951                      m_image.setDotsPerMeterY ((int) (yres / 0.0254));
00952                      m_imageInfoRecord.xres = qRound(xres);
00953                      m_imageInfoRecord.yres = qRound(yres);
00954               }
00955               else if (resolutionunit == RESUNIT_CENTIMETER)
00956               {
00957                      m_image.setDotsPerMeterX ((int) (xres * 100.0));
00958                      m_image.setDotsPerMeterY ((int) (yres * 100.0));
00959                      m_imageInfoRecord.xres = qRound(xres*2.54);
00960                      m_imageInfoRecord.yres = qRound(yres*2.54);
00961               }
00962               if (isCMYK)
00963                      m_imageInfoRecord.colorspace = 1;
00964               else if (bilevel)
00965                      m_imageInfoRecord.colorspace = 2;
00966               else
00967                      m_imageInfoRecord.colorspace = 0;
00968               m_imageInfoRecord.BBoxX = 0;
00969               m_imageInfoRecord.BBoxH = r_image.height();
00970               if ((m_imageInfoRecord.layerInfo.isEmpty()) && (m_imageInfoRecord.PDSpathData.isEmpty()))
00971                      m_imageInfoRecord.valid = false;
00972               else
00973                      m_imageInfoRecord.valid = true;
00974               return true;
00975        }
00976        return false;
00977 }
00978 
00979 QString ScImgDataLoader_TIFF::getLayerString(QDataStream & s)
00980 {
00981        uchar len, tmp;
00982        uint adj;
00983        QString ret = "";
00984        s >> len;
00985        if (len == 0)
00986        {
00987               s >> tmp;
00988               s >> tmp;
00989               s >> tmp;
00990               return ret;
00991        }
00992        for( int i = 0; i < len; i++ )
00993        {
00994               s >> tmp;
00995               ret += QChar(tmp);
00996        }
00997        adj = 0;
00998        if (((ret.length()+1) % 4) != 0)
00999               adj = 4 - ((ret.length()+1) % 4);
01000        s.device()->at( s.device()->at() + adj );
01001        return ret;
01002 }
01003 
01004 bool ScImgDataLoader_TIFF::loadChannel( QDataStream & s, const PSDHeader & header, QValueList<PSDLayer> &layerInfo, uint layer, int channel, int component, RawImage &tmpImg)
01005 {
01006        uint base = s.device()->at();
01007        uchar cbyte;
01008        ushort compression;
01009        s >> compression;
01010        if( compression > 1 )
01011               return false;
01012        if (compression == 0)
01013        {
01014               int count = layerInfo[layer].channelLen[channel]-2;
01015               for (int i = 0; i < tmpImg.height(); i++)
01016               {
01017                      uchar *ptr =  tmpImg.scanLine(i);
01018                      for (int j = 0; j < tmpImg.width(); j++)
01019                      {
01020                             s >> cbyte;
01021                             count--;
01022                             if ((header.color_mode == CM_CMYK) && (component < 4))
01023                                    cbyte = 255 - cbyte;
01024                             ptr[component] = cbyte;
01025                             if (count == 0)
01026                                    break;
01027                             ptr += tmpImg.channels();
01028                      }
01029                      if (count == 0)
01030                             break;
01031               }
01032        }
01033        else
01034        {
01035               s.device()->at( s.device()->at() + tmpImg.height() * 2 );
01036               uint pixel_count = tmpImg.width();
01037               for (int hh = 0; hh < tmpImg.height(); hh++)
01038               {
01039                      uint count = 0;
01040                      uchar *ptr = tmpImg.scanLine(hh);
01041                      uchar *ptr2 = ptr+tmpImg.width() * tmpImg.channels();
01042                      ptr += component;
01043                      while( count < pixel_count )
01044                      {
01045                             uchar c;
01046                             if(s.atEnd())
01047                                    return false;
01048                             s >> c;
01049                             uint len = c;
01050                             if( len < 128 )
01051                             {
01052                                    // Copy next len+1 bytes literally.
01053                                    len++;
01054                                    count += len;
01055                                    while( len != 0 )
01056                                    {
01057                                           s >> cbyte;
01058                                           if (ptr < ptr2)
01059                                           {
01060                                                  if ((header.color_mode == CM_CMYK) && (component < 4))
01061                                                         cbyte = 255 - cbyte;
01062                                                  *ptr = cbyte;
01063                                           }
01064                                           ptr += tmpImg.channels();
01065                                           len--;
01066                                    }
01067                             }
01068                             else if( len > 128 )
01069                             {
01070                                    // Next -len+1 bytes in the dest are replicated from next source byte.
01071                                    // (Interpret len as a negative 8-bit int.)
01072                                    len ^= 0xFF;
01073                                    len += 2;
01074                                    count += len;
01075                                    uchar val;
01076                                    s >> val;
01077                                    if ((header.color_mode == CM_CMYK) && (component < 4))
01078                                           val = 255 - val;
01079                                    while( len != 0 )
01080                                    {
01081                                           if (ptr < ptr2)
01082                                                  *ptr = val;
01083                                           ptr += tmpImg.channels();
01084                                           len--;
01085                                    }
01086                             }
01087                             else if( len == 128 )
01088                             {
01089                                    // No-op.
01090                             }
01091                      }
01092               }
01093        }
01094        s.device()->at( base+layerInfo[layer].channelLen[channel] );
01095        return true;
01096 }
01097 
01098 bool ScImgDataLoader_TIFF::loadLayerChannels( QDataStream & s, const PSDHeader & header, QValueList<PSDLayer> &layerInfo, uint layer, bool* firstLayer)
01099 {
01100        // Find out if the data is compressed.
01101        // Known values:
01102        //   0: no compression
01103        //   1: RLE compressed
01104        uint base = s.device()->at();
01105        uint base2 = base;
01106        uint channel_num = layerInfo[layer].channelLen.count();
01107        bool hasMask = false;
01108        bool hasAlpha = false;
01109        RawImage r2_image;
01110        RawImage mask;
01111        bool createOk = false;
01112        if (header.color_mode == CM_CMYK)
01113        {
01114               createOk = r2_image.create(layerInfo[layer].width, layerInfo[layer].height, QMAX(channel_num, 5));
01115               r2_image.fill(0);
01116        }
01117        else
01118        {
01119               createOk = r2_image.create(layerInfo[layer].width, layerInfo[layer].height, QMAX(channel_num, 4));
01120               r2_image.fill(0);
01121        }
01122        if( !createOk )
01123        {
01124               for(uint channel = 0; channel < channel_num; channel++)
01125               {
01126                      base2 += layerInfo[layer].channelLen[channel];
01127               }
01128               s.device()->at( base2 );
01129               return false;
01130        }
01131        channel_num = QMIN(channel_num, 39);
01132        uint components[40];
01133        for(uint channel = 0; channel < channel_num; channel++)
01134        {
01135               switch(layerInfo[layer].channelType[channel])
01136               {
01137               case 0:
01138                      components[channel] = 0;
01139                      break;
01140               case 1:
01141                      components[channel] = 1;
01142                      break;
01143               case 2:
01144                      components[channel] = 2;
01145                      break;
01146               case 3:
01147                      components[channel] = 3;
01148                      break;
01149               case -1:
01150                      if (header.color_mode == CM_CMYK)
01151                      {
01152                             if (channel_num == 6)
01153                                    components[channel] = channel_num-2;
01154                             else
01155                                    components[channel] = channel_num-1;
01156                      }
01157                      else
01158                      {
01159                             if (channel_num == 5)
01160                                    components[channel] = channel_num-2;
01161                             else
01162                                    components[channel] = channel_num-1;
01163                      }
01164                      hasAlpha = true;
01165                      break;
01166               case -2:
01167                      components[channel] = channel_num-1;
01168                      break;
01169               }
01170        }
01171        if (!hasAlpha)
01172               r2_image.fill(255);
01173        for(uint channel = 0; channel < channel_num; channel++)
01174        {
01175               if (layerInfo[layer].channelType[channel] == -2)
01176               {
01177                      if (!mask.create( layerInfo[layer].maskWidth, layerInfo[layer].maskHeight, 1 ))
01178                             break;
01179                      mask.fill(0);
01180                      if (!loadChannel(s, header, layerInfo, layer, channel, 0, mask))
01181                             break;
01182                      hasMask = true;
01183               }
01184               if (!loadChannel(s, header, layerInfo, layer, channel, components[channel], r2_image))
01185                      break;
01186        }
01187        for(uint channel = 0; channel < channel_num; channel++)
01188        {
01189               base2 += layerInfo[layer].channelLen[channel];
01190        }
01191        s.device()->at( base2 );
01192        QImage tmpImg2;
01193        if (header.color_mode == CM_CMYK)
01194               tmpImg2 = r2_image.convertToQImage(true);
01195        else
01196               tmpImg2 = r2_image.convertToQImage(false);
01197        QImage imt;
01198        double sx = tmpImg2.width() / 40.0;
01199        double sy = tmpImg2.height() / 40.0;
01200        imt = sy < sx ?  tmpImg2.smoothScale(qRound(tmpImg2.width() / sx), qRound(tmpImg2.height() / sx)) :
01201              tmpImg2.smoothScale(qRound(tmpImg2.width() / sy), qRound(tmpImg2.height() / sy));
01202        layerInfo[layer].thumb = imt.copy();
01203        if (hasMask)
01204        {
01205               QImage imt2;
01206               QImage tmpImg;
01207               tmpImg = mask.convertToQImage(true);
01208               double sx = tmpImg.width() / 40.0;
01209               double sy = tmpImg.height() / 40.0;
01210               imt2 = sy < sx ?  tmpImg.smoothScale(qRound(tmpImg.width() / sx), qRound(tmpImg.height() / sx)) :
01211              tmpImg.smoothScale(qRound(tmpImg.width() / sy), qRound(tmpImg.height() / sy));
01212               imt2.invertPixels();
01213               layerInfo[layer].thumb_mask = imt2.copy();
01214        }
01215        else
01216               layerInfo[layer].thumb_mask = QImage();
01217        if ((m_imageInfoRecord.isRequest) && (m_imageInfoRecord.RequestProps.contains(layer)))
01218               m_imageInfoRecord.RequestProps[layer].useMask = m_imageInfoRecord.RequestProps[layer].useMask;
01219        else
01220               m_imageInfoRecord.RequestProps[layer].useMask = true;
01221        bool visible = !(layerInfo[layer].flags & 2);
01222        if ((m_imageInfoRecord.isRequest) && (m_imageInfoRecord.RequestProps.contains(layer)))
01223               visible = m_imageInfoRecord.RequestProps[layer].visible;
01224        if (visible)
01225        {
01226               unsigned int startSrcY, startSrcX, startDstY, startDstX;
01227               if (layerInfo[layer].ypos < 0)
01228               {
01229                      startSrcY = abs(layerInfo[layer].ypos);
01230                      startDstY = 0;
01231               }
01232               else
01233               {
01234                      startSrcY = 0;
01235                      startDstY = layerInfo[layer].ypos;
01236               }
01237               if (layerInfo[layer].xpos < 0)
01238               {
01239                      startSrcX = abs(layerInfo[layer].xpos);
01240                      startDstX = 0;
01241               }
01242               else
01243               {
01244                      startSrcX = 0;
01245                      startDstX = layerInfo[layer].xpos;
01246               }
01247               unsigned int startSrcYm, startSrcXm, startDstYm, startDstXm;
01248               if (layerInfo[layer].maskYpos < 0)
01249               {
01250                      startSrcYm = abs(layerInfo[layer].maskYpos);
01251                      startDstYm = 0;
01252               }
01253               else
01254               {
01255                      startSrcYm = 0;
01256                      startDstYm = layerInfo[layer].maskYpos;
01257               }
01258               if (layerInfo[layer].maskXpos < 0)
01259               {
01260                      startSrcXm = abs(layerInfo[layer].maskXpos);
01261                      startDstXm = 0;
01262               }
01263               else
01264               {
01265                      startSrcXm = 0;
01266                      startDstXm = layerInfo[layer].maskXpos;
01267               }
01268               QString layBlend2 = layerInfo[layer].blend;
01269               if ((m_imageInfoRecord.isRequest) && (m_imageInfoRecord.RequestProps.contains(layer)))
01270                      layBlend2 = m_imageInfoRecord.RequestProps[layer].blend;
01271               if (layBlend2 == "diss")
01272               {
01273                      hasAlpha = true;
01274                      int layOpa = layerInfo[layer].opacity;
01275                      if ((m_imageInfoRecord.isRequest) && (m_imageInfoRecord.RequestProps.contains(layer)))
01276                             layOpa = m_imageInfoRecord.RequestProps[layer].opacity;
01277                      for (int l = 0; l < r2_image.height(); l++)
01278                      {
01279                             srand(random_table[ l  % 4096]);
01280                             for (int k = 0; k < r2_image.width(); k++)
01281                             {
01282                                    int rand_val = rand() & 0xff;
01283                                    if (rand_val > layOpa)
01284                                           r2_image.setAlpha(k, l, 0);
01285                             }
01286                      }
01287               }
01288               if (*firstLayer)
01289               {
01290                      for( int yi=static_cast<int>(startSrcY); yi < QMIN(r2_image.height(),  r_image.height()); ++yi )
01291                      {
01292                             unsigned char *s = r2_image.scanLine( yi );
01293                             unsigned char *d = r_image.scanLine( QMIN(static_cast<int>(startDstY),  r_image.height()-1) );
01294                             d += QMIN(static_cast<int>(startDstX), r_image.width()-1) * r_image.channels();
01295                             s += QMIN(static_cast<int>(startSrcX), r2_image.width()-1) * r2_image.channels();
01296                             for(int xi=static_cast<int>(startSrcX); xi < QMIN(r2_image.width(),  r_image.width()); ++xi )
01297                             {
01298                                    d[0] = s[0];
01299                                    d[1] = s[1];
01300                                    d[2] = s[2];
01301                                    if (header.color_mode == CM_RGB)
01302                                    {
01303                                           if (hasAlpha)
01304                                                  d[3] = s[3];
01305                                           else
01306                                                  d[3] = 255;
01307                                    }
01308                                    else
01309                                    {
01310                                           d[3] = s[3];
01311                                           if (hasAlpha)
01312                                                  d[4] = s[4];
01313                                           else
01314                                                  d[4] = 255;
01315                                    }
01316                                    s += r2_image.channels();
01317                                    d += r_image.channels();
01318                             }
01319                             startDstY++;
01320                      }
01321               }
01322               else
01323               {
01324                      for (int i = static_cast<int>(startSrcY); i < layerInfo[layer].height; i++)
01325                      {
01326                             unsigned char *d = r_image.scanLine(QMIN(static_cast<int>(startDstY),  r_image.height()-1));
01327                             unsigned char *s = r2_image.scanLine(QMIN(i, r2_image.height()-1));
01328                             d += QMIN(static_cast<int>(startDstX),  r_image.width()-1) * r_image.channels();
01329                             s += QMIN(static_cast<int>(startSrcX), r2_image.width()-1) * r2_image.channels();
01330                             unsigned char *sm = 0;
01331                             if (hasMask)
01332                             {
01333                                    sm = mask.scanLine(QMIN(i, mask.height()-1));
01334                                    sm += QMIN(static_cast<int>(startSrcXm), mask.width()-1) * mask.channels();
01335                             }
01336                             startDstY++;
01337                             unsigned char r, g, b, src_r, src_g, src_b, src_a, src_alpha, dst_alpha;
01338                             unsigned char a = 0;
01339                             unsigned int maxDestX = r_image.width() - startDstX + startSrcX - 1;
01340                             for (unsigned int j = startSrcX; j < QMIN(maxDestX, static_cast<unsigned int>(layerInfo[layer].width)); j++)
01341                             {
01342                                    src_r = s[0];
01343                                    src_g = s[1];
01344                                    src_b = s[2];
01345                                    src_a = s[3];
01346                                    if (hasAlpha)
01347                                    {
01348                                           if (hasMask)
01349                                           {
01350                                                  if (m_imageInfoRecord.RequestProps[layer].useMask)
01351                                                         src_alpha = sm[0];
01352                                                  else
01353                                                         src_alpha = s[channel_num - 2];
01354                                           }
01355                                           else
01356                                                  src_alpha = s[channel_num - 1];
01357                                    }
01358                                    else
01359                                           src_alpha = 255;
01360                                    if ((hasMask) && (m_imageInfoRecord.RequestProps[layer].useMask))
01361                                           src_alpha = sm[0];
01362                                    int layOpa = layerInfo[layer].opacity;
01363                                    if ((m_imageInfoRecord.isRequest) && (m_imageInfoRecord.RequestProps.contains(layer)))
01364                                           layOpa = m_imageInfoRecord.RequestProps[layer].opacity;
01365                                    QString layBlend = layerInfo[layer].blend;
01366                                    if ((m_imageInfoRecord.isRequest) && (m_imageInfoRecord.RequestProps.contains(layer)))
01367                                           layBlend = m_imageInfoRecord.RequestProps[layer].blend;
01368                                    if (layBlend != "diss")
01369                                           src_alpha = INT_MULT(src_alpha, layOpa);
01370                                    if (header.color_mode == CM_CMYK)
01371                                           dst_alpha = d[4];
01372                                    else
01373                                           dst_alpha = d[3];
01374                                    if ((dst_alpha > 0) && (src_alpha > 0))
01375                                    {
01376                                           if (layBlend == "mul ")
01377                                           {
01378                                                  src_r = INT_MULT(src_r, d[0]);
01379                                                  src_g = INT_MULT(src_g, d[1]);
01380                                                  src_b = INT_MULT(src_b, d[2]);
01381                                                  if (header.color_mode == CM_CMYK)
01382                                                         src_a = INT_MULT(src_a, d[3]);
01383                                           }
01384                                           else if (layBlend == "scrn")
01385                                           {
01386                                                  src_r = 255 - ((255-src_r) * (255-d[0]) / 128);
01387                                                  src_g = 255 - ((255-src_g) * (255-d[1]) / 128);
01388                                                  src_b = 255 - ((255-src_b) * (255-d[2]) / 128);
01389                                                  if (header.color_mode == CM_CMYK)
01390                                                         src_a = 255 - ((255-src_a) * (255-d[3]) / 128);
01391                                           }
01392                                           else if (layBlend == "over")
01393                                           {
01394                                                  src_g = d[1] < 128 ? src_g * d[1] / 128 : 255 - ((255-src_g) * (255-d[1]) / 128);
01395                                                  src_b = d[2] < 128 ? src_b * d[2] / 128 : 255 - ((255-src_b) * (255-d[2]) / 128);
01396                                                  src_a = d[3] < 128 ? src_a * d[3] / 128 : 255 - ((255-src_a) * (255-d[3]) / 128);
01397                                                  if (header.color_mode == CM_CMYK)
01398                                                         src_r = d[0] < 128 ? src_r * d[0] / 128 : 255 - ((255-src_r) * (255-d[0]) / 128);
01399                                           }
01400                                           else if (layBlend == "diff")
01401                                           {
01402                                                  src_r = d[0] > src_r ? d[0] - src_r : src_r - d[0];
01403                                                  src_g = d[1] > src_g ? d[1] - src_g : src_g - d[1];
01404                                                  src_b = d[2] > src_b ? d[2] - src_b : src_b - d[2];
01405                                                  if (header.color_mode == CM_CMYK)
01406                                                         src_a = d[3] > src_a ? d[3] - src_a : src_a - d[3];
01407                                           }
01408                                           else if (layBlend == "dark")
01409                                           {
01410                                                  src_r = d[0]  < src_r ? d[0]  : src_r;
01411                                                  src_g = d[1] < src_g ? d[1] : src_g;
01412                                                  src_b = d[2] < src_b ? d[2] : src_b;
01413                                                  if (header.color_mode == CM_CMYK)
01414                                                         src_a = d[3] < src_a ? d[3] : src_a;
01415                                           }
01416                                           else if (layBlend == "hLit")
01417                                           {
01418                                                  src_r = src_r < 128 ? src_r * d[0] / 128 : 255 - ((255-src_r) * (255-d[0]) / 128);
01419                                                  src_g = src_g < 128 ? src_g * d[1] / 128 : 255 - ((255-src_g) * (255-d[1]) / 128);
01420                                                  src_b = src_b < 128 ? src_b * d[2] / 128 : 255 - ((255-src_b) * (255-d[2]) / 128);
01421                                                  if (header.color_mode == CM_CMYK)
01422                                                         src_a = src_a < 128 ? src_a * d[3] / 128 : 255 - ((255-src_a) * (255-d[3]) / 128);
01423                                           }
01424                                           else if (layBlend == "sLit")
01425                                           {
01426                                                  src_r = src_r * d[0] / 256 + src_r * (255 - ((255-src_r)*(255-d[0]) / 256) - src_r * d[0] / 256) / 256;
01427                                                  src_g = src_g * d[1] / 256 + src_g * (255 - ((255-src_g)*(255-d[1]) / 256) - src_g * d[1] / 256) / 256;
01428                                                  src_b = src_b * d[2] / 256 + src_b * (255 - ((255-src_b)*(255-d[2]) / 256) - src_b * d[2] / 256) / 256;
01429                                                  if (header.color_mode == CM_CMYK)
01430                                                         src_a = src_a * d[3] / 256 + src_a * (255 - ((255-src_a)*(255-d[3]) / 256) - src_a * d[3] / 256) / 256;
01431                                           }
01432                                           else if (layBlend == "lite")
01433                                           {
01434                                                  src_r = d[0] < src_r ? src_r : d[0];
01435                                                  src_g = d[1] < src_g ? src_g : d[1];
01436                                                  src_b = d[2] < src_b ? src_b : d[2];
01437                                                  if (header.color_mode == CM_CMYK)
01438                                                         src_a = d[3] < src_a ? src_a : d[3];
01439                                           }
01440                                           else if (layBlend == "smud")
01441                                           {
01442                                                  src_r = d[0] + src_r - src_r * d[0] / 128;
01443                                                  src_g = d[1] + src_g - src_g * d[1] / 128;
01444                                                  src_b = d[2] + src_b - src_b * d[2] / 128;
01445                                                  if (header.color_mode == CM_CMYK)
01446                                                         src_a = d[3] + src_a - src_a * d[3] / 128;
01447                                           }
01448                                           else if (layBlend == "div ")
01449                                           {
01450                                                  src_r = src_r == 255 ? 255 : ((d[0] * 256) / (255-src_r)) > 255 ? 255 : (d[0] * 256) / (255-src_r);
01451                                                  src_g = src_g == 255 ? 255 : ((d[1] * 256) / (255-src_g)) > 255 ? 255 : (d[1] * 256) / (255-src_g);
01452                                                  src_b = src_b == 255 ? 255 : ((d[2] * 256) / (255-src_b)) > 255 ? 255 : (d[2] * 256) / (255-src_b);
01453                                                  if (header.color_mode == CM_CMYK)
01454                                                         src_a = src_a == 255 ? 255 : ((d[3] * 256) / (255-src_a)) > 255 ? 255 : (d[3] * 256) / (255-src_a);
01455                                           }
01456                                           else if (layBlend == "idiv")
01457                                           {
01458                                                  src_r = src_r == 0 ? 0 : (255 - (((255-d[0]) * 256) / src_r)) < 0 ? 0 : 255 - (((255-d[0]) * 256) / src_r);
01459                                                  src_g = src_g == 0 ? 0 : (255 - (((255-d[1]) * 256) / src_g)) < 0 ? 0 : 255 - (((255-d[1]) * 256) / src_g);
01460                                                  src_b = src_b == 0 ? 0 : (255 - (((255-d[2]) * 256) / src_b)) < 0 ? 0 : 255 - (((255-d[2]) * 256) / src_b);
01461                                                  if (header.color_mode == CM_CMYK)
01462                                                         src_a = src_a == 0 ? 0 : (255 - (((255-d[3]) * 256) / src_a)) < 0 ? 0 : 255 - (((255-d[3]) * 256) / src_a);
01463                                           }
01464                                           else if (layBlend == "hue ")
01465                                           {
01466                                                  if (header.color_mode != CM_CMYK)
01467                                                  {
01468                                                         uchar new_r = d[0];
01469                                                         uchar new_g = d[1];
01470                                                         uchar new_b = d[2];
01471                                                         RGBTOHSV(src_r, src_g, src_b);
01472                                                         RGBTOHSV(new_r, new_g, new_b);
01473                                                         new_r = src_r;
01474                                                         HSVTORGB(new_r, new_g, new_b);
01475                                                         src_r = new_r;
01476                                                         src_g = new_g;
01477                                                         src_b = new_b;
01478                                                  }
01479                                           }
01480                                           else if (layBlend == "sat ")
01481                                           {
01482                                                  if (header.color_mode != CM_CMYK)
01483                                                  {
01484                                                         uchar new_r = d[0];
01485                                                         uchar new_g = d[1];
01486                                                         uchar new_b = d[2];
01487                                                         RGBTOHSV(src_r, src_g, src_b);
01488                                                         RGBTOHSV(new_r, new_g, new_b);
01489                                                         new_g = src_g;
01490                                                         HSVTORGB(new_r, new_g, new_b);
01491                                                         src_r = new_r;
01492                                                         src_g = new_g;
01493                                                         src_b = new_b;
01494                                                  }
01495                                           }
01496                                           else if (layBlend == "lum ")
01497                                           {
01498                                                  if (header.color_mode != CM_CMYK)
01499                                                  {
01500                                                         uchar new_r = d[0];
01501                                                         uchar new_g = d[1];
01502                                                         uchar new_b = d[2];
01503                                                         RGBTOHSV(src_r, src_g, src_b);
01504                                                         RGBTOHSV(new_r, new_g, new_b);
01505                                                         new_b = src_b;
01506                                                         HSVTORGB(new_r, new_g, new_b);
01507                                                         src_r = new_r;
01508                                                         src_g = new_g;
01509                                                         src_b = new_b;
01510                                                  }
01511                                           }
01512                                           else if (layBlend == "colr")
01513                                           {
01514                                                  if (header.color_mode != CM_CMYK)
01515                                                  {
01516                                                         uchar new_r = d[0];
01517                                                         uchar new_g = d[1];
01518                                                         uchar new_b = d[2];
01519                                                         RGBTOHLS(src_r, src_g, src_b);
01520                                                         RGBTOHLS(new_r, new_g, new_b);
01521                                                         new_r = src_r;
01522                                                         new_b = src_b;
01523                                                         HLSTORGB(new_r, new_g, new_b);
01524                                                         src_r = new_r;
01525                                                         src_g = new_g;
01526                                                         src_b = new_b;
01527                                                  }
01528                                           }
01529                                    }
01530                                    if (dst_alpha == 0)
01531                                    {
01532                                           r = src_r;
01533                                           g = src_g;
01534                                           b = src_b;
01535                                           a = src_a;
01536                                    }
01537                                    else
01538                                    {
01539                                           if (src_alpha > 0)
01540                                           {
01541                                                  r = (d[0] * (255 - src_alpha) + src_r * src_alpha) / 255;
01542                                                  g = (d[1] * (255 - src_alpha) + src_g * src_alpha) / 255;
01543                                                  b = (d[2] * (255 - src_alpha) + src_b * src_alpha) / 255;
01544                                                  if (header.color_mode == CM_CMYK)
01545                                                         a = (d[3] * (255 - src_alpha) + src_a * src_alpha) / 255;
01546                                                  if (layBlend != "diss")
01547                                                         src_alpha = dst_alpha + INT_MULT(255 - dst_alpha, src_alpha);
01548                                           }
01549                                    }
01550                                    if (src_alpha > 0)
01551                                    {
01552                                           d[0] = r;
01553                                           d[1] = g;
01554                                           d[2] = b;
01555                                           if (header.color_mode == CM_CMYK)
01556                                           {
01557                                                  d[3] = a;
01558                                                  d[4] = src_alpha;
01559                                           }
01560                                           else
01561                                                  d[3] = src_alpha;
01562                                    }
01563                                    s += r2_image.channels();
01564                                    d += r_image.channels();
01565                                    if (hasMask)
01566                                           sm += mask.channels();
01567                             }
01568                      }
01569               }
01570        }
01571        *firstLayer = false;
01572        return true;
01573 }