1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
21 #include <tools/stream.hxx>
22 #include <tools/fract.hxx>
23 #include <tools/urlobj.hxx>
24 #include <vcl/TypeSerializer.hxx>
25 #include <vcl/outdev.hxx>
26 #include <vcl/graphicfilter.hxx>
27 #include <unotools/ucbstreamhelper.hxx>
28 #include "graphicfilter_internal.hxx"
32 GraphicDescriptor::GraphicDescriptor( const INetURLObject
& rPath
) :
33 pFileStm( ::utl::UcbStreamHelper::CreateStream( rPath
.GetMainURL( INetURLObject::DecodeMechanism::NONE
), StreamMode::READ
).release() ),
34 aPathExt( rPath
.GetFileExtension().toAsciiLowerCase() ),
40 GraphicDescriptor::GraphicDescriptor( SvStream
& rInStream
, const OUString
* pPath
) :
41 pFileStm ( &rInStream
),
48 INetURLObject
aURL( *pPath
);
49 aPathExt
= aURL
.GetFileExtension().toAsciiLowerCase();
53 GraphicDescriptor::~GraphicDescriptor()
59 bool GraphicDescriptor::Detect( bool bExtendedInfo
)
62 if ( pFileStm
&& !pFileStm
->GetError() )
64 SvStream
& rStm
= *pFileStm
;
65 SvStreamEndian nOldFormat
= rStm
.GetEndian();
67 if ( ImpDetectGIF( rStm
, bExtendedInfo
) ) bRet
= true;
68 else if ( ImpDetectJPG( rStm
, bExtendedInfo
) ) bRet
= true;
69 else if ( ImpDetectBMP( rStm
, bExtendedInfo
) ) bRet
= true;
70 else if ( ImpDetectPNG( rStm
, bExtendedInfo
) ) bRet
= true;
71 else if ( ImpDetectTIF( rStm
, bExtendedInfo
) ) bRet
= true;
72 else if ( ImpDetectPCX( rStm
) ) bRet
= true;
73 else if ( ImpDetectDXF( rStm
, bExtendedInfo
) ) bRet
= true;
74 else if ( ImpDetectMET( rStm
, bExtendedInfo
) ) bRet
= true;
75 else if ( ImpDetectSVM( rStm
, bExtendedInfo
) ) bRet
= true;
76 else if ( ImpDetectWMF( rStm
, bExtendedInfo
) ) bRet
= true;
77 else if ( ImpDetectEMF( rStm
, bExtendedInfo
) ) bRet
= true;
78 else if ( ImpDetectSVG( rStm
, bExtendedInfo
) ) bRet
= true;
79 else if ( ImpDetectPCT( rStm
, bExtendedInfo
) ) bRet
= true;
80 else if ( ImpDetectXBM( rStm
, bExtendedInfo
) ) bRet
= true;
81 else if ( ImpDetectXPM( rStm
, bExtendedInfo
) ) bRet
= true;
82 else if ( ImpDetectPBM( rStm
, bExtendedInfo
) ) bRet
= true;
83 else if ( ImpDetectPGM( rStm
, bExtendedInfo
) ) bRet
= true;
84 else if ( ImpDetectPPM( rStm
, bExtendedInfo
) ) bRet
= true;
85 else if ( ImpDetectRAS( rStm
, bExtendedInfo
) ) bRet
= true;
86 else if ( ImpDetectTGA( rStm
, bExtendedInfo
) ) bRet
= true;
87 else if ( ImpDetectPSD( rStm
, bExtendedInfo
) ) bRet
= true;
88 else if ( ImpDetectEPS( rStm
, bExtendedInfo
) ) bRet
= true;
89 else if ( ImpDetectPCD( rStm
, bExtendedInfo
) ) bRet
= true;
91 rStm
.SetEndian( nOldFormat
);
96 void GraphicDescriptor::ImpConstruct()
98 nFormat
= GraphicFileFormat::NOT
;
101 mnNumberOfImageComponents
= 0;
102 bIsTransparent
= false;
106 bool GraphicDescriptor::ImpDetectBMP( SvStream
& rStm
, bool bExtendedInfo
)
108 sal_uInt16 nTemp16
= 0;
110 sal_Int32 nStmPos
= rStm
.Tell();
112 rStm
.SetEndian( SvStreamEndian::LITTLE
);
113 rStm
.ReadUInt16( nTemp16
);
116 if ( nTemp16
== 0x4142 )
118 rStm
.SeekRel( 0x0c );
119 rStm
.ReadUInt16( nTemp16
);
123 if ( nTemp16
== 0x4d42 )
125 nFormat
= GraphicFileFormat::BMP
;
131 sal_uInt32 nCompression
;
134 rStm
.SeekRel( 0x10 );
137 rStm
.ReadUInt32( nTemp32
);
138 aPixSize
.setWidth( nTemp32
);
141 rStm
.ReadUInt32( nTemp32
);
142 aPixSize
.setHeight( nTemp32
);
145 rStm
.ReadUInt16( nTemp16
);
149 rStm
.ReadUInt16( nTemp16
);
150 nBitsPerPixel
= nTemp16
;
153 rStm
.ReadUInt32( nTemp32
);
154 nCompression
= nTemp32
;
158 rStm
.ReadUInt32( nTemp32
);
159 sal_uInt32 nXPelsPerMeter
= 0;
162 aLogSize
.setWidth( ( aPixSize
.Width() * 100000 ) / nTemp32
);
163 nXPelsPerMeter
= nTemp32
;
167 rStm
.ReadUInt32( nTemp32
);
168 sal_uInt32 nYPelsPerMeter
= 0;
171 aLogSize
.setHeight( ( aPixSize
.Height() * 100000 ) / nTemp32
);
172 nYPelsPerMeter
= nTemp32
;
175 // further validation, check for rational values
176 if ( ( nBitsPerPixel
> 24 ) || ( nCompression
> 3 ) )
178 nFormat
= GraphicFileFormat::NOT
;
182 if (bRet
&& nXPelsPerMeter
&& nYPelsPerMeter
)
185 = MapMode(MapUnit::MapMM
, Point(), Fraction(1000, nXPelsPerMeter
),
186 Fraction(1000, nYPelsPerMeter
));
188 maPreferredLogSize
= Size(aPixSize
.getWidth(), aPixSize
.getHeight());
192 rStm
.Seek( nStmPos
);
196 bool GraphicDescriptor::ImpDetectGIF( SvStream
& rStm
, bool bExtendedInfo
)
201 sal_Int32 nStmPos
= rStm
.Tell();
202 rStm
.SetEndian( SvStreamEndian::LITTLE
);
203 rStm
.ReadUInt32( n32
);
205 if ( n32
== 0x38464947 )
208 rStm
.ReadUInt16( n16
);
209 if ( ( n16
== 0x6137 ) || ( n16
== 0x6139 ) )
211 nFormat
= GraphicFileFormat::GIF
;
216 sal_uInt16 nTemp16
= 0;
220 rStm
.ReadUInt16( nTemp16
);
221 aPixSize
.setWidth( nTemp16
);
224 rStm
.ReadUInt16( nTemp16
);
225 aPixSize
.setHeight( nTemp16
);
228 rStm
.ReadUChar( cByte
);
229 nBitsPerPixel
= ( ( cByte
& 112 ) >> 4 ) + 1;
233 rStm
.Seek( nStmPos
);
237 // returns the next jpeg marker, a return value of 0 represents an error
238 static sal_uInt8
ImpDetectJPG_GetNextMarker( SvStream
& rStm
)
245 rStm
.ReadUChar( nByte
);
246 if (!rStm
.good()) // as 0 is not allowed as marker,
247 return 0; // we can use it as errorcode
249 while ( nByte
!= 0xff );
252 rStm
.ReadUChar( nByte
);
256 while( nByte
== 0xff );
258 while( nByte
== 0 ); // 0xff00 represents 0xff and not a marker,
259 // the marker detection has to be restarted.
263 bool GraphicDescriptor::ImpDetectJPG( SvStream
& rStm
, bool bExtendedInfo
)
265 sal_uInt32 nTemp32
= 0;
268 sal_Int32 nStmPos
= rStm
.Tell();
270 rStm
.SetEndian( SvStreamEndian::BIG
);
271 rStm
.ReadUInt32( nTemp32
);
273 // compare upper 24 bits
274 if( 0xffd8ff00 == ( nTemp32
& 0xffffff00 ) )
276 nFormat
= GraphicFileFormat::JPG
;
283 ErrCode
nError( rStm
.GetError() );
285 bool bScanFailure
= false;
286 bool bScanFinished
= false;
289 while (!bScanFailure
&& !bScanFinished
&& rStm
.good())
291 sal_uInt8 nMarker
= ImpDetectJPG_GetNextMarker( rStm
);
294 // fixed size marker, not having a two byte length parameter
306 case 0xd8 : // SOI (has already been checked, there should not be a second one)
307 case 0x00 : // marker is invalid, we should stop now
312 bScanFinished
= true;
315 // per default we assume marker segments containing a length parameter
318 sal_uInt16 nLength
= 0;
319 rStm
.ReadUInt16( nLength
);
325 sal_uInt32 nNextMarkerPos
= rStm
.Tell() + nLength
- 2;
328 case 0xe0 : // APP0 Marker
332 sal_Int32 nIdentifier
= 0;
333 rStm
.ReadInt32( nIdentifier
);
334 if ( nIdentifier
== 0x4a464946 ) // JFIF Identifier
336 sal_uInt8 nStringTerminator
= 0;
337 sal_uInt8 nMajorRevision
= 0;
338 sal_uInt8 nMinorRevision
= 0;
339 sal_uInt8 nUnits
= 0;
340 sal_uInt16 nHorizontalResolution
= 0;
341 sal_uInt16 nVerticalResolution
= 0;
342 sal_uInt8 nHorzThumbnailPixelCount
= 0;
343 sal_uInt8 nVertThumbnailPixelCount
= 0;
345 rStm
.ReadUChar( nStringTerminator
)
346 .ReadUChar( nMajorRevision
)
347 .ReadUChar( nMinorRevision
)
349 .ReadUInt16( nHorizontalResolution
)
350 .ReadUInt16( nVerticalResolution
)
351 .ReadUChar( nHorzThumbnailPixelCount
)
352 .ReadUChar( nVertThumbnailPixelCount
);
354 // setting the logical size
355 if ( nUnits
&& nHorizontalResolution
&& nVerticalResolution
)
357 aMap
.SetMapUnit( nUnits
== 1 ? MapUnit::MapInch
: MapUnit::MapCM
);
358 aMap
.SetScaleX( Fraction( 1, nHorizontalResolution
) );
359 aMap
.SetScaleY( Fraction( 1, nVerticalResolution
) );
360 aLogSize
= OutputDevice::LogicToLogic( aPixSize
, aMap
, MapMode( MapUnit::Map100thMM
) );
367 // Start of Frame Markers
382 sal_uInt8 nSamplePrecision
= 0;
383 sal_uInt16 nNumberOfLines
= 0;
384 sal_uInt16 nSamplesPerLine
= 0;
385 sal_uInt8 nNumberOfImageComponents
= 0;
386 sal_uInt8 nComponentsIdentifier
= 0;
387 sal_uInt8 nSamplingFactor
= 0;
388 sal_uInt8 nQuantizationTableDestinationSelector
= 0;
389 rStm
.ReadUChar( nSamplePrecision
)
390 .ReadUInt16( nNumberOfLines
)
391 .ReadUInt16( nSamplesPerLine
)
392 .ReadUChar( nNumberOfImageComponents
)
393 .ReadUChar( nComponentsIdentifier
)
394 .ReadUChar( nSamplingFactor
)
395 .ReadUChar( nQuantizationTableDestinationSelector
);
396 mnNumberOfImageComponents
= nNumberOfImageComponents
;
398 // nSamplingFactor (lower nibble: vertical,
399 // upper nibble: horizontal) is unused
401 aPixSize
.setHeight( nNumberOfLines
);
402 aPixSize
.setWidth( nSamplesPerLine
);
403 nBitsPerPixel
= ( nNumberOfImageComponents
== 3 ? 24 : nNumberOfImageComponents
== 1 ? 8 : 0 );
406 if (aMap
.GetMapUnit() != MapUnit::MapPixel
)
407 // We already know the DPI, but the
408 // pixel size arrived later, so do the
410 aLogSize
= OutputDevice::LogicToLogic(
411 aPixSize
, aMap
, MapMode(MapUnit::Map100thMM
));
413 bScanFinished
= true;
417 rStm
.Seek( nNextMarkerPos
);
423 rStm
.SetError( nError
);
426 rStm
.Seek( nStmPos
);
430 bool GraphicDescriptor::ImpDetectPCD( SvStream
& rStm
, bool )
434 sal_Int32 nStmPos
= rStm
.Tell();
435 rStm
.SetEndian( SvStreamEndian::LITTLE
);
437 sal_uInt32 nTemp32
= 0;
438 sal_uInt16 nTemp16
= 0;
441 rStm
.SeekRel( 2048 );
442 rStm
.ReadUInt32( nTemp32
);
443 rStm
.ReadUInt16( nTemp16
);
444 rStm
.ReadUChar( cByte
);
446 if ( ( nTemp32
== 0x5f444350 ) &&
447 ( nTemp16
== 0x5049 ) &&
450 nFormat
= GraphicFileFormat::PCD
;
453 rStm
.Seek( nStmPos
);
457 bool GraphicDescriptor::ImpDetectPCX( SvStream
& rStm
)
459 // ! Because 0x0a can be interpreted as LF too ...
460 // we can't be sure that this special sign represent a PCX file only.
461 // Every Ascii file is possible here :-(
462 // We must detect the whole header.
467 sal_Int32 nStmPos
= rStm
.Tell();
468 rStm
.SetEndian( SvStreamEndian::LITTLE
);
469 rStm
.ReadUChar( cByte
);
473 nFormat
= GraphicFileFormat::PCX
;
478 rStm
.ReadUChar( cByte
);
480 bRet
= (cByte
==0 || cByte
==1);
492 rStm
.ReadUChar( cByte
);
493 nBitsPerPixel
= cByte
;
496 rStm
.ReadUInt16( nTemp16
);
498 rStm
.ReadUInt16( nTemp16
);
500 rStm
.ReadUInt16( nTemp16
);
502 rStm
.ReadUInt16( nTemp16
);
505 aPixSize
.setWidth( nXmax
- nXmin
+ 1 );
506 aPixSize
.setHeight( nYmax
- nYmin
+ 1 );
509 rStm
.ReadUInt16( nTemp16
);
511 rStm
.ReadUInt16( nTemp16
);
515 MapMode
aMap( MapUnit::MapInch
, Point(),
516 Fraction( 1, nDPIx
), Fraction( 1, nDPIy
) );
517 aLogSize
= OutputDevice::LogicToLogic( aPixSize
, aMap
,
518 MapMode( MapUnit::Map100thMM
) );
520 // number of color planes
521 cByte
= 5; // Illegal value in case of EOF.
523 rStm
.ReadUChar( cByte
);
530 rStm
.Seek( nStmPos
);
534 bool GraphicDescriptor::ImpDetectPNG( SvStream
& rStm
, bool bExtendedInfo
)
536 sal_uInt32 nTemp32
= 0;
539 sal_Int32 nStmPos
= rStm
.Tell();
540 rStm
.SetEndian( SvStreamEndian::BIG
);
541 rStm
.ReadUInt32( nTemp32
);
543 if ( nTemp32
== 0x89504e47 )
545 rStm
.ReadUInt32( nTemp32
);
546 if ( nTemp32
== 0x0d0a1a0a )
548 nFormat
= GraphicFileFormat::PNG
;
560 rStm
.ReadUInt32( nTemp32
);
563 aPixSize
.setWidth( nTemp32
);
566 rStm
.ReadUInt32( nTemp32
);
569 aPixSize
.setHeight( nTemp32
);
572 rStm
.ReadUChar( cByte
);
575 nBitsPerPixel
= cByte
;
577 // Colour type - check whether it supports alpha values
578 sal_uInt8 cColType
= 0;
579 rStm
.ReadUChar( cColType
);
582 bIsAlpha
= bIsTransparent
= ( cColType
== 4 || cColType
== 6 );
585 // compression always
588 sal_uInt32 nLen32
= 0;
593 // read up to the start of the image
594 rStm
.ReadUInt32( nLen32
);
595 rStm
.ReadUInt32( nTemp32
);
596 while( ( nTemp32
!= 0x49444154 ) && rStm
.good() )
598 if ( nTemp32
== 0x70485973 ) // physical pixel dimensions
603 // horizontal resolution
605 rStm
.ReadUInt32( nTemp32
);
608 // vertical resolution
610 rStm
.ReadUInt32( nTemp32
);
615 rStm
.ReadUChar( cByte
);
620 aLogSize
.setWidth( (aPixSize
.Width() * 100000) / nXRes
);
623 aLogSize
.setHeight( (aPixSize
.Height() * 100000) / nYRes
);
628 else if ( nTemp32
== 0x74524e53 ) // transparency
630 bIsTransparent
= true;
631 bIsAlpha
= ( cColType
!= 0 && cColType
!= 2 );
634 // skip forward to next chunk
635 rStm
.SeekRel( 4 + nLen32
);
636 rStm
.ReadUInt32( nLen32
);
637 rStm
.ReadUInt32( nTemp32
);
643 rStm
.Seek( nStmPos
);
647 bool GraphicDescriptor::ImpDetectTIF( SvStream
& rStm
, bool bExtendedInfo
)
650 sal_uInt8 cByte1
= 0;
651 sal_uInt8 cByte2
= 1;
653 sal_Int32 nStmPos
= rStm
.Tell();
654 rStm
.ReadUChar( cByte1
);
655 rStm
.ReadUChar( cByte2
);
656 if ( cByte1
== cByte2
)
658 bool bDetectOk
= false;
660 if ( cByte1
== 0x49 )
662 rStm
.SetEndian( SvStreamEndian::LITTLE
);
665 else if ( cByte1
== 0x4d )
667 rStm
.SetEndian( SvStreamEndian::BIG
);
673 sal_uInt16 nTemp16
= 0;
675 rStm
.ReadUInt16( nTemp16
);
676 if ( nTemp16
== 0x2a )
678 nFormat
= GraphicFileFormat::TIF
;
684 sal_uLong nMax
= DATA_SIZE
- 48;
685 sal_uInt32 nTemp32
= 0;
687 // Offset of the first IFD
688 rStm
.ReadUInt32( nTemp32
);
689 nCount
= nTemp32
+ 2;
690 rStm
.SeekRel( nCount
- 0x08 );
696 // read tags till we find Tag256 ( Width )
697 // do not read more bytes than DATA_SIZE
698 rStm
.ReadUInt16( nTemp16
);
699 while ( nTemp16
!= 256 )
707 rStm
.ReadUInt16( nTemp16
);
714 rStm
.ReadUInt16( nTemp16
);
718 rStm
.ReadUInt16( nTemp16
);
719 aPixSize
.setWidth( nTemp16
);
724 rStm
.ReadUInt32( nTemp32
);
725 aPixSize
.setWidth( nTemp32
);
730 rStm
.ReadUInt16( nTemp16
);
734 rStm
.ReadUInt16( nTemp16
);
735 aPixSize
.setHeight( nTemp16
);
740 rStm
.ReadUInt32( nTemp32
);
741 aPixSize
.setHeight( nTemp32
);
745 rStm
.ReadUInt16( nTemp16
);
746 if ( nTemp16
== 258 )
749 rStm
.ReadUInt16( nTemp16
);
750 nBitsPerPixel
= nTemp16
;
757 rStm
.ReadUInt16( nTemp16
);
758 if ( nTemp16
== 259 )
761 rStm
.ReadUInt16( nTemp16
); // compression
772 rStm
.Seek( nStmPos
);
776 bool GraphicDescriptor::ImpDetectXBM( SvStream
&, bool )
778 bool bRet
= aPathExt
.startsWith( "xbm" );
780 nFormat
= GraphicFileFormat::XBM
;
785 bool GraphicDescriptor::ImpDetectXPM( SvStream
&, bool )
787 bool bRet
= aPathExt
.startsWith( "xpm" );
789 nFormat
= GraphicFileFormat::XPM
;
794 bool GraphicDescriptor::ImpDetectPBM( SvStream
& rStm
, bool )
798 // check file extension first, as this trumps the 2 ID bytes
799 if ( aPathExt
.startsWith( "pbm" ) )
803 sal_Int32 nStmPos
= rStm
.Tell();
804 sal_uInt8 nFirst
= 0, nSecond
= 0;
805 rStm
.ReadUChar( nFirst
).ReadUChar( nSecond
);
806 if ( nFirst
== 'P' && ( ( nSecond
== '1' ) || ( nSecond
== '4' ) ) )
808 rStm
.Seek( nStmPos
);
812 nFormat
= GraphicFileFormat::PBM
;
817 bool GraphicDescriptor::ImpDetectPGM( SvStream
& rStm
, bool )
821 if ( aPathExt
.startsWith( "pgm" ) )
825 sal_uInt8 nFirst
= 0, nSecond
= 0;
826 sal_Int32 nStmPos
= rStm
.Tell();
827 rStm
.ReadUChar( nFirst
).ReadUChar( nSecond
);
828 if ( nFirst
== 'P' && ( ( nSecond
== '2' ) || ( nSecond
== '5' ) ) )
830 rStm
.Seek( nStmPos
);
834 nFormat
= GraphicFileFormat::PGM
;
839 bool GraphicDescriptor::ImpDetectPPM( SvStream
& rStm
, bool )
843 if ( aPathExt
.startsWith( "ppm" ) )
847 sal_uInt8 nFirst
= 0, nSecond
= 0;
848 sal_Int32 nStmPos
= rStm
.Tell();
849 rStm
.ReadUChar( nFirst
).ReadUChar( nSecond
);
850 if ( nFirst
== 'P' && ( ( nSecond
== '3' ) || ( nSecond
== '6' ) ) )
852 rStm
.Seek( nStmPos
);
856 nFormat
= GraphicFileFormat::PPM
;
861 bool GraphicDescriptor::ImpDetectRAS( SvStream
& rStm
, bool )
863 sal_uInt32 nMagicNumber
= 0;
865 sal_Int32 nStmPos
= rStm
.Tell();
866 rStm
.SetEndian( SvStreamEndian::BIG
);
867 rStm
.ReadUInt32( nMagicNumber
);
868 if ( nMagicNumber
== 0x59a66a95 )
870 nFormat
= GraphicFileFormat::RAS
;
873 rStm
.Seek( nStmPos
);
877 bool GraphicDescriptor::ImpDetectTGA( SvStream
&, bool )
879 bool bRet
= aPathExt
.startsWith( "tga" );
881 nFormat
= GraphicFileFormat::TGA
;
886 bool GraphicDescriptor::ImpDetectPSD( SvStream
& rStm
, bool bExtendedInfo
)
890 sal_uInt32 nMagicNumber
= 0;
891 sal_Int32 nStmPos
= rStm
.Tell();
892 rStm
.SetEndian( SvStreamEndian::BIG
);
893 rStm
.ReadUInt32( nMagicNumber
);
894 if ( nMagicNumber
== 0x38425053 )
896 sal_uInt16 nVersion
= 0;
897 rStm
.ReadUInt16( nVersion
);
903 sal_uInt16 nChannels
= 0;
904 sal_uInt32 nRows
= 0;
905 sal_uInt32 nColumns
= 0;
906 sal_uInt16 nDepth
= 0;
907 sal_uInt16 nMode
= 0;
908 rStm
.SeekRel( 6 ); // Pad
909 rStm
.ReadUInt16( nChannels
).ReadUInt32( nRows
).ReadUInt32( nColumns
).ReadUInt16( nDepth
).ReadUInt16( nMode
);
910 if ( ( nDepth
== 1 ) || ( nDepth
== 8 ) || ( nDepth
== 16 ) )
912 nBitsPerPixel
= ( nDepth
== 16 ) ? 8 : nDepth
;
921 aPixSize
.setWidth( nColumns
);
922 aPixSize
.setHeight( nRows
);
935 nFormat
= GraphicFileFormat::PSD
;
936 rStm
.Seek( nStmPos
);
940 bool GraphicDescriptor::ImpDetectEPS( SvStream
& rStm
, bool )
942 // check the EPS preview and the file extension
943 sal_uInt32 nFirstLong
= 0;
944 sal_uInt8 nFirstBytes
[20] = {};
947 sal_Int32 nStmPos
= rStm
.Tell();
948 rStm
.SetEndian( SvStreamEndian::BIG
);
949 rStm
.ReadUInt32( nFirstLong
);
951 rStm
.ReadBytes( &nFirstBytes
, 20 );
953 if ( ( nFirstLong
== 0xC5D0D3C6 ) || aPathExt
.startsWith( "eps" ) ||
954 ( ImplSearchEntry( nFirstBytes
, reinterpret_cast<sal_uInt8
const *>("%!PS-Adobe"), 10, 10 )
955 && ImplSearchEntry( &nFirstBytes
[15], reinterpret_cast<sal_uInt8
const *>("EPS"), 3, 3 ) ) )
957 nFormat
= GraphicFileFormat::EPS
;
960 rStm
.Seek( nStmPos
);
964 bool GraphicDescriptor::ImpDetectDXF( SvStream
&, bool )
966 bool bRet
= aPathExt
.startsWith( "dxf" );
968 nFormat
= GraphicFileFormat::DXF
;
973 bool GraphicDescriptor::ImpDetectMET( SvStream
&, bool )
975 bool bRet
= aPathExt
.startsWith( "met" );
977 nFormat
= GraphicFileFormat::MET
;
982 bool GraphicDescriptor::ImpDetectPCT( SvStream
& rStm
, bool )
984 bool bRet
= aPathExt
.startsWith( "pct" );
986 nFormat
= GraphicFileFormat::PCT
;
989 sal_uInt64
const nStreamPos
= rStm
.Tell();
990 sal_uInt64
const nStreamLen
= rStm
.remainingSize();
991 if (isPCT(rStm
, nStreamPos
, nStreamLen
))
994 nFormat
= GraphicFileFormat::PCT
;
996 rStm
.Seek(nStreamPos
);
1002 bool GraphicDescriptor::ImpDetectSVM( SvStream
& rStm
, bool bExtendedInfo
)
1007 sal_Int32 nStmPos
= rStm
.Tell();
1008 rStm
.SetEndian( SvStreamEndian::LITTLE
);
1009 rStm
.ReadUInt32( n32
);
1010 if ( n32
== 0x44475653 )
1012 sal_uInt8 cByte
= 0;
1013 rStm
.ReadUChar( cByte
);
1014 if ( cByte
== 0x49 )
1016 nFormat
= GraphicFileFormat::SVM
;
1019 if ( bExtendedInfo
)
1024 rStm
.SeekRel( 0x04 );
1028 rStm
.ReadUInt32( nTemp32
);
1029 aLogSize
.setWidth( nTemp32
);
1033 rStm
.ReadUInt32( nTemp32
);
1034 aLogSize
.setHeight( nTemp32
);
1036 // read MapUnit and determine PrefSize
1038 rStm
.ReadUInt16( nTemp16
);
1039 aLogSize
= OutputDevice::LogicToLogic( aLogSize
,
1040 MapMode( static_cast<MapUnit
>(nTemp16
) ),
1041 MapMode( MapUnit::Map100thMM
) );
1049 rStm
.ReadUInt32( n32
);
1051 if( n32
== 0x4D4C4356 )
1053 sal_uInt16 nTmp16
= 0;
1055 rStm
.ReadUInt16( nTmp16
);
1057 if( nTmp16
== 0x4654 )
1059 nFormat
= GraphicFileFormat::SVM
;
1065 rStm
.SeekRel( 0x06 );
1066 TypeSerializer
aSerializer(rStm
);
1067 aSerializer
.readMapMode(aMapMode
);
1068 aSerializer
.readSize(aLogSize
);
1069 aLogSize
= OutputDevice::LogicToLogic( aLogSize
, aMapMode
, MapMode( MapUnit::Map100thMM
) );
1074 rStm
.Seek( nStmPos
);
1078 bool GraphicDescriptor::ImpDetectWMF( SvStream
&, bool )
1080 bool bRet
= aPathExt
.startsWith( "wmf" );
1082 nFormat
= GraphicFileFormat::WMF
;
1087 bool GraphicDescriptor::ImpDetectEMF( SvStream
& rStm
, bool bExtendedInfo
)
1089 sal_uInt32 nRecordType
= 0;
1092 sal_Int32 nStmPos
= rStm
.Tell();
1093 rStm
.SetEndian( SvStreamEndian::LITTLE
);
1094 rStm
.ReadUInt32( nRecordType
);
1096 if ( nRecordType
== 0x00000001 )
1098 sal_uInt32 nHeaderSize
= 0;
1099 sal_Int32 nBoundLeft
= 0, nBoundTop
= 0, nBoundRight
= 0, nBoundBottom
= 0;
1100 sal_Int32 nFrameLeft
= 0, nFrameTop
= 0, nFrameRight
= 0, nFrameBottom
= 0;
1101 sal_uInt32 nSignature
= 0;
1103 rStm
.ReadUInt32( nHeaderSize
);
1104 rStm
.ReadInt32( nBoundLeft
);
1105 rStm
.ReadInt32( nBoundTop
);
1106 rStm
.ReadInt32( nBoundRight
);
1107 rStm
.ReadInt32( nBoundBottom
);
1108 rStm
.ReadInt32( nFrameLeft
);
1109 rStm
.ReadInt32( nFrameTop
);
1110 rStm
.ReadInt32( nFrameRight
);
1111 rStm
.ReadInt32( nFrameBottom
);
1112 rStm
.ReadUInt32( nSignature
);
1114 if ( nSignature
== 0x464d4520 )
1116 nFormat
= GraphicFileFormat::EMF
;
1119 if ( bExtendedInfo
)
1122 aPixSize
.setWidth( nBoundRight
- nBoundLeft
+ 1 );
1123 aPixSize
.setHeight( nBoundBottom
- nBoundTop
+ 1 );
1125 // size in 0.01mm units
1126 aLogSize
.setWidth( nFrameRight
- nFrameLeft
+ 1 );
1127 aLogSize
.setHeight( nFrameBottom
- nFrameTop
+ 1 );
1132 rStm
.Seek( nStmPos
);
1136 bool GraphicDescriptor::ImpDetectSVG( SvStream
& /*rStm*/, bool /*bExtendedInfo*/ )
1138 bool bRet
= aPathExt
.startsWith( "svg" );
1140 nFormat
= GraphicFileFormat::SVG
;
1145 OUString
GraphicDescriptor::GetImportFormatShortName( GraphicFileFormat nFormat
)
1147 const char *pKeyName
= nullptr;
1151 case GraphicFileFormat::BMP
: pKeyName
= "bmp"; break;
1152 case GraphicFileFormat::GIF
: pKeyName
= "gif"; break;
1153 case GraphicFileFormat::JPG
: pKeyName
= "jpg"; break;
1154 case GraphicFileFormat::PCD
: pKeyName
= "pcd"; break;
1155 case GraphicFileFormat::PCX
: pKeyName
= "pcx"; break;
1156 case GraphicFileFormat::PNG
: pKeyName
= "png"; break;
1157 case GraphicFileFormat::XBM
: pKeyName
= "xbm"; break;
1158 case GraphicFileFormat::XPM
: pKeyName
= "xpm"; break;
1159 case GraphicFileFormat::PBM
: pKeyName
= "pbm"; break;
1160 case GraphicFileFormat::PGM
: pKeyName
= "pgm"; break;
1161 case GraphicFileFormat::PPM
: pKeyName
= "ppm"; break;
1162 case GraphicFileFormat::RAS
: pKeyName
= "ras"; break;
1163 case GraphicFileFormat::TGA
: pKeyName
= "tga"; break;
1164 case GraphicFileFormat::PSD
: pKeyName
= "psd"; break;
1165 case GraphicFileFormat::EPS
: pKeyName
= "eps"; break;
1166 case GraphicFileFormat::TIF
: pKeyName
= "tif"; break;
1167 case GraphicFileFormat::DXF
: pKeyName
= "dxf"; break;
1168 case GraphicFileFormat::MET
: pKeyName
= "met"; break;
1169 case GraphicFileFormat::PCT
: pKeyName
= "pct"; break;
1170 case GraphicFileFormat::SVM
: pKeyName
= "svm"; break;
1171 case GraphicFileFormat::WMF
: pKeyName
= "wmf"; break;
1172 case GraphicFileFormat::EMF
: pKeyName
= "emf"; break;
1173 case GraphicFileFormat::SVG
: pKeyName
= "svg"; break;
1174 default: assert(false);
1177 return OUString::createFromAscii(pKeyName
);
1180 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */