/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /************************************************************************* * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * Copyright 2000, 2010 Oracle and/or its affiliates. * * OpenOffice.org - a multi-platform office productivity suite * * This file is part of OpenOffice.org. * * OpenOffice.org is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 3 * only, as published by the Free Software Foundation. * * OpenOffice.org is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License version 3 for more details * (a copy is included in the LICENSE file that accompanied this code). * * You should have received a copy of the GNU Lesser General Public License * version 3 along with OpenOffice.org. If not, see * * for a copy of the LGPLv3 License. * ************************************************************************/ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "FilterConfigCache.hxx" #include #include #include #include "gifread.hxx" #include "jpeg.hxx" #include "xbmread.hxx" #include "xpmread.hxx" #include #include #include "sgffilt.hxx" #include "osl/module.hxx" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "SvFilterOptionsDialog.hxx" #define PMGCHUNG_msOG 0x6d734f47 // Microsoft Office Animated GIF #define IMPORT_FUNCTION_NAME "GraphicImport" #define EXPORT_FUNCTION_NAME "GraphicExport" // ----------- // - statics - // ----------- using namespace ::rtl; using namespace ::com::sun::star; using comphelper::string::getTokenCount; using comphelper::string::getToken; typedef ::std::vector< GraphicFilter* > FilterList_impl; static FilterList_impl* pFilterHdlList = NULL; static ::osl::Mutex& getListMutex() { static ::osl::Mutex s_aListProtection; return s_aListProtection; } // ------------------------- // - ImpFilterOutputStream - // ------------------------- class ImpFilterOutputStream : public ::cppu::WeakImplHelper1< ::com::sun::star::io::XOutputStream > { protected: SvStream& mrStm; virtual void SAL_CALL writeBytes( const ::com::sun::star::uno::Sequence< sal_Int8 >& rData ) throw (::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException) { mrStm.Write( rData.getConstArray(), rData.getLength() ); } virtual void SAL_CALL flush() throw (::com::sun::star::io::NotConnectedException, ::com::sun::star::io::BufferSizeExceededException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException) { mrStm.Flush(); } virtual void SAL_CALL closeOutput() throw() {} public: ImpFilterOutputStream( SvStream& rStm ) : mrStm( rStm ) {} ~ImpFilterOutputStream() {} }; sal_Bool ImplDirEntryHelper::Exists( const INetURLObject& rObj ) { sal_Bool bExists = sal_False; try { ::ucbhelper::Content aCnt( rObj.GetMainURL( INetURLObject::NO_DECODE ), ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XCommandEnvironment >() ); bExists = aCnt.isDocument(); } catch(const ::com::sun::star::ucb::CommandAbortedException&) { SAL_WARN( "svtools.filter", "CommandAbortedException" ); } catch(const ::com::sun::star::ucb::ContentCreationException&) { SAL_WARN( "svtools.filter", "ContentCreationException" ); } catch( ... ) { SAL_WARN( "svtools.filter", "Any other exception" ); } return bExists; } // ----------------------------------------------------------------------------- void ImplDirEntryHelper::Kill( const String& rMainUrl ) { try { ::ucbhelper::Content aCnt( rMainUrl, ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XCommandEnvironment >() ); aCnt.executeCommand( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "delete" )), ::com::sun::star::uno::makeAny( sal_Bool( sal_True ) ) ); } catch(const ::com::sun::star::ucb::CommandAbortedException&) { SAL_WARN( "svtools.filter", "CommandAbortedException" ); } catch( ... ) { SAL_WARN( "svtools.filter", "Any other exception" ); } } // -------------------- // - Helper functions - // -------------------- //-------------------------------------------------------------------------- sal_uInt8* ImplSearchEntry( sal_uInt8* pSource, sal_uInt8* pDest, sal_uLong nComp, sal_uLong nSize ) { while ( nComp-- >= nSize ) { sal_uLong i; for ( i = 0; i < nSize; i++ ) { if ( ( pSource[i]&~0x20 ) != ( pDest[i]&~0x20 ) ) break; } if ( i == nSize ) return pSource; pSource++; } return NULL; } //-------------------------------------------------------------------------- inline String ImpGetExtension( const String &rPath ) { String aExt; INetURLObject aURL( rPath ); aExt = aURL.GetFileExtension().toAsciiUpperCase(); return aExt; } /************************************************************************* |* |* ImpPeekGraphicFormat() |* |* Beschreibung: |* Diese Funktion kann zweierlei: |* 1.) Datei anlesen, Dateiformat ermitteln |* Eingabe-prarameter: |* rPath - Dateipfad |* rFormatExtension - Inhalt egal |* bTest - setze sal_False |* Ausgabe-parameter: |* Funkionswert - sal_True wenn Erfolg |* rFormatExtension - Bei Erfolg: uebliche Dateiendung |* des Formats (Grossbuchstaben) |* 2.) Datei anlesen, Dateiformat ueberpruefen |* Eingabe-prarameter: |* rPath - Dateipfad |* rFormatExtension - uebliche Dateiendung des Formats |* (Grossbuchstaben) |* bTest - setze sal_True |* Ausgabe-parameter: |* Funkionswert - sal_False, wenn die Datei bestimmt nicht |* vom uebgebenen Format ist. |* sal_True, wenn die Datei WAHRSCHEINLICH von |* dem Format ist, ODER WENN DAS FORMAT |* DIESER FUNKTION NICHT BEKANNT IST! |* *************************************************************************/ static sal_Bool ImpPeekGraphicFormat( SvStream& rStream, String& rFormatExtension, sal_Bool bTest ) { sal_uInt16 i; sal_uInt8 sFirstBytes[ 256 ]; sal_uLong nFirstLong,nSecondLong; sal_uLong nStreamPos = rStream.Tell(); rStream.Seek( STREAM_SEEK_TO_END ); sal_uLong nStreamLen = rStream.Tell() - nStreamPos; rStream.Seek( nStreamPos ); if ( !nStreamLen ) { SvLockBytes* pLockBytes = rStream.GetLockBytes(); if ( pLockBytes ) pLockBytes->SetSynchronMode( sal_True ); rStream.Seek( STREAM_SEEK_TO_END ); nStreamLen = rStream.Tell() - nStreamPos; rStream.Seek( nStreamPos ); } if (!nStreamLen) { return false; // this prevents at least a STL assertion } else if (nStreamLen >= 256) { // load first 256 bytes into a buffer rStream.Read( sFirstBytes, 256 ); } else { rStream.Read( sFirstBytes, nStreamLen ); for( i = (sal_uInt16) nStreamLen; i < 256; i++ ) sFirstBytes[ i ]=0; } if( rStream.GetError() ) return sal_False; // Die ersten 8 Bytes in nFirstLong, nSecondLong unterbringen, // Big-Endian: for( i = 0, nFirstLong = 0L, nSecondLong = 0L; i < 4; i++ ) { nFirstLong=(nFirstLong<<8)|(sal_uLong)sFirstBytes[i]; nSecondLong=(nSecondLong<<8)|(sal_uLong)sFirstBytes[i+4]; } // Folgende Variable ist nur bei bTest==sal_True interessant. Sie // bleibt sal_False, wenn das Format (rFormatExtension) hier noch nicht // einprogrammiert wurde. sal_Bool bSomethingTested = sal_False; // Nun werden die verschieden Formate ueberprueft. Dabei ist die // Reihenfolge nicht egal. Z.b. koennte eine MET-Datei auch durch // den BMP-Test gehen, umgekehrt kann eine BMP-Datei kaum durch den // MET-Test gehen. Also sollte MET vor BMP getestet werden. // Theoretisch waere aber vielleicht auch eine BMP-Datei denkbar, // die durch den MET-Test geht. // Diese Probleme gibt es natuerlich nicht nur bei MET und BMP. // Deshalb wird im Falle der Uberpruefung eines Formats (bTest==sal_True) // nur genau dieses eine Format getestet. Alles andere koennte fatale // Folgen haben, z.B. wenn der Benutzer sagt, es sei BMP-Datei (und es // ist BMP-Datei), und hier wuerde die Datei durch den MET-Test gehen... //--------------------------- MET ------------------------------------ if( !bTest || ( rFormatExtension.CompareToAscii( "MET", 3 ) == COMPARE_EQUAL ) ) { bSomethingTested=sal_True; if( sFirstBytes[2] == 0xd3 ) { rStream.SetNumberFormatInt( NUMBERFORMAT_INT_BIGENDIAN ); rStream.Seek( nStreamPos ); sal_uInt16 nFieldSize; sal_uInt8 nMagic; sal_Bool bOK=sal_True; rStream >> nFieldSize >> nMagic; for (i=0; i<3; i++) { if (nFieldSize<6) { bOK=sal_False; break; } if (nStreamLen < rStream.Tell() + nFieldSize ) { bOK=sal_False; break; } rStream.SeekRel(nFieldSize-3); rStream >> nFieldSize >> nMagic; if (nMagic!=0xd3) { bOK=sal_False; break; } } rStream.SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN ); if (bOK && !rStream.GetError()) { rFormatExtension= UniString::CreateFromAscii( "MET", 3 ); return sal_True; } } } //--------------------------- BMP ------------------------------------ if( !bTest || ( rFormatExtension.CompareToAscii( "BMP", 3 ) == COMPARE_EQUAL ) ) { sal_uInt8 nOffs; bSomethingTested=sal_True; // OS/2-Bitmaparray ('BA') koennen wir evtl. auch lesen, // dementspr. muessen wir den Offset anpassen, // um auf die erste Bitmap im Array zu stossen if ( sFirstBytes[0] == 0x42 && sFirstBytes[1] == 0x41 ) nOffs = 14; else nOffs = 0; // Jetzt testen wir zunaechst auf 'BM' if ( sFirstBytes[0+nOffs]==0x42 && sFirstBytes[1+nOffs]==0x4d ) { // unter OS/2 koennen die Reserved-Flags != 0 sein // (was sie eigentlich nicht duerften); // in diesem Fall testen wir die Groesse des BmpInfoHeaders if ( ( sFirstBytes[6+nOffs]==0x00 && sFirstBytes[7+nOffs]==0x00 && sFirstBytes[8+nOffs]==0x00 && sFirstBytes[9+nOffs]==0x00 ) || sFirstBytes[14+nOffs] == 0x28 || sFirstBytes[14+nOffs] == 0x0c ) { rFormatExtension = UniString::CreateFromAscii( "BMP", 3 ); return sal_True; } } } //--------------------------- WMF/EMF ------------------------------------ if( !bTest || ( rFormatExtension.CompareToAscii( "WMF", 3 ) == COMPARE_EQUAL ) || ( rFormatExtension.CompareToAscii( "EMF", 3 ) == COMPARE_EQUAL ) ) { bSomethingTested = sal_True; if ( nFirstLong==0xd7cdc69a || nFirstLong==0x01000900 ) { rFormatExtension = UniString::CreateFromAscii( "WMF", 3 ); return sal_True; } else if( nFirstLong == 0x01000000 && sFirstBytes[ 40 ] == 0x20 && sFirstBytes[ 41 ] == 0x45 && sFirstBytes[ 42 ] == 0x4d && sFirstBytes[ 43 ] == 0x46 ) { rFormatExtension = UniString::CreateFromAscii( "EMF", 3 ); return sal_True; } } //--------------------------- PCX ------------------------------------ if( !bTest || ( rFormatExtension.CompareToAscii( "PCX", 3 ) == COMPARE_EQUAL ) ) { bSomethingTested=sal_True; if (sFirstBytes[0]==0x0a) { sal_uInt8 nVersion=sFirstBytes[1]; sal_uInt8 nEncoding=sFirstBytes[2]; if( ( nVersion==0 || nVersion==2 || nVersion==3 || nVersion==5 ) && nEncoding<=1 ) { rFormatExtension = UniString::CreateFromAscii( "PCX", 3 ); return sal_True; } } } //--------------------------- TIF ------------------------------------ if( !bTest || ( rFormatExtension.CompareToAscii( "TIF", 3 ) == COMPARE_EQUAL ) ) { bSomethingTested=sal_True; if ( nFirstLong==0x49492a00 || nFirstLong==0x4d4d002a ) { rFormatExtension=UniString::CreateFromAscii( "TIF", 3 ); return sal_True; } } //--------------------------- GIF ------------------------------------ if( !bTest || ( rFormatExtension.CompareToAscii( "GIF", 3 ) == COMPARE_EQUAL ) ) { bSomethingTested=sal_True; if ( nFirstLong==0x47494638 && (sFirstBytes[4]==0x37 || sFirstBytes[4]==0x39) && sFirstBytes[5]==0x61 ) { rFormatExtension = UniString::CreateFromAscii( "GIF", 3 ); return sal_True; } } //--------------------------- PNG ------------------------------------ if( !bTest || ( rFormatExtension.CompareToAscii( "PNG", 3 ) == COMPARE_EQUAL ) ) { bSomethingTested=sal_True; if (nFirstLong==0x89504e47 && nSecondLong==0x0d0a1a0a) { rFormatExtension = UniString::CreateFromAscii( "PNG", 3 ); return sal_True; } } //--------------------------- JPG ------------------------------------ if( !bTest || ( rFormatExtension.CompareToAscii( "JPG", 3 ) == COMPARE_EQUAL ) ) { bSomethingTested=sal_True; if ( ( nFirstLong==0xffd8ffe0 && sFirstBytes[6]==0x4a && sFirstBytes[7]==0x46 && sFirstBytes[8]==0x49 && sFirstBytes[9]==0x46 ) || ( nFirstLong==0xffd8fffe ) || ( 0xffd8ff00 == ( nFirstLong & 0xffffff00 ) ) ) { rFormatExtension = UniString::CreateFromAscii( "JPG", 3 ); return sal_True; } } //--------------------------- SVM ------------------------------------ if( !bTest || ( rFormatExtension.CompareToAscii( "SVM", 3 ) == COMPARE_EQUAL ) ) { bSomethingTested=sal_True; if( nFirstLong==0x53564744 && sFirstBytes[4]==0x49 ) { rFormatExtension = UniString::CreateFromAscii( "SVM", 3 ); return sal_True; } else if( sFirstBytes[0]==0x56 && sFirstBytes[1]==0x43 && sFirstBytes[2]==0x4C && sFirstBytes[3]==0x4D && sFirstBytes[4]==0x54 && sFirstBytes[5]==0x46 ) { rFormatExtension = UniString::CreateFromAscii( "SVM", 3 ); return sal_True; } } //--------------------------- PCD ------------------------------------ if( !bTest || ( rFormatExtension.CompareToAscii( "PCD", 3 ) == COMPARE_EQUAL ) ) { bSomethingTested = sal_True; if( nStreamLen >= 2055 ) { char sBuf[8]; rStream.Seek( nStreamPos + 2048 ); rStream.Read( sBuf, 7 ); if( strncmp( sBuf, "PCD_IPI", 7 ) == 0 ) { rFormatExtension = UniString::CreateFromAscii( "PCD", 3 ); return sal_True; } } } //--------------------------- PSD ------------------------------------ if( !bTest || ( rFormatExtension.CompareToAscii( "PSD", 3 ) == COMPARE_EQUAL ) ) { bSomethingTested = sal_True; if ( ( nFirstLong == 0x38425053 ) && ( (nSecondLong >> 16 ) == 1 ) ) { rFormatExtension = UniString::CreateFromAscii( "PSD", 3 ); return sal_True; } } //--------------------------- EPS ------------------------------------ if( !bTest || ( rFormatExtension.CompareToAscii( "EPS", 3 ) == COMPARE_EQUAL ) ) { bSomethingTested = sal_True; if ( ( nFirstLong == 0xC5D0D3C6 ) || ( ImplSearchEntry( sFirstBytes, (sal_uInt8*)"%!PS-Adobe", 10, 10 ) && ImplSearchEntry( &sFirstBytes[15], (sal_uInt8*)"EPS", 3, 3 ) ) ) { rFormatExtension = UniString::CreateFromAscii( "EPS", 3 ); return sal_True; } } //--------------------------- DXF ------------------------------------ if( !bTest || ( rFormatExtension.CompareToAscii( "DXF", 3 ) == COMPARE_EQUAL ) ) { //Binary DXF File Format if( strncmp( (const char*) sFirstBytes, "AutoCAD Binary DXF", 18 ) == 0 ) { rFormatExtension = UniString::CreateFromAscii( "DXF", 3 ); return sal_True; } //ASCII DXF File Format i=0; while (i<256 && sFirstBytes[i]<=32) ++i; if (i<256 && sFirstBytes[i]=='0') { ++i; //only now do we have sufficient data to make a judgement //based on a '0' + 'SECTION' == DXF argument bSomethingTested=sal_True; while( i<256 && sFirstBytes[i]<=32 ) ++i; if (i+7<256 && (strncmp((const char*)(sFirstBytes+i),"SECTION",7)==0)) { rFormatExtension = UniString::CreateFromAscii( "DXF", 3 ); return sal_True; } } } //--------------------------- PCT ------------------------------------ if( !bTest || ( rFormatExtension.CompareToAscii( "PCT", 3 ) == COMPARE_EQUAL ) ) { bSomethingTested = sal_True; sal_uInt8 sBuf[3]; // store number format sal_uInt16 oldNumberFormat = rStream.GetNumberFormatInt(); sal_uInt32 nOffset; // in ms documents the pict format is used without the first 512 bytes for ( nOffset = 0; ( nOffset <= 512 ) && ( ( nStreamPos + nOffset + 14 ) <= nStreamLen ); nOffset += 512 ) { short y1,x1,y2,x2; sal_Bool bdBoxOk = sal_True; rStream.Seek( nStreamPos + nOffset); // size of the pict in version 1 pict ( 2bytes) : ignored rStream.SeekRel(2); // bounding box (bytes 2 -> 9) rStream.SetNumberFormatInt(NUMBERFORMAT_INT_BIGENDIAN); rStream >> y1 >> x1 >> y2 >> x2; rStream.SetNumberFormatInt(oldNumberFormat); // reset format if (x1 > x2 || y1 > y2 || // bad bdbox (x1 == x2 && y1 == y2) || // 1 pixel picture x2-x1 > 2048 || y2-y1 > 2048 ) // picture anormaly big bdBoxOk = sal_False; // read version op rStream.Read( sBuf,3 ); // see http://developer.apple.com/legacy/mac/library/documentation/mac/pdf/Imaging_With_QuickDraw/Appendix_A.pdf // normal version 2 - page A23 and A24 if ( sBuf[ 0 ] == 0x00 && sBuf[ 1 ] == 0x11 && sBuf[ 2 ] == 0x02) { rFormatExtension = UniString::CreateFromAscii( "PCT", 3 ); return sal_True; } // normal version 1 - page A25 else if (sBuf[ 0 ] == 0x11 && sBuf[ 1 ] == 0x01 && bdBoxOk) { rFormatExtension = UniString::CreateFromAscii( "PCT", 3 ); return sal_True; } // previous code kept in order to do not break any compatibility // probably eroneous else if ( sBuf[ 0 ] == 0x00 && sBuf[ 1 ] == 0x11 && sBuf[ 2 ] == 0x01 && bdBoxOk) { rFormatExtension = UniString::CreateFromAscii( "PCT", 3 ); return sal_True; } } } //------------------------- PBM + PGM + PPM --------------------------- if( !bTest || ( rFormatExtension.CompareToAscii( "PBM", 3 ) == COMPARE_EQUAL ) || ( rFormatExtension.CompareToAscii( "PGM", 3 ) == COMPARE_EQUAL ) || ( rFormatExtension.CompareToAscii( "PPM", 3 ) == COMPARE_EQUAL ) ) { bSomethingTested=sal_True; if ( sFirstBytes[ 0 ] == 'P' ) { switch( sFirstBytes[ 1 ] ) { case '1' : case '4' : rFormatExtension = UniString::CreateFromAscii( "PBM", 3 ); return sal_True; case '2' : case '5' : rFormatExtension = UniString::CreateFromAscii( "PGM", 3 ); return sal_True; case '3' : case '6' : rFormatExtension = UniString::CreateFromAscii( "PPM", 3 ); return sal_True; } } } //--------------------------- RAS( SUN RasterFile )------------------ if( !bTest || ( rFormatExtension.CompareToAscii( "RAS", 3 ) == COMPARE_EQUAL ) ) { bSomethingTested=sal_True; if( nFirstLong == 0x59a66a95 ) { rFormatExtension = UniString::CreateFromAscii( "RAS", 3 ); return sal_True; } } //--------------------------- XPM ------------------------------------ if( !bTest ) { bSomethingTested = sal_True; if( ImplSearchEntry( sFirstBytes, (sal_uInt8*)"/* XPM */", 256, 9 ) ) { rFormatExtension = UniString::CreateFromAscii( "XPM", 3 ); return sal_True; } } else if( rFormatExtension.CompareToAscii( "XPM", 3 ) == COMPARE_EQUAL ) { bSomethingTested = sal_True; return sal_True; } //--------------------------- XBM ------------------------------------ if( !bTest ) { sal_uLong nSize = ( nStreamLen > 2048 ) ? 2048 : nStreamLen; sal_uInt8* pBuf = new sal_uInt8 [ nSize ]; rStream.Seek( nStreamPos ); rStream.Read( pBuf, nSize ); sal_uInt8* pPtr = ImplSearchEntry( pBuf, (sal_uInt8*)"#define", nSize, 7 ); if( pPtr ) { if( ImplSearchEntry( pPtr, (sal_uInt8*)"_width", pBuf + nSize - pPtr, 6 ) ) { rFormatExtension = UniString::CreateFromAscii( "XBM", 3 ); delete[] pBuf; return sal_True; } } delete[] pBuf; } else if( rFormatExtension.CompareToAscii( "XBM", 3 ) == COMPARE_EQUAL ) { bSomethingTested = sal_True; return sal_True; } //--------------------------- SVG ------------------------------------ if( !bTest || ( rFormatExtension.CompareToAscii( "SVG", 3 ) == COMPARE_EQUAL ) ) { bSomethingTested=sal_True; // just a simple test for the extension if( rFormatExtension.CompareToAscii( "SVG", 3 ) == COMPARE_EQUAL ) return sal_True; sal_uLong nSize = ( nStreamLen > 1024 ) ? 1024 : nStreamLen; std::vector aBuf(nSize); rStream.Seek( nStreamPos ); rStream.Read( &aBuf[0], nSize ); // read the first 1024 bytes & check a few magic string // constants (heuristically) sal_Int8 aMagic1[] = {'<', 's', 'v', 'g'}; if( std::search(aBuf.begin(), aBuf.end(), aMagic1, aMagic1+SAL_N_ELEMENTS(aMagic1)) != aBuf.end() ) { rFormatExtension = UniString::CreateFromAscii( "SVG", 3 ); return sal_True; } sal_Int8 aMagic2[] = {'D', 'O', 'C', 'T', 'Y', 'P', 'E', ' ', 's', 'v', 'g'}; if( std::search(aBuf.begin(), aBuf.end(), aMagic2, aMagic2+SAL_N_ELEMENTS(aMagic2)) != aBuf.end() ) { rFormatExtension = UniString::CreateFromAscii( "SVG", 3 ); return sal_True; } } //--------------------------- TGA ------------------------------------ if( !bTest || ( rFormatExtension.CompareToAscii( "TGA", 3 ) == COMPARE_EQUAL ) ) { bSomethingTested = sal_True; // just a simple test for the extension if( rFormatExtension.CompareToAscii( "TGA", 3 ) == COMPARE_EQUAL ) return sal_True; } //--------------------------- SGV ------------------------------------ if( !bTest || ( rFormatExtension.CompareToAscii( "SGV", 3 ) == COMPARE_EQUAL ) ) { bSomethingTested = sal_True; // just a simple test for the extension if( rFormatExtension.CompareToAscii( "SGV", 3 ) == COMPARE_EQUAL ) return sal_True; } //--------------------------- SGF ------------------------------------ if( !bTest || ( rFormatExtension.CompareToAscii( "SGF", 3 ) == COMPARE_EQUAL ) ) { bSomethingTested=sal_True; if( sFirstBytes[ 0 ] == 'J' && sFirstBytes[ 1 ] == 'J' ) { rFormatExtension = UniString::CreateFromAscii( "SGF", 3 ); return sal_True; } } return bTest && !bSomethingTested; } //-------------------------------------------------------------------------- sal_uInt16 GraphicFilter::ImpTestOrFindFormat( const String& rPath, SvStream& rStream, sal_uInt16& rFormat ) { sal_uInt16 n = pConfig->GetImportFormatCount(); // ggf. Filter bzw. Format durch anlesen ermitteln, // oder durch anlesen zusichern, dass das Format stimmt: if( rFormat == GRFILTER_FORMAT_DONTKNOW ) { String aFormatExt; if( ImpPeekGraphicFormat( rStream, aFormatExt, sal_False ) ) { for( sal_uInt16 i = 0; i < n; i++ ) { if( pConfig->GetImportFormatExtension( i ).EqualsIgnoreCaseAscii( aFormatExt ) ) { rFormat = i; return GRFILTER_OK; } } } // ggf. Filter anhand der Datei-Endung raussuchen: if( rPath.Len() ) { String aExt( ImpGetExtension( rPath ) ); for( sal_uInt16 i = 0; i < n; i++ ) { if( pConfig->GetImportFormatExtension( i ).EqualsIgnoreCaseAscii( aExt ) ) { rFormat = i; return GRFILTER_OK; } } } return GRFILTER_FORMATERROR; } else { String aTmpStr( pConfig->GetImportFormatExtension( rFormat ) ); if( !ImpPeekGraphicFormat( rStream, aTmpStr.ToUpperAscii(), sal_True ) ) return GRFILTER_FORMATERROR; if ( pConfig->GetImportFormatExtension( rFormat ).EqualsIgnoreCaseAscii( "pcd" ) ) { sal_Int32 nBase = 2; // default Base0 if ( pConfig->GetImportFilterType( rFormat ).EqualsIgnoreCaseAscii( "pcd_Photo_CD_Base4" ) ) nBase = 1; else if ( pConfig->GetImportFilterType( rFormat ).EqualsIgnoreCaseAscii( "pcd_Photo_CD_Base16" ) ) nBase = 0; String aFilterConfigPath( RTL_CONSTASCII_USTRINGPARAM( "Office.Common/Filter/Graphic/Import/PCD" ) ); FilterConfigItem aFilterConfigItem( aFilterConfigPath ); aFilterConfigItem.WriteInt32( String( RTL_CONSTASCII_USTRINGPARAM( "Resolution" ) ), nBase ); } } return GRFILTER_OK; } //-------------------------------------------------------------------------- static Graphic ImpGetScaledGraphic( const Graphic& rGraphic, FilterConfigItem& rConfigItem ) { Graphic aGraphic; ResMgr* pResMgr = ResMgr::CreateResMgr( "svt", Application::GetSettings().GetUILocale() ); sal_Int32 nLogicalWidth = rConfigItem.ReadInt32( String( RTL_CONSTASCII_USTRINGPARAM( "LogicalWidth" ) ), 0 ); sal_Int32 nLogicalHeight = rConfigItem.ReadInt32( String( RTL_CONSTASCII_USTRINGPARAM( "LogicalHeight" ) ), 0 ); if ( rGraphic.GetType() != GRAPHIC_NONE ) { sal_Int32 nMode = rConfigItem.ReadInt32( String( RTL_CONSTASCII_USTRINGPARAM( "ExportMode" ) ), -1 ); if ( nMode == -1 ) // the property is not there, this is possible, if the graphic filter { // is called via UnoGraphicExporter and not from a graphic export Dialog nMode = 0; // then we are defaulting this mode to 0 if ( nLogicalWidth || nLogicalHeight ) nMode = 2; } Size aOriginalSize; Size aPrefSize( rGraphic.GetPrefSize() ); MapMode aPrefMapMode( rGraphic.GetPrefMapMode() ); if ( aPrefMapMode == MAP_PIXEL ) aOriginalSize = Application::GetDefaultDevice()->PixelToLogic( aPrefSize, MAP_100TH_MM ); else aOriginalSize = Application::GetDefaultDevice()->LogicToLogic( aPrefSize, aPrefMapMode, MAP_100TH_MM ); if ( !nLogicalWidth ) nLogicalWidth = aOriginalSize.Width(); if ( !nLogicalHeight ) nLogicalHeight = aOriginalSize.Height(); if( rGraphic.GetType() == GRAPHIC_BITMAP ) { // Aufloesung wird eingestellt if( nMode == 1 ) { Bitmap aBitmap( rGraphic.GetBitmap() ); MapMode aMap( MAP_100TH_INCH ); sal_Int32 nDPI = rConfigItem.ReadInt32( String( RTL_CONSTASCII_USTRINGPARAM( "Resolution" ) ), 75 ); Fraction aFrac( 1, Min( Max( nDPI, sal_Int32( 75 ) ), sal_Int32( 600 ) ) ); aMap.SetScaleX( aFrac ); aMap.SetScaleY( aFrac ); Size aOldSize = aBitmap.GetSizePixel(); aGraphic = rGraphic; aGraphic.SetPrefMapMode( aMap ); aGraphic.SetPrefSize( Size( aOldSize.Width() * 100, aOldSize.Height() * 100 ) ); } // Groesse wird eingestellt else if( nMode == 2 ) { aGraphic = rGraphic; aGraphic.SetPrefMapMode( MapMode( MAP_100TH_MM ) ); aGraphic.SetPrefSize( Size( nLogicalWidth, nLogicalHeight ) ); } else aGraphic = rGraphic; sal_Int32 nColors = rConfigItem.ReadInt32( String( RTL_CONSTASCII_USTRINGPARAM( "Color" ) ), 0 ); // #92767# if ( nColors ) // graphic conversion necessary ? { BitmapEx aBmpEx( aGraphic.GetBitmapEx() ); aBmpEx.Convert( (BmpConversion)nColors ); // the entries in the xml section have the same meaning as aGraphic = aBmpEx; // they have in the BmpConversion enum, so it should be } // allowed to cast them } else { if( ( nMode == 1 ) || ( nMode == 2 ) ) { GDIMetaFile aMtf( rGraphic.GetGDIMetaFile() ); ::com::sun::star::awt::Size aDefaultSize( 10000, 10000 ); Size aNewSize( OutputDevice::LogicToLogic( Size( nLogicalWidth, nLogicalHeight ), MAP_100TH_MM, aMtf.GetPrefMapMode() ) ); if( aNewSize.Width() && aNewSize.Height() ) { const Size aPreferredSize( aMtf.GetPrefSize() ); aMtf.Scale( Fraction( aNewSize.Width(), aPreferredSize.Width() ), Fraction( aNewSize.Height(), aPreferredSize.Height() ) ); } aGraphic = Graphic( aMtf ); } else aGraphic = rGraphic; } } else aGraphic = rGraphic; delete pResMgr; return aGraphic; } static String ImpCreateFullFilterPath( const String& rPath, const String& rFilterName ) { ::rtl::OUString aPathURL; ::osl::FileBase::getFileURLFromSystemPath( rPath, aPathURL ); aPathURL += String( '/' ); ::rtl::OUString aSystemPath; ::osl::FileBase::getSystemPathFromFileURL( aPathURL, aSystemPath ); aSystemPath += ::rtl::OUString( rFilterName ); return String( aSystemPath ); } // -------------------------- // - ImpFilterLibCacheEntry - // -------------------------- class ImpFilterLibCache; struct ImpFilterLibCacheEntry { ImpFilterLibCacheEntry* mpNext; osl::Module maLibrary; String maFiltername; PFilterCall mpfnImport; PFilterDlgCall mpfnImportDlg; ImpFilterLibCacheEntry( const String& rPathname, const String& rFiltername ); int operator==( const String& rFiltername ) const { return maFiltername == rFiltername; } PFilterCall GetImportFunction(); }; // ------------------------------------------------------------------------ ImpFilterLibCacheEntry::ImpFilterLibCacheEntry( const String& rPathname, const String& rFiltername ) : mpNext ( NULL ), maLibrary ( rPathname ), maFiltername ( rFiltername ), mpfnImport ( NULL ), mpfnImportDlg ( NULL ) { } // ------------------------------------------------------------------------ PFilterCall ImpFilterLibCacheEntry::GetImportFunction() { if( !mpfnImport ) mpfnImport = (PFilterCall) maLibrary.getFunctionSymbol( UniString::CreateFromAscii( IMPORT_FUNCTION_NAME ) ); return mpfnImport; } // ------------------------------------------------------------------------ // --------------------- // - ImpFilterLibCache - // --------------------- class ImpFilterLibCache { ImpFilterLibCacheEntry* mpFirst; ImpFilterLibCacheEntry* mpLast; public: ImpFilterLibCache(); ~ImpFilterLibCache(); ImpFilterLibCacheEntry* GetFilter( const String& rFilterPath, const String& rFiltername ); }; // ------------------------------------------------------------------------ ImpFilterLibCache::ImpFilterLibCache() : mpFirst ( NULL ), mpLast ( NULL ) { } // ------------------------------------------------------------------------ ImpFilterLibCache::~ImpFilterLibCache() { ImpFilterLibCacheEntry* pEntry = mpFirst; while( pEntry ) { ImpFilterLibCacheEntry* pNext = pEntry->mpNext; delete pEntry; pEntry = pNext; } } // ------------------------------------------------------------------------ ImpFilterLibCacheEntry* ImpFilterLibCache::GetFilter( const String& rFilterPath, const String& rFilterName ) { ImpFilterLibCacheEntry* pEntry = mpFirst; while( pEntry ) { if( *pEntry == rFilterName ) break; else pEntry = pEntry->mpNext; } if( !pEntry ) { String aPhysicalName( ImpCreateFullFilterPath( rFilterPath, rFilterName ) ); pEntry = new ImpFilterLibCacheEntry( aPhysicalName, rFilterName ); if ( pEntry->maLibrary.is() ) { if( !mpFirst ) mpFirst = mpLast = pEntry; else mpLast = mpLast->mpNext = pEntry; } else { delete pEntry; pEntry = NULL; } } return pEntry; }; // ------------------------------------------------------------------------ namespace { struct Cache : public rtl::Static {}; } // ----------------- // - GraphicFilter - // ----------------- GraphicFilter::GraphicFilter( sal_Bool bConfig ) : bUseConfig ( bConfig ), nExpGraphHint ( 0 ) { ImplInit(); } // ------------------------------------------------------------------------ GraphicFilter::~GraphicFilter() { { ::osl::MutexGuard aGuard( getListMutex() ); for( FilterList_impl::iterator it = pFilterHdlList->begin(); it != pFilterHdlList->end(); ++it ) { if( *it == this ) { pFilterHdlList->erase( it ); break; } } if( pFilterHdlList->empty() ) { delete pFilterHdlList, pFilterHdlList = NULL; delete pConfig; } } delete pErrorEx; } // ------------------------------------------------------------------------ void GraphicFilter::ImplInit() { { ::osl::MutexGuard aGuard( getListMutex() ); if ( !pFilterHdlList ) { pFilterHdlList = new FilterList_impl; pConfig = new FilterConfigCache( bUseConfig ); } else pConfig = pFilterHdlList->front()->pConfig; pFilterHdlList->push_back( this ); } if( bUseConfig ) { rtl::OUString url(RTL_CONSTASCII_USTRINGPARAM("$BRAND_BASE_DIR/program")); rtl::Bootstrap::expandMacros(url); //TODO: detect failure utl::LocalFileHelper::ConvertURLToPhysicalName(url, aFilterPath); } pErrorEx = new FilterErrorEx; bAbort = sal_False; } // ------------------------------------------------------------------------ sal_uLong GraphicFilter::ImplSetError( sal_uLong nError, const SvStream* pStm ) { pErrorEx->nFilterError = nError; pErrorEx->nStreamError = pStm ? pStm->GetError() : ERRCODE_NONE; return nError; } // ------------------------------------------------------------------------ sal_uInt16 GraphicFilter::GetImportFormatCount() { return pConfig->GetImportFormatCount(); } // ------------------------------------------------------------------------ sal_uInt16 GraphicFilter::GetImportFormatNumber( const String& rFormatName ) { return pConfig->GetImportFormatNumber( rFormatName ); } // ------------------------------------------------------------------------ sal_uInt16 GraphicFilter::GetImportFormatNumberForMediaType( const String& rMediaType ) { return pConfig->GetImportFormatNumberForMediaType( rMediaType ); } // ------------------------------------------------------------------------ sal_uInt16 GraphicFilter::GetImportFormatNumberForShortName( const String& rShortName ) { return pConfig->GetImportFormatNumberForShortName( rShortName ); } // ------------------------------------------------------------------------ sal_uInt16 GraphicFilter::GetImportFormatNumberForTypeName( const String& rType ) { return pConfig->GetImportFormatNumberForTypeName( rType ); } // ------------------------------------------------------------------------ String GraphicFilter::GetImportFormatName( sal_uInt16 nFormat ) { return pConfig->GetImportFormatName( nFormat ); } // ------------------------------------------------------------------------ String GraphicFilter::GetImportFormatTypeName( sal_uInt16 nFormat ) { return pConfig->GetImportFilterTypeName( nFormat ); } // ------------------------------------------------------------------------ String GraphicFilter::GetImportFormatMediaType( sal_uInt16 nFormat ) { return pConfig->GetImportFormatMediaType( nFormat ); } // ------------------------------------------------------------------------ String GraphicFilter::GetImportFormatShortName( sal_uInt16 nFormat ) { return pConfig->GetImportFormatShortName( nFormat ); } // ------------------------------------------------------------------------ String GraphicFilter::GetImportOSFileType( sal_uInt16 ) { String aOSFileType; return aOSFileType; } // ------------------------------------------------------------------------ String GraphicFilter::GetImportWildcard( sal_uInt16 nFormat, sal_Int32 nEntry ) { return pConfig->GetImportWildcard( nFormat, nEntry ); } // ------------------------------------------------------------------------ sal_Bool GraphicFilter::IsImportPixelFormat( sal_uInt16 nFormat ) { return pConfig->IsImportPixelFormat( nFormat ); } // ------------------------------------------------------------------------ sal_uInt16 GraphicFilter::GetExportFormatCount() { return pConfig->GetExportFormatCount(); } // ------------------------------------------------------------------------ sal_uInt16 GraphicFilter::GetExportFormatNumber( const String& rFormatName ) { return pConfig->GetExportFormatNumber( rFormatName ); } // ------------------------------------------------------------------------ sal_uInt16 GraphicFilter::GetExportFormatNumberForMediaType( const String& rMediaType ) { return pConfig->GetExportFormatNumberForMediaType( rMediaType ); } // ------------------------------------------------------------------------ sal_uInt16 GraphicFilter::GetExportFormatNumberForShortName( const String& rShortName ) { return pConfig->GetExportFormatNumberForShortName( rShortName ); } // ------------------------------------------------------------------------ sal_uInt16 GraphicFilter::GetExportFormatNumberForTypeName( const String& rType ) { return pConfig->GetExportFormatNumberForTypeName( rType ); } // ------------------------------------------------------------------------ String GraphicFilter::GetExportFormatName( sal_uInt16 nFormat ) { return pConfig->GetExportFormatName( nFormat ); } // ------------------------------------------------------------------------ String GraphicFilter::GetExportFormatTypeName( sal_uInt16 nFormat ) { return pConfig->GetExportFilterTypeName( nFormat ); } // ------------------------------------------------------------------------ String GraphicFilter::GetExportFormatMediaType( sal_uInt16 nFormat ) { return pConfig->GetExportFormatMediaType( nFormat ); } // ------------------------------------------------------------------------ String GraphicFilter::GetExportFormatShortName( sal_uInt16 nFormat ) { return pConfig->GetExportFormatShortName( nFormat ); } // ------------------------------------------------------------------------ String GraphicFilter::GetExportOSFileType( sal_uInt16 ) { String aOSFileType; return aOSFileType; } // ------------------------------------------------------------------------ String GraphicFilter::GetExportWildcard( sal_uInt16 nFormat, sal_Int32 nEntry ) { return pConfig->GetExportWildcard( nFormat, nEntry ); } // ------------------------------------------------------------------------ sal_Bool GraphicFilter::IsExportPixelFormat( sal_uInt16 nFormat ) { return pConfig->IsExportPixelFormat( nFormat ); } // ------------------------------------------------------------------------ sal_uInt16 GraphicFilter::CanImportGraphic( const INetURLObject& rPath, sal_uInt16 nFormat, sal_uInt16* pDeterminedFormat ) { sal_uInt16 nRetValue = GRFILTER_FORMATERROR; DBG_ASSERT( rPath.GetProtocol() != INET_PROT_NOT_VALID, "GraphicFilter::CanImportGraphic() : ProtType == INET_PROT_NOT_VALID" ); String aMainUrl( rPath.GetMainURL( INetURLObject::NO_DECODE ) ); SvStream* pStream = ::utl::UcbStreamHelper::CreateStream( aMainUrl, STREAM_READ | STREAM_SHARE_DENYNONE ); if ( pStream ) { nRetValue = CanImportGraphic( aMainUrl, *pStream, nFormat, pDeterminedFormat ); delete pStream; } return nRetValue; } // ------------------------------------------------------------------------ sal_uInt16 GraphicFilter::CanImportGraphic( const String& rMainUrl, SvStream& rIStream, sal_uInt16 nFormat, sal_uInt16* pDeterminedFormat ) { sal_uLong nStreamPos = rIStream.Tell(); sal_uInt16 nRes = ImpTestOrFindFormat( rMainUrl, rIStream, nFormat ); rIStream.Seek(nStreamPos); if( nRes==GRFILTER_OK && pDeterminedFormat!=NULL ) *pDeterminedFormat = nFormat; return (sal_uInt16) ImplSetError( nRes, &rIStream ); } // ------------------------------------------------------------------------ //SJ: TODO, we need to create a GraphicImporter component sal_uInt16 GraphicFilter::ImportGraphic( Graphic& rGraphic, const INetURLObject& rPath, sal_uInt16 nFormat, sal_uInt16 * pDeterminedFormat, sal_uInt32 nImportFlags ) { sal_uInt16 nRetValue = GRFILTER_FORMATERROR; DBG_ASSERT( rPath.GetProtocol() != INET_PROT_NOT_VALID, "GraphicFilter::ImportGraphic() : ProtType == INET_PROT_NOT_VALID" ); String aMainUrl( rPath.GetMainURL( INetURLObject::NO_DECODE ) ); SvStream* pStream = ::utl::UcbStreamHelper::CreateStream( aMainUrl, STREAM_READ | STREAM_SHARE_DENYNONE ); if ( pStream ) { nRetValue = ImportGraphic( rGraphic, aMainUrl, *pStream, nFormat, pDeterminedFormat, nImportFlags ); delete pStream; } return nRetValue; } sal_uInt16 GraphicFilter::ImportGraphic( Graphic& rGraphic, const String& rPath, SvStream& rIStream, sal_uInt16 nFormat, sal_uInt16* pDeterminedFormat, sal_uInt32 nImportFlags, WMF_EXTERNALHEADER *pExtHeader ) { return ImportGraphic( rGraphic, rPath, rIStream, nFormat, pDeterminedFormat, nImportFlags, NULL, pExtHeader ); } //------------------------------------------------------------------------- sal_uInt16 GraphicFilter::ImportGraphic( Graphic& rGraphic, const String& rPath, SvStream& rIStream, sal_uInt16 nFormat, sal_uInt16* pDeterminedFormat, sal_uInt32 nImportFlags, com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValue >* pFilterData, WMF_EXTERNALHEADER *pExtHeader ) { String aFilterName; sal_uLong nStmBegin; sal_uInt16 nStatus; GraphicReader* pContext = rGraphic.GetContext(); GfxLinkType eLinkType = GFX_LINK_TYPE_NONE; sal_Bool bDummyContext = ( pContext == (GraphicReader*) 1 ); const sal_Bool bLinkSet = rGraphic.IsLink(); FilterConfigItem* pFilterConfigItem = NULL; Size aPreviewSizeHint( 0, 0 ); sal_Bool bAllowPartialStreamRead = sal_False; sal_Bool bCreateNativeLink = sal_True; ResetLastError(); if ( pFilterData ) { sal_Int32 i; for ( i = 0; i < pFilterData->getLength(); i++ ) { if ( (*pFilterData)[ i ].Name == "PreviewSizeHint" ) { awt::Size aSize; if ( (*pFilterData)[ i ].Value >>= aSize ) { aPreviewSizeHint = Size( aSize.Width, aSize.Height ); if ( aSize.Width || aSize.Height ) nImportFlags |= GRFILTER_I_FLAGS_FOR_PREVIEW; else nImportFlags &=~GRFILTER_I_FLAGS_FOR_PREVIEW; } } else if ( (*pFilterData)[ i ].Name == "AllowPartialStreamRead" ) { (*pFilterData)[ i ].Value >>= bAllowPartialStreamRead; if ( bAllowPartialStreamRead ) nImportFlags |= GRFILTER_I_FLAGS_ALLOW_PARTIAL_STREAMREAD; else nImportFlags &=~GRFILTER_I_FLAGS_ALLOW_PARTIAL_STREAMREAD; } else if ( (*pFilterData)[ i ].Name == "CreateNativeLink" ) { (*pFilterData)[ i ].Value >>= bCreateNativeLink; } } } if( !pContext || bDummyContext ) { if( bDummyContext ) { rGraphic.SetContext( NULL ); nStmBegin = 0; } else nStmBegin = rIStream.Tell(); bAbort = sal_False; nStatus = ImpTestOrFindFormat( rPath, rIStream, nFormat ); // Falls Pending, geben wir GRFILTER_OK zurueck, // um mehr Bytes anzufordern if( rIStream.GetError() == ERRCODE_IO_PENDING ) { rGraphic.SetContext( (GraphicReader*) 1 ); rIStream.ResetError(); rIStream.Seek( nStmBegin ); return (sal_uInt16) ImplSetError( GRFILTER_OK ); } rIStream.Seek( nStmBegin ); if( ( nStatus != GRFILTER_OK ) || rIStream.GetError() ) return (sal_uInt16) ImplSetError( ( nStatus != GRFILTER_OK ) ? nStatus : GRFILTER_OPENERROR, &rIStream ); if( pDeterminedFormat ) *pDeterminedFormat = nFormat; aFilterName = pConfig->GetImportFilterName( nFormat ); } else { if( pContext && !bDummyContext ) aFilterName = pContext->GetUpperFilterName(); nStmBegin = 0; nStatus = GRFILTER_OK; } // read graphic if ( pConfig->IsImportInternalFilter( nFormat ) ) { if( aFilterName.EqualsIgnoreCaseAscii( IMP_GIF ) ) { if( rGraphic.GetContext() == (GraphicReader*) 1 ) rGraphic.SetContext( NULL ); if( !ImportGIF( rIStream, rGraphic ) ) nStatus = GRFILTER_FILTERERROR; else eLinkType = GFX_LINK_TYPE_NATIVE_GIF; } else if( aFilterName.EqualsIgnoreCaseAscii( IMP_PNG ) ) { if ( rGraphic.GetContext() == (GraphicReader*) 1 ) rGraphic.SetContext( NULL ); vcl::PNGReader aPNGReader( rIStream ); // ignore animation for previews and set preview size if( aPreviewSizeHint.Width() || aPreviewSizeHint.Height() ) { // position the stream at the end of the image if requested if( !bAllowPartialStreamRead ) aPNGReader.GetChunks(); } else { // check if this PNG contains a GIF chunk! const std::vector< vcl::PNGReader::ChunkData >& rChunkData = aPNGReader.GetChunks(); std::vector< vcl::PNGReader::ChunkData >::const_iterator aIter( rChunkData.begin() ); std::vector< vcl::PNGReader::ChunkData >::const_iterator aEnd ( rChunkData.end() ); while( aIter != aEnd ) { // Microsoft Office is storing Animated GIFs in following chunk if ( aIter->nType == PMGCHUNG_msOG ) { sal_uInt32 nChunkSize = aIter->aData.size(); if ( nChunkSize > 11 ) { const std::vector< sal_uInt8 >& rData = aIter->aData; SvMemoryStream aIStrm( (void*)&rData[ 11 ], nChunkSize - 11, STREAM_READ ); ImportGIF( aIStrm, rGraphic ); eLinkType = GFX_LINK_TYPE_NATIVE_PNG; break; } } ++aIter; } } if ( eLinkType == GFX_LINK_TYPE_NONE ) { BitmapEx aBmpEx( aPNGReader.Read( aPreviewSizeHint ) ); if ( aBmpEx.IsEmpty() ) nStatus = GRFILTER_FILTERERROR; else { rGraphic = aBmpEx; eLinkType = GFX_LINK_TYPE_NATIVE_PNG; } } } else if( aFilterName.EqualsIgnoreCaseAscii( IMP_JPEG ) ) { if( rGraphic.GetContext() == (GraphicReader*) 1 ) rGraphic.SetContext( NULL ); // set LOGSIZE flag always, if not explicitly disabled // (see #90508 and #106763) if( 0 == ( nImportFlags & GRFILTER_I_FLAGS_DONT_SET_LOGSIZE_FOR_JPEG ) ) nImportFlags |= GRFILTER_I_FLAGS_SET_LOGSIZE_FOR_JPEG; if( !ImportJPEG( rIStream, rGraphic, NULL, nImportFlags ) ) nStatus = GRFILTER_FILTERERROR; else eLinkType = GFX_LINK_TYPE_NATIVE_JPG; } else if( aFilterName.EqualsIgnoreCaseAscii( IMP_SVG ) ) { if( rGraphic.GetContext() == (GraphicReader*) 1 ) rGraphic.SetContext( NULL ); vcl::SVGReader aSVGReader( rIStream ); GDIMetaFile aSVGMtf; if( 0 == aSVGReader.Read( aSVGMtf ).GetActionSize() ) { nStatus = GRFILTER_FILTERERROR; } else { rGraphic = Graphic( aSVGMtf ); eLinkType = GFX_LINK_TYPE_NATIVE_SVG; } } else if( aFilterName.EqualsIgnoreCaseAscii( IMP_XBM ) ) { if( rGraphic.GetContext() == (GraphicReader*) 1 ) rGraphic.SetContext( NULL ); if( !ImportXBM( rIStream, rGraphic ) ) nStatus = GRFILTER_FILTERERROR; } else if( aFilterName.EqualsIgnoreCaseAscii( IMP_XPM ) ) { if( rGraphic.GetContext() == (GraphicReader*) 1 ) rGraphic.SetContext( NULL ); if( !ImportXPM( rIStream, rGraphic ) ) nStatus = GRFILTER_FILTERERROR; } else if( aFilterName.EqualsIgnoreCaseAscii( IMP_BMP ) || aFilterName.EqualsIgnoreCaseAscii( IMP_SVMETAFILE ) ) { // SV interne Importfilter fuer Bitmaps und MetaFiles rIStream >> rGraphic; if( rIStream.GetError() ) nStatus = GRFILTER_FORMATERROR; } else if( aFilterName.EqualsIgnoreCaseAscii( IMP_WMF ) || aFilterName.EqualsIgnoreCaseAscii( IMP_EMF ) ) { GDIMetaFile aMtf; if( !ConvertWMFToGDIMetaFile( rIStream, aMtf, NULL, pExtHeader ) ) nStatus = GRFILTER_FORMATERROR; else { rGraphic = aMtf; eLinkType = GFX_LINK_TYPE_NATIVE_WMF; } } else if( aFilterName.EqualsIgnoreCaseAscii( IMP_SVSGF ) || aFilterName.EqualsIgnoreCaseAscii( IMP_SVSGV ) ) { sal_uInt16 nVersion; unsigned char nTyp = CheckSgfTyp( rIStream, nVersion ); switch( nTyp ) { case SGF_BITIMAGE: { SvMemoryStream aTempStream; if( aTempStream.GetError() ) return GRFILTER_OPENERROR; if( !SgfBMapFilter( rIStream, aTempStream ) ) nStatus = GRFILTER_FILTERERROR; else { aTempStream.Seek( 0L ); aTempStream >> rGraphic; if( aTempStream.GetError() ) nStatus = GRFILTER_FILTERERROR; } } break; case SGF_SIMPVECT: { GDIMetaFile aMtf; if( !SgfVectFilter( rIStream, aMtf ) ) nStatus = GRFILTER_FILTERERROR; else rGraphic = Graphic( aMtf ); } break; case SGF_STARDRAW: { if( nVersion != SGV_VERSION ) nStatus = GRFILTER_VERSIONERROR; else { GDIMetaFile aMtf; if( !SgfSDrwFilter( rIStream, aMtf, INetURLObject(aFilterPath) ) ) { nStatus = GRFILTER_FILTERERROR; } else rGraphic = Graphic( aMtf ); } } break; default: { nStatus = GRFILTER_FORMATERROR; } break; } } else nStatus = GRFILTER_FILTERERROR; } else { ImpFilterLibCacheEntry* pFilter = NULL; // find first filter in filter paths sal_Int32 i, nTokenCount = getTokenCount(aFilterPath, ';'); ImpFilterLibCache &rCache = Cache::get(); for( i = 0; ( i < nTokenCount ) && ( pFilter == NULL ); i++ ) pFilter = rCache.GetFilter( getToken(aFilterPath, i, ';'), aFilterName ); if( !pFilter ) nStatus = GRFILTER_FILTERERROR; else { PFilterCall pFunc = pFilter->GetImportFunction(); if( !pFunc ) nStatus = GRFILTER_FILTERERROR; else { String aShortName; if( nFormat != GRFILTER_FORMAT_DONTKNOW ) { aShortName = GetImportFormatShortName( nFormat ).ToUpperAscii(); if ( ( pFilterConfigItem == NULL ) && aShortName.EqualsAscii( "PCD" ) ) { String aFilterConfigPath( RTL_CONSTASCII_USTRINGPARAM( "Office.Common/Filter/Graphic/Import/PCD" ) ); pFilterConfigItem = new FilterConfigItem( aFilterConfigPath ); } } if( !(*pFunc)( rIStream, rGraphic, pFilterConfigItem, sal_False ) ) nStatus = GRFILTER_FORMATERROR; else { // try to set link type if format matches if( nFormat != GRFILTER_FORMAT_DONTKNOW ) { if( aShortName.CompareToAscii( TIF_SHORTNAME ) == COMPARE_EQUAL ) eLinkType = GFX_LINK_TYPE_NATIVE_TIF; else if( aShortName.CompareToAscii( MET_SHORTNAME ) == COMPARE_EQUAL ) eLinkType = GFX_LINK_TYPE_NATIVE_MET; else if( aShortName.CompareToAscii( PCT_SHORTNAME ) == COMPARE_EQUAL ) eLinkType = GFX_LINK_TYPE_NATIVE_PCT; } } } } } if( nStatus == GRFILTER_OK && bCreateNativeLink && ( eLinkType != GFX_LINK_TYPE_NONE ) && !rGraphic.GetContext() && !bLinkSet ) { const sal_uLong nStmEnd = rIStream.Tell(); const sal_uLong nBufSize = nStmEnd - nStmBegin; if( nBufSize ) { sal_uInt8* pBuf=0; try { pBuf = new sal_uInt8[ nBufSize ]; } catch (const std::bad_alloc&) { nStatus = GRFILTER_TOOBIG; } if( nStatus == GRFILTER_OK ) { rIStream.Seek( nStmBegin ); rIStream.Read( pBuf, nBufSize ); rGraphic.SetLink( GfxLink( pBuf, nBufSize, eLinkType, sal_True ) ); } } } // Set error code or try to set native buffer if( nStatus != GRFILTER_OK ) { if( bAbort ) nStatus = GRFILTER_ABORT; ImplSetError( nStatus, &rIStream ); rIStream.Seek( nStmBegin ); rGraphic.Clear(); } delete pFilterConfigItem; return nStatus; } // ------------------------------------------------------------------------ sal_uInt16 GraphicFilter::ExportGraphic( const Graphic& rGraphic, const INetURLObject& rPath, sal_uInt16 nFormat, const uno::Sequence< beans::PropertyValue >* pFilterData ) { RTL_LOGFILE_CONTEXT( aLog, "GraphicFilter::ExportGraphic() (thb)" ); sal_uInt16 nRetValue = GRFILTER_FORMATERROR; DBG_ASSERT( rPath.GetProtocol() != INET_PROT_NOT_VALID, "GraphicFilter::ExportGraphic() : ProtType == INET_PROT_NOT_VALID" ); sal_Bool bAlreadyExists = ImplDirEntryHelper::Exists( rPath ); String aMainUrl( rPath.GetMainURL( INetURLObject::NO_DECODE ) ); SvStream* pStream = ::utl::UcbStreamHelper::CreateStream( aMainUrl, STREAM_WRITE | STREAM_TRUNC ); if ( pStream ) { nRetValue = ExportGraphic( rGraphic, aMainUrl, *pStream, nFormat, pFilterData ); delete pStream; if( ( GRFILTER_OK != nRetValue ) && !bAlreadyExists ) ImplDirEntryHelper::Kill( aMainUrl ); } return nRetValue; } // ------------------------------------------------------------------------ sal_uInt16 GraphicFilter::ExportGraphic( const Graphic& rGraphic, const String& rPath, SvStream& rOStm, sal_uInt16 nFormat, const uno::Sequence< beans::PropertyValue >* pFilterData ) { RTL_LOGFILE_CONTEXT( aLog, "GraphicFilter::ExportGraphic() (thb)" ); sal_uInt16 nFormatCount = GetExportFormatCount(); ResetLastError(); nExpGraphHint = 0; if( nFormat == GRFILTER_FORMAT_DONTKNOW ) { INetURLObject aURL( rPath ); String aExt( aURL.GetFileExtension().toAsciiUpperCase() ); for( sal_uInt16 i = 0; i < nFormatCount; i++ ) { if ( pConfig->GetExportFormatExtension( i ).EqualsIgnoreCaseAscii( aExt ) ) { nFormat=i; break; } } } if( nFormat >= nFormatCount ) return (sal_uInt16) ImplSetError( GRFILTER_FORMATERROR ); FilterConfigItem aConfigItem( (uno::Sequence< beans::PropertyValue >*)pFilterData ); String aFilterName( pConfig->GetExportFilterName( nFormat ) ); bAbort = sal_False; sal_uInt16 nStatus = GRFILTER_OK; GraphicType eType; Graphic aGraphic( rGraphic ); aGraphic = ImpGetScaledGraphic( rGraphic, aConfigItem ); eType = aGraphic.GetType(); if( pConfig->IsExportPixelFormat( nFormat ) ) { if( eType != GRAPHIC_BITMAP ) { Size aSizePixel; sal_uLong nColorCount,nBitsPerPixel,nNeededMem,nMaxMem; VirtualDevice aVirDev; // Maximalen Speicherbedarf fuer das Bildes holen: // if( GetOptionsConfig() ) // nMaxMem = (UINT32)GetOptionsConfig()->ReadKey( "VEC-TO-PIX-MAX-KB", "1024" ).ToInt32(); // else nMaxMem = 1024; nMaxMem *= 1024; // In Bytes // Berechnen, wie gross das Bild normalerweise werden wuerde: aSizePixel=aVirDev.LogicToPixel(aGraphic.GetPrefSize(),aGraphic.GetPrefMapMode()); // Berechnen, wieviel Speicher das Bild benoetigen wuerde: nColorCount=aVirDev.GetColorCount(); if (nColorCount<=2) nBitsPerPixel=1; else if (nColorCount<=4) nBitsPerPixel=2; else if (nColorCount<=16) nBitsPerPixel=4; else if (nColorCount<=256) nBitsPerPixel=8; else if (nColorCount<=65536) nBitsPerPixel=16; else nBitsPerPixel=24; nNeededMem=((sal_uLong)aSizePixel.Width()*(sal_uLong)aSizePixel.Height()*nBitsPerPixel+7)/8; // ggf. Groesse des Bildes einschraenken: if (nMaxMemIsExportInternalFilter( nFormat ) ) { if( aFilterName.EqualsIgnoreCaseAscii( EXP_BMP ) ) { Bitmap aBmp( aGraphic.GetBitmap() ); sal_Int32 nColorRes = aConfigItem.ReadInt32( String( RTL_CONSTASCII_USTRINGPARAM( "Colors" ) ), 0 ); if ( nColorRes && ( nColorRes <= (sal_uInt16)BMP_CONVERSION_24BIT) ) { if( !aBmp.Convert( (BmpConversion) nColorRes ) ) aBmp = aGraphic.GetBitmap(); } ResMgr* pResMgr = CREATERESMGR( svt ); sal_Bool bRleCoding = aConfigItem.ReadBool( String( RTL_CONSTASCII_USTRINGPARAM( "RLE_Coding" ) ), sal_True ); // Wollen wir RLE-Kodiert speichern? aBmp.Write( rOStm, bRleCoding ); delete pResMgr; if( rOStm.GetError() ) nStatus = GRFILTER_IOERROR; } else if( aFilterName.EqualsIgnoreCaseAscii( EXP_SVMETAFILE ) ) { sal_Int32 nVersion = aConfigItem.ReadInt32( String( RTL_CONSTASCII_USTRINGPARAM( "Version" ) ), 0 ) ; if ( nVersion ) rOStm.SetVersion( nVersion ); GDIMetaFile aMTF; if ( eType != GRAPHIC_BITMAP ) aMTF = aGraphic.GetGDIMetaFile(); else { VirtualDevice aVirDev; aMTF.Record( &aVirDev ); aGraphic.Draw( &aVirDev, Point(), aGraphic.GetPrefSize() ); aMTF.Stop(); aMTF.SetPrefSize( aGraphic.GetPrefSize() ); aMTF.SetPrefMapMode( aGraphic.GetPrefMapMode() ); } aMTF.Write( rOStm, GDIMETAFILE_WRITE_REPLACEMENT_RENDERGRAPHIC ); if( rOStm.GetError() ) nStatus = GRFILTER_IOERROR; } else if ( aFilterName.EqualsIgnoreCaseAscii( EXP_WMF ) ) { if( eType == GRAPHIC_GDIMETAFILE ) { if ( !ConvertGDIMetaFileToWMF( aGraphic.GetGDIMetaFile(), rOStm, &aConfigItem ) ) nStatus = GRFILTER_FORMATERROR; } else { Bitmap aBmp( aGraphic.GetBitmap() ); GDIMetaFile aMTF; VirtualDevice aVirDev; aMTF.Record( &aVirDev ); aVirDev.DrawBitmap( Point(), aBmp ); aMTF.Stop(); aMTF.SetPrefSize( aBmp.GetSizePixel() ); if( !ConvertGDIMetaFileToWMF( aMTF, rOStm, &aConfigItem ) ) nStatus = GRFILTER_FORMATERROR; } if( rOStm.GetError() ) nStatus = GRFILTER_IOERROR; } else if ( aFilterName.EqualsIgnoreCaseAscii( EXP_EMF ) ) { if( eType == GRAPHIC_GDIMETAFILE ) { if ( !ConvertGDIMetaFileToEMF( aGraphic.GetGDIMetaFile(), rOStm, &aConfigItem ) ) nStatus = GRFILTER_FORMATERROR; } else { Bitmap aBmp( aGraphic.GetBitmap() ); GDIMetaFile aMTF; VirtualDevice aVirDev; aMTF.Record( &aVirDev ); aVirDev.DrawBitmap( Point(), aBmp ); aMTF.Stop(); aMTF.SetPrefSize( aBmp.GetSizePixel() ); if( !ConvertGDIMetaFileToEMF( aMTF, rOStm, &aConfigItem ) ) nStatus = GRFILTER_FORMATERROR; } if( rOStm.GetError() ) nStatus = GRFILTER_IOERROR; } else if( aFilterName.EqualsIgnoreCaseAscii( EXP_JPEG ) ) { bool bExportedGrayJPEG = false; if( !ExportJPEG( rOStm, aGraphic, pFilterData, &bExportedGrayJPEG ) ) nStatus = GRFILTER_FORMATERROR; nExpGraphHint = bExportedGrayJPEG ? GRFILTER_OUTHINT_GREY : 0; if( rOStm.GetError() ) nStatus = GRFILTER_IOERROR; } else if ( aFilterName.EqualsIgnoreCaseAscii( EXP_PNG ) ) { vcl::PNGWriter aPNGWriter( aGraphic.GetBitmapEx(), pFilterData ); if ( pFilterData ) { sal_Int32 k, j, i = 0; for ( i = 0; i < pFilterData->getLength(); i++ ) { if ( (*pFilterData)[ i ].Name == "AdditionalChunks" ) { com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValue > aAdditionalChunkSequence; if ( (*pFilterData)[ i ].Value >>= aAdditionalChunkSequence ) { for ( j = 0; j < aAdditionalChunkSequence.getLength(); j++ ) { if ( aAdditionalChunkSequence[ j ].Name.getLength() == 4 ) { sal_uInt32 nChunkType = 0; for ( k = 0; k < 4; k++ ) { nChunkType <<= 8; nChunkType |= (sal_uInt8)aAdditionalChunkSequence[ j ].Name[ k ]; } com::sun::star::uno::Sequence< sal_Int8 > aByteSeq; if ( aAdditionalChunkSequence[ j ].Value >>= aByteSeq ) { std::vector< vcl::PNGWriter::ChunkData >& rChunkData = aPNGWriter.GetChunks(); if ( !rChunkData.empty() ) { sal_uInt32 nChunkLen = aByteSeq.getLength(); vcl::PNGWriter::ChunkData aChunkData; aChunkData.nType = nChunkType; if ( nChunkLen ) { aChunkData.aData.resize( nChunkLen ); rtl_copyMemory( &aChunkData.aData[ 0 ], aByteSeq.getConstArray(), nChunkLen ); } std::vector< vcl::PNGWriter::ChunkData >::iterator aIter = rChunkData.end() - 1; rChunkData.insert( aIter, aChunkData ); } } } } } } } } aPNGWriter.Write( rOStm ); if( rOStm.GetError() ) nStatus = GRFILTER_IOERROR; } else if( aFilterName.EqualsIgnoreCaseAscii( EXP_SVG ) ) { sal_Bool bDone = sal_False; // do we have a native SVG RenderGraphic, whose data can be written directly? if( ( GRAPHIC_GDIMETAFILE == eType ) && aGraphic.IsRenderGraphic() ) { const ::vcl::RenderGraphic aRenderGraphic( aGraphic.GetRenderGraphic() ); if( aRenderGraphic.GetGraphicDataLength() && aRenderGraphic.GetGraphicDataMimeType().equalsIgnoreAsciiCase( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "image/svg+xml" ) ) ) ) { rOStm.Write( aRenderGraphic.GetGraphicData().get(), aRenderGraphic.GetGraphicDataLength() ); if( rOStm.GetError() ) { nStatus = GRFILTER_IOERROR; } } } if( !bDone ) { // do the normal GDIMetaFile export instead try { ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > xMgr( ::comphelper::getProcessServiceFactory() ); if( xMgr.is() ) { ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XDocumentHandler > xSaxWriter( xMgr->createInstance( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.xml.sax.Writer" )) ), ::com::sun::star::uno::UNO_QUERY ); ::com::sun::star::uno::Reference< ::com::sun::star::svg::XSVGWriter > xSVGWriter( xMgr->createInstance( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.svg.SVGWriter" )) ), ::com::sun::star::uno::UNO_QUERY ); if( xSaxWriter.is() && xSVGWriter.is() ) { ::com::sun::star::uno::Reference< ::com::sun::star::io::XActiveDataSource > xActiveDataSource( xSaxWriter, ::com::sun::star::uno::UNO_QUERY ); if( xActiveDataSource.is() ) { const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > xStmIf( static_cast< ::cppu::OWeakObject* >( new ImpFilterOutputStream( rOStm ) ) ); SvMemoryStream aMemStm( 65535, 65535 ); ( (GDIMetaFile&) aGraphic.GetGDIMetaFile() ).Write( aMemStm ); xActiveDataSource->setOutputStream( ::com::sun::star::uno::Reference< ::com::sun::star::io::XOutputStream >( xStmIf, ::com::sun::star::uno::UNO_QUERY ) ); ::com::sun::star::uno::Sequence< sal_Int8 > aMtfSeq( (sal_Int8*) aMemStm.GetData(), aMemStm.Tell() ); xSVGWriter->write( xSaxWriter, aMtfSeq ); } } } } catch(const ::com::sun::star::uno::Exception&) { nStatus = GRFILTER_IOERROR; } } } else nStatus = GRFILTER_FILTERERROR; } else { sal_Int32 i, nTokenCount = getTokenCount(aFilterPath, ';'); for ( i = 0; i < nTokenCount; i++ ) { String aPhysicalName( ImpCreateFullFilterPath( getToken(aFilterPath, i, ';'), aFilterName ) ); osl::Module aLibrary( aPhysicalName ); PFilterCall pFunc = (PFilterCall) aLibrary.getFunctionSymbol( UniString::CreateFromAscii( EXPORT_FUNCTION_NAME ) ); // Dialog in DLL ausfuehren if( pFunc ) { if ( !(*pFunc)( rOStm, aGraphic, &aConfigItem, sal_False ) ) nStatus = GRFILTER_FORMATERROR; break; } else nStatus = GRFILTER_FILTERERROR; } } } if( nStatus != GRFILTER_OK ) { if( bAbort ) nStatus = GRFILTER_ABORT; ImplSetError( nStatus, &rOStm ); } return nStatus; } // ------------------------------------------------------------------------ sal_Bool GraphicFilter::Setup( sal_uInt16 ) { return sal_False; } // ------------------------------------------------------------------------ sal_Bool GraphicFilter::HasExportDialog( sal_uInt16 nFormat ) { return pConfig->IsExportDialog( nFormat ); } // ------------------------------------------------------------------------ sal_Bool GraphicFilter::DoExportDialog( Window* pWindow, sal_uInt16 nFormat ) { return DoExportDialog( pWindow, nFormat, FUNIT_MM ); } sal_Bool GraphicFilter::DoExportDialog( Window*, sal_uInt16 nFormat, FieldUnit ) { sal_Bool bRet = sal_False; com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory > xSMgr( ::comphelper::getProcessServiceFactory() ); uno::Reference< com::sun::star::uno::XInterface > xFilterOptionsDialog ( xSMgr->createInstance( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.svtools.SvFilterOptionsDialog" )) ), com::sun::star::uno::UNO_QUERY ); if ( xFilterOptionsDialog.is() ) { com::sun::star::uno::Reference< com::sun::star::ui::dialogs::XExecutableDialog > xExecutableDialog ( xFilterOptionsDialog, ::com::sun::star::uno::UNO_QUERY ); com::sun::star::uno::Reference< com::sun::star::beans::XPropertyAccess > xPropertyAccess ( xFilterOptionsDialog, ::com::sun::star::uno::UNO_QUERY ); if ( xExecutableDialog.is() && xPropertyAccess.is() ) { com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue > aMediaDescriptor( 1 ); aMediaDescriptor[ 0 ].Name = String( RTL_CONSTASCII_USTRINGPARAM( "FilterName" ) ); rtl::OUString aStr( pConfig->GetExportInternalFilterName( nFormat ) ); aMediaDescriptor[ 0 ].Value <<= aStr; xPropertyAccess->setPropertyValues( aMediaDescriptor ); bRet = xExecutableDialog->execute() == com::sun::star::ui::dialogs::ExecutableDialogResults::OK; } } return bRet; } // ------------------------------------------------------------------------ const FilterErrorEx& GraphicFilter::GetLastError() const { return *pErrorEx; } // ------------------------------------------------------------------------ void GraphicFilter::ResetLastError() { pErrorEx->nFilterError = pErrorEx->nStreamError = 0UL; } // ------------------------------------------------------------------------ const Link GraphicFilter::GetFilterCallback() const { const Link aLink( LINK( this, GraphicFilter, FilterCallback ) ); return aLink; } // ------------------------------------------------------------------------ IMPL_LINK( GraphicFilter, FilterCallback, ConvertData*, pData ) { long nRet = 0L; if( pData ) { sal_uInt16 nFormat = GRFILTER_FORMAT_DONTKNOW; rtl::OString aShortName; switch( pData->mnFormat ) { case( CVT_BMP ): aShortName = BMP_SHORTNAME; break; case( CVT_GIF ): aShortName = GIF_SHORTNAME; break; case( CVT_JPG ): aShortName = JPG_SHORTNAME; break; case( CVT_MET ): aShortName = MET_SHORTNAME; break; case( CVT_PCT ): aShortName = PCT_SHORTNAME; break; case( CVT_PNG ): aShortName = PNG_SHORTNAME; break; case( CVT_SVM ): aShortName = SVM_SHORTNAME; break; case( CVT_TIF ): aShortName = TIF_SHORTNAME; break; case( CVT_WMF ): aShortName = WMF_SHORTNAME; break; case( CVT_EMF ): aShortName = EMF_SHORTNAME; break; case( CVT_SVG ): aShortName = SVG_SHORTNAME; break; default: break; } if( GRAPHIC_NONE == pData->maGraphic.GetType() || pData->maGraphic.GetContext() ) // Import { // Import nFormat = GetImportFormatNumberForShortName( rtl::OStringToOUString( aShortName, RTL_TEXTENCODING_UTF8) ); nRet = ImportGraphic( pData->maGraphic, String(), pData->mrStm, nFormat ) == 0; } else if( !aShortName.isEmpty() ) { // Export nFormat = GetExportFormatNumberForShortName( rtl::OStringToOUString(aShortName, RTL_TEXTENCODING_UTF8) ); nRet = ExportGraphic( pData->maGraphic, String(), pData->mrStm, nFormat ) == 0; } } return nRet; } namespace { class StandardGraphicFilter { public: StandardGraphicFilter() { m_aFilter.GetImportFormatCount(); } GraphicFilter m_aFilter; }; class theGraphicFilter : public rtl::Static {}; } GraphicFilter& GraphicFilter::GetGraphicFilter() { return theGraphicFilter::get().m_aFilter; } int GraphicFilter::LoadGraphic( const String &rPath, const String &rFilterName, Graphic& rGraphic, GraphicFilter* pFilter, sal_uInt16* pDeterminedFormat ) { if ( !pFilter ) pFilter = &GetGraphicFilter(); const sal_uInt16 nFilter = rFilterName.Len() && pFilter->GetImportFormatCount() ? pFilter->GetImportFormatNumber( rFilterName ) : GRFILTER_FORMAT_DONTKNOW; SvStream* pStream = NULL; INetURLObject aURL( rPath ); if ( aURL.HasError() || INET_PROT_NOT_VALID == aURL.GetProtocol() ) { aURL.SetSmartProtocol( INET_PROT_FILE ); aURL.SetSmartURL( rPath ); } else if ( INET_PROT_FILE != aURL.GetProtocol() ) { pStream = ::utl::UcbStreamHelper::CreateStream( rPath, STREAM_READ ); } int nRes = GRFILTER_OK; if ( !pStream ) nRes = pFilter->ImportGraphic( rGraphic, aURL, nFilter, pDeterminedFormat ); else nRes = pFilter->ImportGraphic( rGraphic, rPath, *pStream, nFilter, pDeterminedFormat ); #ifdef DBG_UTIL if( nRes ) DBG_WARNING2( "GrafikFehler [%d] - [%s]", nRes, rPath.GetBuffer() ); #endif return nRes; } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */