LCOV - code coverage report
Current view: top level - filter/source/graphicfilter/ieps - ieps.cxx (source / functions) Hit Total Coverage
Test: commit e02a6cb2c3e2b23b203b422e4e0680877f232636 Lines: 0 372 0.0 %
Date: 2014-04-14 Functions: 0 13 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : 
      21             : #include <stdio.h>
      22             : 
      23             : #include <tools/solar.h>
      24             : #include <vcl/svapp.hxx>
      25             : #include <vcl/bitmap.hxx>
      26             : #include <vcl/bitmapex.hxx>
      27             : #include <vcl/animate.hxx>
      28             : #include <vcl/gdimtf.hxx>
      29             : #include <vcl/graph.h>
      30             : #include <vcl/window.hxx>
      31             : #include <vcl/graph.hxx>
      32             : #include <vcl/metaact.hxx>
      33             : #include <vcl/virdev.hxx>
      34             : #include <vcl/cvtgrf.hxx>
      35             : #include <vcl/bmpacc.hxx>
      36             : #include <unotools/tempfile.hxx>
      37             : #include <osl/process.h>
      38             : #include <osl/file.hxx>
      39             : #include <boost/scoped_array.hpp>
      40             : 
      41             : class FilterConfigItem;
      42             : 
      43             : /*************************************************************************
      44             : |*
      45             : |*    ImpSearchEntry()
      46             : |*
      47             : |*    Description       Checks if there is a string(pDest) of length nSize
      48             : |*                      inside the memory area pSource which is nComp bytes long.
      49             : |*                      Check is NON-CASE-SENSITIVE. The return value is the
      50             : |*                      address where the string is found or NULL
      51             : |*
      52             : *************************************************************************/
      53             : 
      54           0 : static sal_uInt8* ImplSearchEntry( sal_uInt8* pSource, sal_uInt8* pDest, sal_uLong nComp, sal_uLong nSize )
      55             : {
      56           0 :     while ( nComp-- >= nSize )
      57             :     {
      58             :         sal_uLong i;
      59           0 :         for ( i = 0; i < nSize; i++ )
      60             :         {
      61           0 :             if ( ( pSource[i]&~0x20 ) != ( pDest[i]&~0x20 ) )
      62           0 :                 break;
      63             :         }
      64           0 :         if ( i == nSize )
      65           0 :             return pSource;
      66           0 :         pSource++;
      67             :     }
      68           0 :     return NULL;
      69             : }
      70             : 
      71             : 
      72             : // SecurityCount is the buffersize of the buffer in which we will parse for a number
      73           0 : static long ImplGetNumber( sal_uInt8 **pBuf, int& nSecurityCount )
      74             : {
      75           0 :     sal_Bool    bValid = sal_True;
      76           0 :     sal_Bool    bNegative = sal_False;
      77           0 :     long    nRetValue = 0;
      78           0 :     while ( ( --nSecurityCount ) && ( ( **pBuf == ' ' ) || ( **pBuf == 0x9 ) ) )
      79           0 :         (*pBuf)++;
      80           0 :     sal_uInt8 nByte = **pBuf;
      81           0 :     while ( nSecurityCount && ( nByte != ' ' ) && ( nByte != 0x9 ) && ( nByte != 0xd ) && ( nByte != 0xa ) )
      82             :     {
      83           0 :         switch ( nByte )
      84             :         {
      85             :             case '.' :
      86             :                 // we'll only use the integer format
      87           0 :                 bValid = sal_False;
      88           0 :                 break;
      89             :             case '-' :
      90           0 :                 bNegative = sal_True;
      91           0 :                 break;
      92             :             default :
      93           0 :                 if ( ( nByte < '0' ) || ( nByte > '9' ) )
      94           0 :                     nSecurityCount = 1;         // error parsing the bounding box values
      95           0 :                 else if ( bValid )
      96             :                 {
      97           0 :                     nRetValue *= 10;
      98           0 :                     nRetValue += nByte - '0';
      99             :                 }
     100           0 :                 break;
     101             :         }
     102           0 :         nSecurityCount--;
     103           0 :         nByte = *(++(*pBuf));
     104             :     }
     105           0 :     if ( bNegative )
     106           0 :         nRetValue = -nRetValue;
     107           0 :     return nRetValue;
     108             : }
     109             : 
     110             : 
     111             : 
     112           0 : static int ImplGetLen( sal_uInt8* pBuf, int nMax )
     113             : {
     114           0 :     int nLen = 0;
     115           0 :     while( nLen != nMax )
     116             :     {
     117           0 :         sal_uInt8 nDat = *pBuf++;
     118           0 :         if ( nDat == 0x0a || nDat == 0x25 )
     119             :             break;
     120           0 :         nLen++;
     121             :     }
     122           0 :     return nLen;
     123             : }
     124             : 
     125           0 : static void MakeAsMeta(Graphic &rGraphic)
     126             : {
     127           0 :     VirtualDevice   aVDev;
     128           0 :     GDIMetaFile     aMtf;
     129           0 :     Bitmap          aBmp( rGraphic.GetBitmap() );
     130           0 :     Size            aSize = aBmp.GetPrefSize();
     131             : 
     132           0 :     if( !aSize.Width() || !aSize.Height() )
     133             :         aSize = Application::GetDefaultDevice()->PixelToLogic(
     134           0 :             aBmp.GetSizePixel(), MAP_100TH_MM );
     135             :     else
     136           0 :         aSize = Application::GetDefaultDevice()->LogicToLogic( aSize,
     137           0 :             aBmp.GetPrefMapMode(), MAP_100TH_MM );
     138             : 
     139           0 :     aVDev.EnableOutput( false );
     140           0 :     aMtf.Record( &aVDev );
     141           0 :     aVDev.DrawBitmap( Point(), aSize, rGraphic.GetBitmap() );
     142           0 :     aMtf.Stop();
     143           0 :     aMtf.WindStart();
     144           0 :     aMtf.SetPrefMapMode( MAP_100TH_MM );
     145           0 :     aMtf.SetPrefSize( aSize );
     146           0 :     rGraphic = aMtf;
     147           0 : }
     148             : 
     149           0 : static oslProcessError runProcessWithPathSearch(const OUString &rProgName,
     150             :     rtl_uString* pArgs[], sal_uInt32 nArgs, oslProcess *pProcess,
     151             :     oslFileHandle *pIn, oslFileHandle *pOut, oslFileHandle *pErr)
     152             : {
     153             :     oslProcessError result;
     154           0 :     oslSecurity pSecurity = osl_getCurrentSecurity();
     155             : #ifdef WNT
     156             :     /*
     157             :      * ooo#72096
     158             :      * On Window the underlying SearchPath searches in order of...
     159             :      * The directory from which the application loaded.
     160             :      * The current directory.
     161             :      * The Windows system directory.
     162             :      * The Windows directory.
     163             :      * The directories that are listed in the PATH environment variable.
     164             :      *
     165             :      * Because one of our programs is called "convert" and there is a convert
     166             :      * in the windows system directory, we want to explicitly search the PATH
     167             :      * to avoid picking up on that one if ImageMagick's convert preceeds it in
     168             :      * PATH.
     169             :      *
     170             :      */
     171             :     OUString url;
     172             :     OUString path(reinterpret_cast<const sal_Unicode*>(_wgetenv(L"PATH")));
     173             : 
     174             :     oslFileError err = osl_searchFileURL(rProgName.pData, path.pData, &url.pData);
     175             :     if (err != osl_File_E_None)
     176             :         return osl_Process_E_NotFound;
     177             : 
     178             :     result = osl_executeProcess_WithRedirectedIO(url.pData,
     179             :     pArgs, nArgs, osl_Process_HIDDEN,
     180             :         pSecurity, 0, 0, 0, pProcess, pIn, pOut, pErr);
     181             : #else
     182             :     result = osl_executeProcess_WithRedirectedIO(rProgName.pData,
     183             :         pArgs, nArgs, osl_Process_SEARCHPATH | osl_Process_HIDDEN,
     184           0 :         pSecurity, 0, 0, 0, pProcess, pIn, pOut, pErr);
     185             : #endif
     186           0 :     osl_freeSecurityHandle( pSecurity );
     187           0 :     return result;
     188             : }
     189             : 
     190             : #if defined(WNT)
     191             : #    define EXESUFFIX ".exe"
     192             : #else
     193             : #    define EXESUFFIX ""
     194             : #endif
     195             : 
     196           0 : static bool RenderAsEMF(const sal_uInt8* pBuf, sal_uInt32 nBytesRead, Graphic &rGraphic)
     197             : {
     198           0 :     utl::TempFile aTemp;
     199           0 :     aTemp.EnableKillingFile();
     200           0 :     OUString fileName("pstoedit" EXESUFFIX);
     201           0 :     OUString arg1("-f");
     202           0 :     OUString arg2("emf:-OO");
     203           0 :     OUString arg3("-");
     204           0 :     OUString output;
     205           0 :     osl::FileBase::getSystemPathFromFileURL(aTemp.GetURL(), output);
     206             :     rtl_uString *args[] =
     207             :     {
     208             :         arg1.pData, arg2.pData, arg3.pData, output.pData
     209           0 :     };
     210             :     oslProcess aProcess;
     211           0 :     oslFileHandle pIn = NULL;
     212           0 :     oslFileHandle pOut = NULL;
     213           0 :     oslFileHandle pErr = NULL;
     214             :         oslProcessError eErr = runProcessWithPathSearch(fileName,
     215           0 :             args, sizeof(args)/sizeof(rtl_uString *),
     216           0 :             &aProcess, &pIn, &pOut, &pErr);
     217             : 
     218           0 :     if (eErr!=osl_Process_E_None)
     219           0 :         return false;
     220             : 
     221           0 :     bool bRet = false;
     222             :     sal_uInt64 nCount;
     223           0 :     osl_writeFile(pIn, pBuf, nBytesRead, &nCount);
     224           0 :     if (pIn) osl_closeFile(pIn);
     225           0 :     bool bEMFSupported=true;
     226           0 :     if (pOut)
     227             :     {
     228           0 :         rtl::ByteSequence seq;
     229           0 :         if (osl_File_E_None == osl_readLine(pOut, (sal_Sequence **)&seq))
     230             :         {
     231           0 :             OString line( (const sal_Char *) seq.getConstArray(), seq.getLength() );
     232           0 :             if (line.startsWith("Unsupported output format"))
     233           0 :                 bEMFSupported=false;
     234             :         }
     235           0 :         osl_closeFile(pOut);
     236             :     }
     237           0 :     if (pErr) osl_closeFile(pErr);
     238           0 :     if (nCount == nBytesRead && bEMFSupported)
     239             :     {
     240           0 :         SvFileStream aFile(output, STREAM_READ);
     241           0 :         if (GraphicConverter::Import(aFile, rGraphic, CVT_EMF) == ERRCODE_NONE)
     242           0 :             bRet = true;
     243             :     }
     244           0 :     osl_joinProcess(aProcess);
     245           0 :     osl_freeProcessHandle(aProcess);
     246           0 :     return bRet;
     247             : }
     248             : 
     249           0 : static bool RenderAsBMPThroughHelper(const sal_uInt8* pBuf, sal_uInt32 nBytesRead,
     250             :     Graphic &rGraphic, OUString &rProgName, rtl_uString *pArgs[], size_t nArgs)
     251             : {
     252             :     oslProcess aProcess;
     253           0 :     oslFileHandle pIn = NULL;
     254           0 :     oslFileHandle pOut = NULL;
     255           0 :     oslFileHandle pErr = NULL;
     256             :         oslProcessError eErr = runProcessWithPathSearch(rProgName,
     257             :             pArgs, nArgs,
     258           0 :             &aProcess, &pIn, &pOut, &pErr);
     259           0 :     if (eErr!=osl_Process_E_None)
     260           0 :         return false;
     261             : 
     262           0 :     bool bRet = false;
     263             :     sal_uInt64 nCount;
     264           0 :     osl_writeFile(pIn, pBuf, nBytesRead, &nCount);
     265           0 :     if (pIn) osl_closeFile(pIn);
     266           0 :     if (nCount == nBytesRead)
     267             :     {
     268           0 :         SvMemoryStream aMemStm;
     269             :         sal_uInt8 aBuf[32000];
     270           0 :         oslFileError eFileErr = osl_readFile(pOut, aBuf, 32000, &nCount);
     271           0 :         while (eFileErr == osl_File_E_None && nCount)
     272             :         {
     273           0 :             aMemStm.Write(aBuf, sal::static_int_cast< sal_Size >(nCount));
     274           0 :             eFileErr = osl_readFile(pOut, aBuf, 32000, &nCount);
     275             :         }
     276             : 
     277           0 :         aMemStm.Seek(0);
     278           0 :         if (
     279           0 :             aMemStm.GetEndOfData() &&
     280           0 :             GraphicConverter::Import(aMemStm, rGraphic, CVT_BMP) == ERRCODE_NONE
     281             :            )
     282             :         {
     283           0 :             MakeAsMeta(rGraphic);
     284           0 :             bRet = true;
     285           0 :         }
     286             :     }
     287           0 :     if (pOut) osl_closeFile(pOut);
     288           0 :     if (pErr) osl_closeFile(pErr);
     289           0 :     osl_joinProcess(aProcess);
     290           0 :     osl_freeProcessHandle(aProcess);
     291           0 :     return bRet;
     292             : }
     293             : 
     294           0 : static bool RenderAsBMPThroughConvert(const sal_uInt8* pBuf, sal_uInt32 nBytesRead,
     295             :     Graphic &rGraphic)
     296             : {
     297           0 :     OUString fileName("convert" EXESUFFIX);
     298             :     // density in pixel/inch
     299           0 :     OUString arg1("-density");
     300             :     // since the preview is also used for PDF-Export & printing on non-PS-printers,
     301             :     // use some better quality - 300x300 should allow some resizing as well
     302           0 :     OUString arg2("300x300");
     303             :     // read eps from STDIN
     304           0 :     OUString arg3("eps:-");
     305             :     // write bmp to STDOUT
     306           0 :     OUString arg4("bmp:-");
     307             :     rtl_uString *args[] =
     308             :     {
     309             :         arg1.pData, arg2.pData, arg3.pData, arg4.pData
     310           0 :     };
     311             :     return RenderAsBMPThroughHelper(pBuf, nBytesRead, rGraphic, fileName, args,
     312           0 :         sizeof(args)/sizeof(rtl_uString *));
     313             : }
     314             : 
     315           0 : static bool RenderAsBMPThroughGS(const sal_uInt8* pBuf, sal_uInt32 nBytesRead,
     316             :     Graphic &rGraphic)
     317             : {
     318             : #ifdef WNT
     319             :     OUString fileName("gswin32c" EXESUFFIX);
     320             : #else
     321           0 :     OUString fileName("gs" EXESUFFIX);
     322             : #endif
     323           0 :     OUString arg1("-q");
     324           0 :     OUString arg2("-dBATCH");
     325           0 :     OUString arg3("-dNOPAUSE");
     326           0 :     OUString arg4("-dPARANOIDSAFER");
     327           0 :     OUString arg5("-dEPSCrop");
     328           0 :     OUString arg6("-dTextAlphaBits=4");
     329           0 :     OUString arg7("-dGraphicsAlphaBits=4");
     330           0 :     OUString arg8("-r300x300");
     331           0 :     OUString arg9("-sDEVICE=bmp256");
     332           0 :     OUString arg10("-sOutputFile=-");
     333           0 :     OUString arg11("-");
     334             :     rtl_uString *args[] =
     335             :     {
     336             :         arg1.pData, arg2.pData, arg3.pData, arg4.pData, arg5.pData,
     337             :         arg6.pData, arg7.pData, arg8.pData, arg9.pData, arg10.pData,
     338             :         arg11.pData
     339           0 :     };
     340             :     return RenderAsBMPThroughHelper(pBuf, nBytesRead, rGraphic, fileName, args,
     341           0 :         sizeof(args)/sizeof(rtl_uString *));
     342             : }
     343             : 
     344           0 : static bool RenderAsBMP(const sal_uInt8* pBuf, sal_uInt32 nBytesRead, Graphic &rGraphic)
     345             : {
     346           0 :     if (RenderAsBMPThroughGS(pBuf, nBytesRead, rGraphic))
     347           0 :         return true;
     348             :     else
     349           0 :         return RenderAsBMPThroughConvert(pBuf, nBytesRead, rGraphic);
     350             : }
     351             : 
     352             : // this method adds a replacement action containing the original wmf or tiff replacement,
     353             : // so the original eps can be written when storing to ODF.
     354           0 : void CreateMtfReplacementAction( GDIMetaFile& rMtf, SvStream& rStrm, sal_uInt32 nOrigPos, sal_uInt32 nPSSize,
     355             :                                 sal_uInt32 nPosWMF, sal_uInt32 nSizeWMF, sal_uInt32 nPosTIFF, sal_uInt32 nSizeTIFF )
     356             : {
     357           0 :     OString aComment("EPSReplacementGraphic");
     358           0 :     if ( nSizeWMF || nSizeTIFF )
     359             :     {
     360           0 :         SvMemoryStream aReplacement( nSizeWMF + nSizeTIFF + 28 );
     361           0 :         sal_uInt32 nMagic = 0xc6d3d0c5;
     362           0 :         sal_uInt32 nPPos = 28 + nSizeWMF + nSizeTIFF;
     363           0 :         sal_uInt32 nWPos = nSizeWMF ? 28 : 0;
     364           0 :         sal_uInt32 nTPos = nSizeTIFF ? 28 + nSizeWMF : 0;
     365             : 
     366           0 :         aReplacement.WriteUInt32( nMagic ).WriteUInt32( nPPos ).WriteUInt32( nPSSize )
     367           0 :                     .WriteUInt32( nWPos ).WriteUInt32( nSizeWMF )
     368           0 :                     .WriteUInt32( nTPos ).WriteUInt32( nSizeTIFF );
     369           0 :         if ( nSizeWMF )
     370             :         {
     371           0 :             boost::scoped_array<sal_uInt8> pBuf(new sal_uInt8[ nSizeWMF ]);
     372           0 :             rStrm.Seek( nOrigPos + nPosWMF );
     373           0 :             rStrm.Read( pBuf.get(), nSizeWMF );
     374           0 :             aReplacement.Write( pBuf.get(), nSizeWMF );
     375             :         }
     376           0 :         if ( nSizeTIFF )
     377             :         {
     378           0 :             boost::scoped_array<sal_uInt8> pBuf(new sal_uInt8[ nSizeTIFF ]);
     379           0 :             rStrm.Seek( nOrigPos + nPosTIFF );
     380           0 :             rStrm.Read( pBuf.get(), nSizeTIFF );
     381           0 :             aReplacement.Write( pBuf.get(), nSizeTIFF );
     382             :         }
     383           0 :         rMtf.AddAction( (MetaAction*)( new MetaCommentAction( aComment, 0, (const sal_uInt8*)aReplacement.GetData(), aReplacement.Tell() ) ) );
     384             :     }
     385             :     else
     386           0 :         rMtf.AddAction( (MetaAction*)( new MetaCommentAction( aComment, 0, NULL, 0 ) ) );
     387           0 : }
     388             : 
     389             : //there is no preview -> make a red box
     390           0 : void MakePreview(sal_uInt8* pBuf, sal_uInt32 nBytesRead,
     391             :     long nWidth, long nHeight, Graphic &rGraphic)
     392             : {
     393           0 :     GDIMetaFile aMtf;
     394           0 :     VirtualDevice   aVDev;
     395           0 :     Font            aFont;
     396             : 
     397           0 :     aVDev.EnableOutput( false );
     398           0 :     aMtf.Record( &aVDev );
     399           0 :     aVDev.SetLineColor( Color( COL_RED ) );
     400           0 :     aVDev.SetFillColor();
     401             : 
     402           0 :     aFont.SetColor( COL_LIGHTRED );
     403             : //  aFont.SetSize( Size( 0, 32 ) );
     404             : 
     405           0 :     aVDev.Push( PUSH_FONT );
     406           0 :     aVDev.SetFont( aFont );
     407             : 
     408           0 :     Rectangle aRect( Point( 1, 1 ), Size( nWidth - 2, nHeight - 2 ) );
     409           0 :     aVDev.DrawRect( aRect );
     410             : 
     411           0 :     OUString aString;
     412             :     int nLen;
     413           0 :     sal_uInt8* pDest = ImplSearchEntry( pBuf, (sal_uInt8*)"%%Title:", nBytesRead - 32, 8 );
     414           0 :     if ( pDest )
     415             :     {
     416           0 :         pDest += 8;
     417           0 :         if ( *pDest == ' ' )
     418           0 :             pDest++;
     419           0 :         nLen = ImplGetLen( pDest, 32 );
     420           0 :         sal_uInt8 aOldValue(pDest[ nLen ]); pDest[ nLen ] = 0;
     421           0 :         if ( strcmp( (const char*)pDest, "none" ) != 0 )
     422             :         {
     423           0 :             aString += " Title:" + OUString::createFromAscii( (char*)pDest ) + "\n";
     424             :         }
     425           0 :         pDest[ nLen ] = aOldValue;
     426             :     }
     427           0 :     pDest = ImplSearchEntry( pBuf, (sal_uInt8*)"%%Creator:", nBytesRead - 32, 10 );
     428           0 :     if ( pDest )
     429             :     {
     430           0 :         pDest += 10;
     431           0 :         if ( *pDest == ' ' )
     432           0 :             pDest++;
     433           0 :         nLen = ImplGetLen( pDest, 32 );
     434           0 :         sal_uInt8 aOldValue(pDest[ nLen ]); pDest[ nLen ] = 0;
     435           0 :         aString += " Creator:" + OUString::createFromAscii( (char*)pDest ) + "\n";
     436           0 :         pDest[ nLen ] = aOldValue;
     437             :     }
     438           0 :     pDest = ImplSearchEntry( pBuf, (sal_uInt8*)"%%CreationDate:", nBytesRead - 32, 15 );
     439           0 :     if ( pDest )
     440             :     {
     441           0 :         pDest += 15;
     442           0 :         if ( *pDest == ' ' )
     443           0 :             pDest++;
     444           0 :         nLen = ImplGetLen( pDest, 32 );
     445           0 :         sal_uInt8 aOldValue(pDest[ nLen ]); pDest[ nLen ] = 0;
     446           0 :         if ( strcmp( (const char*)pDest, "none" ) != 0 )
     447             :         {
     448           0 :             aString += " CreationDate:" + OUString::createFromAscii( (char*)pDest ) + "\n";
     449             :         }
     450           0 :         pDest[ nLen ] = aOldValue;
     451             :     }
     452           0 :     pDest = ImplSearchEntry( pBuf, (sal_uInt8*)"%%LanguageLevel:", nBytesRead - 4, 16 );
     453           0 :     if ( pDest )
     454             :     {
     455           0 :         pDest += 16;
     456           0 :         int nCount = 4;
     457           0 :         long nNumber = ImplGetNumber( &pDest, nCount );
     458           0 :         if ( nCount && ( (sal_uInt32)nNumber < 10 ) )
     459             :         {
     460           0 :             aString += " LanguageLevel:" + OUString::number( nNumber );
     461             :         }
     462             :     }
     463           0 :     aVDev.DrawText( aRect, aString, TEXT_DRAW_CLIP | TEXT_DRAW_MULTILINE );
     464           0 :     aVDev.Pop();
     465           0 :     aMtf.Stop();
     466           0 :     aMtf.WindStart();
     467           0 :     aMtf.SetPrefMapMode( MAP_POINT );
     468           0 :     aMtf.SetPrefSize( Size( nWidth, nHeight ) );
     469           0 :     rGraphic = aMtf;
     470           0 : }
     471             : 
     472             : 
     473             : //================== GraphicImport - the exported function ================
     474             : 
     475             : // this needs to be kept in sync with
     476             : // ImpFilterLibCacheEntry::GetImportFunction() from
     477             : // vcl/source/filter/graphicfilter.cxx
     478             : #if defined(DISABLE_DYNLOADING)
     479             : #define GraphicImport ipsGraphicImport
     480             : #endif
     481             : 
     482             : extern "C" SAL_DLLPUBLIC_EXPORT bool SAL_CALL
     483           0 : GraphicImport( SvStream & rStream, Graphic & rGraphic, FilterConfigItem* )
     484             : {
     485           0 :     if ( rStream.GetError() )
     486           0 :         return false;
     487             : 
     488           0 :     Graphic     aGraphic;
     489           0 :     sal_Bool    bRetValue = sal_False;
     490           0 :     sal_Bool    bHasPreview = sal_False;
     491           0 :     sal_Bool    bGraphicLinkCreated = sal_False;
     492             :     sal_uInt32  nSignature, nPSStreamPos, nPSSize;
     493           0 :     sal_uInt32  nSizeWMF = 0;
     494           0 :     sal_uInt32  nPosWMF = 0;
     495           0 :     sal_uInt32  nSizeTIFF = 0;
     496           0 :     sal_uInt32  nPosTIFF = 0;
     497           0 :     sal_uInt32  nOrigPos = nPSStreamPos = rStream.Tell();
     498           0 :     sal_uInt16  nOldFormat = rStream.GetNumberFormatInt();
     499           0 :     rStream.SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
     500           0 :     rStream.ReadUInt32( nSignature );
     501           0 :     if ( nSignature == 0xc6d3d0c5 )
     502             :     {
     503           0 :         rStream.ReadUInt32( nPSStreamPos ).ReadUInt32( nPSSize ).ReadUInt32( nPosWMF ).ReadUInt32( nSizeWMF );
     504             : 
     505             :         // first we try to get the metafile grafix
     506             : 
     507           0 :         if ( nSizeWMF )
     508             :         {
     509           0 :             if ( nPosWMF != 0 )
     510             :             {
     511           0 :                 rStream.Seek( nOrigPos + nPosWMF );
     512           0 :                 if ( GraphicConverter::Import( rStream, aGraphic, CVT_WMF ) == ERRCODE_NONE )
     513           0 :                     bHasPreview = bRetValue = sal_True;
     514             :             }
     515             :         }
     516             :         else
     517             :         {
     518           0 :             rStream.ReadUInt32( nPosTIFF ).ReadUInt32( nSizeTIFF );
     519             : 
     520             :             // else we have to get the tiff grafix
     521             : 
     522           0 :             if ( nPosTIFF && nSizeTIFF )
     523             :             {
     524           0 :                 rStream.Seek( nOrigPos + nPosTIFF );
     525           0 :                 if ( GraphicConverter::Import( rStream, aGraphic, CVT_TIF ) == ERRCODE_NONE )
     526             :                 {
     527           0 :                     MakeAsMeta(aGraphic);
     528           0 :                     rStream.Seek( nOrigPos + nPosTIFF );
     529           0 :                     bHasPreview = bRetValue = sal_True;
     530             :                 }
     531             :             }
     532             :         }
     533             :     }
     534             :     else
     535             :     {
     536           0 :         nPSStreamPos = nOrigPos;            // no preview available _>so we must get the size manually
     537           0 :         nPSSize = rStream.Seek( STREAM_SEEK_TO_END ) - nOrigPos;
     538             :     }
     539           0 :     sal_uInt8* pHeader = new sal_uInt8[ 22 ];
     540           0 :     rStream.Seek( nPSStreamPos );
     541           0 :     rStream.Read( pHeader, 22 );    // check PostScript header
     542           0 :     if ( ImplSearchEntry( pHeader, (sal_uInt8*)"%!PS-Adobe", 10, 10 ) &&
     543           0 :         ImplSearchEntry( &pHeader[ 15 ], (sal_uInt8*)"EPS", 3, 3 ) )
     544             :     {
     545           0 :         rStream.Seek( nPSStreamPos );
     546           0 :         sal_uInt8* pBuf = new sal_uInt8[ nPSSize ];
     547           0 :         if ( pBuf )
     548             :         {
     549           0 :             sal_uInt32  nBufStartPos = rStream.Tell();
     550           0 :             sal_uInt32  nBytesRead = rStream.Read( pBuf, nPSSize );
     551           0 :             if ( nBytesRead == nPSSize )
     552             :             {
     553           0 :                 int nSecurityCount = 32;
     554           0 :                 if ( !bHasPreview )     // if there is no tiff/wmf preview, we will parse for an preview in the eps prolog
     555             :                 {
     556           0 :                     sal_uInt8* pDest = ImplSearchEntry( pBuf, (sal_uInt8*)"%%BeginPreview:", nBytesRead - 32, 15 );
     557           0 :                     if ( pDest  )
     558             :                     {
     559           0 :                         pDest += 15;
     560           0 :                         long nWidth = ImplGetNumber( &pDest, nSecurityCount );
     561           0 :                         long nHeight = ImplGetNumber( &pDest, nSecurityCount );
     562           0 :                         long nBitDepth = ImplGetNumber( &pDest, nSecurityCount );
     563           0 :                         long nScanLines = ImplGetNumber( &pDest, nSecurityCount );
     564           0 :                         pDest = ImplSearchEntry( pDest, (sal_uInt8*)"%", 16, 1 );       // go to the first Scanline
     565           0 :                         if ( nSecurityCount && pDest && nWidth && nHeight && ( ( nBitDepth == 1 ) || ( nBitDepth == 8 ) ) && nScanLines )
     566             :                         {
     567           0 :                             rStream.Seek( nBufStartPos + ( pDest - pBuf ) );
     568             : 
     569           0 :                             Bitmap aBitmap( Size( nWidth, nHeight ), 1 );
     570           0 :                             BitmapWriteAccess* pAcc = aBitmap.AcquireWriteAccess();
     571           0 :                             if ( pAcc )
     572             :                             {
     573             :                                 int  nBitsLeft;
     574           0 :                                 sal_Bool bIsValid = sal_True;
     575           0 :                                 sal_uInt8 nDat = 0;
     576             :                                 char nByte;
     577           0 :                                 for ( long y = 0; bIsValid && ( y < nHeight ); y++ )
     578             :                                 {
     579           0 :                                     nBitsLeft = 0;
     580           0 :                                     for ( long x = 0; x < nWidth; x++ )
     581             :                                     {
     582           0 :                                         if ( --nBitsLeft < 0 )
     583             :                                         {
     584           0 :                                             while ( bIsValid && ( nBitsLeft != 7 ) )
     585             :                                             {
     586           0 :                                                 rStream.ReadChar( nByte );
     587           0 :                                                 switch ( nByte )
     588             :                                                 {
     589             :                                                     case 0x0a :
     590           0 :                                                         if ( --nScanLines < 0 )
     591           0 :                                                             bIsValid = sal_False;
     592             :                                                     case 0x09 :
     593             :                                                     case 0x0d :
     594             :                                                     case 0x20 :
     595             :                                                     case 0x25 :
     596           0 :                                                     break;
     597             :                                                     default:
     598             :                                                     {
     599           0 :                                                         if ( nByte >= '0' )
     600             :                                                         {
     601           0 :                                                             if ( nByte > '9' )
     602             :                                                             {
     603           0 :                                                                 nByte &=~0x20;  // case none sensitive for hexadecimal values
     604           0 :                                                                 nByte -= ( 'A' - 10 );
     605           0 :                                                                 if ( nByte > 15 )
     606           0 :                                                                     bIsValid = sal_False;
     607             :                                                             }
     608             :                                                             else
     609           0 :                                                                 nByte -= '0';
     610           0 :                                                             nBitsLeft += 4;
     611           0 :                                                             nDat <<= 4;
     612           0 :                                                             nDat |= ( nByte ^ 0xf ); // in epsi a zero bit represents white color
     613             :                                                         }
     614             :                                                         else
     615           0 :                                                             bIsValid = sal_False;
     616             :                                                     }
     617           0 :                                                     break;
     618             :                                                 }
     619             :                                             }
     620             :                                         }
     621           0 :                                         if ( nBitDepth == 1 )
     622           0 :                                             pAcc->SetPixelIndex( y, x, static_cast<sal_uInt8>(nDat >> nBitsLeft) & 1 );
     623             :                                         else
     624             :                                         {
     625           0 :                                             pAcc->SetPixelIndex( y, x, nDat ? 1 : 0 );  // nBitDepth == 8
     626           0 :                                             nBitsLeft = 0;
     627             :                                         }
     628             :                                     }
     629             :                                 }
     630           0 :                                 if ( bIsValid )
     631             :                                 {
     632           0 :                                     VirtualDevice   aVDev;
     633           0 :                                     GDIMetaFile     aMtf;
     634           0 :                                     Size            aSize;
     635           0 :                                     aVDev.EnableOutput( false );
     636           0 :                                     aMtf.Record( &aVDev );
     637           0 :                                     aSize = aBitmap.GetPrefSize();
     638           0 :                                     if( !aSize.Width() || !aSize.Height() )
     639           0 :                                         aSize = Application::GetDefaultDevice()->PixelToLogic( aBitmap.GetSizePixel(), MAP_100TH_MM );
     640             :                                     else
     641           0 :                                         aSize = Application::GetDefaultDevice()->LogicToLogic( aSize, aBitmap.GetPrefMapMode(), MAP_100TH_MM );
     642           0 :                                     aVDev.DrawBitmap( Point(), aSize, aBitmap );
     643           0 :                                     aMtf.Stop();
     644           0 :                                     aMtf.WindStart();
     645           0 :                                     aMtf.SetPrefMapMode( MAP_100TH_MM );
     646           0 :                                     aMtf.SetPrefSize( aSize );
     647           0 :                                     aGraphic = aMtf;
     648           0 :                                     bHasPreview = bRetValue = sal_True;
     649             :                                 }
     650           0 :                                 aBitmap.ReleaseAccess( pAcc );
     651           0 :                             }
     652             :                         }
     653             :                     }
     654             :                 }
     655             : 
     656           0 :                 sal_uInt8* pDest = ImplSearchEntry( pBuf, (sal_uInt8*)"%%BoundingBox:", nBytesRead, 14 );
     657           0 :                 if ( pDest )
     658             :                 {
     659           0 :                     nSecurityCount = 100;
     660             :                     long nNumb[4];
     661           0 :                     nNumb[0] = nNumb[1] = nNumb[2] = nNumb[3] = 0;
     662           0 :                     pDest += 14;
     663           0 :                     for ( int i = 0; ( i < 4 ) && nSecurityCount; i++ )
     664             :                     {
     665           0 :                         nNumb[ i ] = ImplGetNumber( &pDest, nSecurityCount );
     666             :                     }
     667           0 :                     if ( nSecurityCount)
     668             :                     {
     669           0 :                         bGraphicLinkCreated = sal_True;
     670           0 :                         GfxLink     aGfxLink( pBuf, nPSSize, GFX_LINK_TYPE_EPS_BUFFER, true ) ;
     671           0 :                         GDIMetaFile aMtf;
     672             : 
     673           0 :                         long nWidth =  nNumb[2] - nNumb[0] + 1;
     674           0 :                         long nHeight = nNumb[3] - nNumb[1] + 1;
     675             : 
     676             :                         // if there is no preview -> try with gs to make one
     677           0 :                         if( !bHasPreview )
     678             :                         {
     679           0 :                             bHasPreview = RenderAsEMF(pBuf, nBytesRead, aGraphic);
     680           0 :                             if (!bHasPreview)
     681           0 :                                 bHasPreview = RenderAsBMP(pBuf, nBytesRead, aGraphic);
     682             :                         }
     683             : 
     684             :                         // if there is no preview -> make a red box
     685           0 :                         if( !bHasPreview )
     686             :                         {
     687             :                             MakePreview(pBuf, nBytesRead, nWidth, nHeight,
     688           0 :                                 aGraphic);
     689             :                         }
     690             : 
     691             :                         aMtf.AddAction( (MetaAction*)( new MetaEPSAction( Point(), Size( nWidth, nHeight ),
     692           0 :                                                                           aGfxLink, aGraphic.GetGDIMetaFile() ) ) );
     693           0 :                         CreateMtfReplacementAction( aMtf, rStream, nOrigPos, nPSSize, nPosWMF, nSizeWMF, nPosTIFF, nSizeTIFF );
     694           0 :                         aMtf.WindStart();
     695           0 :                         aMtf.SetPrefMapMode( MAP_POINT );
     696           0 :                         aMtf.SetPrefSize( Size( nWidth, nHeight ) );
     697           0 :                         rGraphic = aMtf;
     698           0 :                         bRetValue = sal_True;
     699             :                     }
     700             :                 }
     701             :             }
     702             :         }
     703           0 :         if ( !bGraphicLinkCreated )
     704           0 :             delete[] pBuf;
     705             :     }
     706           0 :     delete[] pHeader;
     707           0 :     rStream.SetNumberFormatInt(nOldFormat);
     708           0 :     rStream.Seek( nOrigPos );
     709           0 :     return ( bRetValue );
     710             : }
     711             : 
     712             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10