LCOV - code coverage report
Current view: top level - libreoffice/filter/source/graphicfilter/ipsd - ipsd.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 0 365 0.0 %
Date: 2012-12-27 Functions: 0 6 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : 
      21             : #include <vcl/graph.hxx>
      22             : #include <vcl/bmpacc.hxx>
      23             : #include <vcl/outdev.hxx>
      24             : 
      25             : class FilterConfigItem;
      26             : 
      27             : //============================ PSDReader ==================================
      28             : 
      29             : #define PSD_BITMAP          0
      30             : #define PSD_GRAYSCALE       1
      31             : #define PSD_INDEXED         2
      32             : #define PSD_RGB             3
      33             : #define PSD_CMYK            4
      34             : #define PSD_MULTICHANNEL    7
      35             : #define PSD_DUOTONE         8
      36             : #define PSD_LAB             9
      37             : 
      38             : typedef struct
      39             : {
      40             :     sal_uInt32  nSignature;
      41             :     sal_uInt16  nVersion;
      42             :     sal_uInt32  nPad1;
      43             :     sal_uInt16  nPad2;
      44             :     sal_uInt16  nChannels;
      45             :     sal_uInt32  nRows;
      46             :     sal_uInt32  nColumns;
      47             :     sal_uInt16  nDepth;
      48             :     sal_uInt16  nMode;
      49             : 
      50             : } PSDFileHeader;
      51             : 
      52             : class PSDReader {
      53             : 
      54             : private:
      55             : 
      56             :     SvStream& m_rPSD;           // Die einzulesende PSD-Datei
      57             :     PSDFileHeader*      mpFileHeader;
      58             : 
      59             :     sal_uInt32          mnXResFixed;
      60             :     sal_uInt32          mnYResFixed;
      61             : 
      62             :     sal_Bool            mbStatus;
      63             :     sal_Bool            mbTransparent;
      64             : 
      65             :     Bitmap              maBmp;
      66             :     Bitmap              maMaskBmp;
      67             :     BitmapReadAccess*   mpReadAcc;
      68             :     BitmapWriteAccess*  mpWriteAcc;
      69             :     BitmapWriteAccess*  mpMaskWriteAcc;
      70             :     sal_uInt16              mnDestBitDepth;
      71             :     sal_Bool                mbCompression;  // RLE decoding
      72             :     sal_uInt8*              mpPalette;
      73             : 
      74             :     sal_Bool                ImplReadBody();
      75             :     sal_Bool                ImplReadHeader();
      76             : 
      77             : public:
      78             :     PSDReader(SvStream &rStream);
      79             :     ~PSDReader();
      80             :     sal_Bool ReadPSD(Graphic & rGraphic);
      81             : };
      82             : 
      83             : //=================== Methods of PSDReader ==============================
      84             : 
      85           0 : PSDReader::PSDReader(SvStream &rStream)
      86             :     : m_rPSD(rStream)
      87             :     , mpFileHeader(NULL)
      88             :     , mnXResFixed(0)
      89             :     , mnYResFixed(0)
      90             :     , mbStatus(sal_True)
      91             :     , mbTransparent(sal_False)
      92             :     , mpReadAcc(NULL)
      93             :     , mpWriteAcc(NULL)
      94             :     , mpMaskWriteAcc(NULL)
      95           0 :     , mpPalette(NULL)
      96             : {
      97           0 : }
      98             : 
      99           0 : PSDReader::~PSDReader()
     100             : {
     101           0 :     delete[] mpPalette;
     102           0 :     delete mpFileHeader;
     103           0 : }
     104             : 
     105             : // ------------------------------------------------------------------------
     106             : 
     107           0 : sal_Bool PSDReader::ReadPSD(Graphic & rGraphic )
     108             : {
     109           0 :     if (m_rPSD.GetError())
     110           0 :         return sal_False;
     111             : 
     112           0 :     m_rPSD.SetNumberFormatInt( NUMBERFORMAT_INT_BIGENDIAN );
     113             : 
     114             :     // read header:
     115             : 
     116           0 :     if ( ImplReadHeader() == sal_False )
     117           0 :         return sal_False;
     118             : 
     119           0 :     Size aBitmapSize( mpFileHeader->nColumns, mpFileHeader->nRows );
     120           0 :     maBmp = Bitmap( aBitmapSize, mnDestBitDepth );
     121           0 :     if ( ( mpWriteAcc = maBmp.AcquireWriteAccess() ) == NULL )
     122           0 :         mbStatus = sal_False;
     123           0 :     if ( ( mpReadAcc = maBmp.AcquireReadAccess() ) == NULL )
     124           0 :         mbStatus = sal_False;
     125           0 :     if ( mbTransparent && mbStatus )
     126             :     {
     127           0 :         maMaskBmp = Bitmap( aBitmapSize, 1 );
     128           0 :         if ( ( mpMaskWriteAcc = maMaskBmp.AcquireWriteAccess() ) == NULL )
     129           0 :             mbStatus = sal_False;
     130             :     }
     131           0 :     if ( mpPalette && mbStatus )
     132             :     {
     133           0 :         mpWriteAcc->SetPaletteEntryCount( 256 );
     134           0 :         for ( sal_uInt16 i = 0; i < 256; i++ )
     135             :         {
     136           0 :             mpWriteAcc->SetPaletteColor( i, Color( mpPalette[ i ], mpPalette[ i + 256 ], mpPalette[ i + 512 ] ) );
     137             :         }
     138             :     }
     139             :     // read bitmap data
     140           0 :     if ( mbStatus && ImplReadBody() )
     141             :     {
     142           0 :         if ( mbTransparent )
     143           0 :             rGraphic = Graphic( BitmapEx( maBmp, maMaskBmp ) );
     144             :         else
     145           0 :             rGraphic = maBmp;
     146             : 
     147           0 :         if ( mnXResFixed && mnYResFixed )
     148             :         {
     149           0 :             Point       aEmptyPoint;
     150           0 :             Fraction    aFractX( 1, mnXResFixed >> 16 );
     151           0 :             Fraction    aFractY( 1, mnYResFixed >> 16 );
     152           0 :             MapMode     aMapMode( MAP_INCH, aEmptyPoint, aFractX, aFractY );
     153           0 :             Size        aPrefSize = OutputDevice::LogicToLogic( aBitmapSize, aMapMode, MAP_100TH_MM );
     154           0 :             rGraphic.SetPrefSize( aPrefSize );
     155           0 :             rGraphic.SetPrefMapMode( MapMode( MAP_100TH_MM ) );
     156             :         }
     157             :     }
     158             :     else
     159           0 :         mbStatus = sal_False;
     160           0 :     if ( mpWriteAcc )
     161           0 :         maBmp.ReleaseAccess( mpWriteAcc );
     162           0 :     if ( mpReadAcc )
     163           0 :         maBmp.ReleaseAccess( mpReadAcc );
     164           0 :     if ( mpMaskWriteAcc )
     165           0 :         maMaskBmp.ReleaseAccess( mpMaskWriteAcc );
     166           0 :     return mbStatus;
     167             : }
     168             : 
     169             : // ------------------------------------------------------------------------
     170             : 
     171           0 : sal_Bool PSDReader::ImplReadHeader()
     172             : {
     173             :     sal_uInt16  nCompression;
     174             :     sal_uInt32  nColorLength, nResourceLength, nLayerMaskLength;
     175             : 
     176           0 :     mpFileHeader = new PSDFileHeader;
     177             : 
     178           0 :     if ( !mpFileHeader )
     179           0 :         return sal_False;
     180             : 
     181           0 :     m_rPSD >> mpFileHeader->nSignature >> mpFileHeader->nVersion >> mpFileHeader->nPad1 >>
     182           0 :         mpFileHeader->nPad2 >> mpFileHeader->nChannels >> mpFileHeader->nRows >>
     183           0 :             mpFileHeader->nColumns >> mpFileHeader->nDepth >> mpFileHeader->nMode;
     184             : 
     185           0 :     if ( ( mpFileHeader->nSignature != 0x38425053 ) || ( mpFileHeader->nVersion != 1 ) )
     186           0 :         return sal_False;
     187             : 
     188           0 :     if ( mpFileHeader->nRows == 0 || mpFileHeader->nColumns == 0 )
     189           0 :         return sal_False;
     190             : 
     191           0 :     if ( ( mpFileHeader->nRows > 30000 ) || ( mpFileHeader->nColumns > 30000 ) )
     192           0 :         return sal_False;
     193             : 
     194           0 :     sal_uInt16 nDepth = mpFileHeader->nDepth;
     195           0 :     if (!( ( nDepth == 1 ) || ( nDepth == 8 ) || ( nDepth == 16 ) ) )
     196           0 :         return sal_False;
     197             : 
     198           0 :     mnDestBitDepth = ( nDepth == 16 ) ? 8 : nDepth;
     199             : 
     200           0 :     m_rPSD >> nColorLength;
     201           0 :     if ( mpFileHeader->nMode == PSD_CMYK )
     202             :     {
     203           0 :         switch ( mpFileHeader->nChannels )
     204             :         {
     205             :             case 5 :
     206           0 :                 mbTransparent = sal_True;
     207             :             case 4 :
     208           0 :                 mnDestBitDepth = 24;
     209           0 :             break;
     210             :             default :
     211           0 :                 return sal_False;
     212             :         }
     213             :     }
     214           0 :     else switch ( mpFileHeader->nChannels )
     215             :     {
     216             :         case 2 :
     217           0 :             mbTransparent = sal_True;
     218             :         case 1 :
     219           0 :             break;
     220             :         case 4 :
     221           0 :             mbTransparent = sal_True;
     222             :         case 3 :
     223           0 :             mnDestBitDepth = 24;
     224           0 :             break;
     225             :         default:
     226           0 :             return sal_False;
     227             :     }
     228             : 
     229           0 :     switch ( mpFileHeader->nMode )
     230             :     {
     231             :         case PSD_BITMAP :
     232             :         {
     233           0 :             if ( nColorLength || ( nDepth != 1 ) )
     234           0 :                 return sal_False;
     235             :         }
     236           0 :         break;
     237             : 
     238             :         case PSD_INDEXED :
     239             :         {
     240           0 :             if ( nColorLength != 768 )      // we need the color map
     241           0 :                 return sal_False;
     242           0 :             mpPalette = new sal_uInt8[ 768 ];
     243           0 :             if ( mpPalette == NULL )
     244           0 :                 return sal_False;
     245           0 :             m_rPSD.Read( mpPalette, 768 );
     246             :         }
     247           0 :         break;
     248             : 
     249             :         case PSD_DUOTONE :                  // we'll handle the duotone color like a normal grayscale picture
     250           0 :             m_rPSD.SeekRel( nColorLength );
     251           0 :             nColorLength = 0;
     252             :         case PSD_GRAYSCALE :
     253             :         {
     254           0 :             if ( nColorLength )
     255           0 :                 return sal_False;
     256           0 :             mpPalette = new sal_uInt8[ 768 ];
     257           0 :             if ( mpPalette == NULL )
     258           0 :                 return sal_False;
     259           0 :             for ( sal_uInt16 i = 0; i < 256; i++ )
     260             :             {
     261           0 :                 mpPalette[ i ] = mpPalette[ i + 256 ] = mpPalette[ i + 512 ] = (sal_uInt8)i;
     262             :             }
     263             :         }
     264           0 :         break;
     265             : 
     266             :         case PSD_CMYK :
     267             :         case PSD_RGB :
     268             :         case PSD_MULTICHANNEL :
     269             :         case PSD_LAB :
     270             :         {
     271           0 :             if ( nColorLength )     // color table is not supported by the other graphic modes
     272           0 :                 return sal_False;
     273             :         }
     274           0 :         break;
     275             : 
     276             :         default:
     277           0 :             return sal_False;
     278             :     }
     279           0 :     m_rPSD >> nResourceLength;
     280           0 :     sal_uInt32 nLayerPos = m_rPSD.Tell() + nResourceLength;
     281             : 
     282             :     // this is a loop over the resource entries to get the resolution info
     283           0 :     while( m_rPSD.Tell() < nLayerPos )
     284             :     {
     285             :         sal_uInt8 n8;
     286             :         sal_uInt32 nType, nPStringLen, nResEntryLen;
     287             :         sal_uInt16 nUniqueID;
     288             : 
     289           0 :         m_rPSD >> nType >> nUniqueID >> n8;
     290           0 :         nPStringLen = n8;
     291           0 :         if ( nType != 0x3842494d )
     292             :             break;
     293           0 :         if ( ! ( nPStringLen & 1 ) )
     294           0 :             nPStringLen++;
     295           0 :         m_rPSD.SeekRel( nPStringLen );  // skipping the pstring
     296           0 :         m_rPSD >> nResEntryLen;
     297           0 :         if ( nResEntryLen & 1 )
     298           0 :             nResEntryLen++;             // the resource entries are padded
     299           0 :         sal_uInt32 nCurrentPos = m_rPSD.Tell();
     300           0 :         if ( ( nResEntryLen + nCurrentPos ) > nLayerPos )   // check if size
     301             :             break;                                          // is possible
     302           0 :         switch( nUniqueID )
     303             :         {
     304             :             case 0x3ed :    // UID for the resolution info
     305             :             {
     306             :                 sal_Int16   nUnit;
     307             : 
     308           0 :                 m_rPSD >> mnXResFixed >> nUnit >> nUnit
     309           0 :                        >> mnYResFixed >> nUnit >> nUnit;
     310             :             }
     311           0 :             break;
     312             :         }
     313           0 :         m_rPSD.Seek( nCurrentPos + nResEntryLen );          // set the stream to the next
     314             :     }                                                       // resource entry
     315           0 :     m_rPSD.Seek( nLayerPos );
     316           0 :     m_rPSD >> nLayerMaskLength;
     317           0 :     m_rPSD.SeekRel( nLayerMaskLength );
     318             : 
     319           0 :     m_rPSD >> nCompression;
     320           0 :     if ( nCompression == 0 )
     321             :     {
     322           0 :         mbCompression = sal_False;
     323             :     }
     324           0 :     else if ( nCompression == 1 )
     325             :     {
     326           0 :         m_rPSD.SeekRel( ( mpFileHeader->nRows * mpFileHeader->nChannels ) << 1 );
     327           0 :         mbCompression = sal_True;
     328             :     }
     329             :     else
     330           0 :         return sal_False;
     331             : 
     332           0 :     return sal_True;
     333             : }
     334             : 
     335             : // ------------------------------------------------------------------------
     336             : 
     337           0 : sal_Bool PSDReader::ImplReadBody()
     338             : {
     339             :     sal_uLong       nX, nY;
     340           0 :     char        nRunCount = 0;
     341           0 :     signed char nBitCount = -1;
     342           0 :     sal_uInt8       nDat = 0, nDummy, nRed, nGreen, nBlue;
     343           0 :     BitmapColor aBitmapColor;
     344           0 :     nX = nY = 0;
     345             : 
     346           0 :     switch ( mnDestBitDepth )
     347             :     {
     348             :         case 1 :
     349             :         {
     350           0 :             while ( nY < mpFileHeader->nRows )
     351             :             {
     352           0 :                 if ( nBitCount == -1 )
     353             :                 {
     354           0 :                     if ( mbCompression )    // else nRunCount = 0 -> so we use only single raw packets
     355           0 :                         m_rPSD >> nRunCount;
     356             :                 }
     357           0 :                 if ( nRunCount & 0x80 )     // a run length packet
     358             :                 {
     359           0 :                     if ( nBitCount == -1 )  // bits left in nDat?
     360             :                     {
     361           0 :                         m_rPSD >> nDat;
     362           0 :                         nDat ^= 0xff;
     363           0 :                         nBitCount = 7;
     364             :                     }
     365           0 :                     for ( sal_uInt16 i = 0; i < ( -nRunCount + 1 ); i++ )
     366             :                     {
     367           0 :                         mpWriteAcc->SetPixel( nY, nX, (sal_uInt8)nDat >> nBitCount-- );
     368           0 :                         if ( ++nX == mpFileHeader->nColumns )
     369             :                         {
     370           0 :                             nX = 0;
     371           0 :                             nY++;
     372           0 :                             nBitCount = -1;
     373           0 :                             if ( nY == mpFileHeader->nRows )
     374           0 :                                 break;
     375             :                         }
     376             :                     }
     377             :                 }
     378             :                 else                        // a raw packet
     379             :                 {
     380           0 :                     for ( sal_uInt16 i = 0; i < ( ( nRunCount & 0x7f ) + 1 ); i++ )
     381             :                     {
     382           0 :                         if ( nBitCount == -1 )  // bits left in nDat ?
     383             :                         {
     384           0 :                             m_rPSD >> nDat;
     385           0 :                             nDat ^= 0xff;
     386           0 :                             nBitCount = 7;
     387             :                         }
     388           0 :                         mpWriteAcc->SetPixel( nY, nX, (sal_uInt8)nDat >> nBitCount-- );
     389           0 :                         if ( ++nX == mpFileHeader->nColumns )
     390             :                         {
     391           0 :                             nX = 0;
     392           0 :                             nY++;
     393           0 :                             nBitCount = -1;
     394           0 :                             if ( nY == mpFileHeader->nRows )
     395           0 :                                 break;
     396             :                         }
     397             :                     }
     398             :                 }
     399             :             }
     400             :         }
     401           0 :         break;
     402             : 
     403             :         case 8 :
     404             :         {
     405           0 :             while ( nY < mpFileHeader->nRows )
     406             :             {
     407           0 :                 if ( mbCompression )        // else nRunCount = 0 -> so we use only single raw packets
     408           0 :                     m_rPSD >> nRunCount;
     409             : 
     410           0 :                 if ( nRunCount & 0x80 )     // a run length packet
     411             :                 {
     412           0 :                     m_rPSD >> nDat;
     413           0 :                     if ( mpFileHeader->nDepth == 16 )   // 16 bit depth is to be skipped
     414           0 :                         m_rPSD >> nDummy;
     415           0 :                     for ( sal_uInt16 i = 0; i < ( -nRunCount + 1 ); i++ )
     416             :                     {
     417           0 :                         mpWriteAcc->SetPixel( nY, nX, (sal_uInt8)nDat );
     418           0 :                         if ( ++nX == mpFileHeader->nColumns )
     419             :                         {
     420           0 :                             nX = 0;
     421           0 :                             nY++;
     422           0 :                             if ( nY == mpFileHeader->nRows )
     423           0 :                                 break;
     424             :                         }
     425             :                     }
     426             :                 }
     427             :                 else                        // a raw packet
     428             :                 {
     429           0 :                     for ( sal_uInt16 i = 0; i < ( ( nRunCount & 0x7f ) + 1 ); i++ )
     430             :                     {
     431           0 :                         m_rPSD >> nDat;
     432           0 :                         if ( mpFileHeader->nDepth == 16 )   // 16 bit depth is to be skipped
     433           0 :                             m_rPSD >> nDummy;
     434           0 :                         mpWriteAcc->SetPixel( nY, nX, (sal_uInt8)nDat );
     435           0 :                         if ( ++nX == mpFileHeader->nColumns )
     436             :                         {
     437           0 :                             nX = 0;
     438           0 :                             nY++;
     439           0 :                             if ( nY == mpFileHeader->nRows )
     440           0 :                                 break;
     441             :                         }
     442             :                     }
     443             :                 }
     444             :             }
     445             :         }
     446           0 :         break;
     447             : 
     448             :         case 24 :
     449             :         {
     450             : 
     451             :             // the psd format is in plain order (RRRR GGGG BBBB) so we have to set each pixel three times
     452             :             // maybe the format is CCCC MMMM YYYY KKKK
     453             : 
     454           0 :             while ( nY < mpFileHeader->nRows )
     455             :             {
     456           0 :                 if ( mbCompression )        // else nRunCount = 0 -> so we use only single raw packets
     457           0 :                     m_rPSD >> nRunCount;
     458             : 
     459           0 :                 if ( nRunCount & 0x80 )     // a run length packet
     460             :                 {
     461           0 :                     m_rPSD >> nRed;
     462           0 :                     if ( mpFileHeader->nDepth == 16 )   // 16 bit depth is to be skipped
     463           0 :                         m_rPSD >> nDummy;
     464           0 :                     for ( sal_uInt16 i = 0; i < ( -nRunCount + 1 ); i++ )
     465             :                     {
     466           0 :                         mpWriteAcc->SetPixel( nY, nX, BitmapColor( nRed, (sal_uInt8)0, (sal_uInt8)0 ) );
     467           0 :                         if ( ++nX == mpFileHeader->nColumns )
     468             :                         {
     469           0 :                             nX = 0;
     470           0 :                             nY++;
     471           0 :                             if ( nY == mpFileHeader->nRows )
     472           0 :                                 break;
     473             :                         }
     474             :                     }
     475             :                 }
     476             :                 else                        // a raw packet
     477             :                 {
     478           0 :                     for ( sal_uInt16 i = 0; i < ( ( nRunCount & 0x7f ) + 1 ); i++ )
     479             :                     {
     480           0 :                         m_rPSD >> nRed;
     481           0 :                         if ( mpFileHeader->nDepth == 16 )   // 16 bit depth is to be skipped
     482           0 :                             m_rPSD >> nDummy;
     483           0 :                         mpWriteAcc->SetPixel( nY, nX, BitmapColor( nRed, (sal_uInt8)0, (sal_uInt8)0 ) );
     484           0 :                         if ( ++nX == mpFileHeader->nColumns )
     485             :                         {
     486           0 :                             nX = 0;
     487           0 :                             nY++;
     488           0 :                             if ( nY == mpFileHeader->nRows )
     489           0 :                                 break;
     490             :                         }
     491             :                     }
     492             :                 }
     493             :             }
     494           0 :             nY = 0;
     495           0 :             while ( nY < mpFileHeader->nRows )
     496             :             {
     497           0 :                 if ( mbCompression )
     498           0 :                     m_rPSD >> nRunCount;
     499           0 :                 if ( nRunCount & 0x80 )     // a run length packet
     500             :                 {
     501           0 :                     m_rPSD >> nGreen;
     502           0 :                     if ( mpFileHeader->nDepth == 16 )   // 16 bit depth is to be skipped
     503           0 :                         m_rPSD >> nDummy;
     504           0 :                     for ( sal_uInt16 i = 0; i < ( -nRunCount + 1 ); i++ )
     505             :                     {
     506           0 :                         aBitmapColor = mpReadAcc->GetPixel( nY, nX );
     507           0 :                         mpWriteAcc->SetPixel( nY, nX, BitmapColor( aBitmapColor.GetRed(), nGreen, aBitmapColor.GetBlue() ) );
     508           0 :                         if ( ++nX == mpFileHeader->nColumns )
     509             :                         {
     510           0 :                             nX = 0;
     511           0 :                             nY++;
     512           0 :                             if ( nY == mpFileHeader->nRows )
     513           0 :                                 break;
     514             :                         }
     515             :                     }
     516             :                 }
     517             :                 else                        // a raw packet
     518             :                 {
     519           0 :                     for ( sal_uInt16 i = 0; i < ( ( nRunCount & 0x7f ) + 1 ); i++ )
     520             :                     {
     521           0 :                         m_rPSD >> nGreen;
     522           0 :                         if ( mpFileHeader->nDepth == 16 )   // 16 bit depth is to be skipped
     523           0 :                             m_rPSD >> nDummy;
     524           0 :                         aBitmapColor = mpReadAcc->GetPixel( nY, nX );
     525           0 :                         mpWriteAcc->SetPixel( nY, nX, BitmapColor( aBitmapColor.GetRed(), nGreen, aBitmapColor.GetBlue() ) );
     526           0 :                         if ( ++nX == mpFileHeader->nColumns )
     527             :                         {
     528           0 :                             nX = 0;
     529           0 :                             nY++;
     530           0 :                             if ( nY == mpFileHeader->nRows )
     531           0 :                                 break;
     532             :                         }
     533             :                     }
     534             :                 }
     535             :             }
     536           0 :             nY = 0;
     537           0 :             while ( nY < mpFileHeader->nRows )
     538             :             {
     539           0 :                 if ( mbCompression )
     540           0 :                     m_rPSD >> nRunCount;
     541           0 :                 if ( nRunCount & 0x80 )     // a run length packet
     542             :                 {
     543           0 :                     m_rPSD >> nBlue;
     544           0 :                     if ( mpFileHeader->nDepth == 16 )   // 16 bit depth is to be skipped
     545           0 :                         m_rPSD >> nDummy;
     546           0 :                     for ( sal_uInt16 i = 0; i < ( -nRunCount + 1 ); i++ )
     547             :                     {
     548           0 :                         aBitmapColor = mpReadAcc->GetPixel( nY, nX );
     549           0 :                         mpWriteAcc->SetPixel( nY, nX, BitmapColor( aBitmapColor.GetRed(), aBitmapColor.GetGreen(), nBlue ) );
     550           0 :                         if ( ++nX == mpFileHeader->nColumns )
     551             :                         {
     552           0 :                             nX = 0;
     553           0 :                             nY++;
     554           0 :                             if ( nY == mpFileHeader->nRows )
     555           0 :                                 break;
     556             :                         }
     557             :                     }
     558             :                 }
     559             :                 else                        // a raw packet
     560             :                 {
     561           0 :                     for ( sal_uInt16 i = 0; i < ( ( nRunCount & 0x7f ) + 1 ); i++ )
     562             :                     {
     563           0 :                         m_rPSD >> nBlue;
     564           0 :                         if ( mpFileHeader->nDepth == 16 )   // 16 bit depth is to be skipped
     565           0 :                             m_rPSD >> nDummy;
     566           0 :                         aBitmapColor = mpReadAcc->GetPixel( nY, nX );
     567           0 :                         mpWriteAcc->SetPixel( nY, nX, BitmapColor( aBitmapColor.GetRed(), aBitmapColor.GetGreen(), nBlue ) );
     568           0 :                         if ( ++nX == mpFileHeader->nColumns )
     569             :                         {
     570           0 :                             nX = 0;
     571           0 :                             nY++;
     572           0 :                             if ( nY == mpFileHeader->nRows )
     573           0 :                                 break;
     574             :                         }
     575             :                     }
     576             :                 }
     577             :             }
     578           0 :             if ( mpFileHeader->nMode == PSD_CMYK )
     579             :             {
     580           0 :                 sal_uInt32  nBlack, nBlackMax = 0;
     581           0 :                 sal_uInt8*  pBlack = new sal_uInt8[ mpFileHeader->nRows * mpFileHeader->nColumns ];
     582           0 :                 nY = 0;
     583           0 :                 while ( nY < mpFileHeader->nRows )
     584             :                 {
     585           0 :                     if ( mbCompression )        // else nRunCount = 0 -> so we use only single raw packets
     586           0 :                         m_rPSD >> nRunCount;
     587             : 
     588           0 :                     if ( nRunCount & 0x80 )     // a run length packet
     589             :                     {
     590           0 :                         m_rPSD >> nDat;
     591             : 
     592           0 :                         if ( mpFileHeader->nDepth == 16 )   // 16 bit depth is to be skipped
     593           0 :                             m_rPSD >> nDummy;
     594             : 
     595           0 :                         for ( sal_uInt16 i = 0; i < ( -nRunCount + 1 ); i++ )
     596             :                         {
     597           0 :                             nBlack = (sal_uInt8)mpReadAcc->GetPixel( nY, nX ).GetRed() + nDat;
     598           0 :                             if ( nBlack > nBlackMax )
     599           0 :                                 nBlackMax = nBlack;
     600           0 :                             nBlack = (sal_uInt8)mpReadAcc->GetPixel( nY, nX ).GetGreen() + nDat;
     601           0 :                             if ( nBlack > nBlackMax )
     602           0 :                                 nBlackMax = nBlack;
     603           0 :                             nBlack = (sal_uInt8)mpReadAcc->GetPixel( nY, nX ).GetBlue() + nDat;
     604           0 :                             if ( nBlack > nBlackMax )
     605           0 :                                 nBlackMax = nBlack;
     606           0 :                             pBlack[ nX + nY * mpFileHeader->nColumns ] = nDat ^ 0xff;
     607           0 :                             if ( ++nX == mpFileHeader->nColumns )
     608             :                             {
     609           0 :                                 nX = 0;
     610           0 :                                 nY++;
     611           0 :                             if ( nY == mpFileHeader->nRows )
     612           0 :                                 break;
     613             :                             }
     614             :                         }
     615             :                     }
     616             :                     else                        // a raw packet
     617             :                     {
     618           0 :                         for ( sal_uInt16 i = 0; i < ( ( nRunCount & 0x7f ) + 1 ); i++ )
     619             :                         {
     620           0 :                             m_rPSD >> nDat;
     621             : 
     622           0 :                             if ( mpFileHeader->nDepth == 16 )   // 16 bit depth is to be skipped
     623           0 :                                 m_rPSD >> nDummy;
     624           0 :                             nBlack = (sal_uInt8)mpReadAcc->GetPixel( nY, nX ).GetRed() + nDat;
     625           0 :                             if ( nBlack > nBlackMax )
     626           0 :                                 nBlackMax = nBlack;
     627           0 :                             nBlack = (sal_uInt8)mpReadAcc->GetPixel( nY, nX ).GetGreen() + nDat;
     628           0 :                             if ( nBlack > nBlackMax )
     629           0 :                                 nBlackMax = nBlack;
     630           0 :                             nBlack = (sal_uInt8)mpReadAcc->GetPixel( nY, nX ).GetBlue() + nDat;
     631           0 :                             if ( nBlack > nBlackMax )
     632           0 :                                 nBlackMax = nBlack;
     633           0 :                             pBlack[ nX + nY * mpFileHeader->nColumns ] = nDat ^ 0xff;
     634           0 :                             if ( ++nX == mpFileHeader->nColumns )
     635             :                             {
     636           0 :                                 nX = 0;
     637           0 :                                 nY++;
     638           0 :                                 if ( nY == mpFileHeader->nRows )
     639           0 :                                     break;
     640             :                             }
     641             :                         }
     642             :                     }
     643             :                 }
     644             : 
     645           0 :                 for ( nY = 0; nY < mpFileHeader->nRows; nY++ )
     646             :                 {
     647           0 :                     for ( nX = 0; nX < mpFileHeader->nColumns; nX++ )
     648             :                     {
     649           0 :                         sal_Int32 nDAT = pBlack[ nX + nY * mpFileHeader->nColumns ] * ( nBlackMax - 256 ) / 0x1ff;
     650             : 
     651           0 :                         aBitmapColor = mpReadAcc->GetPixel( nY, nX );
     652           0 :                         sal_uInt8 cR = (sal_uInt8) MinMax( aBitmapColor.GetRed() - nDAT, 0L, 255L );
     653           0 :                         sal_uInt8 cG = (sal_uInt8) MinMax( aBitmapColor.GetGreen() - nDAT, 0L, 255L );
     654           0 :                         sal_uInt8 cB = (sal_uInt8) MinMax( aBitmapColor.GetBlue() - nDAT, 0L, 255L );
     655           0 :                         mpWriteAcc->SetPixel( nY, nX, BitmapColor( cR, cG, cB ) );
     656             :                     }
     657             :                 }
     658           0 :                 delete[] pBlack;
     659             :             }
     660             :         }
     661           0 :         break;
     662             :     }
     663             : 
     664           0 :     if ( mbTransparent )
     665             :     {
     666             :         // the psd is 24 or 8 bit grafix + alphachannel
     667             : 
     668           0 :         nY = nX = 0;
     669           0 :         while ( nY < mpFileHeader->nRows )
     670             :         {
     671           0 :             if ( mbCompression )        // else nRunCount = 0 -> so we use only single raw packets
     672           0 :                 m_rPSD >> nRunCount;
     673             : 
     674           0 :             if ( nRunCount & 0x80 )     // a run length packet
     675             :             {
     676           0 :                 m_rPSD >> nDat;
     677           0 :                 if ( nDat )
     678           0 :                     nDat = 0;
     679             :                 else
     680           0 :                     nDat = 1;
     681           0 :                 if ( mpFileHeader->nDepth == 16 )   // 16 bit depth is to be skipped
     682           0 :                     m_rPSD >> nDummy;
     683           0 :                 for ( sal_uInt16 i = 0; i < ( -nRunCount + 1 ); i++ )
     684             :                 {
     685           0 :                     mpMaskWriteAcc->SetPixel( nY, nX, (sal_uInt8)nDat );
     686           0 :                     if ( ++nX == mpFileHeader->nColumns )
     687             :                     {
     688           0 :                         nX = 0;
     689           0 :                         nY++;
     690           0 :                         if ( nY == mpFileHeader->nRows )
     691           0 :                             break;
     692             :                     }
     693             :                 }
     694             :             }
     695             :             else                        // a raw packet
     696             :             {
     697           0 :                 for ( sal_uInt16 i = 0; i < ( ( nRunCount & 0x7f ) + 1 ); i++ )
     698             :                 {
     699           0 :                     m_rPSD >> nDat;
     700           0 :                     if ( nDat )
     701           0 :                         nDat = 0;
     702             :                     else
     703           0 :                         nDat = 1;
     704           0 :                     if ( mpFileHeader->nDepth == 16 )   // 16 bit depth is to be skipped
     705           0 :                         m_rPSD >> nDummy;
     706           0 :                     mpMaskWriteAcc->SetPixel( nY, nX, (sal_uInt8)nDat );
     707           0 :                     if ( ++nX == mpFileHeader->nColumns )
     708             :                     {
     709           0 :                         nX = 0;
     710           0 :                         nY++;
     711           0 :                         if ( nY == mpFileHeader->nRows )
     712           0 :                             break;
     713             :                     }
     714             :                 }
     715             :             }
     716             :         }
     717             :     }
     718           0 :     return sal_True;
     719             : }
     720             : 
     721             : //================== GraphicImport - the exported function ================
     722             : 
     723             : #ifdef DISABLE_DYNLOADING
     724             : #define GraphicImport ipdGraphicImport
     725             : #endif
     726             : 
     727             : extern "C" SAL_DLLPUBLIC_EXPORT sal_Bool SAL_CALL
     728           0 : GraphicImport(SvStream & rStream, Graphic & rGraphic, FilterConfigItem*, sal_Bool)
     729             : {
     730           0 :     PSDReader aPSDReader(rStream);
     731             : 
     732           0 :     return aPSDReader.ReadPSD(rGraphic);
     733             : }
     734             : 
     735             : 
     736             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10