/* -*- 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. * ************************************************************************/ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_svtools.hxx" #include #include #include #include #include #include #include #include "FilterConfigCache.hxx" #include #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 nQuantizationTableDestinationSelector; rStm >> nSamplePrecision >> nNumberOfLines >> nSamplesPerLine >> nNumberOfImageComponents >> nComponentsIdentifier >> nHorizontalSamplingFactor >> nQuantizationTableDestinationSelector; 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 ); } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */