LCOV - code coverage report
Current view: top level - filter/source/graphicfilter/ipsd - ipsd.cxx (source / functions) Hit Total Coverage
Test: commit 0e63ca4fde4e446f346e35849c756a30ca294aab Lines: 0 365 0.0 %
Date: 2014-04-11 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             : #include <boost/scoped_array.hpp>
      25             : 
      26             : class FilterConfigItem;
      27             : 
      28             : //============================ PSDReader ==================================
      29             : 
      30             : #define PSD_BITMAP          0
      31             : #define PSD_GRAYSCALE       1
      32             : #define PSD_INDEXED         2
      33             : #define PSD_RGB             3
      34             : #define PSD_CMYK            4
      35             : #define PSD_MULTICHANNEL    7
      36             : #define PSD_DUOTONE         8
      37             : #define PSD_LAB             9
      38             : 
      39             : typedef struct
      40             : {
      41             :     sal_uInt32  nSignature;
      42             :     sal_uInt16  nVersion;
      43             :     sal_uInt32  nPad1;
      44             :     sal_uInt16  nPad2;
      45             :     sal_uInt16  nChannels;
      46             :     sal_uInt32  nRows;
      47             :     sal_uInt32  nColumns;
      48             :     sal_uInt16  nDepth;
      49             :     sal_uInt16  nMode;
      50             : 
      51             : } PSDFileHeader;
      52             : 
      53             : class PSDReader {
      54             : 
      55             : private:
      56             : 
      57             :     SvStream& m_rPSD;           // Die einzulesende PSD-Datei
      58             :     PSDFileHeader*      mpFileHeader;
      59             : 
      60             :     sal_uInt32          mnXResFixed;
      61             :     sal_uInt32          mnYResFixed;
      62             : 
      63             :     sal_Bool            mbStatus;
      64             :     sal_Bool            mbTransparent;
      65             : 
      66             :     Bitmap              maBmp;
      67             :     Bitmap              maMaskBmp;
      68             :     BitmapReadAccess*   mpReadAcc;
      69             :     BitmapWriteAccess*  mpWriteAcc;
      70             :     BitmapWriteAccess*  mpMaskWriteAcc;
      71             :     sal_uInt16              mnDestBitDepth;
      72             :     sal_Bool                mbCompression;  // RLE decoding
      73             :     sal_uInt8*              mpPalette;
      74             : 
      75             :     sal_Bool                ImplReadBody();
      76             :     sal_Bool                ImplReadHeader();
      77             : 
      78             : public:
      79             :     PSDReader(SvStream &rStream);
      80             :     ~PSDReader();
      81             :     sal_Bool ReadPSD(Graphic & rGraphic);
      82             : };
      83             : 
      84             : //=================== Methods of PSDReader ==============================
      85             : 
      86           0 : PSDReader::PSDReader(SvStream &rStream)
      87             :     : m_rPSD(rStream)
      88             :     , mpFileHeader(NULL)
      89             :     , mnXResFixed(0)
      90             :     , mnYResFixed(0)
      91             :     , mbStatus(sal_True)
      92             :     , mbTransparent(sal_False)
      93             :     , mpReadAcc(NULL)
      94             :     , mpWriteAcc(NULL)
      95             :     , mpMaskWriteAcc(NULL)
      96             :     , mnDestBitDepth(0)
      97             :     , mbCompression(false)
      98           0 :     , mpPalette(NULL)
      99             : {
     100           0 : }
     101             : 
     102           0 : PSDReader::~PSDReader()
     103             : {
     104           0 :     delete[] mpPalette;
     105           0 :     delete mpFileHeader;
     106           0 : }
     107             : 
     108           0 : sal_Bool PSDReader::ReadPSD(Graphic & rGraphic )
     109             : {
     110           0 :     if (m_rPSD.GetError())
     111           0 :         return sal_False;
     112             : 
     113           0 :     m_rPSD.SetNumberFormatInt( NUMBERFORMAT_INT_BIGENDIAN );
     114             : 
     115             :     // read header:
     116             : 
     117           0 :     if ( ImplReadHeader() == sal_False )
     118           0 :         return sal_False;
     119             : 
     120           0 :     Size aBitmapSize( mpFileHeader->nColumns, mpFileHeader->nRows );
     121           0 :     maBmp = Bitmap( aBitmapSize, mnDestBitDepth );
     122           0 :     if ( ( mpWriteAcc = maBmp.AcquireWriteAccess() ) == NULL )
     123           0 :         mbStatus = sal_False;
     124           0 :     if ( ( mpReadAcc = maBmp.AcquireReadAccess() ) == NULL )
     125           0 :         mbStatus = sal_False;
     126           0 :     if ( mbTransparent && mbStatus )
     127             :     {
     128           0 :         maMaskBmp = Bitmap( aBitmapSize, 1 );
     129           0 :         if ( ( mpMaskWriteAcc = maMaskBmp.AcquireWriteAccess() ) == NULL )
     130           0 :             mbStatus = sal_False;
     131             :     }
     132           0 :     if ( mpPalette && mbStatus )
     133             :     {
     134           0 :         mpWriteAcc->SetPaletteEntryCount( 256 );
     135           0 :         for ( sal_uInt16 i = 0; i < 256; i++ )
     136             :         {
     137           0 :             mpWriteAcc->SetPaletteColor( i, Color( mpPalette[ i ], mpPalette[ i + 256 ], mpPalette[ i + 512 ] ) );
     138             :         }
     139             :     }
     140             :     // read bitmap data
     141           0 :     if ( mbStatus && ImplReadBody() )
     142             :     {
     143           0 :         if ( mbTransparent )
     144           0 :             rGraphic = Graphic( BitmapEx( maBmp, maMaskBmp ) );
     145             :         else
     146           0 :             rGraphic = maBmp;
     147             : 
     148           0 :         if ( mnXResFixed && mnYResFixed )
     149             :         {
     150           0 :             Point       aEmptyPoint;
     151           0 :             Fraction    aFractX( 1, mnXResFixed >> 16 );
     152           0 :             Fraction    aFractY( 1, mnYResFixed >> 16 );
     153           0 :             MapMode     aMapMode( MAP_INCH, aEmptyPoint, aFractX, aFractY );
     154           0 :             Size        aPrefSize = OutputDevice::LogicToLogic( aBitmapSize, aMapMode, MAP_100TH_MM );
     155           0 :             rGraphic.SetPrefSize( aPrefSize );
     156           0 :             rGraphic.SetPrefMapMode( MapMode( MAP_100TH_MM ) );
     157             :         }
     158             :     }
     159             :     else
     160           0 :         mbStatus = sal_False;
     161           0 :     if ( mpWriteAcc )
     162           0 :         maBmp.ReleaseAccess( mpWriteAcc );
     163           0 :     if ( mpReadAcc )
     164           0 :         maBmp.ReleaseAccess( mpReadAcc );
     165           0 :     if ( mpMaskWriteAcc )
     166           0 :         maMaskBmp.ReleaseAccess( mpMaskWriteAcc );
     167           0 :     return mbStatus;
     168             : }
     169             : 
     170             : 
     171             : 
     172           0 : sal_Bool PSDReader::ImplReadHeader()
     173             : {
     174             :     sal_uInt16  nCompression;
     175             :     sal_uInt32  nColorLength, nResourceLength, nLayerMaskLength;
     176             : 
     177           0 :     mpFileHeader = new PSDFileHeader;
     178             : 
     179           0 :     if ( !mpFileHeader )
     180           0 :         return sal_False;
     181             : 
     182           0 :     m_rPSD.ReadUInt32( mpFileHeader->nSignature ).ReadUInt16( mpFileHeader->nVersion ).ReadUInt32( mpFileHeader->nPad1 ).        ReadUInt16( mpFileHeader->nPad2 ).ReadUInt16( mpFileHeader->nChannels ).ReadUInt32( mpFileHeader->nRows ).            ReadUInt32( mpFileHeader->nColumns ).ReadUInt16( mpFileHeader->nDepth ).ReadUInt16( mpFileHeader->nMode );
     183             : 
     184           0 :     if ( ( mpFileHeader->nSignature != 0x38425053 ) || ( mpFileHeader->nVersion != 1 ) )
     185           0 :         return sal_False;
     186             : 
     187           0 :     if ( mpFileHeader->nRows == 0 || mpFileHeader->nColumns == 0 )
     188           0 :         return sal_False;
     189             : 
     190           0 :     if ( ( mpFileHeader->nRows > 30000 ) || ( mpFileHeader->nColumns > 30000 ) )
     191           0 :         return sal_False;
     192             : 
     193           0 :     sal_uInt16 nDepth = mpFileHeader->nDepth;
     194           0 :     if (!( ( nDepth == 1 ) || ( nDepth == 8 ) || ( nDepth == 16 ) ) )
     195           0 :         return sal_False;
     196             : 
     197           0 :     mnDestBitDepth = ( nDepth == 16 ) ? 8 : nDepth;
     198             : 
     199           0 :     m_rPSD.ReadUInt32( nColorLength );
     200           0 :     if ( mpFileHeader->nMode == PSD_CMYK )
     201             :     {
     202           0 :         switch ( mpFileHeader->nChannels )
     203             :         {
     204             :             case 5 :
     205           0 :                 mbTransparent = sal_True;
     206             :             case 4 :
     207           0 :                 mnDestBitDepth = 24;
     208           0 :             break;
     209             :             default :
     210           0 :                 return sal_False;
     211             :         }
     212             :     }
     213           0 :     else switch ( mpFileHeader->nChannels )
     214             :     {
     215             :         case 2 :
     216           0 :             mbTransparent = sal_True;
     217             :         case 1 :
     218           0 :             break;
     219             :         case 4 :
     220           0 :             mbTransparent = sal_True;
     221             :         case 3 :
     222           0 :             mnDestBitDepth = 24;
     223           0 :             break;
     224             :         default:
     225           0 :             return sal_False;
     226             :     }
     227             : 
     228           0 :     switch ( mpFileHeader->nMode )
     229             :     {
     230             :         case PSD_BITMAP :
     231             :         {
     232           0 :             if ( nColorLength || ( nDepth != 1 ) )
     233           0 :                 return sal_False;
     234             :         }
     235           0 :         break;
     236             : 
     237             :         case PSD_INDEXED :
     238             :         {
     239           0 :             if ( nColorLength != 768 )      // we need the color map
     240           0 :                 return sal_False;
     241           0 :             mpPalette = new sal_uInt8[ 768 ];
     242           0 :             if ( mpPalette == NULL )
     243           0 :                 return sal_False;
     244           0 :             m_rPSD.Read( mpPalette, 768 );
     245             :         }
     246           0 :         break;
     247             : 
     248             :         case PSD_DUOTONE :                  // we'll handle the duotone color like a normal grayscale picture
     249           0 :             m_rPSD.SeekRel( nColorLength );
     250           0 :             nColorLength = 0;
     251             :             /* Fall through */
     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.ReadUInt32( 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.ReadUInt32( nType ).ReadUInt16( nUniqueID ).ReadUChar( n8 );
     290           0 :         nPStringLen = n8;
     291           0 :         if ( nType != 0x3842494d )
     292           0 :             break;
     293           0 :         if ( ! ( nPStringLen & 1 ) )
     294           0 :             nPStringLen++;
     295           0 :         m_rPSD.SeekRel( nPStringLen );  // skipping the pstring
     296           0 :         m_rPSD.ReadUInt32( 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           0 :             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.ReadUInt32( mnXResFixed ).ReadInt16( nUnit ).ReadInt16( nUnit )
     309           0 :                       .ReadUInt32( mnYResFixed ).ReadInt16( nUnit ).ReadInt16( 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.ReadUInt32( nLayerMaskLength );
     317           0 :     m_rPSD.SeekRel( nLayerMaskLength );
     318             : 
     319           0 :     m_rPSD.ReadUInt16( 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.ReadChar( 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.ReadUChar( 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->SetPixelIndex( nY, nX, 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.ReadUChar( nDat );
     385           0 :                             nDat ^= 0xff;
     386           0 :                             nBitCount = 7;
     387             :                         }
     388           0 :                         mpWriteAcc->SetPixelIndex( nY, nX, 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.ReadChar( nRunCount );
     409             : 
     410           0 :                 if ( nRunCount & 0x80 )     // a run length packet
     411             :                 {
     412           0 :                     m_rPSD.ReadUChar( nDat );
     413           0 :                     if ( mpFileHeader->nDepth == 16 )   // 16 bit depth is to be skipped
     414           0 :                         m_rPSD.ReadUChar( nDummy );
     415           0 :                     for ( sal_uInt16 i = 0; i < ( -nRunCount + 1 ); i++ )
     416             :                     {
     417           0 :                         mpWriteAcc->SetPixelIndex( nY, nX, 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.ReadUChar( nDat );
     432           0 :                         if ( mpFileHeader->nDepth == 16 )   // 16 bit depth is to be skipped
     433           0 :                             m_rPSD.ReadUChar( nDummy );
     434           0 :                         mpWriteAcc->SetPixelIndex( nY, nX, 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.ReadChar( nRunCount );
     458             : 
     459           0 :                 if ( nRunCount & 0x80 )     // a run length packet
     460             :                 {
     461           0 :                     m_rPSD.ReadUChar( nRed );
     462           0 :                     if ( mpFileHeader->nDepth == 16 )   // 16 bit depth is to be skipped
     463           0 :                         m_rPSD.ReadUChar( 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.ReadUChar( nRed );
     481           0 :                         if ( mpFileHeader->nDepth == 16 )   // 16 bit depth is to be skipped
     482           0 :                             m_rPSD.ReadUChar( 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.ReadChar( nRunCount );
     499           0 :                 if ( nRunCount & 0x80 )     // a run length packet
     500             :                 {
     501           0 :                     m_rPSD.ReadUChar( nGreen );
     502           0 :                     if ( mpFileHeader->nDepth == 16 )   // 16 bit depth is to be skipped
     503           0 :                         m_rPSD.ReadUChar( 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.ReadUChar( nGreen );
     522           0 :                         if ( mpFileHeader->nDepth == 16 )   // 16 bit depth is to be skipped
     523           0 :                             m_rPSD.ReadUChar( 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.ReadChar( nRunCount );
     541           0 :                 if ( nRunCount & 0x80 )     // a run length packet
     542             :                 {
     543           0 :                     m_rPSD.ReadUChar( nBlue );
     544           0 :                     if ( mpFileHeader->nDepth == 16 )   // 16 bit depth is to be skipped
     545           0 :                         m_rPSD.ReadUChar( 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.ReadUChar( nBlue );
     564           0 :                         if ( mpFileHeader->nDepth == 16 )   // 16 bit depth is to be skipped
     565           0 :                             m_rPSD.ReadUChar( 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 :                 boost::scoped_array<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.ReadChar( nRunCount );
     587             : 
     588           0 :                     if ( nRunCount & 0x80 )     // a run length packet
     589             :                     {
     590           0 :                         m_rPSD.ReadUChar( nDat );
     591             : 
     592           0 :                         if ( mpFileHeader->nDepth == 16 )   // 16 bit depth is to be skipped
     593           0 :                             m_rPSD.ReadUChar( 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.ReadUChar( nDat );
     621             : 
     622           0 :                             if ( mpFileHeader->nDepth == 16 )   // 16 bit depth is to be skipped
     623           0 :                                 m_rPSD.ReadUChar( 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           0 :                 }
     658             :             }
     659             :         }
     660           0 :         break;
     661             :     }
     662             : 
     663           0 :     if ( mbTransparent )
     664             :     {
     665             :         // the psd is 24 or 8 bit grafix + alphachannel
     666             : 
     667           0 :         nY = nX = 0;
     668           0 :         while ( nY < mpFileHeader->nRows )
     669             :         {
     670           0 :             if ( mbCompression )        // else nRunCount = 0 -> so we use only single raw packets
     671           0 :                 m_rPSD.ReadChar( nRunCount );
     672             : 
     673           0 :             if ( nRunCount & 0x80 )     // a run length packet
     674             :             {
     675           0 :                 m_rPSD.ReadUChar( nDat );
     676           0 :                 if ( nDat )
     677           0 :                     nDat = 0;
     678             :                 else
     679           0 :                     nDat = 1;
     680           0 :                 if ( mpFileHeader->nDepth == 16 )   // 16 bit depth is to be skipped
     681           0 :                     m_rPSD.ReadUChar( nDummy );
     682           0 :                 for ( sal_uInt16 i = 0; i < ( -nRunCount + 1 ); i++ )
     683             :                 {
     684           0 :                     mpMaskWriteAcc->SetPixelIndex( nY, nX, nDat );
     685           0 :                     if ( ++nX == mpFileHeader->nColumns )
     686             :                     {
     687           0 :                         nX = 0;
     688           0 :                         nY++;
     689           0 :                         if ( nY == mpFileHeader->nRows )
     690           0 :                             break;
     691             :                     }
     692             :                 }
     693             :             }
     694             :             else                        // a raw packet
     695             :             {
     696           0 :                 for ( sal_uInt16 i = 0; i < ( ( nRunCount & 0x7f ) + 1 ); i++ )
     697             :                 {
     698           0 :                     m_rPSD.ReadUChar( nDat );
     699           0 :                     if ( nDat )
     700           0 :                         nDat = 0;
     701             :                     else
     702           0 :                         nDat = 1;
     703           0 :                     if ( mpFileHeader->nDepth == 16 )   // 16 bit depth is to be skipped
     704           0 :                         m_rPSD.ReadUChar( nDummy );
     705           0 :                     mpMaskWriteAcc->SetPixelIndex( nY, nX, nDat );
     706           0 :                     if ( ++nX == mpFileHeader->nColumns )
     707             :                     {
     708           0 :                         nX = 0;
     709           0 :                         nY++;
     710           0 :                         if ( nY == mpFileHeader->nRows )
     711           0 :                             break;
     712             :                     }
     713             :                 }
     714             :             }
     715             :         }
     716             :     }
     717           0 :     return sal_True;
     718             : }
     719             : 
     720             : //================== GraphicImport - the exported function ================
     721             : 
     722             : // this needs to be kept in sync with
     723             : // ImpFilterLibCacheEntry::GetImportFunction() from
     724             : // vcl/source/filter/graphicfilter.cxx
     725             : #if defined(DISABLE_DYNLOADING)
     726             : #define GraphicImport ipdGraphicImport
     727             : #endif
     728             : 
     729             : extern "C" SAL_DLLPUBLIC_EXPORT bool SAL_CALL
     730           0 : GraphicImport( SvStream & rStream, Graphic & rGraphic, FilterConfigItem* )
     731             : {
     732           0 :     PSDReader aPSDReader(rStream);
     733             : 
     734           0 :     return aPSDReader.ReadPSD(rGraphic);
     735             : }
     736             : 
     737             : 
     738             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10