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

Generated by: LCOV version 1.11