blob: 85116df6ffbba677cd08044d08aeb133d155f2e1 [file] [log] [blame]
/**************************************************************
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*************************************************************/
// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_svtools.hxx"
#include <string.h>
#include <stdio.h>
#include <tools/stream.hxx>
#include <tools/debug.hxx>
#include <vcl/outdev.hxx>
#include <tools/config.hxx>
#include <svtools/filter.hxx>
#include "FilterConfigCache.hxx"
#include <unotools/ucbstreamhelper.hxx>
#define DATA_SIZE 640
sal_uInt8* ImplSearchEntry( sal_uInt8* , sal_uInt8* , sal_uLong , sal_uLong );
/*************************************************************************
|*
|*
|*
\************************************************************************/
GraphicDescriptor::GraphicDescriptor( const INetURLObject& rPath ) :
pFileStm( ::utl::UcbStreamHelper::CreateStream( rPath.GetMainURL( INetURLObject::NO_DECODE ), STREAM_READ ) ),
aPathExt( rPath.GetFileExtension().toAsciiLowerCase() ),
bOwnStream( sal_True )
{
ImpConstruct();
}
/*************************************************************************
|*
|*
|*
\************************************************************************/
GraphicDescriptor::GraphicDescriptor( SvStream& rInStream, const String* pPath) :
pFileStm ( &rInStream ),
bOwnStream ( sal_False )
{
ImpConstruct();
if ( pPath )
{
INetURLObject aURL( *pPath );
aPathExt = aURL.GetFileExtension().toAsciiLowerCase();
}
}
/*************************************************************************
|*
|*
|*
\************************************************************************/
GraphicDescriptor::~GraphicDescriptor()
{
if ( bOwnStream )
delete pFileStm;
}
/*************************************************************************
|*
|*
|*
\************************************************************************/
sal_Bool GraphicDescriptor::Detect( sal_Bool bExtendedInfo )
{
sal_Bool bRet = sal_False;
if ( pFileStm && !pFileStm->GetError() )
{
SvStream& rStm = *pFileStm;
sal_uInt16 nOldFormat = rStm.GetNumberFormatInt();
if ( ImpDetectGIF( rStm, bExtendedInfo ) ) bRet = sal_True;
else if ( ImpDetectJPG( rStm, bExtendedInfo ) ) bRet = sal_True;
else if ( ImpDetectBMP( rStm, bExtendedInfo ) ) bRet = sal_True;
else if ( ImpDetectPNG( rStm, bExtendedInfo ) ) bRet = sal_True;
else if ( ImpDetectTIF( rStm, bExtendedInfo ) ) bRet = sal_True;
else if ( ImpDetectPCX( rStm, bExtendedInfo ) ) bRet = sal_True;
else if ( ImpDetectDXF( rStm, bExtendedInfo ) ) bRet = sal_True;
else if ( ImpDetectMET( rStm, bExtendedInfo ) ) bRet = sal_True;
else if ( ImpDetectSGF( rStm, bExtendedInfo ) ) bRet = sal_True;
else if ( ImpDetectSGV( rStm, bExtendedInfo ) ) bRet = sal_True;
else if ( ImpDetectSVM( rStm, bExtendedInfo ) ) bRet = sal_True;
else if ( ImpDetectWMF( rStm, bExtendedInfo ) ) bRet = sal_True;
else if ( ImpDetectEMF( rStm, bExtendedInfo ) ) bRet = sal_True;
else if ( ImpDetectSVG( rStm, bExtendedInfo ) ) bRet = sal_True;
else if ( ImpDetectPCT( rStm, bExtendedInfo ) ) bRet = sal_True;
else if ( ImpDetectXBM( rStm, bExtendedInfo ) ) bRet = sal_True;
else if ( ImpDetectXPM( rStm, bExtendedInfo ) ) bRet = sal_True;
else if ( ImpDetectPBM( rStm, bExtendedInfo ) ) bRet = sal_True;
else if ( ImpDetectPGM( rStm, bExtendedInfo ) ) bRet = sal_True;
else if ( ImpDetectPPM( rStm, bExtendedInfo ) ) bRet = sal_True;
else if ( ImpDetectRAS( rStm, bExtendedInfo ) ) bRet = sal_True;
else if ( ImpDetectTGA( rStm, bExtendedInfo ) ) bRet = sal_True;
else if ( ImpDetectPSD( rStm, bExtendedInfo ) ) bRet = sal_True;
else if ( ImpDetectEPS( rStm, bExtendedInfo ) ) bRet = sal_True;
else if ( ImpDetectPCD( rStm, bExtendedInfo ) ) bRet = sal_True;
rStm.SetNumberFormatInt( nOldFormat );
}
return bRet;
}
/*************************************************************************
|*
|*
|*
\************************************************************************/
void GraphicDescriptor::ImpConstruct()
{
nFormat = GFF_NOT;
nBitsPerPixel = 0;
nPlanes = 0;
bCompressed = sal_False;
}
/*************************************************************************
|*
|*
|*
\************************************************************************/
sal_Bool GraphicDescriptor::ImpDetectBMP( SvStream& rStm, sal_Bool bExtendedInfo )
{
sal_uInt16 nTemp16;
sal_Bool bRet = sal_False;
sal_Int32 nStmPos = rStm.Tell();
rStm.SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
rStm >> nTemp16;
// OS/2-BitmapArray
if ( nTemp16 == 0x4142 )
{
rStm.SeekRel( 0x0c );
rStm >> nTemp16;
}
// Bitmap
if ( nTemp16 == 0x4d42 )
{
nFormat = GFF_BMP;
bRet = sal_True;
if ( bExtendedInfo )
{
sal_uInt32 nTemp32;
sal_uInt32 nCompression;
// bis zur ersten Information
rStm.SeekRel( 0x10 );
// PixelBreite auslesen
rStm >> nTemp32;
aPixSize.Width() = nTemp32;
// PixelHoehe auslesen
rStm >> nTemp32;
aPixSize.Height() = nTemp32;
// Planes auslesen
rStm >> nTemp16;
nPlanes = nTemp16;
// BitCount auslesen
rStm >> nTemp16;
nBitsPerPixel = nTemp16;
// Compression auslesen
rStm >> nTemp32;
bCompressed = ( ( nCompression = nTemp32 ) > 0 );
// logische Breite
rStm.SeekRel( 4 );
rStm >> nTemp32;
if ( nTemp32 )
aLogSize.Width() = ( aPixSize.Width() * 100000 ) / nTemp32;
// logische Hoehe
rStm >> nTemp32;
if ( nTemp32 )
aLogSize.Height() = ( aPixSize.Height() * 100000 ) / nTemp32;
// Wir wollen noch etwas feiner differenzieren und
// auf sinnvolle Werte ueberpruefen ( Bug-Id #29001 )
if ( ( nBitsPerPixel > 24 ) || ( nCompression > 3 ) )
{
nFormat = GFF_NOT;
bRet = sal_False;
}
}
}
rStm.Seek( nStmPos );
return bRet;
}
/*************************************************************************
|*
|*
|*
\************************************************************************/
sal_Bool GraphicDescriptor::ImpDetectGIF( SvStream& rStm, sal_Bool bExtendedInfo )
{
sal_uInt32 n32;
sal_uInt16 n16;
sal_Bool bRet = sal_False;
sal_uInt8 cByte;
sal_Int32 nStmPos = rStm.Tell();
rStm.SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
rStm >> n32;
if ( n32 == 0x38464947 )
{
rStm >> n16;
if ( ( n16 == 0x6137 ) || ( n16 == 0x6139 ) )
{
nFormat = GFF_GIF;
bRet = sal_True;
if ( bExtendedInfo )
{
sal_uInt16 nTemp16;
// PixelBreite auslesen
rStm >> nTemp16;
aPixSize.Width() = nTemp16;
// PixelHoehe auslesen
rStm >> nTemp16;
aPixSize.Height() = nTemp16;
// Bits/Pixel auslesen
rStm >> cByte;
nBitsPerPixel = ( ( cByte & 112 ) >> 4 ) + 1;
}
}
}
rStm.Seek( nStmPos );
return bRet;
}
/*************************************************************************
|*
|*
|*
\************************************************************************/
// returns the next jpeg marker, a return value of 0 represents an error
sal_uInt8 ImpDetectJPG_GetNextMarker( SvStream& rStm )
{
sal_uInt8 nByte;
do
{
do
{
rStm >> nByte;
if ( rStm.IsEof() || rStm.GetError() ) // as 0 is not allowed as marker,
return 0; // we can use it as errorcode
}
while ( nByte != 0xff );
do
{
rStm >> nByte;
if ( rStm.IsEof() || rStm.GetError() )
return 0;
}
while( nByte == 0xff );
}
while( nByte == 0 ); // 0xff00 represents 0xff and not a marker,
// the marker detection has to be restartet.
return nByte;
}
sal_Bool GraphicDescriptor::ImpDetectJPG( SvStream& rStm, sal_Bool bExtendedInfo )
{
sal_uInt32 nTemp32;
sal_Bool bRet = sal_False;
sal_Int32 nStmPos = rStm.Tell();
rStm.SetNumberFormatInt( NUMBERFORMAT_INT_BIGENDIAN );
rStm >> nTemp32;
// compare upper 24 bits
if( 0xffd8ff00 == ( nTemp32 & 0xffffff00 ) )
{
nFormat = GFF_JPG;
bRet = sal_True;
if ( bExtendedInfo )
{
rStm.SeekRel( -2 );
sal_uInt32 nError( rStm.GetError() );
sal_Bool bScanFailure = sal_False;
sal_Bool bScanFinished = sal_False;
while( !bScanFailure && !bScanFinished && !rStm.IsEof() && !rStm.GetError() )
{
sal_uInt8 nMarker = ImpDetectJPG_GetNextMarker( rStm );
switch( nMarker )
{
// fixed size marker, not having a two byte length parameter
case 0xd0 : // RST0
case 0xd1 :
case 0xd2 :
case 0xd3 :
case 0xd4 :
case 0xd5 :
case 0xd6 :
case 0xd7 : // RST7
case 0x01 : // TEM
break;
case 0xd8 : // SOI (has already been checked, there should not be a second one)
case 0x00 : // marker is invalid, we should stop now
bScanFailure = sal_True;
break;
case 0xd9 : // EOI
bScanFinished = sal_True;
break;
// per default we assume marker segments conaining a length parameter
default :
{
sal_uInt16 nLength;
rStm >> nLength;
if ( nLength < 2 )
bScanFailure = sal_True;
else
{
sal_uInt32 nNextMarkerPos = rStm.Tell() + nLength - 2;
switch( nMarker )
{
case 0xe0 : // APP0 Marker
{
if ( nLength == 16 )
{
sal_Int32 nIdentifier;
rStm >> nIdentifier;
if ( nIdentifier == 0x4a464946 ) // JFIF Identifier
{
sal_uInt8 nStringTerminator;
sal_uInt8 nMajorRevision;
sal_uInt8 nMinorRevision;
sal_uInt8 nUnits;
sal_uInt16 nHorizontalResolution;
sal_uInt16 nVerticalResolution;
sal_uInt8 nHorzThumbnailPixelCount;
sal_uInt8 nVertThumbnailPixelCount;
rStm >> nStringTerminator
>> nMajorRevision
>> nMinorRevision
>> nUnits
>> nHorizontalResolution
>> nVerticalResolution
>> nHorzThumbnailPixelCount
>> nVertThumbnailPixelCount;
// setting the logical size
if ( nUnits && nHorizontalResolution && nVerticalResolution )
{
MapMode aMap;
aMap.SetMapUnit( nUnits == 1 ? MAP_INCH : MAP_CM );
aMap.SetScaleX( Fraction( 1, nHorizontalResolution ) );
aMap.SetScaleY( Fraction( 1, nVerticalResolution ) );
aLogSize = OutputDevice::LogicToLogic( aPixSize, aMap, MapMode( MAP_100TH_MM ) );
}
}
}
}
break;
// Start of Frame Markers
case 0xc0 : // SOF0
case 0xc1 : // SOF1
case 0xc2 : // SOF2
case 0xc3 : // SOF3
case 0xc5 : // SOF5
case 0xc6 : // SOF6
case 0xc7 : // SOF7
case 0xc9 : // SOF9
case 0xca : // SOF10
case 0xcb : // SOF11
case 0xcd : // SOF13
case 0xce : // SOF14
case 0xcf : // SOF15
{
sal_uInt8 nSamplePrecision;
sal_uInt16 nNumberOfLines;
sal_uInt16 nSamplesPerLine;
sal_uInt8 nNumberOfImageComponents;
sal_uInt8 nComponentsIdentifier;
sal_uInt8 nHorizontalSamplingFactor;
sal_uInt8 nVerticalSamplingFactor;
sal_uInt8 nQuantizationTableDestinationSelector;
rStm >> nSamplePrecision
>> nNumberOfLines
>> nSamplesPerLine
>> nNumberOfImageComponents
>> nComponentsIdentifier
>> nHorizontalSamplingFactor
>> nQuantizationTableDestinationSelector;
nVerticalSamplingFactor = nHorizontalSamplingFactor & 0xf;
nHorizontalSamplingFactor >>= 4;
aPixSize.Height() = nNumberOfLines;
aPixSize.Width() = nSamplesPerLine;
nBitsPerPixel = ( nNumberOfImageComponents == 3 ? 24 : nNumberOfImageComponents == 1 ? 8 : 0 );
nPlanes = 1;
bScanFinished = sal_True;
}
break;
}
rStm.Seek( nNextMarkerPos );
}
}
break;
}
}
rStm.SetError( nError );
}
}
rStm.Seek( nStmPos );
return bRet;
}
/*************************************************************************
|*
|*
|*
\************************************************************************/
sal_Bool GraphicDescriptor::ImpDetectPCD( SvStream& rStm, sal_Bool )
{
sal_Bool bRet = sal_False;
sal_Int32 nStmPos = rStm.Tell();
rStm.SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
sal_uInt32 nTemp32;
sal_uInt16 nTemp16;
sal_uInt8 cByte;
rStm.SeekRel( 2048 );
rStm >> nTemp32;
rStm >> nTemp16;
rStm >> cByte;
if ( ( nTemp32 == 0x5f444350 ) &&
( nTemp16 == 0x5049 ) &&
( cByte == 0x49 ) )
{
nFormat = GFF_PCD;
bRet = sal_True;
}
rStm.Seek( nStmPos );
return bRet;
}
/*************************************************************************
|*
|*
|*
\************************************************************************/
sal_Bool GraphicDescriptor::ImpDetectPCX( SvStream& rStm, sal_Bool bExtendedInfo )
{
// ! Because 0x0a can be interpreted as LF too ...
// we cant be shure that this special sign represent a PCX file only.
// Every Ascii file is possible here :-(
// We must detect the whole header.
bExtendedInfo = sal_True;
sal_Bool bRet = sal_False;
sal_uInt8 cByte;
sal_Int32 nStmPos = rStm.Tell();
rStm.SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
rStm >> cByte;
if ( cByte == 0x0a )
{
nFormat = GFF_PCX;
bRet = sal_True;
if ( bExtendedInfo )
{
sal_uInt16 nTemp16;
sal_uInt16 nXmin;
sal_uInt16 nXmax;
sal_uInt16 nYmin;
sal_uInt16 nYmax;
sal_uInt16 nDPIx;
sal_uInt16 nDPIy;
rStm.SeekRel( 1 );
// Kompression lesen
rStm >> cByte;
bCompressed = ( cByte > 0 );
bRet = (cByte==0 || cByte ==1);
// Bits/Pixel lesen
rStm >> cByte;
nBitsPerPixel = cByte;
// Bildabmessungen
rStm >> nTemp16;
nXmin = nTemp16;
rStm >> nTemp16;
nYmin = nTemp16;
rStm >> nTemp16;
nXmax = nTemp16;
rStm >> nTemp16;
nYmax = nTemp16;
aPixSize.Width() = nXmax - nXmin + 1;
aPixSize.Height() = nYmax - nYmin + 1;
// Aufloesung
rStm >> nTemp16;
nDPIx = nTemp16;
rStm >> nTemp16;
nDPIy = nTemp16;
// logische Groesse setzen
MapMode aMap( MAP_INCH, Point(),
Fraction( 1, nDPIx ), Fraction( 1, nDPIy ) );
aLogSize = OutputDevice::LogicToLogic( aPixSize, aMap,
MapMode( MAP_100TH_MM ) );
// Anzahl Farbebenen
rStm.SeekRel( 49 );
rStm >> cByte;
nPlanes = cByte;
bRet = (nPlanes<=4);
}
}
rStm.Seek( nStmPos );
return bRet;
}
/*************************************************************************
|*
|*
|*
\************************************************************************/
sal_Bool GraphicDescriptor::ImpDetectPNG( SvStream& rStm, sal_Bool bExtendedInfo )
{
sal_uInt32 nTemp32;
sal_Bool bRet = sal_False;
sal_Int32 nStmPos = rStm.Tell();
rStm.SetNumberFormatInt( NUMBERFORMAT_INT_BIGENDIAN );
rStm >> nTemp32;
if ( nTemp32 == 0x89504e47 )
{
rStm >> nTemp32;
if ( nTemp32 == 0x0d0a1a0a )
{
nFormat = GFF_PNG;
bRet = sal_True;
if ( bExtendedInfo )
{
sal_uInt8 cByte;
// IHDR-Chunk
rStm.SeekRel( 8 );
// Breite einlesen
rStm >> nTemp32;
aPixSize.Width() = nTemp32;
// Hoehe einlesen
rStm >> nTemp32;
aPixSize.Height() = nTemp32;
// Bits/Pixel einlesen
rStm >> cByte;
nBitsPerPixel = cByte;
// Planes immer 1;
// Kompression immer
nPlanes = 1;
bCompressed = sal_True;
sal_uInt32 nLen32;
rStm.SeekRel( 8 );
// so lange ueberlesen, bis wir den pHYs-Chunk haben oder
// den Anfang der Bilddaten
rStm >> nLen32;
rStm >> nTemp32;
while( ( nTemp32 != 0x70485973 ) && ( nTemp32 != 0x49444154 ) )
{
rStm.SeekRel( 4 + nLen32 );
rStm >> nLen32;
rStm >> nTemp32;
}
if ( nTemp32 == 0x70485973 )
{
sal_uLong nXRes;
sal_uLong nYRes;
// horizontale Aufloesung
rStm >> nTemp32;
nXRes = nTemp32;
// vertikale Aufloesung
rStm >> nTemp32;
nYRes = nTemp32;
// Unit einlesen
rStm >> cByte;
if ( cByte )
{
if ( nXRes )
aLogSize.Width() = ( aPixSize.Width() * 100000 ) /
nTemp32;
if ( nYRes )
aLogSize.Height() = ( aPixSize.Height() * 100000 ) /
nTemp32;
}
}
}
}
}
rStm.Seek( nStmPos );
return bRet;
}
/*************************************************************************
|*
|*
|*
\************************************************************************/
sal_Bool GraphicDescriptor::ImpDetectTIF( SvStream& rStm, sal_Bool bExtendedInfo )
{
sal_Bool bDetectOk = sal_False;
sal_Bool bRet = sal_False;
sal_uInt8 cByte1;
sal_uInt8 cByte2;
sal_Int32 nStmPos = rStm.Tell();
rStm >> cByte1;
rStm >> cByte2;
if ( cByte1 == cByte2 )
{
if ( cByte1 == 0x49 )
{
rStm.SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
bDetectOk = sal_True;
}
else if ( cByte1 == 0x4d )
{
rStm.SetNumberFormatInt( NUMBERFORMAT_INT_BIGENDIAN );
bDetectOk = sal_True;
}
if ( bDetectOk )
{
sal_uInt16 nTemp16;
rStm >> nTemp16;
if ( nTemp16 == 0x2a )
{
nFormat = GFF_TIF;
bRet = sal_True;
if ( bExtendedInfo )
{
sal_uLong nCount;
sal_uLong nMax = DATA_SIZE - 48;
sal_uInt32 nTemp32;
sal_Bool bOk = sal_False;
// Offset des ersten IFD einlesen
rStm >> nTemp32;
rStm.SeekRel( ( nCount = ( nTemp32 + 2 ) ) - 0x08 );
if ( nCount < nMax )
{
// Tag's lesen, bis wir auf Tag256 ( Width ) treffen
// nicht mehr Bytes als DATA_SIZE lesen
rStm >> nTemp16;
while ( nTemp16 != 256 )
{
bOk = nCount < nMax;
if ( !bOk )
{
break;
}
rStm.SeekRel( 10 );
rStm >> nTemp16;
nCount += 12;
}
if ( bOk )
{
// Breite lesen
rStm >> nTemp16;
rStm.SeekRel( 4 );
if ( nTemp16 == 3 )
{
rStm >> nTemp16;
aPixSize.Width() = nTemp16;
rStm.SeekRel( 2 );
}
else
{
rStm >> nTemp32;
aPixSize.Width() = nTemp32;
}
nCount += 12;
// Hoehe lesen
rStm.SeekRel( 2 );
rStm >> nTemp16;
rStm.SeekRel( 4 );
if ( nTemp16 == 3 )
{
rStm >> nTemp16;
aPixSize.Height() = nTemp16;
rStm.SeekRel( 2 );
}
else
{
rStm >> nTemp32;
aPixSize.Height() = nTemp32;
}
nCount += 12;
// ggf. Bits/Pixel lesen
rStm >> nTemp16;
if ( nTemp16 == 258 )
{
rStm.SeekRel( 6 );
rStm >> nTemp16;
nBitsPerPixel = nTemp16;
rStm.SeekRel( 2 );
nCount += 12;
}
else
rStm.SeekRel( -2 );
// ggf. Compression lesen
rStm >> nTemp16;
if ( nTemp16 == 259 )
{
rStm.SeekRel( 6 );
rStm >> nTemp16;
bCompressed = ( nTemp16 > 1 );
rStm.SeekRel( 2 );
nCount += 12;
}
else
rStm.SeekRel( -2 );
}
}
}
}
}
}
rStm.Seek( nStmPos );
return bRet;
}
/*************************************************************************
|*
|*
|*
\************************************************************************/
sal_Bool GraphicDescriptor::ImpDetectXBM( SvStream&, sal_Bool )
{
sal_Bool bRet = aPathExt.CompareToAscii( "xbm", 3 ) == COMPARE_EQUAL;
if (bRet)
nFormat = GFF_XBM;
return bRet;
}
/*************************************************************************
|*
|*
|*
\************************************************************************/
sal_Bool GraphicDescriptor::ImpDetectXPM( SvStream&, sal_Bool )
{
sal_Bool bRet = aPathExt.CompareToAscii( "xpm", 3 ) == COMPARE_EQUAL;
if (bRet)
nFormat = GFF_XPM;
return bRet;
}
/*************************************************************************
|*
|*
|*
\************************************************************************/
sal_Bool GraphicDescriptor::ImpDetectPBM( SvStream& rStm, sal_Bool )
{
sal_Bool bRet = sal_False;
// erst auf Datei Extension pruefen, da diese aussagekraeftiger ist
// als die 2 ID Bytes
if ( aPathExt.CompareToAscii( "pbm", 3 ) == COMPARE_EQUAL )
bRet = sal_True;
else
{
sal_Int32 nStmPos = rStm.Tell();
sal_uInt8 nFirst, nSecond;
rStm >> nFirst >> nSecond;
if ( nFirst == 'P' && ( ( nSecond == '1' ) || ( nSecond == '4' ) ) )
bRet = sal_True;
rStm.Seek( nStmPos );
}
if ( bRet )
nFormat = GFF_PBM;
return bRet;
}
/*************************************************************************
|*
|*
|*
\************************************************************************/
sal_Bool GraphicDescriptor::ImpDetectPGM( SvStream& rStm, sal_Bool )
{
sal_Bool bRet = sal_False;
if ( aPathExt.CompareToAscii( "pgm", 3 ) == COMPARE_EQUAL )
bRet = sal_True;
else
{
sal_uInt8 nFirst, nSecond;
sal_Int32 nStmPos = rStm.Tell();
rStm >> nFirst >> nSecond;
if ( nFirst == 'P' && ( ( nSecond == '2' ) || ( nSecond == '5' ) ) )
bRet = sal_True;
rStm.Seek( nStmPos );
}
if ( bRet )
nFormat = GFF_PGM;
return bRet;
}
/*************************************************************************
|*
|*
|*
\************************************************************************/
sal_Bool GraphicDescriptor::ImpDetectPPM( SvStream& rStm, sal_Bool )
{
sal_Bool bRet = sal_False;
if ( aPathExt.CompareToAscii( "ppm", 3 ) == COMPARE_EQUAL )
bRet = sal_True;
else
{
sal_uInt8 nFirst, nSecond;
sal_Int32 nStmPos = rStm.Tell();
rStm >> nFirst >> nSecond;
if ( nFirst == 'P' && ( ( nSecond == '3' ) || ( nSecond == '6' ) ) )
bRet = sal_True;
rStm.Seek( nStmPos );
}
if ( bRet )
nFormat = GFF_PPM;
return bRet;
}
/*************************************************************************
|*
|*
|*
\************************************************************************/
sal_Bool GraphicDescriptor::ImpDetectRAS( SvStream& rStm, sal_Bool )
{
sal_uInt32 nMagicNumber;
sal_Bool bRet = sal_False;
sal_Int32 nStmPos = rStm.Tell();
rStm.SetNumberFormatInt( NUMBERFORMAT_INT_BIGENDIAN );
rStm >> nMagicNumber;
if ( nMagicNumber == 0x59a66a95 )
{
nFormat = GFF_RAS;
bRet = sal_True;
}
rStm.Seek( nStmPos );
return bRet;
}
/*************************************************************************
|*
|*
|*
\************************************************************************/
sal_Bool GraphicDescriptor::ImpDetectTGA( SvStream&, sal_Bool )
{
sal_Bool bRet = aPathExt.CompareToAscii( "tga", 3 ) == COMPARE_EQUAL;
if (bRet)
nFormat = GFF_TGA;
return bRet;
}
/*************************************************************************
|*
|*
|*
\************************************************************************/
sal_Bool GraphicDescriptor::ImpDetectPSD( SvStream& rStm, sal_Bool bExtendedInfo )
{
sal_Bool bRet = sal_False;
sal_uInt32 nMagicNumber;
sal_Int32 nStmPos = rStm.Tell();
rStm.SetNumberFormatInt( NUMBERFORMAT_INT_BIGENDIAN );
rStm >> nMagicNumber;
if ( nMagicNumber == 0x38425053 )
{
sal_uInt16 nVersion;
rStm >> nVersion;
if ( nVersion == 1 )
{
bRet = sal_True;
if ( bExtendedInfo )
{
sal_uInt16 nChannels;
sal_uInt32 nRows;
sal_uInt32 nColumns;
sal_uInt16 nDepth;
sal_uInt16 nMode;
rStm.SeekRel( 6 ); // Pad
rStm >> nChannels >> nRows >> nColumns >> nDepth >> nMode;
if ( ( nDepth == 1 ) || ( nDepth == 8 ) || ( nDepth == 16 ) )
{
nBitsPerPixel = ( nDepth == 16 ) ? 8 : nDepth;
switch ( nChannels )
{
case 4 :
case 3 :
nBitsPerPixel = 24;
case 2 :
case 1 :
aPixSize.Width() = nColumns;
aPixSize.Height() = nRows;
break;
default:
bRet = sal_False;
}
}
else
bRet = sal_False;
}
}
}
if ( bRet )
nFormat = GFF_PSD;
rStm.Seek( nStmPos );
return bRet;
}
/*************************************************************************
|*
|*
|*
\************************************************************************/
sal_Bool GraphicDescriptor::ImpDetectEPS( SvStream& rStm, sal_Bool )
{
// es wird die EPS mit Vorschaubild Variante und die Extensionuebereinstimmung
// geprueft
sal_uInt32 nFirstLong;
sal_uInt8 nFirstBytes[20];
sal_Bool bRet = sal_False;
sal_Int32 nStmPos = rStm.Tell();
rStm.SetNumberFormatInt( NUMBERFORMAT_INT_BIGENDIAN );
rStm >> nFirstLong;
rStm.SeekRel( -4 );
rStm.Read( &nFirstBytes, 20 );
if ( ( nFirstLong == 0xC5D0D3C6 ) || ( aPathExt.CompareToAscii( "eps", 3 ) == COMPARE_EQUAL ) ||
( ImplSearchEntry( nFirstBytes, (sal_uInt8*)"%!PS-Adobe", 10, 10 )
&& ImplSearchEntry( &nFirstBytes[15], (sal_uInt8*)"EPS", 3, 3 ) ) )
{
nFormat = GFF_EPS;
bRet = sal_True;
}
rStm.Seek( nStmPos );
return bRet;
}
/*************************************************************************
|*
|*
|*
\************************************************************************/
sal_Bool GraphicDescriptor::ImpDetectDXF( SvStream&, sal_Bool )
{
sal_Bool bRet = aPathExt.CompareToAscii( "dxf", 3 ) == COMPARE_EQUAL;
if (bRet)
nFormat = GFF_DXF;
return bRet;
}
/*************************************************************************
|*
|*
|*
\************************************************************************/
sal_Bool GraphicDescriptor::ImpDetectMET( SvStream&, sal_Bool )
{
sal_Bool bRet = aPathExt.CompareToAscii( "met", 3 ) == COMPARE_EQUAL;
if (bRet)
nFormat = GFF_MET;
return bRet;
}
/*************************************************************************
|*
|*
|*
\************************************************************************/
sal_Bool GraphicDescriptor::ImpDetectPCT( SvStream& rStm, sal_Bool )
{
sal_Bool bRet = aPathExt.CompareToAscii( "pct", 3 ) == COMPARE_EQUAL;
if (bRet)
nFormat = GFF_PCT;
else
{
sal_Int32 nStmPos = rStm.Tell();
sal_uInt8 sBuf[4];
rStm.SeekRel( 522 );
rStm.Read( sBuf, 3 );
if( !rStm.GetError() )
{
if ( ( sBuf[0] == 0x00 ) && ( sBuf[1] == 0x11 ) &&
( ( sBuf[2] == 0x01 ) || ( sBuf[2] == 0x02 ) ) )
{
bRet = sal_True;
nFormat = GFF_PCT;
}
}
rStm.Seek( nStmPos );
}
return bRet;
}
/*************************************************************************
|*
|*
|*
\************************************************************************/
sal_Bool GraphicDescriptor::ImpDetectSGF( SvStream& rStm, sal_Bool )
{
sal_Bool bRet = sal_False;
if( aPathExt.CompareToAscii( "sgf", 3 ) == COMPARE_EQUAL )
bRet = sal_True;
else
{
sal_Int32 nStmPos = rStm.Tell();
sal_uInt8 nFirst, nSecond;
rStm >> nFirst >> nSecond;
if( nFirst == 'J' && nSecond == 'J' )
bRet = sal_True;
rStm.Seek( nStmPos );
}
if( bRet )
nFormat = GFF_SGF;
return bRet;
}
/*************************************************************************
|*
|*
|*
\************************************************************************/
sal_Bool GraphicDescriptor::ImpDetectSGV( SvStream&, sal_Bool )
{
sal_Bool bRet = aPathExt.CompareToAscii( "sgv", 3 ) == COMPARE_EQUAL;
if (bRet)
nFormat = GFF_SGV;
return bRet;
}
/*************************************************************************
|*
|*
|*
\************************************************************************/
sal_Bool GraphicDescriptor::ImpDetectSVM( SvStream& rStm, sal_Bool bExtendedInfo )
{
sal_uInt32 n32;
sal_Bool bRet = sal_False;
sal_uInt8 cByte;
sal_Int32 nStmPos = rStm.Tell();
rStm.SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
rStm >> n32;
if ( n32 == 0x44475653 )
{
rStm >> cByte;
if ( cByte == 0x49 )
{
nFormat = GFF_SVM;
bRet = sal_True;
if ( bExtendedInfo )
{
sal_uInt32 nTemp32;
sal_uInt16 nTemp16;
rStm.SeekRel( 0x04 );
// Breite auslesen
rStm >> nTemp32;
aLogSize.Width() = nTemp32;
// Hoehe auslesen
rStm >> nTemp32;
aLogSize.Height() = nTemp32;
// Map-Unit auslesen und PrefSize ermitteln
rStm >> nTemp16;
aLogSize = OutputDevice::LogicToLogic( aLogSize,
MapMode( (MapUnit) nTemp16 ),
MapMode( MAP_100TH_MM ) );
}
}
}
else
{
rStm.SeekRel( -4L );
rStm >> n32;
if( n32 == 0x4D4C4356 )
{
sal_uInt16 nTmp16;
rStm >> nTmp16;
if( nTmp16 == 0x4654 )
{
nFormat = GFF_SVM;
bRet = sal_True;
if( bExtendedInfo )
{
MapMode aMapMode;
rStm.SeekRel( 0x06 );
rStm >> aMapMode;
rStm >> aLogSize;
aLogSize = OutputDevice::LogicToLogic( aLogSize, aMapMode, MapMode( MAP_100TH_MM ) );
}
}
}
}
rStm.Seek( nStmPos );
return bRet;
}
/*************************************************************************
|*
|*
|*
\************************************************************************/
sal_Bool GraphicDescriptor::ImpDetectWMF( SvStream&, sal_Bool )
{
sal_Bool bRet = aPathExt.CompareToAscii( "wmf",3 ) == COMPARE_EQUAL;
if (bRet)
nFormat = GFF_WMF;
return bRet;
}
/*************************************************************************
|*
|*
|*
\************************************************************************/
sal_Bool GraphicDescriptor::ImpDetectEMF( SvStream&, sal_Bool )
{
sal_Bool bRet = aPathExt.CompareToAscii( "emf", 3 ) == COMPARE_EQUAL;
if (bRet)
nFormat = GFF_EMF;
return bRet;
}
/*************************************************************************
|*
|*
|*
\************************************************************************/
sal_Bool GraphicDescriptor::ImpDetectSVG( SvStream& /*rStm*/, sal_Bool /*bExtendedInfo*/ )
{
sal_Bool bRet = aPathExt.CompareToAscii( "svg", 3 ) == COMPARE_EQUAL;
if (bRet)
nFormat = GFF_SVG;
return bRet;
}
/*************************************************************************
|*
|*
|*
\************************************************************************/
String GraphicDescriptor::GetImportFormatShortName( sal_uInt16 nFormat )
{
ByteString aKeyName;
switch( nFormat )
{
case( GFF_BMP ) : aKeyName = "bmp"; break;
case( GFF_GIF ) : aKeyName = "gif"; break;
case( GFF_JPG ) : aKeyName = "jpg"; break;
case( GFF_PCD ) : aKeyName = "pcd"; break;
case( GFF_PCX ) : aKeyName = "pcx"; break;
case( GFF_PNG ) : aKeyName = "png"; break;
case( GFF_XBM ) : aKeyName = "xbm"; break;
case( GFF_XPM ) : aKeyName = "xpm"; break;
case( GFF_PBM ) : aKeyName = "pbm"; break;
case( GFF_PGM ) : aKeyName = "pgm"; break;
case( GFF_PPM ) : aKeyName = "ppm"; break;
case( GFF_RAS ) : aKeyName = "ras"; break;
case( GFF_TGA ) : aKeyName = "tga"; break;
case( GFF_PSD ) : aKeyName = "psd"; break;
case( GFF_EPS ) : aKeyName = "eps"; break;
case( GFF_TIF ) : aKeyName = "tif"; break;
case( GFF_DXF ) : aKeyName = "dxf"; break;
case( GFF_MET ) : aKeyName = "met"; break;
case( GFF_PCT ) : aKeyName = "pct"; break;
case( GFF_SGF ) : aKeyName = "sgf"; break;
case( GFF_SGV ) : aKeyName = "sgv"; break;
case( GFF_SVM ) : aKeyName = "svm"; break;
case( GFF_WMF ) : aKeyName = "wmf"; break;
case( GFF_EMF ) : aKeyName = "emf"; break;
case( GFF_SVG ) : aKeyName = "svg"; break;
}
return String( aKeyName, RTL_TEXTENCODING_ASCII_US );
}