LCOV - code coverage report
Current view: top level - vcl/source/filter - graphicfilter.cxx (source / functions) Hit Total Coverage
Test: commit 0e63ca4fde4e446f346e35849c756a30ca294aab Lines: 612 1020 60.0 %
Date: 2014-04-11 Functions: 39 68 57.4 %
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             : #include <config_folders.h>
      21             : 
      22             : #include <osl/mutex.hxx>
      23             : #include <comphelper/processfactory.hxx>
      24             : #include <comphelper/string.hxx>
      25             : #include <ucbhelper/content.hxx>
      26             : #include <cppuhelper/implbase1.hxx>
      27             : #include <tools/urlobj.hxx>
      28             : #include <tools/zcodec.hxx>
      29             : #include <vcl/dibtools.hxx>
      30             : #include <vcl/salctype.hxx>
      31             : #include <vcl/pngread.hxx>
      32             : #include <vcl/pngwrite.hxx>
      33             : #include <vcl/svgdata.hxx>
      34             : #include <vcl/virdev.hxx>
      35             : #include <vcl/svapp.hxx>
      36             : #include <osl/file.hxx>
      37             : #include <vcl/graphicfilter.hxx>
      38             : #include <vcl/FilterConfigItem.hxx>
      39             : #include <vcl/wmf.hxx>
      40             : #include <vcl/settings.hxx>
      41             : #include "igif/gifread.hxx"
      42             : #include "jpeg/jpeg.hxx"
      43             : #include "ixbm/xbmread.hxx"
      44             : #include "ixpm/xpmread.hxx"
      45             : #include "sgffilt.hxx"
      46             : #include "osl/module.hxx"
      47             : #include <com/sun/star/uno/Reference.h>
      48             : #include <com/sun/star/awt/Size.hpp>
      49             : #include <com/sun/star/uno/XInterface.hpp>
      50             : #include <com/sun/star/uno/XWeak.hpp>
      51             : #include <com/sun/star/uno/XAggregation.hpp>
      52             : #include <com/sun/star/lang/XTypeProvider.hpp>
      53             : #include <com/sun/star/lang/XMultiServiceFactory.hpp>
      54             : #include <com/sun/star/io/XActiveDataSource.hpp>
      55             : #include <com/sun/star/io/XOutputStream.hpp>
      56             : #include <com/sun/star/svg/XSVGWriter.hpp>
      57             : #include <com/sun/star/xml/sax/XDocumentHandler.hpp>
      58             : #include <com/sun/star/xml/sax/Writer.hpp>
      59             : #include <com/sun/star/ucb/CommandAbortedException.hpp>
      60             : #include <unotools/ucbstreamhelper.hxx>
      61             : #include <unotools/localfilehelper.hxx>
      62             : #include <rtl/bootstrap.hxx>
      63             : #include <rtl/instance.hxx>
      64             : #include <vcl/metaact.hxx>
      65             : #include <vector>
      66             : #include <boost/scoped_array.hpp>
      67             : #include <boost/scoped_ptr.hpp>
      68             : 
      69             : #include "FilterConfigCache.hxx"
      70             : 
      71             : #define PMGCHUNG_msOG       0x6d734f47      // Microsoft Office Animated GIF
      72             : 
      73             : #ifndef DISABLE_DYNLOADING
      74             : #define IMPORT_FUNCTION_NAME    "GraphicImport"
      75             : #define EXPORT_FUNCTION_NAME    "GraphicExport"
      76             : #endif
      77             : 
      78             : using namespace ::rtl;
      79             : using namespace ::com::sun::star;
      80             : 
      81             : using comphelper::string::getTokenCount;
      82             : using comphelper::string::getToken;
      83             : 
      84             : typedef ::std::vector< GraphicFilter* > FilterList_impl;
      85             : static FilterList_impl* pFilterHdlList = NULL;
      86             : 
      87         206 : static ::osl::Mutex& getListMutex()
      88             : {
      89         206 :     static ::osl::Mutex s_aListProtection;
      90         206 :     return s_aListProtection;
      91             : }
      92             : 
      93             : class ImpFilterOutputStream : public ::cppu::WeakImplHelper1< css::io::XOutputStream >
      94             : {
      95             : protected:
      96             : 
      97             :     SvStream&               mrStm;
      98             : 
      99           0 :     virtual void SAL_CALL   writeBytes( const css::uno::Sequence< sal_Int8 >& rData )
     100             :         throw (css::io::NotConnectedException, css::io::BufferSizeExceededException, css::io::IOException, css::uno::RuntimeException, std::exception) SAL_OVERRIDE
     101           0 :         { mrStm.Write( rData.getConstArray(), rData.getLength() ); }
     102           0 :     virtual void SAL_CALL   flush()
     103             :         throw (css::io::NotConnectedException, css::io::BufferSizeExceededException, css::io::IOException, css::uno::RuntimeException, std::exception) SAL_OVERRIDE
     104           0 :         { mrStm.Flush(); }
     105           0 :     virtual void SAL_CALL   closeOutput() throw(std::exception) SAL_OVERRIDE {}
     106             : 
     107             : public:
     108             : 
     109           0 :     ImpFilterOutputStream( SvStream& rStm ) : mrStm( rStm ) {}
     110           0 :     virtual ~ImpFilterOutputStream() {}
     111             : };
     112             : 
     113             : #ifndef DISABLE_EXPORT
     114             : 
     115           0 : static bool DirEntryExists( const INetURLObject& rObj )
     116             : {
     117           0 :     bool bExists = false;
     118             : 
     119             :     try
     120             :     {
     121             :         ::ucbhelper::Content aCnt( rObj.GetMainURL( INetURLObject::NO_DECODE ),
     122             :                              css::uno::Reference< css::ucb::XCommandEnvironment >(),
     123           0 :                              comphelper::getProcessComponentContext() );
     124             : 
     125           0 :         bExists = aCnt.isDocument();
     126             :     }
     127           0 :     catch(const css::ucb::CommandAbortedException&)
     128             :     {
     129             :         SAL_WARN( "vcl.filter", "CommandAbortedException" );
     130             :     }
     131           0 :     catch(const css::ucb::ContentCreationException&)
     132             :     {
     133             :         SAL_WARN( "vcl.filter", "ContentCreationException" );
     134             :     }
     135           0 :     catch( ... )
     136             :     {
     137             :         SAL_WARN( "vcl.filter", "Any other exception" );
     138             :     }
     139           0 :     return bExists;
     140             : }
     141             : 
     142           0 : static void KillDirEntry( const OUString& rMainUrl )
     143             : {
     144             :     try
     145             :     {
     146             :         ::ucbhelper::Content aCnt( rMainUrl,
     147             :                              css::uno::Reference< css::ucb::XCommandEnvironment >(),
     148           0 :                              comphelper::getProcessComponentContext() );
     149             : 
     150             :         aCnt.executeCommand( "delete",
     151           0 :                              css::uno::makeAny( true ) );
     152             :     }
     153           0 :     catch(const css::ucb::CommandAbortedException&)
     154             :     {
     155             :         SAL_WARN( "vcl.filter", "CommandAbortedException" );
     156             :     }
     157           0 :     catch( ... )
     158             :     {
     159             :         SAL_WARN( "vcl.filter", "Any other exception" );
     160             :     }
     161           0 : }
     162             : 
     163             : #endif // !DISABLE_EXPORT
     164             : 
     165             : // Helper functions
     166             : 
     167        2410 : sal_uInt8* ImplSearchEntry( sal_uInt8* pSource, sal_uInt8* pDest, sal_uLong nComp, sal_uLong nSize )
     168             : {
     169      816810 :     while ( nComp-- >= nSize )
     170             :     {
     171             :         sal_uLong i;
     172      828141 :         for ( i = 0; i < nSize; i++ )
     173             :         {
     174      826979 :             if ( ( pSource[i]&~0x20 ) != ( pDest[i]&~0x20 ) )
     175      811990 :                 break;
     176             :         }
     177      813152 :         if ( i == nSize )
     178        1162 :             return pSource;
     179      811990 :         pSource++;
     180             :     }
     181        1248 :     return NULL;
     182             : }
     183             : 
     184         204 : inline OUString ImpGetExtension( const OUString &rPath )
     185             : {
     186         204 :     OUString        aExt;
     187         408 :     INetURLObject   aURL( rPath );
     188         204 :     aExt = aURL.GetFileExtension().toAsciiUpperCase();
     189         408 :     return aExt;
     190             : }
     191             : 
     192         456 : bool isPCT(SvStream& rStream, sal_uLong nStreamPos, sal_uLong nStreamLen)
     193             : {
     194             :     sal_uInt8 sBuf[3];
     195             :     // store number format
     196         456 :     sal_uInt16 oldNumberFormat = rStream.GetNumberFormatInt();
     197             :     sal_uInt32 nOffset; // in MS documents the pict format is used without the first 512 bytes
     198        2478 :     for ( nOffset = 0; ( nOffset <= 512 ) && ( ( nStreamPos + nOffset + 14 ) <= nStreamLen ); nOffset += 512 )
     199             :     {
     200             :         short y1,x1,y2,x2;
     201         906 :         bool bdBoxOk = true;
     202             : 
     203         906 :         rStream.Seek( nStreamPos + nOffset);
     204             :         // size of the pict in version 1 pict ( 2bytes) : ignored
     205         906 :         rStream.SeekRel(2);
     206             :         // bounding box (bytes 2 -> 9)
     207         906 :         rStream.SetNumberFormatInt(NUMBERFORMAT_INT_BIGENDIAN);
     208         906 :         rStream.ReadInt16( y1 ).ReadInt16( x1 ).ReadInt16( y2 ).ReadInt16( x2 );
     209         906 :         rStream.SetNumberFormatInt(oldNumberFormat); // reset format
     210             : 
     211        1313 :         if (x1 > x2 || y1 > y2 || // bad bdbox
     212         815 :             (x1 == x2 && y1 == y2) || // 1 pixel picture
     213         451 :             x2-x1 > 2048 || y2-y1 > 2048 ) // picture anormaly big
     214         774 :           bdBoxOk = false;
     215             : 
     216             :         // read version op
     217         906 :         rStream.Read( sBuf,3 );
     218             :         // see http://developer.apple.com/legacy/mac/library/documentation/mac/pdf/Imaging_With_QuickDraw/Appendix_A.pdf
     219             :         // normal version 2 - page A23 and A24
     220         906 :         if ( sBuf[ 0 ] == 0x00 && sBuf[ 1 ] == 0x11 && sBuf[ 2 ] == 0x02)
     221         246 :             return true;
     222             :         // normal version 1 - page A25
     223         783 :         else if (sBuf[ 0 ] == 0x11 && sBuf[ 1 ] == 0x01 && bdBoxOk)
     224           0 :             return true;
     225             :     }
     226         333 :     return false;
     227             : }
     228             : 
     229             : /*************************************************************************
     230             :  *
     231             :  *    ImpPeekGraphicFormat()
     232             :  *
     233             :  *    Description:
     234             :  *        This function is two-fold:
     235             :  *        1.) Start reading file, determine the file format:
     236             :  *            Input parameters:
     237             :  *              rPath            - file path
     238             :  *              rFormatExtension - content matter
     239             :  *              bTest            - set false
     240             :  *            Output parameters:
     241             :  *              Return value     - true if success
     242             :  *              rFormatExtension - on success: normal file extension in capitals
     243             :  *        2.) Start reading file, verify file format
     244             :  *            Input parameters:
     245             :  *              rPath            - file path
     246             :  *              rFormatExtension - normal file extension in capitals
     247             :  *              bTest            - set true
     248             :  *            Output parameters:
     249             :  *              Return value    - false, if cannot verify the file type
     250             :  *                                  passed to the function
     251             :  *                                 true, when the format is PROBABLY verified or
     252             :  *                                 WHEN THE FORMAT IS NOT KNOWN!
     253             :  *
     254             :  *************************************************************************/
     255             : 
     256        6596 : static bool ImpPeekGraphicFormat( SvStream& rStream, OUString& rFormatExtension, bool bTest )
     257             : {
     258             :     sal_uInt16  i;
     259             :     sal_uInt8   sFirstBytes[ 256 ];
     260             :     sal_uLong   nFirstLong,nSecondLong;
     261        6596 :     sal_uLong   nStreamPos = rStream.Tell();
     262             : 
     263        6596 :     rStream.Seek( STREAM_SEEK_TO_END );
     264        6596 :     sal_uLong nStreamLen = rStream.Tell() - nStreamPos;
     265        6596 :     rStream.Seek( nStreamPos );
     266             : 
     267        6596 :     if ( !nStreamLen )
     268             :     {
     269           5 :         SvLockBytes* pLockBytes = rStream.GetLockBytes();
     270           5 :         if ( pLockBytes  )
     271           0 :             pLockBytes->SetSynchronMode( true );
     272             : 
     273           5 :         rStream.Seek( STREAM_SEEK_TO_END );
     274           5 :         nStreamLen = rStream.Tell() - nStreamPos;
     275           5 :         rStream.Seek( nStreamPos );
     276             :     }
     277        6596 :     if (!nStreamLen)
     278             :     {
     279           5 :         return false; // this prevents at least a STL assertion
     280             :     }
     281        6591 :     else if (nStreamLen >= 256)
     282             :     {   // load first 256 bytes into a buffer
     283        6319 :         rStream.Read( sFirstBytes, 256 );
     284             :     }
     285             :     else
     286             :     {
     287         272 :         rStream.Read( sFirstBytes, nStreamLen );
     288             : 
     289       13111 :         for( i = (sal_uInt16) nStreamLen; i < 256; i++ )
     290       12839 :             sFirstBytes[ i ]=0;
     291             :     }
     292             : 
     293        6591 :     if( rStream.GetError() )
     294         168 :         return false;
     295             : 
     296             :     // Accommodate the first 8 bytes in nFirstLong, nSecondLong
     297             :     // Big-Endian:
     298       32115 :     for( i = 0, nFirstLong = 0L, nSecondLong = 0L; i < 4; i++ )
     299             :     {
     300       25692 :         nFirstLong=(nFirstLong<<8)|(sal_uLong)sFirstBytes[i];
     301       25692 :         nSecondLong=(nSecondLong<<8)|(sal_uLong)sFirstBytes[i+4];
     302             :     }
     303             : 
     304             :     // The following variable is used when bTest == true. It remains false
     305             :     // if the format (rFormatExtension) has not yet been set.
     306        6423 :     bool bSomethingTested = false;
     307             : 
     308             :     // Now the different formats are checked. The order *does* matter. e.g. a MET file
     309             :     // could also go through the BMP test, however, a BMP file can hardly go through the MET test.
     310             :     // So MET should be tested prior to BMP. However, theoretically a BMP file could conceivably
     311             :     // go through the MET test. These problems are of course not only in MET and BMP.
     312             :     // Therefore, in the case of a format check (bTest == true)  we only test *exactly* this
     313             :     // format. Everything else could have fatal consequences, for example if the user says it is
     314             :     // a BMP file (and it is a BMP) file, and the file would go through the MET test ...
     315             :     //--------------------------- MET ------------------------------------
     316        6423 :     if( !bTest || rFormatExtension.startsWith( "MET" ) )
     317             :     {
     318        6412 :         bSomethingTested=true;
     319        6412 :         if( sFirstBytes[2] == 0xd3 )
     320             :         {
     321           0 :             rStream.SetNumberFormatInt( NUMBERFORMAT_INT_BIGENDIAN );
     322           0 :             rStream.Seek( nStreamPos );
     323             :             sal_uInt16 nFieldSize;
     324             :             sal_uInt8 nMagic;
     325           0 :             bool bOK=true;
     326           0 :             rStream.ReadUInt16( nFieldSize ).ReadUChar( nMagic );
     327           0 :             for (i=0; i<3; i++) {
     328           0 :                 if (nFieldSize<6) { bOK=false; break; }
     329           0 :                 if (nStreamLen < rStream.Tell() + nFieldSize ) { bOK=false; break; }
     330           0 :                 rStream.SeekRel(nFieldSize-3);
     331           0 :                 rStream.ReadUInt16( nFieldSize ).ReadUChar( nMagic );
     332           0 :                 if (nMagic!=0xd3) { bOK=false; break; }
     333             :             }
     334           0 :             rStream.SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
     335           0 :             if (bOK && !rStream.GetError()) {
     336           0 :                 rFormatExtension = "MET";
     337           0 :                 return true;
     338             :             }
     339             :         }
     340             :     }
     341             : 
     342             :     //--------------------------- BMP ------------------------------------
     343        6423 :     if( !bTest || rFormatExtension.startsWith( "BMP" )  )
     344             :     {
     345             :         sal_uInt8 nOffs;
     346             : 
     347        6412 :         bSomethingTested=true;
     348             : 
     349             :         // We're possibly also able to read an OS/2 bitmap array
     350             :         // ('BA'), therefore we must adjust the offset to discover the
     351             :         // first bitmap in the array
     352        6412 :         if ( sFirstBytes[0] == 0x42 && sFirstBytes[1] == 0x41 )
     353           0 :             nOffs = 14;
     354             :         else
     355        6412 :             nOffs = 0;
     356             : 
     357             :         // Now we initially test on 'BM'
     358        6412 :         if ( sFirstBytes[0+nOffs]==0x42 && sFirstBytes[1+nOffs]==0x4d )
     359             :         {
     360             : 
     361             :             // OS/2 can set the Reserved flags to a value other than 0
     362             :             // (which they really should not do...);
     363             :             // In this case we test the size of the BmpInfoHeaders
     364          18 :             if ( ( sFirstBytes[6+nOffs]==0x00 &&
     365          18 :                    sFirstBytes[7+nOffs]==0x00 &&
     366          18 :                    sFirstBytes[8+nOffs]==0x00 &&
     367           9 :                    sFirstBytes[9+nOffs]==0x00 ) ||
     368           0 :                    sFirstBytes[14+nOffs] == 0x28 ||
     369           0 :                    sFirstBytes[14+nOffs] == 0x0c )
     370             :             {
     371           9 :                 rFormatExtension = "BMP";
     372           9 :                 return true;
     373             :             }
     374             :         }
     375             :     }
     376             : 
     377             :     //--------------------------- WMF/EMF ------------------------------------
     378             : 
     379       12839 :     if( !bTest ||
     380        6425 :         rFormatExtension.startsWith( "WMF" ) ||
     381          11 :         rFormatExtension.startsWith( "EMF" ) )
     382             :     {
     383        6403 :         bSomethingTested = true;
     384             : 
     385        6403 :         if ( nFirstLong==0xd7cdc69a || nFirstLong==0x01000900 )
     386             :         {
     387          89 :             rFormatExtension = "WMF";
     388          89 :             return true;
     389             :         }
     390        6384 :         else if( nFirstLong == 0x01000000 && sFirstBytes[ 40 ] == 0x20 && sFirstBytes[ 41 ] == 0x45 &&
     391         140 :             sFirstBytes[ 42 ] == 0x4d && sFirstBytes[ 43 ] == 0x46 )
     392             :         {
     393          70 :             rFormatExtension = "EMF";
     394          70 :             return true;
     395             :         }
     396             :     }
     397             : 
     398             :     //--------------------------- PCX ------------------------------------
     399        6255 :     if( !bTest || rFormatExtension.startsWith( "PCX" ) )
     400             :     {
     401        6244 :         bSomethingTested=true;
     402        6244 :         if (sFirstBytes[0]==0x0a)
     403             :         {
     404           1 :             sal_uInt8 nVersion=sFirstBytes[1];
     405           1 :             sal_uInt8 nEncoding=sFirstBytes[2];
     406           1 :             if( ( nVersion==0 || nVersion==2 || nVersion==3 || nVersion==5 ) && nEncoding<=1 )
     407             :             {
     408           0 :                 rFormatExtension = "PCX";
     409           0 :                 return true;
     410             :             }
     411             :         }
     412             :     }
     413             : 
     414             :     //--------------------------- TIF ------------------------------------
     415        6255 :     if( !bTest || rFormatExtension.startsWith( "TIF" ) )
     416             :     {
     417        6244 :         bSomethingTested=true;
     418        6244 :         if ( nFirstLong==0x49492a00 || nFirstLong==0x4d4d002a )
     419             :         {
     420           0 :             rFormatExtension = "TIF";
     421           0 :             return true;
     422             :         }
     423             :     }
     424             : 
     425             :     //--------------------------- GIF ------------------------------------
     426        6255 :     if( !bTest || rFormatExtension.startsWith( "GIF" ) )
     427             :     {
     428        6244 :         bSomethingTested=true;
     429        6244 :         if ( nFirstLong==0x47494638 && (sFirstBytes[4]==0x37 || sFirstBytes[4]==0x39) && sFirstBytes[5]==0x61 )
     430             :         {
     431          52 :             rFormatExtension = "GIF";
     432          52 :             return true;
     433             :         }
     434             :     }
     435             : 
     436             :     //--------------------------- PNG ------------------------------------
     437        6203 :     if( !bTest || rFormatExtension.startsWith( "PNG" ) )
     438             :     {
     439        6199 :         bSomethingTested=true;
     440        6199 :         if (nFirstLong==0x89504e47 && nSecondLong==0x0d0a1a0a)
     441             :         {
     442         617 :             rFormatExtension = "PNG";
     443         617 :             return true;
     444             :         }
     445             :     }
     446             : 
     447             :     //--------------------------- JPG ------------------------------------
     448        5586 :     if( !bTest || rFormatExtension.startsWith( "JPG" ) )
     449             :     {
     450        5586 :         bSomethingTested=true;
     451        5586 :         if ( ( nFirstLong==0xffd8ffe0 && sFirstBytes[6]==0x4a && sFirstBytes[7]==0x46 && sFirstBytes[8]==0x49 && sFirstBytes[9]==0x46 ) ||
     452        5477 :              ( nFirstLong==0xffd8fffe ) || ( 0xffd8ff00 == ( nFirstLong & 0xffffff00 ) ) )
     453             :         {
     454         111 :             rFormatExtension = "JPG";
     455         111 :             return true;
     456             :         }
     457             :     }
     458             : 
     459             :     //--------------------------- SVM ------------------------------------
     460        5475 :     if( !bTest || rFormatExtension.startsWith( "SVM" ) )
     461             :     {
     462        5475 :         bSomethingTested=true;
     463        5475 :         if( nFirstLong==0x53564744 && sFirstBytes[4]==0x49 )
     464             :         {
     465           0 :             rFormatExtension = "SVM";
     466           0 :             return true;
     467             :         }
     468       10494 :         else if( sFirstBytes[0]==0x56 && sFirstBytes[1]==0x43 && sFirstBytes[2]==0x4C &&
     469       10038 :                  sFirstBytes[3]==0x4D && sFirstBytes[4]==0x54 && sFirstBytes[5]==0x46 )
     470             :         {
     471        5019 :             rFormatExtension = "SVM";
     472        5019 :             return true;
     473             :         }
     474             :     }
     475             : 
     476             :     //--------------------------- PCD ------------------------------------
     477         456 :     if( !bTest || rFormatExtension.startsWith( "PCD" ) )
     478             :     {
     479         456 :         bSomethingTested = true;
     480         456 :         if( nStreamLen >= 2055 )
     481             :         {
     482             :             char sBuf[8];
     483         284 :             rStream.Seek( nStreamPos + 2048 );
     484         284 :             rStream.Read( sBuf, 7 );
     485             : 
     486         284 :             if( strncmp( sBuf, "PCD_IPI", 7 ) == 0 )
     487             :             {
     488           0 :                 rFormatExtension = "PCD";
     489           0 :                 return true;
     490             :             }
     491             :         }
     492             :     }
     493             : 
     494             :     //--------------------------- PSD ------------------------------------
     495         456 :     if( !bTest || rFormatExtension.startsWith( "PSD" ) )
     496             :     {
     497         456 :         bSomethingTested = true;
     498         456 :         if ( ( nFirstLong == 0x38425053 ) && ( (nSecondLong >> 16 ) == 1 ) )
     499             :         {
     500           0 :             rFormatExtension = "PSD";
     501           0 :             return true;
     502             :         }
     503             :     }
     504             : 
     505             :     //--------------------------- EPS ------------------------------------
     506         456 :     if( !bTest || rFormatExtension.startsWith( "EPS" ) )
     507             :     {
     508         456 :         bSomethingTested = true;
     509         456 :         if ( ( nFirstLong == 0xC5D0D3C6 ) || ( ImplSearchEntry( sFirstBytes, (sal_uInt8*)"%!PS-Adobe", 10, 10 ) &&
     510           0 :              ImplSearchEntry( &sFirstBytes[15], (sal_uInt8*)"EPS", 3, 3 ) ) )
     511             :         {
     512           0 :             rFormatExtension = "EPS";
     513           0 :             return true;
     514             :         }
     515             :     }
     516             : 
     517             :     //--------------------------- DXF ------------------------------------
     518         456 :     if( !bTest || rFormatExtension.startsWith( "DXF" ) )
     519             :     {
     520             :         // Binary DXF File Format
     521         456 :         if( strncmp( (const char*) sFirstBytes, "AutoCAD Binary DXF", 18 ) == 0 )
     522             :         {
     523           0 :             rFormatExtension = "DXF";
     524           0 :             return true;
     525             :         }
     526             : 
     527             :         // ASCII DXF File Format
     528         456 :         i=0;
     529       31386 :         while (i<256 && sFirstBytes[i]<=32)
     530       30474 :             ++i;
     531             : 
     532         456 :         if (i<256 && sFirstBytes[i]=='0')
     533             :         {
     534           0 :             ++i;
     535             : 
     536             :             // only now do we have sufficient data to make a judgement
     537             :             // based on a '0' + 'SECTION' == DXF argument
     538           0 :             bSomethingTested=true;
     539             : 
     540           0 :             while( i<256 && sFirstBytes[i]<=32 )
     541           0 :                 ++i;
     542             : 
     543           0 :             if (i+7<256 && (strncmp((const char*)(sFirstBytes+i),"SECTION",7)==0))
     544             :             {
     545           0 :                 rFormatExtension = "DXF";
     546           0 :                 return true;
     547             :             }
     548             :         }
     549             : 
     550             :     }
     551             : 
     552             :     //--------------------------- PCT ------------------------------------
     553         456 :     if( !bTest || rFormatExtension.startsWith( "PCT" ) )
     554             :     {
     555         456 :         bSomethingTested = true;
     556         456 :         if (isPCT(rStream, nStreamPos, nStreamLen))
     557             :         {
     558         123 :             rFormatExtension = "PCT";
     559         123 :             return true;
     560             :         }
     561             :     }
     562             : 
     563             :     //------------------------- PBM + PGM + PPM ---------------------------
     564         666 :     if( !bTest ||
     565           0 :         rFormatExtension.startsWith( "PBM" ) ||
     566         333 :         rFormatExtension.startsWith( "PGM" ) ||
     567           0 :         rFormatExtension.startsWith( "PPM" ) )
     568             :     {
     569         333 :         bSomethingTested=true;
     570         333 :         if ( sFirstBytes[ 0 ] == 'P' )
     571             :         {
     572           1 :             switch( sFirstBytes[ 1 ] )
     573             :             {
     574             :                 case '1' :
     575             :                 case '4' :
     576           0 :                     rFormatExtension = "PBM";
     577           0 :                 return true;
     578             : 
     579             :                 case '2' :
     580             :                 case '5' :
     581           0 :                     rFormatExtension = "PGM";
     582           0 :                 return true;
     583             : 
     584             :                 case '3' :
     585             :                 case '6' :
     586           1 :                     rFormatExtension = "PPM";
     587           1 :                 return true;
     588             :             }
     589             :         }
     590             :     }
     591             : 
     592             :     //--------------------------- RAS( SUN RasterFile )------------------
     593         332 :     if( !bTest || rFormatExtension.startsWith( "RAS" ) )
     594             :     {
     595         332 :         bSomethingTested=true;
     596         332 :         if( nFirstLong == 0x59a66a95 )
     597             :         {
     598           0 :             rFormatExtension = "RAS";
     599           0 :             return true;
     600             :         }
     601             :     }
     602             : 
     603             :     //--------------------------- XPM ------------------------------------
     604         332 :     if( !bTest )
     605             :     {
     606         332 :         bSomethingTested = true;
     607         332 :         if( ImplSearchEntry( sFirstBytes, (sal_uInt8*)"/* XPM */", 256, 9 ) )
     608             :         {
     609           0 :             rFormatExtension = "XPM";
     610           0 :             return true;
     611             :         }
     612             :     }
     613           0 :     else if( rFormatExtension.startsWith( "XPM" ) )
     614             :     {
     615           0 :         bSomethingTested = true;
     616           0 :         return true;
     617             :     }
     618             : 
     619             :     //--------------------------- XBM ------------------------------------
     620         332 :     if( !bTest )
     621             :     {
     622         332 :         sal_uLong nSize = ( nStreamLen > 2048 ) ? 2048 : nStreamLen;
     623         332 :         boost::scoped_array<sal_uInt8> pBuf(new sal_uInt8 [ nSize ]);
     624             : 
     625         332 :         rStream.Seek( nStreamPos );
     626         332 :         rStream.Read( pBuf.get(), nSize );
     627         332 :         sal_uInt8* pPtr = ImplSearchEntry( pBuf.get(), (sal_uInt8*)"#define", nSize, 7 );
     628             : 
     629         332 :         if( pPtr )
     630             :         {
     631           0 :             if( ImplSearchEntry( pPtr, (sal_uInt8*)"_width", pBuf.get() + nSize - pPtr, 6 ) )
     632             :             {
     633           0 :                 rFormatExtension = "XBM";
     634           0 :                 return true;
     635             :             }
     636         332 :         }
     637             :     }
     638           0 :     else if( rFormatExtension.startsWith( "XBM" ) )
     639             :     {
     640           0 :         bSomethingTested = true;
     641           0 :         return true;
     642             :     }
     643             : 
     644             :     //--------------------------- SVG ------------------------------------
     645         332 :     if( !bTest )
     646             :     {
     647         332 :         sal_uInt8* pCheckArray = sFirstBytes;
     648         332 :         sal_uLong nCheckSize = nStreamLen < 256 ? nStreamLen : 256;
     649             : 
     650             :         sal_uInt8 sExtendedOrDecompressedFirstBytes[2048];
     651         332 :         sal_uLong nDecompressedSize = nCheckSize;
     652             : 
     653         332 :         bool bIsGZip(false);
     654             : 
     655             :         // check if it is gzipped -> svgz
     656         332 :         if(sFirstBytes[0] == 0x1F && sFirstBytes[1] == 0x8B)
     657             :         {
     658           0 :             GZCodec aCodec;
     659           0 :             rStream.Seek(nStreamPos);
     660           0 :             aCodec.BeginCompression();
     661           0 :             nDecompressedSize = aCodec.Read(rStream, sExtendedOrDecompressedFirstBytes, 2048);
     662           0 :             nCheckSize = nDecompressedSize < 256 ? nDecompressedSize : 256;
     663           0 :             aCodec.EndCompression();
     664           0 :             pCheckArray = sExtendedOrDecompressedFirstBytes;
     665             :         }
     666             : 
     667         332 :         bool bIsSvg(false);
     668             : 
     669             :         // check for Xml
     670             :         // #119176# SVG files which have no xml header at all have shown up this is optional
     671         664 :         if( ImplSearchEntry(pCheckArray, (sal_uInt8*)"<?xml", nCheckSize, 5 ) // is it xml
     672         332 :             && ImplSearchEntry(pCheckArray, (sal_uInt8*)"version", nCheckSize, 7 )) // does it have a version (required for xml)
     673             :         {
     674             : 
     675             :             // check for DOCTYPE svg combination
     676         588 :             if( ImplSearchEntry(pCheckArray, (sal_uInt8*)"DOCTYPE", nCheckSize, 7 ) // 'DOCTYPE' is there
     677         294 :                 && ImplSearchEntry(pCheckArray, (sal_uInt8*)"svg", nCheckSize, 3 )) // 'svg' is there
     678             :             {
     679         280 :                 bIsSvg = true;
     680             :             }
     681             :         }
     682             : 
     683             :         // check for svg element in 1st 256 bytes
     684         332 :         if(!bIsSvg && ImplSearchEntry(pCheckArray, (sal_uInt8*)"<svg", nCheckSize, 4 )) // '<svg'
     685             :         {
     686          14 :             bIsSvg = true;
     687             :         }
     688             : 
     689             :         // extended search for svg element
     690         332 :         if(!bIsSvg)
     691             :         {
     692             :             // it's a xml, look for '<svg' in full file. Should not happen too
     693             :             // often since the tests above will handle most cases, but can happen
     694             :             // with Svg files containing big comment headers or Svg as the host
     695             :             // language
     696             : 
     697          38 :             pCheckArray = sExtendedOrDecompressedFirstBytes;
     698             : 
     699          38 :             if(!bIsGZip)
     700             :             {
     701          38 :                 nCheckSize = nDecompressedSize < 2048 ? nDecompressedSize : 2048;
     702             :             }
     703             :             else
     704             :             {
     705           0 :                 nCheckSize = nStreamLen < 2048 ? nStreamLen : 2048;
     706           0 :                 rStream.Seek(nStreamPos);
     707           0 :                 rStream.Read(sExtendedOrDecompressedFirstBytes, nCheckSize);
     708             :             }
     709             : 
     710          38 :             if(ImplSearchEntry(pCheckArray, (sal_uInt8*)"<svg", nCheckSize, 4)) // '<svg'
     711             :             {
     712           0 :                 bIsSvg = true;
     713             :             }
     714             :         }
     715             : 
     716         332 :         if(bIsSvg)
     717             :         {
     718         294 :             rFormatExtension = "SVG";
     719         294 :             return true;
     720             :         }
     721             :     }
     722           0 :     else if( rFormatExtension.startsWith( "SVG" ) )
     723             :     {
     724           0 :         bSomethingTested = true;
     725           0 :         return true;
     726             :     }
     727             : 
     728             :     //--------------------------- TGA ------------------------------------
     729          38 :     if( !bTest || rFormatExtension.startsWith( "TGA" ) )
     730             :     {
     731          38 :         bSomethingTested = true;
     732             : 
     733             :         // just a simple test for the extension
     734          38 :         if( rFormatExtension.startsWith( "TGA" ) )
     735           0 :             return true;
     736             :     }
     737             : 
     738             :     //--------------------------- SGV ------------------------------------
     739          38 :     if( !bTest || rFormatExtension.startsWith( "SGV" ) )
     740             :     {
     741          38 :         bSomethingTested = true;
     742             : 
     743             :         // just a simple test for the extension
     744          38 :         if( rFormatExtension.startsWith( "SGV" ) )
     745           0 :             return true;
     746             :     }
     747             : 
     748             :     //--------------------------- SGF ------------------------------------
     749          38 :     if( !bTest || rFormatExtension.startsWith( "SGF" ) )
     750             :     {
     751          38 :         bSomethingTested=true;
     752          38 :         if( sFirstBytes[ 0 ] == 'J' && sFirstBytes[ 1 ] == 'J' )
     753             :         {
     754           2 :             rFormatExtension = "SGF";
     755           2 :             return true;
     756             :         }
     757             :     }
     758             : 
     759          36 :     if(!bTest || rFormatExtension.startsWith( "MOV" ))
     760             :     {
     761          36 :         if ((sFirstBytes[ 4 ] == 'f' && sFirstBytes[ 5 ] == 't' && sFirstBytes[ 6 ] == 'y' &&
     762          36 :              sFirstBytes[ 7 ] == 'p' && sFirstBytes[ 8 ] == 'q' && sFirstBytes[ 9 ] == 't') ||
     763          36 :             (sFirstBytes[ 4 ] == 'm' && sFirstBytes[ 5 ] == 'o' && sFirstBytes[ 6 ] == 'o' &&
     764           0 :              sFirstBytes[ 7 ] == 'v' && sFirstBytes[ 11 ] == 'l' && sFirstBytes[ 12 ] == 'm'))
     765             :         {
     766           0 :             bSomethingTested=true;
     767           0 :             rFormatExtension = "MOV";
     768           0 :             return true;
     769             :         }
     770             :     }
     771             : 
     772          36 :     return bTest && !bSomethingTested;
     773             : }
     774             : 
     775        6596 : sal_uInt16 GraphicFilter::ImpTestOrFindFormat( const OUString& rPath, SvStream& rStream, sal_uInt16& rFormat )
     776             : {
     777             :     // determine or check the filter/format by reading into it
     778        6596 :     if( rFormat == GRFILTER_FORMAT_DONTKNOW )
     779             :     {
     780        6585 :         OUString aFormatExt;
     781        6585 :         if( ImpPeekGraphicFormat( rStream, aFormatExt, false ) )
     782             :         {
     783        6376 :             rFormat = pConfig->GetImportFormatNumberForExtension( aFormatExt );
     784        6376 :             if( rFormat != GRFILTER_FORMAT_DONTKNOW )
     785        6376 :                 return GRFILTER_OK;
     786             :         }
     787             :         // determine filter by file extension
     788         209 :         if( !rPath.isEmpty() )
     789             :         {
     790         204 :             OUString aExt( ImpGetExtension( rPath ) );
     791         204 :             rFormat = pConfig->GetImportFormatNumberForExtension( aExt );
     792         204 :             if( rFormat != GRFILTER_FORMAT_DONTKNOW )
     793         140 :                 return GRFILTER_OK;
     794             :         }
     795          69 :         return GRFILTER_FORMATERROR;
     796             :     }
     797             :     else
     798             :     {
     799          11 :         OUString aTmpStr( pConfig->GetImportFormatExtension( rFormat ) );
     800          11 :         aTmpStr = aTmpStr.toAsciiUpperCase();
     801          11 :         if( !ImpPeekGraphicFormat( rStream, aTmpStr, true ) )
     802           0 :             return GRFILTER_FORMATERROR;
     803          11 :         if ( pConfig->GetImportFormatExtension( rFormat ).equalsIgnoreAsciiCase( "pcd" ) )
     804             :         {
     805           0 :             sal_Int32 nBase = 2;    // default Base0
     806           0 :             if ( pConfig->GetImportFilterType( rFormat ).equalsIgnoreAsciiCase( "pcd_Photo_CD_Base4" ) )
     807           0 :                 nBase = 1;
     808           0 :             else if ( pConfig->GetImportFilterType( rFormat ).equalsIgnoreAsciiCase( "pcd_Photo_CD_Base16" ) )
     809           0 :                 nBase = 0;
     810           0 :             OUString aFilterConfigPath( "Office.Common/Filter/Graphic/Import/PCD" );
     811           0 :             FilterConfigItem aFilterConfigItem( aFilterConfigPath );
     812           0 :             aFilterConfigItem.WriteInt32( "Resolution", nBase );
     813          11 :         }
     814             :     }
     815             : 
     816          11 :     return GRFILTER_OK;
     817             : }
     818             : 
     819             : #ifndef DISABLE_EXPORT
     820             : 
     821         138 : static Graphic ImpGetScaledGraphic( const Graphic& rGraphic, FilterConfigItem& rConfigItem )
     822             : {
     823         138 :     Graphic     aGraphic;
     824             : 
     825         276 :     boost::scoped_ptr<ResMgr> pResMgr(ResMgr::CreateResMgr( "svt", Application::GetSettings().GetUILanguageTag() ));
     826             : 
     827         138 :     sal_Int32 nLogicalWidth = rConfigItem.ReadInt32( "LogicalWidth", 0 );
     828         138 :     sal_Int32 nLogicalHeight = rConfigItem.ReadInt32( "LogicalHeight", 0 );
     829             : 
     830         138 :     if ( rGraphic.GetType() != GRAPHIC_NONE )
     831             :     {
     832         138 :         sal_Int32 nMode = rConfigItem.ReadInt32( "ExportMode", -1 );
     833             : 
     834         138 :         if ( nMode == -1 )  // the property is not there, this is possible, if the graphic filter
     835             :         {                   // is called via UnoGraphicExporter and not from a graphic export Dialog
     836         138 :             nMode = 0;      // then we are defaulting this mode to 0
     837         138 :             if ( nLogicalWidth || nLogicalHeight )
     838          10 :                 nMode = 2;
     839             :         }
     840             : 
     841         138 :         Size aOriginalSize;
     842         138 :         Size aPrefSize( rGraphic.GetPrefSize() );
     843         138 :         MapMode aPrefMapMode( rGraphic.GetPrefMapMode() );
     844         138 :         if ( aPrefMapMode == MAP_PIXEL )
     845          38 :             aOriginalSize = Application::GetDefaultDevice()->PixelToLogic( aPrefSize, MAP_100TH_MM );
     846             :         else
     847         100 :             aOriginalSize = Application::GetDefaultDevice()->LogicToLogic( aPrefSize, aPrefMapMode, MAP_100TH_MM );
     848         138 :         if ( !nLogicalWidth )
     849         128 :             nLogicalWidth = aOriginalSize.Width();
     850         138 :         if ( !nLogicalHeight )
     851         128 :             nLogicalHeight = aOriginalSize.Height();
     852         138 :         if( rGraphic.GetType() == GRAPHIC_BITMAP )
     853             :         {
     854             : 
     855             :             // Resolution is set
     856          57 :             if( nMode == 1 )
     857             :             {
     858           0 :                 Bitmap      aBitmap( rGraphic.GetBitmap() );
     859           0 :                 MapMode     aMap( MAP_100TH_INCH );
     860             : 
     861           0 :                 sal_Int32   nDPI = rConfigItem.ReadInt32( "Resolution", 75 );
     862           0 :                 Fraction    aFrac( 1, std::min( std::max( nDPI, sal_Int32( 75 ) ), sal_Int32( 600 ) ) );
     863             : 
     864           0 :                 aMap.SetScaleX( aFrac );
     865           0 :                 aMap.SetScaleY( aFrac );
     866             : 
     867           0 :                 Size aOldSize = aBitmap.GetSizePixel();
     868           0 :                aGraphic = rGraphic;
     869           0 :                aGraphic.SetPrefMapMode( aMap );
     870           0 :                aGraphic.SetPrefSize( Size( aOldSize.Width() * 100,
     871           0 :                                            aOldSize.Height() * 100 ) );
     872             :             }
     873             :             // Size is set
     874          57 :             else if( nMode == 2 )
     875             :             {
     876          10 :                aGraphic = rGraphic;
     877          10 :                aGraphic.SetPrefMapMode( MapMode( MAP_100TH_MM ) );
     878          10 :                aGraphic.SetPrefSize( Size( nLogicalWidth, nLogicalHeight ) );
     879             :             }
     880             :             else
     881          47 :                 aGraphic = rGraphic;
     882             : 
     883          57 :             sal_Int32 nColors = rConfigItem.ReadInt32( "Color", 0 ); // #92767#
     884          57 :             if ( nColors )  // graphic conversion necessary ?
     885             :             {
     886           0 :                 BitmapEx aBmpEx( aGraphic.GetBitmapEx() );
     887           0 :                 aBmpEx.Convert( (BmpConversion)nColors );   // the entries in the xml section have the same meaning as
     888           0 :                 aGraphic = aBmpEx;                          // they have in the BmpConversion enum, so it should be
     889             :             }                                               // allowed to cast them
     890             :         }
     891             :         else
     892             :         {
     893          81 :             if( ( nMode == 1 ) || ( nMode == 2 ) )
     894             :             {
     895           0 :                 GDIMetaFile aMtf( rGraphic.GetGDIMetaFile() );
     896           0 :                 css::awt::Size aDefaultSize( 10000, 10000 );
     897           0 :                 Size aNewSize( OutputDevice::LogicToLogic( Size( nLogicalWidth, nLogicalHeight ), MAP_100TH_MM, aMtf.GetPrefMapMode() ) );
     898             : 
     899           0 :                 if( aNewSize.Width() && aNewSize.Height() )
     900             :                 {
     901           0 :                     const Size aPreferredSize( aMtf.GetPrefSize() );
     902           0 :                     aMtf.Scale( Fraction( aNewSize.Width(), aPreferredSize.Width() ),
     903           0 :                                 Fraction( aNewSize.Height(), aPreferredSize.Height() ) );
     904             :                 }
     905           0 :                 aGraphic = Graphic( aMtf );
     906             :             }
     907             :             else
     908          81 :                 aGraphic = rGraphic;
     909         138 :         }
     910             : 
     911             :     }
     912             :     else
     913           0 :         aGraphic = rGraphic;
     914             : 
     915         276 :     return aGraphic;
     916             : }
     917             : 
     918             : #endif
     919             : 
     920           2 : static OUString ImpCreateFullFilterPath( const OUString& rPath, const OUString& rFilterName )
     921             : {
     922           2 :     OUString aPathURL;
     923             : 
     924           2 :     ::osl::FileBase::getFileURLFromSystemPath( rPath, aPathURL );
     925           2 :     aPathURL += "/";
     926             : 
     927           4 :     OUString aSystemPath;
     928           2 :     ::osl::FileBase::getSystemPathFromFileURL( aPathURL, aSystemPath );
     929           2 :     aSystemPath += rFilterName;
     930             : 
     931           4 :     return OUString( aSystemPath );
     932             : }
     933             : 
     934             : class ImpFilterLibCache;
     935             : 
     936           2 : struct ImpFilterLibCacheEntry
     937             : {
     938             :     ImpFilterLibCacheEntry* mpNext;
     939             : #ifndef DISABLE_DYNLOADING
     940             :     osl::Module             maLibrary;
     941             : #endif
     942             :     OUString                maFiltername;
     943             :     PFilterCall             mpfnImport;
     944             : 
     945             :                             ImpFilterLibCacheEntry( const OUString& rPathname, const OUString& rFiltername );
     946         123 :     bool                    operator==( const OUString& rFiltername ) const { return maFiltername == rFiltername; }
     947             : 
     948             :     PFilterCall             GetImportFunction();
     949             : };
     950             : 
     951           2 : ImpFilterLibCacheEntry::ImpFilterLibCacheEntry( const OUString& rPathname, const OUString& rFiltername ) :
     952             :         mpNext          ( NULL ),
     953             : #ifndef DISABLE_DYNLOADING
     954             :         maLibrary       ( rPathname ),
     955             : #endif
     956             :         maFiltername    ( rFiltername ),
     957           2 :         mpfnImport      ( NULL )
     958             : {
     959             : #ifdef DISABLE_DYNLOADING
     960             :     (void) rPathname;
     961             : #endif
     962           2 : }
     963             : 
     964             : #ifdef DISABLE_DYNLOADING
     965             : 
     966             : extern "C" bool icdGraphicImport( SvStream& rStream, Graphic& rGraphic, FilterConfigItem* pConfigItem );
     967             : extern "C" bool idxGraphicImport( SvStream& rStream, Graphic& rGraphic, FilterConfigItem* pConfigItem );
     968             : extern "C" bool imeGraphicImport( SvStream& rStream, Graphic& rGraphic, FilterConfigItem* pConfigItem );
     969             : extern "C" bool ipbGraphicImport( SvStream& rStream, Graphic& rGraphic, FilterConfigItem* pConfigItem );
     970             : extern "C" bool ipdGraphicImport( SvStream& rStream, Graphic& rGraphic, FilterConfigItem* pConfigItem );
     971             : extern "C" bool ipsGraphicImport( SvStream& rStream, Graphic& rGraphic, FilterConfigItem* pConfigItem );
     972             : extern "C" bool iptGraphicImport( SvStream& rStream, Graphic& rGraphic, FilterConfigItem* pConfigItem );
     973             : extern "C" bool ipxGraphicImport( SvStream& rStream, Graphic& rGraphic, FilterConfigItem* pConfigItem );
     974             : extern "C" bool iraGraphicImport( SvStream& rStream, Graphic& rGraphic, FilterConfigItem* pConfigItem );
     975             : extern "C" bool itgGraphicImport( SvStream& rStream, Graphic& rGraphic, FilterConfigItem* pConfigItem );
     976             : extern "C" bool itiGraphicImport( SvStream& rStream, Graphic& rGraphic, FilterConfigItem* pConfigItem );
     977             : 
     978             : #endif
     979             : 
     980         124 : PFilterCall ImpFilterLibCacheEntry::GetImportFunction()
     981             : {
     982         124 :     if( !mpfnImport )
     983             :     {
     984             : #ifndef DISABLE_DYNLOADING
     985           2 :         mpfnImport = (PFilterCall) maLibrary.getFunctionSymbol(OUString(IMPORT_FUNCTION_NAME));
     986             : #else
     987             :         if( maFiltername.equalsAscii( "icd" ) )
     988             :             mpfnImport = icdGraphicImport;
     989             :         else if( maFiltername.equalsAscii( "idx" ) )
     990             :             mpfnImport = idxGraphicImport;
     991             :         else if( maFiltername.equalsAscii( "ime" ) )
     992             :             mpfnImport = imeGraphicImport;
     993             :         else if( maFiltername.equalsAscii( "ipb" ) )
     994             :             mpfnImport = ipbGraphicImport;
     995             :         else if( maFiltername.equalsAscii( "ipd" ) )
     996             :             mpfnImport = ipdGraphicImport;
     997             :         else if( maFiltername.equalsAscii( "ips" ) )
     998             :             mpfnImport = ipsGraphicImport;
     999             :         else if( maFiltername.equalsAscii( "ipt" ) )
    1000             :             mpfnImport = iptGraphicImport;
    1001             :         else if( maFiltername.equalsAscii( "ipx" ) )
    1002             :             mpfnImport = ipxGraphicImport;
    1003             :         else if( maFiltername.equalsAscii( "ira" ) )
    1004             :             mpfnImport = iraGraphicImport;
    1005             :         else if( maFiltername.equalsAscii( "itg" ) )
    1006             :             mpfnImport = itgGraphicImport;
    1007             :         else if( maFiltername.equalsAscii( "iti" ) )
    1008             :             mpfnImport = itiGraphicImport;
    1009             : #endif
    1010             :     }
    1011             : 
    1012         124 :     return mpfnImport;
    1013             : }
    1014             : 
    1015             : class ImpFilterLibCache
    1016             : {
    1017             :     ImpFilterLibCacheEntry* mpFirst;
    1018             :     ImpFilterLibCacheEntry* mpLast;
    1019             : 
    1020             : public:
    1021             :                             ImpFilterLibCache();
    1022             :                             ~ImpFilterLibCache();
    1023             : 
    1024             :     ImpFilterLibCacheEntry* GetFilter( const OUString& rFilterPath, const OUString& rFiltername );
    1025             : };
    1026             : 
    1027           1 : ImpFilterLibCache::ImpFilterLibCache() :
    1028             :     mpFirst     ( NULL ),
    1029           1 :     mpLast      ( NULL )
    1030             : {
    1031           1 : }
    1032             : 
    1033           1 : ImpFilterLibCache::~ImpFilterLibCache()
    1034             : {
    1035           1 :     ImpFilterLibCacheEntry* pEntry = mpFirst;
    1036           4 :     while( pEntry )
    1037             :     {
    1038           2 :         ImpFilterLibCacheEntry* pNext = pEntry->mpNext;
    1039           2 :         delete pEntry;
    1040           2 :         pEntry = pNext;
    1041             :     }
    1042           1 : }
    1043             : 
    1044         124 : ImpFilterLibCacheEntry* ImpFilterLibCache::GetFilter( const OUString& rFilterPath, const OUString& rFilterName )
    1045             : {
    1046         124 :     ImpFilterLibCacheEntry* pEntry = mpFirst;
    1047             : 
    1048         249 :     while( pEntry )
    1049             :     {
    1050         123 :         if( *pEntry == rFilterName )
    1051         122 :             break;
    1052             :         else
    1053           1 :             pEntry = pEntry->mpNext;
    1054             :     }
    1055         124 :     if( !pEntry )
    1056             :     {
    1057           2 :         OUString aPhysicalName( ImpCreateFullFilterPath( rFilterPath, rFilterName ) );
    1058           2 :         pEntry = new ImpFilterLibCacheEntry( aPhysicalName, rFilterName );
    1059             : #ifndef DISABLE_DYNLOADING
    1060           2 :         if ( pEntry->maLibrary.is() )
    1061             : #endif
    1062             :         {
    1063           2 :             if( !mpFirst )
    1064           1 :                 mpFirst = mpLast = pEntry;
    1065             :             else
    1066           1 :                 mpLast = mpLast->mpNext = pEntry;
    1067             :         }
    1068             : #ifndef DISABLE_DYNLOADING
    1069             :         else
    1070             :         {
    1071           0 :             delete pEntry;
    1072           0 :             pEntry = NULL;
    1073           2 :         }
    1074             : #endif
    1075             :     }
    1076         124 :     return pEntry;
    1077             : };
    1078             : 
    1079             : namespace { struct Cache : public rtl::Static<ImpFilterLibCache, Cache> {}; }
    1080             : 
    1081         103 : GraphicFilter::GraphicFilter( bool bConfig ) :
    1082             :     bUseConfig        ( bConfig ),
    1083         103 :     nExpGraphHint     ( 0 )
    1084             : {
    1085         103 :     ImplInit();
    1086         103 : }
    1087             : 
    1088         206 : GraphicFilter::~GraphicFilter()
    1089             : {
    1090             :     {
    1091         103 :         ::osl::MutexGuard aGuard( getListMutex() );
    1092         354 :         for(
    1093         103 :             FilterList_impl::iterator it = pFilterHdlList->begin();
    1094         236 :             it != pFilterHdlList->end();
    1095             :             ++it
    1096             :         ) {
    1097         118 :             if( *it == this )
    1098             :             {
    1099         103 :                 pFilterHdlList->erase( it );
    1100         103 :                 break;
    1101             :             }
    1102             :         }
    1103         103 :         if( pFilterHdlList->empty() )
    1104             :         {
    1105          86 :             delete pFilterHdlList, pFilterHdlList = NULL;
    1106          86 :             delete pConfig;
    1107         103 :         }
    1108             :     }
    1109             : 
    1110         103 :     delete pErrorEx;
    1111         103 : }
    1112             : 
    1113         103 : void GraphicFilter::ImplInit()
    1114             : {
    1115             :     {
    1116         103 :         ::osl::MutexGuard aGuard( getListMutex() );
    1117             : 
    1118         103 :         if ( !pFilterHdlList )
    1119             :         {
    1120          86 :             pFilterHdlList = new FilterList_impl;
    1121          86 :             pConfig = new FilterConfigCache( bUseConfig );
    1122             :         }
    1123             :         else
    1124          17 :             pConfig = pFilterHdlList->front()->pConfig;
    1125             : 
    1126         103 :         pFilterHdlList->push_back( this );
    1127             :     }
    1128             : 
    1129         103 :     if( bUseConfig )
    1130             :     {
    1131          85 :         OUString url("$BRAND_BASE_DIR/" LIBO_LIB_FOLDER);
    1132          85 :         rtl::Bootstrap::expandMacros(url); //TODO: detect failure
    1133          85 :         utl::LocalFileHelper::ConvertURLToPhysicalName(url, aFilterPath);
    1134             :     }
    1135             : 
    1136         103 :     pErrorEx = new FilterErrorEx;
    1137         103 :     bAbort = false;
    1138         103 : }
    1139             : 
    1140         235 : sal_uLong GraphicFilter::ImplSetError( sal_uLong nError, const SvStream* pStm )
    1141             : {
    1142         235 :     pErrorEx->nFilterError = nError;
    1143         235 :     pErrorEx->nStreamError = pStm ? pStm->GetError() : ERRCODE_NONE;
    1144         235 :     return nError;
    1145             : }
    1146             : 
    1147          87 : sal_uInt16 GraphicFilter::GetImportFormatCount()
    1148             : {
    1149          87 :     return pConfig->GetImportFormatCount();
    1150             : }
    1151             : 
    1152           2 : sal_uInt16 GraphicFilter::GetImportFormatNumber( const OUString& rFormatName )
    1153             : {
    1154           2 :     return pConfig->GetImportFormatNumber( rFormatName );
    1155             : }
    1156             : 
    1157           0 : sal_uInt16 GraphicFilter::GetImportFormatNumberForMediaType( const OUString& rMediaType )
    1158             : {
    1159           0 :     return pConfig->GetImportFormatNumberForMediaType( rMediaType );
    1160             : }
    1161             : 
    1162          48 : sal_uInt16 GraphicFilter::GetImportFormatNumberForShortName( const OUString& rShortName )
    1163             : {
    1164          48 :     return pConfig->GetImportFormatNumberForShortName( rShortName );
    1165             : }
    1166             : 
    1167           0 : sal_uInt16 GraphicFilter::GetImportFormatNumberForTypeName( const OUString& rType )
    1168             : {
    1169           0 :     return pConfig->GetImportFormatNumberForTypeName( rType );
    1170             : }
    1171             : 
    1172         468 : OUString GraphicFilter::GetImportFormatName( sal_uInt16 nFormat )
    1173             : {
    1174         468 :     return pConfig->GetImportFormatName( nFormat );
    1175             : }
    1176             : 
    1177           0 : OUString GraphicFilter::GetImportFormatTypeName( sal_uInt16 nFormat )
    1178             : {
    1179           0 :     return pConfig->GetImportFilterTypeName( nFormat );
    1180             : }
    1181             : 
    1182           0 : OUString GraphicFilter::GetImportFormatMediaType( sal_uInt16 nFormat )
    1183             : {
    1184           0 :     return pConfig->GetImportFormatMediaType( nFormat );
    1185             : }
    1186             : 
    1187         124 : OUString GraphicFilter::GetImportFormatShortName( sal_uInt16 nFormat )
    1188             : {
    1189         124 :     return pConfig->GetImportFormatShortName( nFormat );
    1190             : }
    1191             : 
    1192           0 : OUString GraphicFilter::GetImportOSFileType( sal_uInt16 )
    1193             : {
    1194           0 :     OUString aOSFileType;
    1195           0 :     return aOSFileType;
    1196             : }
    1197             : 
    1198           0 : OUString GraphicFilter::GetImportWildcard( sal_uInt16 nFormat, sal_Int32 nEntry )
    1199             : {
    1200           0 :     return pConfig->GetImportWildcard( nFormat, nEntry );
    1201             : }
    1202             : 
    1203           0 : bool GraphicFilter::IsImportPixelFormat( sal_uInt16 nFormat )
    1204             : {
    1205           0 :     return pConfig->IsImportPixelFormat( nFormat );
    1206             : }
    1207             : 
    1208         138 : sal_uInt16 GraphicFilter::GetExportFormatCount()
    1209             : {
    1210         138 :     return pConfig->GetExportFormatCount();
    1211             : }
    1212             : 
    1213           0 : sal_uInt16 GraphicFilter::GetExportFormatNumber( const OUString& rFormatName )
    1214             : {
    1215           0 :     return pConfig->GetExportFormatNumber( rFormatName );
    1216             : }
    1217             : 
    1218           0 : sal_uInt16 GraphicFilter::GetExportFormatNumberForMediaType( const OUString& rMediaType )
    1219             : {
    1220           0 :     return pConfig->GetExportFormatNumberForMediaType( rMediaType );
    1221             : }
    1222             : 
    1223         143 : sal_uInt16 GraphicFilter::GetExportFormatNumberForShortName( const OUString& rShortName )
    1224             : {
    1225         143 :     return pConfig->GetExportFormatNumberForShortName( rShortName );
    1226             : }
    1227             : 
    1228           0 : OUString GraphicFilter::GetExportInternalFilterName( sal_uInt16 nFormat )
    1229             : {
    1230           0 :     return pConfig->GetExportInternalFilterName( nFormat );
    1231             : }
    1232             : 
    1233           0 : sal_uInt16 GraphicFilter::GetExportFormatNumberForTypeName( const OUString& rType )
    1234             : {
    1235           0 :     return pConfig->GetExportFormatNumberForTypeName( rType );
    1236             : }
    1237             : 
    1238           0 : OUString GraphicFilter::GetExportFormatName( sal_uInt16 nFormat )
    1239             : {
    1240           0 :     return pConfig->GetExportFormatName( nFormat );
    1241             : }
    1242             : 
    1243           0 : OUString GraphicFilter::GetExportFormatTypeName( sal_uInt16 nFormat )
    1244             : {
    1245           0 :     return pConfig->GetExportFilterTypeName( nFormat );
    1246             : }
    1247             : 
    1248           0 : OUString GraphicFilter::GetExportFormatMediaType( sal_uInt16 nFormat )
    1249             : {
    1250           0 :     return pConfig->GetExportFormatMediaType( nFormat );
    1251             : }
    1252             : 
    1253           0 : OUString GraphicFilter::GetExportFormatShortName( sal_uInt16 nFormat )
    1254             : {
    1255           0 :     return pConfig->GetExportFormatShortName( nFormat );
    1256             : }
    1257             : 
    1258           0 : OUString GraphicFilter::GetExportOSFileType( sal_uInt16 )
    1259             : {
    1260           0 :     OUString aOSFileType;
    1261           0 :     return aOSFileType;
    1262             : }
    1263             : 
    1264           0 : OUString GraphicFilter::GetExportWildcard( sal_uInt16 nFormat, sal_Int32 nEntry )
    1265             : {
    1266           0 :     return pConfig->GetExportWildcard( nFormat, nEntry );
    1267             : }
    1268             : 
    1269          15 : bool GraphicFilter::IsExportPixelFormat( sal_uInt16 nFormat )
    1270             : {
    1271          15 :     return pConfig->IsExportPixelFormat( nFormat );
    1272             : }
    1273             : 
    1274           0 : sal_uInt16 GraphicFilter::CanImportGraphic( const INetURLObject& rPath,
    1275             :                                         sal_uInt16 nFormat, sal_uInt16* pDeterminedFormat )
    1276             : {
    1277           0 :     sal_uInt16  nRetValue = GRFILTER_FORMATERROR;
    1278             :     DBG_ASSERT( rPath.GetProtocol() != INET_PROT_NOT_VALID, "GraphicFilter::CanImportGraphic() : ProtType == INET_PROT_NOT_VALID" );
    1279             : 
    1280           0 :     OUString    aMainUrl( rPath.GetMainURL( INetURLObject::NO_DECODE ) );
    1281           0 :     boost::scoped_ptr<SvStream> pStream(::utl::UcbStreamHelper::CreateStream( aMainUrl, STREAM_READ | STREAM_SHARE_DENYNONE ));
    1282           0 :     if ( pStream )
    1283             :     {
    1284           0 :         nRetValue = CanImportGraphic( aMainUrl, *pStream, nFormat, pDeterminedFormat );
    1285             :     }
    1286           0 :     return nRetValue;
    1287             : }
    1288             : 
    1289           0 : sal_uInt16 GraphicFilter::CanImportGraphic( const OUString& rMainUrl, SvStream& rIStream,
    1290             :                                         sal_uInt16 nFormat, sal_uInt16* pDeterminedFormat )
    1291             : {
    1292           0 :     sal_uLong nStreamPos = rIStream.Tell();
    1293           0 :     sal_uInt16 nRes = ImpTestOrFindFormat( rMainUrl, rIStream, nFormat );
    1294             : 
    1295           0 :     rIStream.Seek(nStreamPos);
    1296             : 
    1297           0 :     if( nRes==GRFILTER_OK && pDeterminedFormat!=NULL )
    1298           0 :         *pDeterminedFormat = nFormat;
    1299             : 
    1300           0 :     return (sal_uInt16) ImplSetError( nRes, &rIStream );
    1301             : }
    1302             : 
    1303             : //SJ: TODO, we need to create a GraphicImporter component
    1304         140 : sal_uInt16 GraphicFilter::ImportGraphic( Graphic& rGraphic, const INetURLObject& rPath,
    1305             :                                      sal_uInt16 nFormat, sal_uInt16 * pDeterminedFormat, sal_uInt32 nImportFlags )
    1306             : {
    1307         140 :     sal_uInt16 nRetValue = GRFILTER_FORMATERROR;
    1308             :     DBG_ASSERT( rPath.GetProtocol() != INET_PROT_NOT_VALID, "GraphicFilter::ImportGraphic() : ProtType == INET_PROT_NOT_VALID" );
    1309             : 
    1310         140 :     OUString    aMainUrl( rPath.GetMainURL( INetURLObject::NO_DECODE ) );
    1311         280 :     boost::scoped_ptr<SvStream> pStream(::utl::UcbStreamHelper::CreateStream( aMainUrl, STREAM_READ | STREAM_SHARE_DENYNONE ));
    1312         140 :     if ( pStream )
    1313             :     {
    1314         140 :         nRetValue = ImportGraphic( rGraphic, aMainUrl, *pStream, nFormat, pDeterminedFormat, nImportFlags );
    1315             :     }
    1316         280 :     return nRetValue;
    1317             : }
    1318             : 
    1319        6581 : sal_uInt16 GraphicFilter::ImportGraphic( Graphic& rGraphic, const OUString& rPath, SvStream& rIStream,
    1320             :                                      sal_uInt16 nFormat, sal_uInt16* pDeterminedFormat, sal_uInt32 nImportFlags, WMF_EXTERNALHEADER *pExtHeader )
    1321             : {
    1322        6581 :     return ImportGraphic( rGraphic, rPath, rIStream, nFormat, pDeterminedFormat, nImportFlags, NULL, pExtHeader );
    1323             : }
    1324             : 
    1325        6596 : sal_uInt16 GraphicFilter::ImportGraphic( Graphic& rGraphic, const OUString& rPath, SvStream& rIStream,
    1326             :                                      sal_uInt16 nFormat, sal_uInt16* pDeterminedFormat, sal_uInt32 nImportFlags,
    1327             :                                      com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValue >* pFilterData,
    1328             :                                      WMF_EXTERNALHEADER *pExtHeader )
    1329             : {
    1330        6596 :     OUString                aFilterName;
    1331             :     sal_uLong               nStreamBegin;
    1332             :     sal_uInt16              nStatus;
    1333        6596 :     GraphicReader*          pContext = rGraphic.GetContext();
    1334        6596 :     GfxLinkType             eLinkType = GFX_LINK_TYPE_NONE;
    1335        6596 :     bool                    bDummyContext = ( pContext == (GraphicReader*) 1 );
    1336        6596 :     const bool              bLinkSet = rGraphic.IsLink();
    1337        6596 :     FilterConfigItem*       pFilterConfigItem = NULL;
    1338             : 
    1339        6596 :     Size                    aPreviewSizeHint( 0, 0 );
    1340        6596 :     bool                bAllowPartialStreamRead = false;
    1341        6596 :     bool                bCreateNativeLink = true;
    1342             : 
    1343        6596 :     sal_uInt8* pGraphicContent = NULL;
    1344        6596 :     bool bGraphicContentOwned = true;
    1345        6596 :     sal_Int32  nGraphicContentSize = 0;
    1346             : 
    1347        6596 :     ResetLastError();
    1348             : 
    1349        6596 :     if ( pFilterData )
    1350             :     {
    1351             :         sal_Int32 i;
    1352           0 :         for ( i = 0; i < pFilterData->getLength(); i++ )
    1353             :         {
    1354           0 :             if ( (*pFilterData)[ i ].Name == "PreviewSizeHint" )
    1355             :             {
    1356           0 :                 awt::Size aSize;
    1357           0 :                 if ( (*pFilterData)[ i ].Value >>= aSize )
    1358             :                 {
    1359           0 :                     aPreviewSizeHint = Size( aSize.Width, aSize.Height );
    1360           0 :                     if ( aSize.Width || aSize.Height )
    1361           0 :                         nImportFlags |= GRFILTER_I_FLAGS_FOR_PREVIEW;
    1362             :                     else
    1363           0 :                         nImportFlags &=~GRFILTER_I_FLAGS_FOR_PREVIEW;
    1364             :                 }
    1365             :             }
    1366           0 :             else if ( (*pFilterData)[ i ].Name == "AllowPartialStreamRead" )
    1367             :             {
    1368           0 :                 (*pFilterData)[ i ].Value >>= bAllowPartialStreamRead;
    1369           0 :                 if ( bAllowPartialStreamRead )
    1370           0 :                     nImportFlags |= GRFILTER_I_FLAGS_ALLOW_PARTIAL_STREAMREAD;
    1371             :                 else
    1372           0 :                     nImportFlags &=~GRFILTER_I_FLAGS_ALLOW_PARTIAL_STREAMREAD;
    1373             :             }
    1374           0 :             else if ( (*pFilterData)[ i ].Name == "CreateNativeLink" )
    1375             :             {
    1376           0 :                 (*pFilterData)[ i ].Value >>= bCreateNativeLink;
    1377             :             }
    1378             :         }
    1379             :     }
    1380             : 
    1381        6596 :     if( !pContext || bDummyContext )
    1382             :     {
    1383        6596 :         if( bDummyContext )
    1384             :         {
    1385           0 :             rGraphic.SetContext( NULL );
    1386           0 :             nStreamBegin = 0;
    1387             :         }
    1388             :         else
    1389        6596 :             nStreamBegin = rIStream.Tell();
    1390             : 
    1391        6596 :         bAbort = false;
    1392        6596 :         nStatus = ImpTestOrFindFormat( rPath, rIStream, nFormat );
    1393             :         // if pending, return GRFILTER_OK in order to request more bytes
    1394        6596 :         if( rIStream.GetError() == ERRCODE_IO_PENDING )
    1395             :         {
    1396           0 :             rGraphic.SetContext( (GraphicReader*) 1 );
    1397           0 :             rIStream.ResetError();
    1398           0 :             rIStream.Seek( nStreamBegin );
    1399           0 :             return (sal_uInt16) ImplSetError( GRFILTER_OK );
    1400             :         }
    1401             : 
    1402        6596 :         rIStream.Seek( nStreamBegin );
    1403             : 
    1404        6596 :         if( ( nStatus != GRFILTER_OK ) || rIStream.GetError() )
    1405         209 :             return (sal_uInt16) ImplSetError( ( nStatus != GRFILTER_OK ) ? nStatus : GRFILTER_OPENERROR, &rIStream );
    1406             : 
    1407        6387 :         if( pDeterminedFormat )
    1408         592 :             *pDeterminedFormat = nFormat;
    1409             : 
    1410        6387 :         aFilterName = pConfig->GetImportFilterName( nFormat );
    1411             :     }
    1412             :     else
    1413             :     {
    1414           0 :         if( pContext && !bDummyContext )
    1415           0 :             aFilterName = pContext->GetUpperFilterName();
    1416             : 
    1417           0 :         nStreamBegin = 0;
    1418           0 :         nStatus = GRFILTER_OK;
    1419             :     }
    1420             : 
    1421             :     // read graphic
    1422        6387 :     if ( pConfig->IsImportInternalFilter( nFormat ) )
    1423             :     {
    1424        6263 :         if( aFilterName.equalsIgnoreAsciiCase( IMP_GIF )  )
    1425             :         {
    1426          52 :             if( rGraphic.GetContext() == (GraphicReader*) 1 )
    1427           0 :                 rGraphic.SetContext( NULL );
    1428             : 
    1429          52 :             if( !ImportGIF( rIStream, rGraphic ) )
    1430           2 :                 nStatus = GRFILTER_FILTERERROR;
    1431             :             else
    1432          50 :                 eLinkType = GFX_LINK_TYPE_NATIVE_GIF;
    1433             :         }
    1434        6211 :         else if( aFilterName.equalsIgnoreAsciiCase( IMP_PNG ) )
    1435             :         {
    1436         617 :             if ( rGraphic.GetContext() == (GraphicReader*) 1 )
    1437           0 :                 rGraphic.SetContext( NULL );
    1438             : 
    1439         617 :             vcl::PNGReader aPNGReader( rIStream );
    1440             : 
    1441             :             // ignore animation for previews and set preview size
    1442         617 :             if( aPreviewSizeHint.Width() || aPreviewSizeHint.Height() )
    1443             :             {
    1444             :                 // position the stream at the end of the image if requested
    1445           0 :                 if( !bAllowPartialStreamRead )
    1446           0 :                     aPNGReader.GetChunks();
    1447             :             }
    1448             :             else
    1449             :             {
    1450             :                 // check if this PNG contains a GIF chunk!
    1451         617 :                 const std::vector< vcl::PNGReader::ChunkData >&    rChunkData = aPNGReader.GetChunks();
    1452         617 :                 std::vector< vcl::PNGReader::ChunkData >::const_iterator aIter( rChunkData.begin() );
    1453         617 :                 std::vector< vcl::PNGReader::ChunkData >::const_iterator aEnd ( rChunkData.end() );
    1454        4413 :                 while( aIter != aEnd )
    1455             :                 {
    1456             :                     // Microsoft Office is storing Animated GIFs in following chunk
    1457        3179 :                     if ( aIter->nType == PMGCHUNG_msOG )
    1458             :                     {
    1459           0 :                         sal_uInt32 nChunkSize = aIter->aData.size();
    1460           0 :                         if ( nChunkSize > 11 )
    1461             :                         {
    1462           0 :                             const std::vector< sal_uInt8 >& rData = aIter->aData;
    1463           0 :                             SvMemoryStream aIStrm( (void*)&rData[ 11 ], nChunkSize - 11, STREAM_READ );
    1464           0 :                             ImportGIF( aIStrm, rGraphic );
    1465           0 :                             eLinkType = GFX_LINK_TYPE_NATIVE_PNG;
    1466           0 :                             break;
    1467             :                         }
    1468             :                     }
    1469        3179 :                     ++aIter;
    1470             :                 }
    1471             :             }
    1472             : 
    1473         617 :             if ( eLinkType == GFX_LINK_TYPE_NONE )
    1474             :             {
    1475         617 :                 BitmapEx aBmpEx( aPNGReader.Read( aPreviewSizeHint ) );
    1476         617 :                 if ( aBmpEx.IsEmpty() )
    1477           6 :                     nStatus = GRFILTER_FILTERERROR;
    1478             :                 else
    1479             :                 {
    1480         611 :                     rGraphic = aBmpEx;
    1481         611 :                     eLinkType = GFX_LINK_TYPE_NATIVE_PNG;
    1482         617 :                 }
    1483         617 :             }
    1484             :         }
    1485        5594 :         else if( aFilterName.equalsIgnoreAsciiCase( IMP_JPEG ) )
    1486             :         {
    1487         111 :             if( rGraphic.GetContext() == (GraphicReader*) 1 )
    1488           0 :                 rGraphic.SetContext( NULL );
    1489             : 
    1490             :             // set LOGSIZE flag always, if not explicitly disabled
    1491             :             // (see #90508 and #106763)
    1492         111 :             if( 0 == ( nImportFlags & GRFILTER_I_FLAGS_DONT_SET_LOGSIZE_FOR_JPEG ) )
    1493         111 :                 nImportFlags |= GRFILTER_I_FLAGS_SET_LOGSIZE_FOR_JPEG;
    1494             : 
    1495         111 :             if( !ImportJPEG( rIStream, rGraphic, NULL, nImportFlags ) )
    1496           5 :                 nStatus = GRFILTER_FILTERERROR;
    1497             :             else
    1498         106 :                 eLinkType = GFX_LINK_TYPE_NATIVE_JPG;
    1499             :         }
    1500        5483 :         else if( aFilterName.equalsIgnoreAsciiCase( IMP_SVG ) )
    1501             :         {
    1502         294 :             if( rGraphic.GetContext() == (GraphicReader*) 1 )
    1503           0 :                 rGraphic.SetContext( NULL );
    1504             : 
    1505         294 :             const sal_uInt32 nStreamPosition(rIStream.Tell());
    1506         294 :             const sal_uInt32 nStreamLength(rIStream.Seek(STREAM_SEEK_TO_END) - nStreamPosition);
    1507             : 
    1508         294 :             bool bOkay(false);
    1509             : 
    1510         294 :             if(nStreamLength > 0)
    1511             :             {
    1512         294 :                 std::vector<sal_uInt8> aTwoBytes(2);
    1513         294 :                 rIStream.Seek(nStreamPosition);
    1514         294 :                 rIStream.Read(&aTwoBytes[0], 2);
    1515         294 :                 rIStream.Seek(nStreamPosition);
    1516         294 :                 if(aTwoBytes[0] == 0x1F && aTwoBytes[1] == 0x8B)
    1517             :                 {
    1518           0 :                     SvMemoryStream aMemStream;
    1519           0 :                     GZCodec aCodec;
    1520             :                     long nMemoryLength;
    1521             : 
    1522           0 :                     aCodec.BeginCompression();
    1523           0 :                     nMemoryLength = aCodec.Decompress(rIStream, aMemStream);
    1524           0 :                     aCodec.EndCompression();
    1525             : 
    1526           0 :                     if (!rIStream.GetError() && nMemoryLength >= 0)
    1527             :                     {
    1528           0 :                         SvgDataArray aNewData(new sal_uInt8[nMemoryLength]);
    1529           0 :                         aMemStream.Seek(STREAM_SEEK_TO_BEGIN);
    1530           0 :                         aMemStream.Read(aNewData.get(), nMemoryLength);
    1531             : 
    1532             :                         // Make a uncompressed copy for GfxLink
    1533           0 :                         nGraphicContentSize = nMemoryLength;
    1534           0 :                         pGraphicContent = new sal_uInt8[nGraphicContentSize];
    1535           0 :                         std::copy(aNewData.get(), aNewData.get() + nMemoryLength, pGraphicContent);
    1536             : 
    1537           0 :                         if(!aMemStream.GetError() )
    1538             :                         {
    1539           0 :                             SvgDataPtr aSvgDataPtr(new SvgData(aNewData, nMemoryLength, rPath));
    1540           0 :                             rGraphic = Graphic(aSvgDataPtr);
    1541           0 :                             bOkay = true;
    1542           0 :                         }
    1543           0 :                     }
    1544             :                 }
    1545             :                 else
    1546             :                 {
    1547         294 :                     SvgDataArray aNewData(new sal_uInt8[nStreamLength]);
    1548         294 :                     rIStream.Seek(nStreamPosition);
    1549         294 :                     rIStream.Read(aNewData.get(), nStreamLength);
    1550             : 
    1551         294 :                     if(!rIStream.GetError())
    1552             :                     {
    1553         294 :                         SvgDataPtr aSvgDataPtr(new SvgData(aNewData, nStreamLength, rPath));
    1554         294 :                         rGraphic = Graphic(aSvgDataPtr);
    1555         294 :                         bOkay = true;
    1556         294 :                     }
    1557         294 :                 }
    1558             :             }
    1559             : 
    1560         294 :             if(bOkay)
    1561             :             {
    1562         294 :                 eLinkType = GFX_LINK_TYPE_NATIVE_SVG;
    1563             :             }
    1564             :             else
    1565             :             {
    1566           0 :                 nStatus = GRFILTER_FILTERERROR;
    1567             :             }
    1568             :         }
    1569        5189 :         else if( aFilterName.equalsIgnoreAsciiCase( IMP_XBM ) )
    1570             :         {
    1571           0 :             if( rGraphic.GetContext() == (GraphicReader*) 1 )
    1572           0 :                 rGraphic.SetContext( NULL );
    1573             : 
    1574           0 :             if( !ImportXBM( rIStream, rGraphic ) )
    1575           0 :                 nStatus = GRFILTER_FILTERERROR;
    1576             :         }
    1577        5189 :         else if( aFilterName.equalsIgnoreAsciiCase( IMP_XPM ) )
    1578             :         {
    1579           0 :             if( rGraphic.GetContext() == (GraphicReader*) 1 )
    1580           0 :                 rGraphic.SetContext( NULL );
    1581             : 
    1582           0 :             if( !ImportXPM( rIStream, rGraphic ) )
    1583           0 :                 nStatus = GRFILTER_FILTERERROR;
    1584             :         }
    1585       10369 :         else if( aFilterName.equalsIgnoreAsciiCase( IMP_BMP ) ||
    1586        5180 :                     aFilterName.equalsIgnoreAsciiCase( IMP_SVMETAFILE ) )
    1587             :         {
    1588             :             // SV internal filters for import bitmaps and MetaFiles
    1589        5028 :             ReadGraphic( rIStream, rGraphic );
    1590        5028 :             if( rIStream.GetError() )
    1591             :             {
    1592           0 :                 nStatus = GRFILTER_FORMATERROR;
    1593             :             }
    1594             :             else
    1595             :             {
    1596             :                 // #i15508# added BMP type (checked, works)
    1597        5028 :                 eLinkType = GFX_LINK_TYPE_NATIVE_BMP;
    1598             :             }
    1599             :         }
    1600         161 :         else if( aFilterName.equalsIgnoreAsciiCase( IMP_MOV ) )
    1601             :         {
    1602           0 :             ReadGraphic( rIStream, rGraphic );
    1603           0 :             if( rIStream.GetError() )
    1604           0 :                 nStatus = GRFILTER_FORMATERROR;
    1605             :             else
    1606             :             {
    1607           0 :                 rGraphic.SetDefaultType();
    1608           0 :                 rIStream.Seek( STREAM_SEEK_TO_END );
    1609           0 :                 eLinkType = GFX_LINK_TYPE_NATIVE_MOV;
    1610             :             }
    1611             :         }
    1612         233 :         else if( aFilterName.equalsIgnoreAsciiCase( IMP_WMF ) ||
    1613          72 :                 aFilterName.equalsIgnoreAsciiCase( IMP_EMF ) )
    1614             :         {
    1615         159 :             GDIMetaFile aMtf;
    1616         159 :             if( !ConvertWMFToGDIMetaFile( rIStream, aMtf, NULL, pExtHeader ) )
    1617          13 :                 nStatus = GRFILTER_FORMATERROR;
    1618             :             else
    1619             :             {
    1620         146 :                 rGraphic = aMtf;
    1621         146 :                 eLinkType = GFX_LINK_TYPE_NATIVE_WMF;
    1622         159 :             }
    1623             :         }
    1624           4 :         else if( aFilterName.equalsIgnoreAsciiCase( IMP_SVSGF )
    1625           2 :                 || aFilterName.equalsIgnoreAsciiCase( IMP_SVSGV ) )
    1626             :         {
    1627             :             sal_uInt16          nVersion;
    1628           2 :             unsigned char   nTyp = CheckSgfTyp( rIStream, nVersion );
    1629             : 
    1630           2 :             switch( nTyp )
    1631             :             {
    1632             :                 case SGF_BITIMAGE:
    1633             :                 {
    1634           0 :                     SvMemoryStream aTempStream;
    1635           0 :                     if( aTempStream.GetError() )
    1636           0 :                         return GRFILTER_OPENERROR;
    1637             : 
    1638           0 :                     if( !SgfBMapFilter( rIStream, aTempStream ) )
    1639           0 :                         nStatus = GRFILTER_FILTERERROR;
    1640             :                     else
    1641             :                     {
    1642           0 :                         aTempStream.Seek( 0L );
    1643           0 :                         ReadGraphic( aTempStream, rGraphic );
    1644             : 
    1645           0 :                         if( aTempStream.GetError() )
    1646           0 :                             nStatus = GRFILTER_FILTERERROR;
    1647           0 :                     }
    1648             :                 }
    1649           0 :                 break;
    1650             : 
    1651             :                 case SGF_SIMPVECT:
    1652             :                 {
    1653           0 :                     GDIMetaFile aMtf;
    1654           0 :                     if( !SgfVectFilter( rIStream, aMtf ) )
    1655           0 :                         nStatus = GRFILTER_FILTERERROR;
    1656             :                     else
    1657           0 :                         rGraphic = Graphic( aMtf );
    1658             :                 }
    1659           0 :                 break;
    1660             : 
    1661             :                 case SGF_STARDRAW:
    1662             :                 {
    1663           2 :                     if( nVersion != SGV_VERSION )
    1664           0 :                         nStatus = GRFILTER_VERSIONERROR;
    1665             :                     else
    1666             :                     {
    1667           2 :                         GDIMetaFile aMtf;
    1668           4 :                         if( !SgfSDrwFilter( rIStream, aMtf,
    1669           4 :                                 INetURLObject(aFilterPath) ) )
    1670             :                         {
    1671           0 :                             nStatus = GRFILTER_FILTERERROR;
    1672             :                         }
    1673             :                         else
    1674           2 :                             rGraphic = Graphic( aMtf );
    1675             :                     }
    1676             :                 }
    1677           2 :                 break;
    1678             : 
    1679             :                 default:
    1680             :                 {
    1681           0 :                     nStatus = GRFILTER_FORMATERROR;
    1682             :                 }
    1683           0 :                 break;
    1684             :             }
    1685             :         }
    1686             :         else
    1687           0 :             nStatus = GRFILTER_FILTERERROR;
    1688             :     }
    1689             :     else
    1690             :     {
    1691         124 :         ImpFilterLibCacheEntry* pFilter = NULL;
    1692             : 
    1693             :         // find first filter in filter paths
    1694         124 :         sal_Int32 i, nTokenCount = getTokenCount(aFilterPath, ';');
    1695         124 :         ImpFilterLibCache &rCache = Cache::get();
    1696         248 :         for( i = 0; ( i < nTokenCount ) && ( pFilter == NULL ); i++ )
    1697         124 :             pFilter = rCache.GetFilter( getToken(aFilterPath, i, ';'), aFilterName );
    1698         124 :         if( !pFilter )
    1699           0 :             nStatus = GRFILTER_FILTERERROR;
    1700             :         else
    1701             :         {
    1702         124 :             PFilterCall pFunc = pFilter->GetImportFunction();
    1703             : 
    1704         124 :             if( !pFunc )
    1705           0 :                 nStatus = GRFILTER_FILTERERROR;
    1706             :             else
    1707             :             {
    1708         124 :                 OUString aShortName;
    1709         124 :                 if( nFormat != GRFILTER_FORMAT_DONTKNOW )
    1710             :                 {
    1711         124 :                     aShortName = GetImportFormatShortName( nFormat ).toAsciiUpperCase();
    1712         124 :                     if ( ( pFilterConfigItem == NULL ) && aShortName == "PCD" )
    1713             :                     {
    1714           0 :                         OUString aFilterConfigPath( "Office.Common/Filter/Graphic/Import/PCD" );
    1715           0 :                         pFilterConfigItem = new FilterConfigItem( aFilterConfigPath );
    1716             :                     }
    1717             :                 }
    1718         124 :                 if( !(*pFunc)( rIStream, rGraphic, pFilterConfigItem ) )
    1719           0 :                     nStatus = GRFILTER_FORMATERROR;
    1720             :                 else
    1721             :                 {
    1722             :                     // try to set link type if format matches
    1723         124 :                     if( nFormat != GRFILTER_FORMAT_DONTKNOW )
    1724             :                     {
    1725         124 :                         if( aShortName.startsWith( TIF_SHORTNAME ) )
    1726           0 :                             eLinkType = GFX_LINK_TYPE_NATIVE_TIF;
    1727         124 :                         else if( aShortName.startsWith( MET_SHORTNAME ) )
    1728           0 :                             eLinkType = GFX_LINK_TYPE_NATIVE_MET;
    1729         124 :                         else if( aShortName.startsWith( PCT_SHORTNAME ) )
    1730         123 :                             eLinkType = GFX_LINK_TYPE_NATIVE_PCT;
    1731             :                     }
    1732         124 :                 }
    1733             :             }
    1734             :         }
    1735             :     }
    1736             : 
    1737        6387 :     if( nStatus == GRFILTER_OK && bCreateNativeLink && ( eLinkType != GFX_LINK_TYPE_NONE ) && !rGraphic.GetContext() && !bLinkSet )
    1738             :     {
    1739        6347 :         if (pGraphicContent == NULL)
    1740             :         {
    1741        6347 :             const sal_uLong nStreamEnd = rIStream.Tell();
    1742        6347 :             nGraphicContentSize = nStreamEnd - nStreamBegin;
    1743             : 
    1744        6347 :             if (nGraphicContentSize > 0)
    1745             :             {
    1746             :                 try
    1747             :                 {
    1748        6343 :                     pGraphicContent = new sal_uInt8[nGraphicContentSize];
    1749             :                 }
    1750           0 :                 catch (const std::bad_alloc&)
    1751             :                 {
    1752           0 :                     nStatus = GRFILTER_TOOBIG;
    1753             :                 }
    1754             : 
    1755        6343 :                 if( nStatus == GRFILTER_OK )
    1756             :                 {
    1757        6343 :                     rIStream.Seek(nStreamBegin);
    1758        6343 :                     rIStream.Read(pGraphicContent, nGraphicContentSize);
    1759             :                 }
    1760             :             }
    1761             :         }
    1762        6347 :         if( nStatus == GRFILTER_OK )
    1763             :         {
    1764        6347 :             rGraphic.SetLink( GfxLink( pGraphicContent, nGraphicContentSize, eLinkType, true ) );
    1765        6347 :             bGraphicContentOwned = false; //ownership passed to the GfxLink
    1766             :         }
    1767             :     }
    1768             : 
    1769        6387 :     if (bGraphicContentOwned)
    1770          40 :         delete[] pGraphicContent;
    1771             : 
    1772             :     // Set error code or try to set native buffer
    1773        6387 :     if( nStatus != GRFILTER_OK )
    1774             :     {
    1775          26 :         if( bAbort )
    1776           0 :             nStatus = GRFILTER_ABORT;
    1777             : 
    1778          26 :         ImplSetError( nStatus, &rIStream );
    1779          26 :         rIStream.Seek( nStreamBegin );
    1780          26 :         rGraphic.Clear();
    1781             :     }
    1782             : 
    1783        6387 :     delete pFilterConfigItem;
    1784        6387 :     return nStatus;
    1785             : }
    1786             : 
    1787           0 : sal_uInt16 GraphicFilter::ExportGraphic( const Graphic& rGraphic, const INetURLObject& rPath,
    1788             :     sal_uInt16 nFormat, const uno::Sequence< beans::PropertyValue >* pFilterData )
    1789             : {
    1790             : #ifdef DISABLE_EXPORT
    1791             :     (void) rGraphic;
    1792             :     (void) rPath;
    1793             :     (void) nFormat;
    1794             :     (void) pFilterData;
    1795             : 
    1796             :     return GRFILTER_FORMATERROR;
    1797             : #else
    1798             :     SAL_INFO( "vcl.filter", "GraphicFilter::ExportGraphic() (thb)" );
    1799           0 :     sal_uInt16  nRetValue = GRFILTER_FORMATERROR;
    1800             :     DBG_ASSERT( rPath.GetProtocol() != INET_PROT_NOT_VALID, "GraphicFilter::ExportGraphic() : ProtType == INET_PROT_NOT_VALID" );
    1801           0 :     bool bAlreadyExists = DirEntryExists( rPath );
    1802             : 
    1803           0 :     OUString    aMainUrl( rPath.GetMainURL( INetURLObject::NO_DECODE ) );
    1804           0 :     boost::scoped_ptr<SvStream> pStream(::utl::UcbStreamHelper::CreateStream( aMainUrl, STREAM_WRITE | STREAM_TRUNC ));
    1805           0 :     if ( pStream )
    1806             :     {
    1807           0 :         nRetValue = ExportGraphic( rGraphic, aMainUrl, *pStream, nFormat, pFilterData );
    1808           0 :         pStream.reset();
    1809             : 
    1810           0 :         if( ( GRFILTER_OK != nRetValue ) && !bAlreadyExists )
    1811           0 :             KillDirEntry( aMainUrl );
    1812             :     }
    1813           0 :     return nRetValue;
    1814             : #endif
    1815             : }
    1816             : 
    1817             : #ifdef DISABLE_DYNLOADING
    1818             : 
    1819             : #ifndef DISABLE_EXPORT
    1820             : 
    1821             : extern "C" bool egiGraphicExport( SvStream& rStream, Graphic& rGraphic, FilterConfigItem* pConfigItem );
    1822             : extern "C" bool emeGraphicExport( SvStream& rStream, Graphic& rGraphic, FilterConfigItem* pConfigItem );
    1823             : extern "C" bool epbGraphicExport( SvStream& rStream, Graphic& rGraphic, FilterConfigItem* pConfigItem );
    1824             : extern "C" bool epgGraphicExport( SvStream& rStream, Graphic& rGraphic, FilterConfigItem* pConfigItem );
    1825             : extern "C" bool eppGraphicExport( SvStream& rStream, Graphic& rGraphic, FilterConfigItem* pConfigItem );
    1826             : extern "C" bool epsGraphicExport( SvStream& rStream, Graphic& rGraphic, FilterConfigItem* pConfigItem );
    1827             : extern "C" bool eptGraphicExport( SvStream& rStream, Graphic& rGraphic, FilterConfigItem* pConfigItem );
    1828             : extern "C" bool eraGraphicExport( SvStream& rStream, Graphic& rGraphic, FilterConfigItem* pConfigItem );
    1829             : extern "C" bool etiGraphicExport( SvStream& rStream, Graphic& rGraphic, FilterConfigItem* pConfigItem );
    1830             : extern "C" bool expGraphicExport( SvStream& rStream, Graphic& rGraphic, FilterConfigItem* pConfigItem );
    1831             : 
    1832             : #endif
    1833             : 
    1834             : #endif
    1835             : 
    1836         138 : sal_uInt16 GraphicFilter::ExportGraphic( const Graphic& rGraphic, const OUString& rPath,
    1837             :     SvStream& rOStm, sal_uInt16 nFormat, const uno::Sequence< beans::PropertyValue >* pFilterData )
    1838             : {
    1839             : #ifdef DISABLE_EXPORT
    1840             :     (void) rGraphic;
    1841             :     (void) rPath;
    1842             :     (void) rOStm;
    1843             :     (void) nFormat;
    1844             :     (void) pFilterData;
    1845             : 
    1846             :     return GRFILTER_FORMATERROR;
    1847             : #else
    1848             :     SAL_INFO( "vcl.filter", "GraphicFilter::ExportGraphic() (thb)" );
    1849         138 :     sal_uInt16 nFormatCount = GetExportFormatCount();
    1850             : 
    1851         138 :     ResetLastError();
    1852         138 :     nExpGraphHint = 0;
    1853             : 
    1854         138 :     if( nFormat == GRFILTER_FORMAT_DONTKNOW )
    1855             :     {
    1856           0 :         INetURLObject aURL( rPath );
    1857           0 :         OUString aExt( aURL.GetFileExtension().toAsciiUpperCase() );
    1858             : 
    1859           0 :         for( sal_uInt16 i = 0; i < nFormatCount; i++ )
    1860             :         {
    1861           0 :             if ( pConfig->GetExportFormatExtension( i ).equalsIgnoreAsciiCase( aExt ) )
    1862             :             {
    1863           0 :                 nFormat=i;
    1864           0 :                 break;
    1865             :             }
    1866           0 :         }
    1867             :     }
    1868         138 :     if( nFormat >= nFormatCount )
    1869           0 :         return (sal_uInt16) ImplSetError( GRFILTER_FORMATERROR );
    1870             : 
    1871         138 :     FilterConfigItem aConfigItem( (uno::Sequence< beans::PropertyValue >*)pFilterData );
    1872         276 :     OUString aFilterName( pConfig->GetExportFilterName( nFormat ) );
    1873             : 
    1874         138 :     bAbort              = false;
    1875         138 :     sal_uInt16      nStatus = GRFILTER_OK;
    1876             :     GraphicType eType;
    1877         276 :     Graphic     aGraphic( rGraphic );
    1878             : 
    1879         138 :     aGraphic = ImpGetScaledGraphic( rGraphic, aConfigItem );
    1880         138 :     eType = aGraphic.GetType();
    1881             : 
    1882         138 :     if( pConfig->IsExportPixelFormat( nFormat ) )
    1883             :     {
    1884          87 :         if( eType != GRAPHIC_BITMAP )
    1885             :         {
    1886          30 :             Size aSizePixel;
    1887             :             sal_uLong nColorCount,nBitsPerPixel,nNeededMem,nMaxMem;
    1888          30 :             VirtualDevice aVirDev;
    1889             : 
    1890          30 :             nMaxMem = 1024;
    1891          30 :             nMaxMem *= 1024; // In Bytes
    1892             : 
    1893             :             // Calculate how big the image would normally be:
    1894          30 :             aSizePixel=aVirDev.LogicToPixel(aGraphic.GetPrefSize(),aGraphic.GetPrefMapMode());
    1895             : 
    1896             :             // Calculate how much memory the image will take up
    1897          30 :             nColorCount=aVirDev.GetColorCount();
    1898          30 :             if      (nColorCount<=2)     nBitsPerPixel=1;
    1899          30 :             else if (nColorCount<=4)     nBitsPerPixel=2;
    1900          30 :             else if (nColorCount<=16)    nBitsPerPixel=4;
    1901          30 :             else if (nColorCount<=256)   nBitsPerPixel=8;
    1902          30 :             else if (nColorCount<=65536) nBitsPerPixel=16;
    1903          30 :             else                         nBitsPerPixel=24;
    1904          30 :             nNeededMem=((sal_uLong)aSizePixel.Width()*(sal_uLong)aSizePixel.Height()*nBitsPerPixel+7)/8;
    1905             : 
    1906             :             // is the image larger than available memory?
    1907          30 :             if (nMaxMem<nNeededMem)
    1908             :             {
    1909           0 :                 double fFak=sqrt(((double)nMaxMem)/((double)nNeededMem));
    1910           0 :                 aSizePixel.Width()=(sal_uLong)(((double)aSizePixel.Width())*fFak);
    1911           0 :                 aSizePixel.Height()=(sal_uLong)(((double)aSizePixel.Height())*fFak);
    1912             :             }
    1913             : 
    1914          30 :             aVirDev.SetMapMode(MapMode(MAP_PIXEL));
    1915          30 :             aVirDev.SetOutputSizePixel(aSizePixel);
    1916          60 :             Graphic aGraphic2=aGraphic;
    1917          30 :             aGraphic2.Draw(&aVirDev,Point(0,0),aSizePixel); // this changes the MapMode
    1918          30 :             aVirDev.SetMapMode(MapMode(MAP_PIXEL));
    1919          60 :             aGraphic=Graphic(aVirDev.GetBitmap(Point(0,0),aSizePixel));
    1920             :         }
    1921             :     }
    1922         138 :     if( rOStm.GetError() )
    1923           0 :         nStatus = GRFILTER_IOERROR;
    1924         138 :     if( GRFILTER_OK == nStatus )
    1925             :     {
    1926         138 :         if ( pConfig->IsExportInternalFilter( nFormat ) )
    1927             :         {
    1928         138 :             if( aFilterName.equalsIgnoreAsciiCase( EXP_BMP ) )
    1929             :             {
    1930           1 :                 Bitmap aBmp( aGraphic.GetBitmap() );
    1931           1 :                 sal_Int32 nColorRes = aConfigItem.ReadInt32( "Colors", 0 );
    1932           1 :                 if ( nColorRes && ( nColorRes <= (sal_uInt16)BMP_CONVERSION_24BIT) )
    1933             :                 {
    1934           0 :                     if( !aBmp.Convert( (BmpConversion) nColorRes ) )
    1935           0 :                         aBmp = aGraphic.GetBitmap();
    1936             :                 }
    1937           1 :                 bool    bRleCoding = aConfigItem.ReadBool( "RLE_Coding", true );
    1938             :                 // save RLE encoded?
    1939           1 :                 WriteDIB(aBmp, rOStm, bRleCoding, true);
    1940             : 
    1941           1 :                 if( rOStm.GetError() )
    1942           0 :                     nStatus = GRFILTER_IOERROR;
    1943             :             }
    1944         137 :             else if( aFilterName.equalsIgnoreAsciiCase( EXP_SVMETAFILE ) )
    1945             :             {
    1946           0 :                 sal_Int32 nVersion = aConfigItem.ReadInt32( "Version", 0 ) ;
    1947           0 :                 if ( nVersion )
    1948           0 :                     rOStm.SetVersion( nVersion );
    1949             : 
    1950             :                 // #i119735# just use GetGDIMetaFile, it will create a bufferd version of contained bitmap now automatically
    1951           0 :                 GDIMetaFile aMTF(aGraphic.GetGDIMetaFile());
    1952             : 
    1953           0 :                 aMTF.Write( rOStm );
    1954             : 
    1955           0 :                 if( rOStm.GetError() )
    1956           0 :                     nStatus = GRFILTER_IOERROR;
    1957             :             }
    1958         137 :             else if ( aFilterName.equalsIgnoreAsciiCase( EXP_WMF ) )
    1959             :             {
    1960             :                 // #i119735# just use GetGDIMetaFile, it will create a bufferd version of contained bitmap now automatically
    1961          31 :                 if ( !ConvertGDIMetaFileToWMF( aGraphic.GetGDIMetaFile(), rOStm, &aConfigItem ) )
    1962           0 :                     nStatus = GRFILTER_FORMATERROR;
    1963             : 
    1964          31 :                 if( rOStm.GetError() )
    1965           0 :                     nStatus = GRFILTER_IOERROR;
    1966             :             }
    1967         106 :             else if ( aFilterName.equalsIgnoreAsciiCase( EXP_EMF ) )
    1968             :             {
    1969             :                 // #i119735# just use GetGDIMetaFile, it will create a bufferd version of contained bitmap now automatically
    1970          20 :                 if ( !ConvertGDIMetaFileToEMF( aGraphic.GetGDIMetaFile(), rOStm, &aConfigItem ) )
    1971           0 :                     nStatus = GRFILTER_FORMATERROR;
    1972             : 
    1973          20 :                 if( rOStm.GetError() )
    1974           0 :                     nStatus = GRFILTER_IOERROR;
    1975             :             }
    1976          86 :             else if( aFilterName.equalsIgnoreAsciiCase( EXP_JPEG ) )
    1977             :             {
    1978           1 :                 bool bExportedGrayJPEG = false;
    1979           1 :                 if( !ExportJPEG( rOStm, aGraphic, pFilterData, &bExportedGrayJPEG ) )
    1980           0 :                     nStatus = GRFILTER_FORMATERROR;
    1981           1 :                 nExpGraphHint = bExportedGrayJPEG ? GRFILTER_OUTHINT_GREY : 0;
    1982             : 
    1983           1 :                 if( rOStm.GetError() )
    1984           0 :                     nStatus = GRFILTER_IOERROR;
    1985             :             }
    1986          85 :             else if ( aFilterName.equalsIgnoreAsciiCase( EXP_PNG ) )
    1987             :             {
    1988          85 :                 vcl::PNGWriter aPNGWriter( aGraphic.GetBitmapEx(), pFilterData );
    1989          85 :                 if ( pFilterData )
    1990             :                 {
    1991          11 :                     sal_Int32 k, j, i = 0;
    1992          84 :                     for ( i = 0; i < pFilterData->getLength(); i++ )
    1993             :                     {
    1994          73 :                         if ( (*pFilterData)[ i ].Name == "AdditionalChunks" )
    1995             :                         {
    1996           0 :                             com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValue > aAdditionalChunkSequence;
    1997           0 :                             if ( (*pFilterData)[ i ].Value >>= aAdditionalChunkSequence )
    1998             :                             {
    1999           0 :                                 for ( j = 0; j < aAdditionalChunkSequence.getLength(); j++ )
    2000             :                                 {
    2001           0 :                                     if ( aAdditionalChunkSequence[ j ].Name.getLength() == 4 )
    2002             :                                     {
    2003           0 :                                         sal_uInt32 nChunkType = 0;
    2004           0 :                                         for ( k = 0; k < 4; k++ )
    2005             :                                         {
    2006           0 :                                             nChunkType <<= 8;
    2007           0 :                                             nChunkType |= (sal_uInt8)aAdditionalChunkSequence[ j ].Name[ k ];
    2008             :                                         }
    2009           0 :                                         com::sun::star::uno::Sequence< sal_Int8 > aByteSeq;
    2010           0 :                                         if ( aAdditionalChunkSequence[ j ].Value >>= aByteSeq )
    2011             :                                         {
    2012           0 :                                             std::vector< vcl::PNGWriter::ChunkData >& rChunkData = aPNGWriter.GetChunks();
    2013           0 :                                             if ( !rChunkData.empty() )
    2014             :                                             {
    2015           0 :                                                 sal_uInt32 nChunkLen = aByteSeq.getLength();
    2016             : 
    2017           0 :                                                 vcl::PNGWriter::ChunkData aChunkData;
    2018           0 :                                                 aChunkData.nType = nChunkType;
    2019           0 :                                                 if ( nChunkLen )
    2020             :                                                 {
    2021           0 :                                                     aChunkData.aData.resize( nChunkLen );
    2022           0 :                                                     memcpy( &aChunkData.aData[ 0 ], aByteSeq.getConstArray(), nChunkLen );
    2023             :                                                 }
    2024           0 :                                                 std::vector< vcl::PNGWriter::ChunkData >::iterator aIter = rChunkData.end() - 1;
    2025           0 :                                                 rChunkData.insert( aIter, aChunkData );
    2026             :                                             }
    2027           0 :                                         }
    2028             :                                     }
    2029             :                                 }
    2030           0 :                             }
    2031             :                         }
    2032             :                     }
    2033             :                 }
    2034          85 :                 aPNGWriter.Write( rOStm );
    2035             : 
    2036          85 :                 if( rOStm.GetError() )
    2037           0 :                     nStatus = GRFILTER_IOERROR;
    2038             :             }
    2039           0 :             else if( aFilterName.equalsIgnoreAsciiCase( EXP_SVG ) )
    2040             :             {
    2041           0 :                 bool bDone(false);
    2042             : 
    2043             :                 // do we have a native SVG RenderGraphic, whose data can be written directly?
    2044           0 :                 const SvgDataPtr aSvgDataPtr(rGraphic.getSvgData());
    2045             : 
    2046           0 :                 if(aSvgDataPtr.get() && aSvgDataPtr->getSvgDataArrayLength())
    2047             :                 {
    2048           0 :                     rOStm.Write(aSvgDataPtr->getSvgDataArray().get(), aSvgDataPtr->getSvgDataArrayLength());
    2049             : 
    2050           0 :                     if( rOStm.GetError() )
    2051             :                     {
    2052           0 :                         nStatus = GRFILTER_IOERROR;
    2053             :                     }
    2054             :                     else
    2055             :                     {
    2056           0 :                         bDone = true;
    2057             :                     }
    2058             :                 }
    2059             : 
    2060           0 :                 if( !bDone )
    2061             :                 {
    2062             :                     // do the normal GDIMetaFile export instead
    2063             :                     try
    2064             :                     {
    2065           0 :                         css::uno::Reference< css::uno::XComponentContext > xContext( ::comphelper::getProcessComponentContext() );
    2066             : 
    2067             :                         css::uno::Reference< css::xml::sax::XDocumentHandler > xSaxWriter(
    2068           0 :                             xml::sax::Writer::create( xContext ), uno::UNO_QUERY_THROW);
    2069           0 :                         css::uno::Sequence< css::uno::Any > aArguments( 1 );
    2070           0 :                         aArguments[ 0 ] <<= aConfigItem.GetFilterData();
    2071             :                         css::uno::Reference< css::svg::XSVGWriter > xSVGWriter(
    2072           0 :                             xContext->getServiceManager()->createInstanceWithArgumentsAndContext( "com.sun.star.svg.SVGWriter", aArguments, xContext),
    2073           0 :                                 css::uno::UNO_QUERY );
    2074           0 :                         if( xSaxWriter.is() && xSVGWriter.is() )
    2075             :                         {
    2076             :                             css::uno::Reference< css::io::XActiveDataSource > xActiveDataSource(
    2077           0 :                                 xSaxWriter, css::uno::UNO_QUERY );
    2078             : 
    2079           0 :                             if( xActiveDataSource.is() )
    2080             :                             {
    2081             :                                 const css::uno::Reference< css::uno::XInterface > xStmIf(
    2082           0 :                                     static_cast< ::cppu::OWeakObject* >( new ImpFilterOutputStream( rOStm ) ) );
    2083             : 
    2084           0 :                                 SvMemoryStream aMemStm( 65535, 65535 );
    2085             : 
    2086             :                                 // #i119735# just use GetGDIMetaFile, it will create a buffered version of contained bitmap now automatically
    2087           0 :                                 ( (GDIMetaFile&) aGraphic.GetGDIMetaFile() ).Write( aMemStm );
    2088             : 
    2089           0 :                                 xActiveDataSource->setOutputStream( css::uno::Reference< css::io::XOutputStream >(
    2090           0 :                                     xStmIf, css::uno::UNO_QUERY ) );
    2091           0 :                                 css::uno::Sequence< sal_Int8 > aMtfSeq( (sal_Int8*) aMemStm.GetData(), aMemStm.Tell() );
    2092           0 :                                 xSVGWriter->write( xSaxWriter, aMtfSeq );
    2093           0 :                             }
    2094           0 :                         }
    2095             :                     }
    2096           0 :                     catch(const css::uno::Exception&)
    2097             :                     {
    2098           0 :                         nStatus = GRFILTER_IOERROR;
    2099             :                     }
    2100           0 :                 }
    2101             :             }
    2102             :             else
    2103           0 :                 nStatus = GRFILTER_FILTERERROR;
    2104             :         }
    2105             :         else
    2106             :         {
    2107           0 :             sal_Int32 i, nTokenCount = getTokenCount(aFilterPath, ';');
    2108           0 :             for ( i = 0; i < nTokenCount; i++ )
    2109             :             {
    2110             : #ifndef DISABLE_DYNLOADING
    2111           0 :                 OUString aPhysicalName( ImpCreateFullFilterPath( getToken(aFilterPath, i, ';'), aFilterName ) );
    2112           0 :                 osl::Module aLibrary( aPhysicalName );
    2113             : 
    2114           0 :                 PFilterCall pFunc = (PFilterCall) aLibrary.getFunctionSymbol(OUString(EXPORT_FUNCTION_NAME));
    2115             :                 // Execute dialog in DLL
    2116             : #else
    2117             :                 PFilterCall pFunc = NULL;
    2118             :                 if( aFilterName.equalsAscii( "egi" ) )
    2119             :                     pFunc = egiGraphicExport;
    2120             :                 else if( aFilterName.equalsAscii( "eme" ) )
    2121             :                     pFunc = emeGraphicExport;
    2122             :                 else if( aFilterName.equalsAscii( "epb" ) )
    2123             :                     pFunc = epbGraphicExport;
    2124             :                 else if( aFilterName.equalsAscii( "epg" ) )
    2125             :                     pFunc = epgGraphicExport;
    2126             :                 else if( aFilterName.equalsAscii( "epp" ) )
    2127             :                     pFunc = eppGraphicExport;
    2128             :                 else if( aFilterName.equalsAscii( "eps" ) )
    2129             :                     pFunc = epsGraphicExport;
    2130             :                 else if( aFilterName.equalsAscii( "ept" ) )
    2131             :                     pFunc = eptGraphicExport;
    2132             :                 else if( aFilterName.equalsAscii( "era" ) )
    2133             :                     pFunc = eraGraphicExport;
    2134             :                 else if( aFilterName.equalsAscii( "eti" ) )
    2135             :                     pFunc = etiGraphicExport;
    2136             :                 else if( aFilterName.equalsAscii( "exp" ) )
    2137             :                     pFunc = expGraphicExport;
    2138             : #endif
    2139           0 :                 if( pFunc )
    2140             :                 {
    2141           0 :                     if ( !(*pFunc)( rOStm, aGraphic, &aConfigItem ) )
    2142           0 :                         nStatus = GRFILTER_FORMATERROR;
    2143           0 :                     break;
    2144             :                 }
    2145             :                 else
    2146           0 :                     nStatus = GRFILTER_FILTERERROR;
    2147           0 :             }
    2148             :         }
    2149             :     }
    2150         138 :     if( nStatus != GRFILTER_OK )
    2151             :     {
    2152           0 :         if( bAbort )
    2153           0 :             nStatus = GRFILTER_ABORT;
    2154             : 
    2155           0 :         ImplSetError( nStatus, &rOStm );
    2156             :     }
    2157         276 :     return nStatus;
    2158             : #endif
    2159             : }
    2160             : 
    2161           0 : const FilterErrorEx& GraphicFilter::GetLastError() const
    2162             : {
    2163           0 :     return *pErrorEx;
    2164             : }
    2165             : 
    2166        6734 : void GraphicFilter::ResetLastError()
    2167             : {
    2168        6734 :     pErrorEx->nFilterError = pErrorEx->nStreamError = 0UL;
    2169        6734 : }
    2170             : 
    2171         173 : const Link GraphicFilter::GetFilterCallback() const
    2172             : {
    2173         173 :     const Link aLink( LINK( this, GraphicFilter, FilterCallback ) );
    2174         173 :     return aLink;
    2175             : }
    2176             : 
    2177         346 : IMPL_LINK( GraphicFilter, FilterCallback, ConvertData*, pData )
    2178             : {
    2179         173 :     bool nRet = false;
    2180             : 
    2181         173 :     if( pData )
    2182             :     {
    2183         173 :         sal_uInt16      nFormat = GRFILTER_FORMAT_DONTKNOW;
    2184         173 :         OString aShortName;
    2185         173 :         switch( pData->mnFormat )
    2186             :         {
    2187           0 :             case( CVT_BMP ): aShortName = BMP_SHORTNAME; break;
    2188           0 :             case( CVT_GIF ): aShortName = GIF_SHORTNAME; break;
    2189           4 :             case( CVT_JPG ): aShortName = JPG_SHORTNAME; break;
    2190           0 :             case( CVT_MET ): aShortName = MET_SHORTNAME; break;
    2191           0 :             case( CVT_PCT ): aShortName = PCT_SHORTNAME; break;
    2192          81 :             case( CVT_PNG ): aShortName = PNG_SHORTNAME; break;
    2193           0 :             case( CVT_SVM ): aShortName = SVM_SHORTNAME; break;
    2194           0 :             case( CVT_TIF ): aShortName = TIF_SHORTNAME; break;
    2195          31 :             case( CVT_WMF ): aShortName = WMF_SHORTNAME; break;
    2196          20 :             case( CVT_EMF ): aShortName = EMF_SHORTNAME; break;
    2197           0 :             case( CVT_SVG ): aShortName = SVG_SHORTNAME; break;
    2198             : 
    2199             :             default:
    2200          37 :             break;
    2201             :         }
    2202         173 :         if( GRAPHIC_NONE == pData->maGraphic.GetType() || pData->maGraphic.GetContext() ) // Import
    2203             :         {
    2204             :             // Import
    2205          48 :             nFormat = GetImportFormatNumberForShortName( OStringToOUString( aShortName, RTL_TEXTENCODING_UTF8) );
    2206          48 :             nRet = ImportGraphic( pData->maGraphic, OUString(), pData->mrStm, nFormat ) == 0;
    2207             :         }
    2208             : #ifndef DISABLE_EXPORT
    2209         125 :         else if( !aShortName.isEmpty() )
    2210             :         {
    2211             :             // Export
    2212         125 :             nFormat = GetExportFormatNumberForShortName( OStringToOUString(aShortName, RTL_TEXTENCODING_UTF8) );
    2213         125 :             nRet = ExportGraphic( pData->maGraphic, OUString(), pData->mrStm, nFormat ) == 0;
    2214         173 :         }
    2215             : #endif
    2216             :     }
    2217         173 :     return long(nRet);
    2218             : }
    2219             : 
    2220             : namespace
    2221             : {
    2222          85 :     class StandardGraphicFilter
    2223             :     {
    2224             :     public:
    2225          85 :         StandardGraphicFilter()
    2226          85 :         {
    2227          85 :             m_aFilter.GetImportFormatCount();
    2228          85 :         }
    2229             :         GraphicFilter m_aFilter;
    2230             :     };
    2231             : 
    2232             :     class theGraphicFilter : public rtl::Static<StandardGraphicFilter, theGraphicFilter> {};
    2233             : }
    2234             : 
    2235        6675 : GraphicFilter& GraphicFilter::GetGraphicFilter()
    2236             : {
    2237        6675 :     return theGraphicFilter::get().m_aFilter;
    2238             : }
    2239             : 
    2240         140 : int GraphicFilter::LoadGraphic( const OUString &rPath, const OUString &rFilterName,
    2241             :                  Graphic& rGraphic, GraphicFilter* pFilter,
    2242             :                  sal_uInt16* pDeterminedFormat )
    2243             : {
    2244         140 :     if ( !pFilter )
    2245         140 :         pFilter = &GetGraphicFilter();
    2246             : 
    2247         140 :     const sal_uInt16 nFilter = !rFilterName.isEmpty() && pFilter->GetImportFormatCount()
    2248             :                     ? pFilter->GetImportFormatNumber( rFilterName )
    2249         140 :                     : GRFILTER_FORMAT_DONTKNOW;
    2250             : 
    2251         140 :     INetURLObject aURL( rPath );
    2252         140 :     if ( aURL.HasError() )
    2253             :     {
    2254           0 :         aURL.SetSmartProtocol( INET_PROT_FILE );
    2255           0 :         aURL.SetSmartURL( rPath );
    2256             :     }
    2257             : 
    2258         140 :     SvStream* pStream = NULL;
    2259         140 :     if ( INET_PROT_FILE != aURL.GetProtocol() )
    2260             :     {
    2261           0 :         pStream = ::utl::UcbStreamHelper::CreateStream( rPath, STREAM_READ );
    2262             :     }
    2263             : 
    2264         140 :     int nRes = GRFILTER_OK;
    2265         140 :     if ( !pStream )
    2266         140 :         nRes = pFilter->ImportGraphic( rGraphic, aURL, nFilter, pDeterminedFormat );
    2267             :     else
    2268           0 :         nRes = pFilter->ImportGraphic( rGraphic, rPath, *pStream, nFilter, pDeterminedFormat );
    2269             : 
    2270             : #ifdef DBG_UTIL
    2271             :     OUString aReturnString;
    2272             : 
    2273             :     switch (nRes)
    2274             :     {
    2275             :         case GRFILTER_OPENERROR:
    2276             :             aReturnString="open error";
    2277             :             break;
    2278             :         case GRFILTER_IOERROR:
    2279             :             aReturnString="IO error";
    2280             :             break;
    2281             :         case GRFILTER_FORMATERROR:
    2282             :             aReturnString="format error";
    2283             :             break;
    2284             :         case GRFILTER_VERSIONERROR:
    2285             :             aReturnString="version error";
    2286             :             break;
    2287             :         case GRFILTER_FILTERERROR:
    2288             :             aReturnString="filter error";
    2289             :             break;
    2290             :         case GRFILTER_ABORT:
    2291             :             aReturnString="import aborted";
    2292             :             break;
    2293             :         case GRFILTER_TOOBIG:
    2294             :             aReturnString="graphic is too big";
    2295             :             break;
    2296             :         default:
    2297             :             // nothing more to do
    2298             :             break;
    2299             :     }
    2300             : 
    2301             :     SAL_INFO_IF( nRes, "vcl.filter", "Problem importing graphic " << rPath << ". Reason: " << aReturnString );
    2302             : #endif
    2303             : 
    2304         140 :     return nRes;
    2305             : }
    2306             : 
    2307             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10