bump product version to 4.1.6.2
[LibreOffice.git] / vcl / source / filter / graphicfilter2.cxx
blob8e2821498e5a65e400b1a3c40feeecd45e72a390
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 <string.h>
22 #include <stdio.h>
23 #include <tools/stream.hxx>
24 #include <vcl/outdev.hxx>
25 #include <vcl/graphicfilter.hxx>
26 #include <unotools/ucbstreamhelper.hxx>
28 #define DATA_SIZE 640
30 sal_uInt8* ImplSearchEntry( sal_uInt8* , sal_uInt8* , sal_uLong , sal_uLong );
32 GraphicDescriptor::GraphicDescriptor( const INetURLObject& rPath ) :
33 pFileStm( ::utl::UcbStreamHelper::CreateStream( rPath.GetMainURL( INetURLObject::NO_DECODE ), STREAM_READ ) ),
34 aPathExt( rPath.GetFileExtension().toAsciiLowerCase() ),
35 bOwnStream( sal_True )
37 ImpConstruct();
40 GraphicDescriptor::GraphicDescriptor( SvStream& rInStream, const String* pPath) :
41 pFileStm ( &rInStream ),
42 bOwnStream ( sal_False )
44 ImpConstruct();
46 if ( pPath )
48 INetURLObject aURL( *pPath );
49 aPathExt = aURL.GetFileExtension().toAsciiLowerCase();
53 GraphicDescriptor::~GraphicDescriptor()
55 if ( bOwnStream )
56 delete pFileStm;
59 sal_Bool GraphicDescriptor::Detect( sal_Bool bExtendedInfo )
61 sal_Bool bRet = sal_False;
62 if ( pFileStm && !pFileStm->GetError() )
64 SvStream& rStm = *pFileStm;
65 sal_uInt16 nOldFormat = rStm.GetNumberFormatInt();
67 if ( ImpDetectGIF( rStm, bExtendedInfo ) ) bRet = sal_True;
68 else if ( ImpDetectJPG( rStm, bExtendedInfo ) ) bRet = sal_True;
69 else if ( ImpDetectBMP( rStm, bExtendedInfo ) ) bRet = sal_True;
70 else if ( ImpDetectPNG( rStm, bExtendedInfo ) ) bRet = sal_True;
71 else if ( ImpDetectTIF( rStm, bExtendedInfo ) ) bRet = sal_True;
72 else if ( ImpDetectPCX( rStm, bExtendedInfo ) ) bRet = sal_True;
73 else if ( ImpDetectDXF( rStm, bExtendedInfo ) ) bRet = sal_True;
74 else if ( ImpDetectMET( rStm, bExtendedInfo ) ) bRet = sal_True;
75 else if ( ImpDetectSGF( rStm, bExtendedInfo ) ) bRet = sal_True;
76 else if ( ImpDetectSGV( rStm, bExtendedInfo ) ) bRet = sal_True;
77 else if ( ImpDetectSVM( rStm, bExtendedInfo ) ) bRet = sal_True;
78 else if ( ImpDetectWMF( rStm, bExtendedInfo ) ) bRet = sal_True;
79 else if ( ImpDetectEMF( rStm, bExtendedInfo ) ) bRet = sal_True;
80 else if ( ImpDetectSVG( rStm, bExtendedInfo ) ) bRet = sal_True;
81 else if ( ImpDetectPCT( rStm, bExtendedInfo ) ) bRet = sal_True;
82 else if ( ImpDetectXBM( rStm, bExtendedInfo ) ) bRet = sal_True;
83 else if ( ImpDetectXPM( rStm, bExtendedInfo ) ) bRet = sal_True;
84 else if ( ImpDetectPBM( rStm, bExtendedInfo ) ) bRet = sal_True;
85 else if ( ImpDetectPGM( rStm, bExtendedInfo ) ) bRet = sal_True;
86 else if ( ImpDetectPPM( rStm, bExtendedInfo ) ) bRet = sal_True;
87 else if ( ImpDetectRAS( rStm, bExtendedInfo ) ) bRet = sal_True;
88 else if ( ImpDetectTGA( rStm, bExtendedInfo ) ) bRet = sal_True;
89 else if ( ImpDetectPSD( rStm, bExtendedInfo ) ) bRet = sal_True;
90 else if ( ImpDetectEPS( rStm, bExtendedInfo ) ) bRet = sal_True;
91 else if ( ImpDetectPCD( rStm, bExtendedInfo ) ) bRet = sal_True;
93 rStm.SetNumberFormatInt( nOldFormat );
95 return bRet;
98 void GraphicDescriptor::ImpConstruct()
100 nFormat = GFF_NOT;
101 nBitsPerPixel = 0;
102 nPlanes = 0;
103 bCompressed = sal_False;
106 sal_Bool GraphicDescriptor::ImpDetectBMP( SvStream& rStm, sal_Bool bExtendedInfo )
108 sal_uInt16 nTemp16;
109 sal_Bool bRet = sal_False;
110 sal_Int32 nStmPos = rStm.Tell();
112 rStm.SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
113 rStm >> nTemp16;
115 // OS/2-BitmapArray
116 if ( nTemp16 == 0x4142 )
118 rStm.SeekRel( 0x0c );
119 rStm >> nTemp16;
122 // Bitmap
123 if ( nTemp16 == 0x4d42 )
125 nFormat = GFF_BMP;
126 bRet = sal_True;
128 if ( bExtendedInfo )
130 sal_uInt32 nTemp32;
131 sal_uInt32 nCompression;
133 // up to first info
134 rStm.SeekRel( 0x10 );
136 // Pixel width
137 rStm >> nTemp32;
138 aPixSize.Width() = nTemp32;
140 // Pixel height
141 rStm >> nTemp32;
142 aPixSize.Height() = nTemp32;
144 // Planes
145 rStm >> nTemp16;
146 nPlanes = nTemp16;
148 // BitCount
149 rStm >> nTemp16;
150 nBitsPerPixel = nTemp16;
152 // Compression
153 rStm >> nTemp32;
154 bCompressed = ( ( nCompression = nTemp32 ) > 0 );
156 // logical width
157 rStm.SeekRel( 4 );
158 rStm >> nTemp32;
159 if ( nTemp32 )
160 aLogSize.Width() = ( aPixSize.Width() * 100000 ) / nTemp32;
162 // logical height
163 rStm >> nTemp32;
164 if ( nTemp32 )
165 aLogSize.Height() = ( aPixSize.Height() * 100000 ) / nTemp32;
167 // further validation, check for rational values
168 if ( ( nBitsPerPixel > 24 ) || ( nCompression > 3 ) )
170 nFormat = GFF_NOT;
171 bRet = sal_False;
175 rStm.Seek( nStmPos );
176 return bRet;
179 sal_Bool GraphicDescriptor::ImpDetectGIF( SvStream& rStm, sal_Bool bExtendedInfo )
181 sal_uInt32 n32;
182 sal_uInt16 n16;
183 sal_Bool bRet = sal_False;
184 sal_uInt8 cByte;
186 sal_Int32 nStmPos = rStm.Tell();
187 rStm.SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
188 rStm >> n32;
190 if ( n32 == 0x38464947 )
192 rStm >> n16;
193 if ( ( n16 == 0x6137 ) || ( n16 == 0x6139 ) )
195 nFormat = GFF_GIF;
196 bRet = sal_True;
198 if ( bExtendedInfo )
200 sal_uInt16 nTemp16;
202 // Pixel width
203 rStm >> nTemp16;
204 aPixSize.Width() = nTemp16;
206 // Pixel height
207 rStm >> nTemp16;
208 aPixSize.Height() = nTemp16;
210 // Bits/Pixel
211 rStm >> cByte;
212 nBitsPerPixel = ( ( cByte & 112 ) >> 4 ) + 1;
216 rStm.Seek( nStmPos );
217 return bRet;
220 // returns the next jpeg marker, a return value of 0 represents an error
221 sal_uInt8 ImpDetectJPG_GetNextMarker( SvStream& rStm )
223 sal_uInt8 nByte;
228 rStm >> nByte;
229 if ( rStm.IsEof() || rStm.GetError() ) // as 0 is not allowed as marker,
230 return 0; // we can use it as errorcode
232 while ( nByte != 0xff );
235 rStm >> nByte;
236 if ( rStm.IsEof() || rStm.GetError() )
237 return 0;
239 while( nByte == 0xff );
241 while( nByte == 0 ); // 0xff00 represents 0xff and not a marker,
242 // the marker detection has to be restartet.
243 return nByte;
246 sal_Bool GraphicDescriptor::ImpDetectJPG( SvStream& rStm, sal_Bool bExtendedInfo )
248 sal_uInt32 nTemp32;
249 sal_Bool bRet = sal_False;
251 sal_Int32 nStmPos = rStm.Tell();
253 rStm.SetNumberFormatInt( NUMBERFORMAT_INT_BIGENDIAN );
254 rStm >> nTemp32;
256 // compare upper 24 bits
257 if( 0xffd8ff00 == ( nTemp32 & 0xffffff00 ) )
259 nFormat = GFF_JPG;
260 bRet = sal_True;
262 if ( bExtendedInfo )
264 rStm.SeekRel( -2 );
266 sal_uInt32 nError( rStm.GetError() );
268 sal_Bool bScanFailure = sal_False;
269 sal_Bool bScanFinished = sal_False;
271 while( !bScanFailure && !bScanFinished && !rStm.IsEof() && !rStm.GetError() )
273 sal_uInt8 nMarker = ImpDetectJPG_GetNextMarker( rStm );
274 switch( nMarker )
276 // fixed size marker, not having a two byte length parameter
277 case 0xd0 : // RST0
278 case 0xd1 :
279 case 0xd2 :
280 case 0xd3 :
281 case 0xd4 :
282 case 0xd5 :
283 case 0xd6 :
284 case 0xd7 : // RST7
285 case 0x01 : // TEM
286 break;
288 case 0xd8 : // SOI (has already been checked, there should not be a second one)
289 case 0x00 : // marker is invalid, we should stop now
290 bScanFailure = sal_True;
291 break;
293 case 0xd9 : // EOI
294 bScanFinished = sal_True;
295 break;
297 // per default we assume marker segments conaining a length parameter
298 default :
300 sal_uInt16 nLength;
301 rStm >> nLength;
303 if ( nLength < 2 )
304 bScanFailure = sal_True;
305 else
307 sal_uInt32 nNextMarkerPos = rStm.Tell() + nLength - 2;
308 switch( nMarker )
310 case 0xe0 : // APP0 Marker
312 if ( nLength == 16 )
314 sal_Int32 nIdentifier;
315 rStm >> nIdentifier;
316 if ( nIdentifier == 0x4a464946 ) // JFIF Identifier
318 sal_uInt8 nStringTerminator;
319 sal_uInt8 nMajorRevision;
320 sal_uInt8 nMinorRevision;
321 sal_uInt8 nUnits;
322 sal_uInt16 nHorizontalResolution;
323 sal_uInt16 nVerticalResolution;
324 sal_uInt8 nHorzThumbnailPixelCount;
325 sal_uInt8 nVertThumbnailPixelCount;
327 rStm >> nStringTerminator
328 >> nMajorRevision
329 >> nMinorRevision
330 >> nUnits
331 >> nHorizontalResolution
332 >> nVerticalResolution
333 >> nHorzThumbnailPixelCount
334 >> nVertThumbnailPixelCount;
336 // setting the logical size
337 if ( nUnits && nHorizontalResolution && nVerticalResolution )
339 MapMode aMap;
340 aMap.SetMapUnit( nUnits == 1 ? MAP_INCH : MAP_CM );
341 aMap.SetScaleX( Fraction( 1, nHorizontalResolution ) );
342 aMap.SetScaleY( Fraction( 1, nVerticalResolution ) );
343 aLogSize = OutputDevice::LogicToLogic( aPixSize, aMap, MapMode( MAP_100TH_MM ) );
348 break;
350 // Start of Frame Markers
351 case 0xc0 : // SOF0
352 case 0xc1 : // SOF1
353 case 0xc2 : // SOF2
354 case 0xc3 : // SOF3
355 case 0xc5 : // SOF5
356 case 0xc6 : // SOF6
357 case 0xc7 : // SOF7
358 case 0xc9 : // SOF9
359 case 0xca : // SOF10
360 case 0xcb : // SOF11
361 case 0xcd : // SOF13
362 case 0xce : // SOF14
363 case 0xcf : // SOF15
365 sal_uInt8 nSamplePrecision;
366 sal_uInt16 nNumberOfLines;
367 sal_uInt16 nSamplesPerLine;
368 sal_uInt8 nNumberOfImageComponents;
369 sal_uInt8 nComponentsIdentifier;
370 sal_uInt8 nHorizontalSamplingFactor;
371 sal_uInt8 nQuantizationTableDestinationSelector;
372 rStm >> nSamplePrecision
373 >> nNumberOfLines
374 >> nSamplesPerLine
375 >> nNumberOfImageComponents
376 >> nComponentsIdentifier
377 >> nHorizontalSamplingFactor
378 >> nQuantizationTableDestinationSelector;
379 nHorizontalSamplingFactor >>= 4;
381 aPixSize.Height() = nNumberOfLines;
382 aPixSize.Width() = nSamplesPerLine;
383 nBitsPerPixel = ( nNumberOfImageComponents == 3 ? 24 : nNumberOfImageComponents == 1 ? 8 : 0 );
384 nPlanes = 1;
386 bScanFinished = sal_True;
388 break;
390 rStm.Seek( nNextMarkerPos );
393 break;
396 rStm.SetError( nError );
399 rStm.Seek( nStmPos );
400 return bRet;
403 sal_Bool GraphicDescriptor::ImpDetectPCD( SvStream& rStm, sal_Bool )
405 sal_Bool bRet = sal_False;
407 sal_Int32 nStmPos = rStm.Tell();
408 rStm.SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
410 sal_uInt32 nTemp32;
411 sal_uInt16 nTemp16;
412 sal_uInt8 cByte;
414 rStm.SeekRel( 2048 );
415 rStm >> nTemp32;
416 rStm >> nTemp16;
417 rStm >> cByte;
419 if ( ( nTemp32 == 0x5f444350 ) &&
420 ( nTemp16 == 0x5049 ) &&
421 ( cByte == 0x49 ) )
423 nFormat = GFF_PCD;
424 bRet = sal_True;
426 rStm.Seek( nStmPos );
427 return bRet;
430 sal_Bool GraphicDescriptor::ImpDetectPCX( SvStream& rStm, sal_Bool bExtendedInfo )
432 // ! Because 0x0a can be interpreted as LF too ...
433 // we cant be shure that this special sign represent a PCX file only.
434 // Every Ascii file is possible here :-(
435 // We must detect the whole header.
436 bExtendedInfo = sal_True;
438 sal_Bool bRet = sal_False;
439 sal_uInt8 cByte;
441 sal_Int32 nStmPos = rStm.Tell();
442 rStm.SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
443 rStm >> cByte;
445 if ( cByte == 0x0a )
447 nFormat = GFF_PCX;
448 bRet = sal_True;
450 if ( bExtendedInfo )
452 sal_uInt16 nTemp16;
453 sal_uInt16 nXmin;
454 sal_uInt16 nXmax;
455 sal_uInt16 nYmin;
456 sal_uInt16 nYmax;
457 sal_uInt16 nDPIx;
458 sal_uInt16 nDPIy;
461 rStm.SeekRel( 1 );
463 // compression
464 rStm >> cByte;
465 bCompressed = ( cByte > 0 );
467 bRet = (cByte==0 || cByte ==1);
469 // Bits/Pixel
470 rStm >> cByte;
471 nBitsPerPixel = cByte;
473 // image dimensions
474 rStm >> nTemp16;
475 nXmin = nTemp16;
476 rStm >> nTemp16;
477 nYmin = nTemp16;
478 rStm >> nTemp16;
479 nXmax = nTemp16;
480 rStm >> nTemp16;
481 nYmax = nTemp16;
483 aPixSize.Width() = nXmax - nXmin + 1;
484 aPixSize.Height() = nYmax - nYmin + 1;
486 // resolution
487 rStm >> nTemp16;
488 nDPIx = nTemp16;
489 rStm >> nTemp16;
490 nDPIy = nTemp16;
492 // set logical size
493 MapMode aMap( MAP_INCH, Point(),
494 Fraction( 1, nDPIx ), Fraction( 1, nDPIy ) );
495 aLogSize = OutputDevice::LogicToLogic( aPixSize, aMap,
496 MapMode( MAP_100TH_MM ) );
499 // number of color planes
500 rStm.SeekRel( 49 );
501 rStm >> cByte;
502 nPlanes = cByte;
504 bRet = (nPlanes<=4);
508 rStm.Seek( nStmPos );
509 return bRet;
512 sal_Bool GraphicDescriptor::ImpDetectPNG( SvStream& rStm, sal_Bool bExtendedInfo )
514 sal_uInt32 nTemp32;
515 sal_Bool bRet = sal_False;
517 sal_Int32 nStmPos = rStm.Tell();
518 rStm.SetNumberFormatInt( NUMBERFORMAT_INT_BIGENDIAN );
519 rStm >> nTemp32;
521 if ( nTemp32 == 0x89504e47 )
523 rStm >> nTemp32;
524 if ( nTemp32 == 0x0d0a1a0a )
526 nFormat = GFF_PNG;
527 bRet = sal_True;
529 if ( bExtendedInfo )
531 sal_uInt8 cByte;
533 // IHDR-Chunk
534 rStm.SeekRel( 8 );
536 // width
537 rStm >> nTemp32;
538 aPixSize.Width() = nTemp32;
540 // height
541 rStm >> nTemp32;
542 aPixSize.Height() = nTemp32;
544 // Bits/Pixel
545 rStm >> cByte;
546 nBitsPerPixel = cByte;
548 // Planes always 1;
549 // compression always
550 nPlanes = 1;
551 bCompressed = sal_True;
553 sal_uInt32 nLen32;
555 rStm.SeekRel( 8 );
557 // read up to the pHYs-Chunk or the start of the image
558 rStm >> nLen32;
559 rStm >> nTemp32;
560 while( ( nTemp32 != 0x70485973 ) && ( nTemp32 != 0x49444154 ) )
562 rStm.SeekRel( 4 + nLen32 );
563 rStm >> nLen32;
564 rStm >> nTemp32;
567 if ( nTemp32 == 0x70485973 )
569 sal_uLong nXRes;
570 sal_uLong nYRes;
572 // horizontal resolution
573 rStm >> nTemp32;
574 nXRes = nTemp32;
576 // vertical resolution
577 rStm >> nTemp32;
578 nYRes = nTemp32;
580 // unit
581 rStm >> cByte;
583 if ( cByte )
585 if ( nXRes )
586 aLogSize.Width() = ( aPixSize.Width() * 100000 ) /
587 nTemp32;
589 if ( nYRes )
590 aLogSize.Height() = ( aPixSize.Height() * 100000 ) /
591 nTemp32;
597 rStm.Seek( nStmPos );
598 return bRet;
601 sal_Bool GraphicDescriptor::ImpDetectTIF( SvStream& rStm, sal_Bool bExtendedInfo )
603 sal_Bool bDetectOk = sal_False;
604 sal_Bool bRet = sal_False;
605 sal_uInt8 cByte1;
606 sal_uInt8 cByte2;
608 sal_Int32 nStmPos = rStm.Tell();
609 rStm >> cByte1;
610 rStm >> cByte2;
611 if ( cByte1 == cByte2 )
613 if ( cByte1 == 0x49 )
615 rStm.SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
616 bDetectOk = sal_True;
618 else if ( cByte1 == 0x4d )
620 rStm.SetNumberFormatInt( NUMBERFORMAT_INT_BIGENDIAN );
621 bDetectOk = sal_True;
624 if ( bDetectOk )
626 sal_uInt16 nTemp16;
628 rStm >> nTemp16;
629 if ( nTemp16 == 0x2a )
631 nFormat = GFF_TIF;
632 bRet = sal_True;
634 if ( bExtendedInfo )
636 sal_uLong nCount;
637 sal_uLong nMax = DATA_SIZE - 48;
638 sal_uInt32 nTemp32;
639 sal_Bool bOk = sal_False;
641 // Offset of the first IFD
642 rStm >> nTemp32;
643 rStm.SeekRel( ( nCount = ( nTemp32 + 2 ) ) - 0x08 );
645 if ( nCount < nMax )
647 // read tags till we find Tag256 ( Width )
648 // do not read more bytes than DATA_SIZE
649 rStm >> nTemp16;
650 while ( nTemp16 != 256 )
652 bOk = nCount < nMax;
653 if ( !bOk )
655 break;
657 rStm.SeekRel( 10 );
658 rStm >> nTemp16;
659 nCount += 12;
662 if ( bOk )
664 // width
665 rStm >> nTemp16;
666 rStm.SeekRel( 4 );
667 if ( nTemp16 == 3 )
669 rStm >> nTemp16;
670 aPixSize.Width() = nTemp16;
671 rStm.SeekRel( 2 );
673 else
675 rStm >> nTemp32;
676 aPixSize.Width() = nTemp32;
678 nCount += 12;
680 // height
681 rStm.SeekRel( 2 );
682 rStm >> nTemp16;
683 rStm.SeekRel( 4 );
684 if ( nTemp16 == 3 )
686 rStm >> nTemp16;
687 aPixSize.Height() = nTemp16;
688 rStm.SeekRel( 2 );
690 else
692 rStm >> nTemp32;
693 aPixSize.Height() = nTemp32;
695 nCount += 12;
697 // Bits/Pixel
698 rStm >> nTemp16;
699 if ( nTemp16 == 258 )
701 rStm.SeekRel( 6 );
702 rStm >> nTemp16;
703 nBitsPerPixel = nTemp16;
704 rStm.SeekRel( 2 );
705 nCount += 12;
707 else
708 rStm.SeekRel( -2 );
710 // compression
711 rStm >> nTemp16;
712 if ( nTemp16 == 259 )
714 rStm.SeekRel( 6 );
715 rStm >> nTemp16;
716 bCompressed = ( nTemp16 > 1 );
717 rStm.SeekRel( 2 );
718 nCount += 12;
720 else
721 rStm.SeekRel( -2 );
728 rStm.Seek( nStmPos );
729 return bRet;
732 sal_Bool GraphicDescriptor::ImpDetectXBM( SvStream&, sal_Bool )
734 sal_Bool bRet = aPathExt.CompareToAscii( "xbm", 3 ) == COMPARE_EQUAL;
735 if (bRet)
736 nFormat = GFF_XBM;
738 return bRet;
741 sal_Bool GraphicDescriptor::ImpDetectXPM( SvStream&, sal_Bool )
743 sal_Bool bRet = aPathExt.CompareToAscii( "xpm", 3 ) == COMPARE_EQUAL;
744 if (bRet)
745 nFormat = GFF_XPM;
747 return bRet;
750 sal_Bool GraphicDescriptor::ImpDetectPBM( SvStream& rStm, sal_Bool )
752 sal_Bool bRet = sal_False;
754 // check file extension first, as this trumps the 2 ID bytes
755 if ( aPathExt.CompareToAscii( "pbm", 3 ) == COMPARE_EQUAL )
756 bRet = sal_True;
757 else
759 sal_Int32 nStmPos = rStm.Tell();
760 sal_uInt8 nFirst, nSecond;
761 rStm >> nFirst >> nSecond;
762 if ( nFirst == 'P' && ( ( nSecond == '1' ) || ( nSecond == '4' ) ) )
763 bRet = sal_True;
764 rStm.Seek( nStmPos );
767 if ( bRet )
768 nFormat = GFF_PBM;
770 return bRet;
773 sal_Bool GraphicDescriptor::ImpDetectPGM( SvStream& rStm, sal_Bool )
775 sal_Bool bRet = sal_False;
777 if ( aPathExt.CompareToAscii( "pgm", 3 ) == COMPARE_EQUAL )
778 bRet = sal_True;
779 else
781 sal_uInt8 nFirst, nSecond;
782 sal_Int32 nStmPos = rStm.Tell();
783 rStm >> nFirst >> nSecond;
784 if ( nFirst == 'P' && ( ( nSecond == '2' ) || ( nSecond == '5' ) ) )
785 bRet = sal_True;
786 rStm.Seek( nStmPos );
789 if ( bRet )
790 nFormat = GFF_PGM;
792 return bRet;
795 sal_Bool GraphicDescriptor::ImpDetectPPM( SvStream& rStm, sal_Bool )
797 sal_Bool bRet = sal_False;
799 if ( aPathExt.CompareToAscii( "ppm", 3 ) == COMPARE_EQUAL )
800 bRet = sal_True;
801 else
803 sal_uInt8 nFirst, nSecond;
804 sal_Int32 nStmPos = rStm.Tell();
805 rStm >> nFirst >> nSecond;
806 if ( nFirst == 'P' && ( ( nSecond == '3' ) || ( nSecond == '6' ) ) )
807 bRet = sal_True;
808 rStm.Seek( nStmPos );
811 if ( bRet )
812 nFormat = GFF_PPM;
814 return bRet;
817 sal_Bool GraphicDescriptor::ImpDetectRAS( SvStream& rStm, sal_Bool )
819 sal_uInt32 nMagicNumber;
820 sal_Bool bRet = sal_False;
821 sal_Int32 nStmPos = rStm.Tell();
822 rStm.SetNumberFormatInt( NUMBERFORMAT_INT_BIGENDIAN );
823 rStm >> nMagicNumber;
824 if ( nMagicNumber == 0x59a66a95 )
826 nFormat = GFF_RAS;
827 bRet = sal_True;
829 rStm.Seek( nStmPos );
830 return bRet;
833 sal_Bool GraphicDescriptor::ImpDetectTGA( SvStream&, sal_Bool )
835 sal_Bool bRet = aPathExt.CompareToAscii( "tga", 3 ) == COMPARE_EQUAL;
836 if (bRet)
837 nFormat = GFF_TGA;
839 return bRet;
842 sal_Bool GraphicDescriptor::ImpDetectPSD( SvStream& rStm, sal_Bool bExtendedInfo )
844 sal_Bool bRet = sal_False;
846 sal_uInt32 nMagicNumber;
847 sal_Int32 nStmPos = rStm.Tell();
848 rStm.SetNumberFormatInt( NUMBERFORMAT_INT_BIGENDIAN );
849 rStm >> nMagicNumber;
850 if ( nMagicNumber == 0x38425053 )
852 sal_uInt16 nVersion;
853 rStm >> nVersion;
854 if ( nVersion == 1 )
856 bRet = sal_True;
857 if ( bExtendedInfo )
859 sal_uInt16 nChannels;
860 sal_uInt32 nRows;
861 sal_uInt32 nColumns;
862 sal_uInt16 nDepth;
863 sal_uInt16 nMode;
864 rStm.SeekRel( 6 ); // Pad
865 rStm >> nChannels >> nRows >> nColumns >> nDepth >> nMode;
866 if ( ( nDepth == 1 ) || ( nDepth == 8 ) || ( nDepth == 16 ) )
868 nBitsPerPixel = ( nDepth == 16 ) ? 8 : nDepth;
869 switch ( nChannels )
871 case 4 :
872 case 3 :
873 nBitsPerPixel = 24;
874 case 2 :
875 case 1 :
876 aPixSize.Width() = nColumns;
877 aPixSize.Height() = nRows;
878 break;
879 default:
880 bRet = sal_False;
883 else
884 bRet = sal_False;
889 if ( bRet )
890 nFormat = GFF_PSD;
891 rStm.Seek( nStmPos );
892 return bRet;
895 sal_Bool GraphicDescriptor::ImpDetectEPS( SvStream& rStm, sal_Bool )
897 // check the EPS preview and the file extension
898 sal_uInt32 nFirstLong;
899 sal_uInt8 nFirstBytes[20];
900 sal_Bool bRet = sal_False;
902 sal_Int32 nStmPos = rStm.Tell();
903 rStm.SetNumberFormatInt( NUMBERFORMAT_INT_BIGENDIAN );
904 rStm >> nFirstLong;
905 rStm.SeekRel( -4 );
906 rStm.Read( &nFirstBytes, 20 );
908 if ( ( nFirstLong == 0xC5D0D3C6 ) || ( aPathExt.CompareToAscii( "eps", 3 ) == COMPARE_EQUAL ) ||
909 ( ImplSearchEntry( nFirstBytes, (sal_uInt8*)"%!PS-Adobe", 10, 10 )
910 && ImplSearchEntry( &nFirstBytes[15], (sal_uInt8*)"EPS", 3, 3 ) ) )
912 nFormat = GFF_EPS;
913 bRet = sal_True;
915 rStm.Seek( nStmPos );
916 return bRet;
919 sal_Bool GraphicDescriptor::ImpDetectDXF( SvStream&, sal_Bool )
921 sal_Bool bRet = aPathExt.CompareToAscii( "dxf", 3 ) == COMPARE_EQUAL;
922 if (bRet)
923 nFormat = GFF_DXF;
925 return bRet;
928 sal_Bool GraphicDescriptor::ImpDetectMET( SvStream&, sal_Bool )
930 sal_Bool bRet = aPathExt.CompareToAscii( "met", 3 ) == COMPARE_EQUAL;
931 if (bRet)
932 nFormat = GFF_MET;
934 return bRet;
937 extern bool isPCT(SvStream& rStream, sal_uLong nStreamPos, sal_uLong nStreamLen);
939 sal_Bool GraphicDescriptor::ImpDetectPCT( SvStream& rStm, sal_Bool )
941 sal_Bool bRet = aPathExt.CompareToAscii( "pct", 3 ) == COMPARE_EQUAL;
942 if (bRet)
943 nFormat = GFF_PCT;
944 else
946 sal_Size nStreamPos = rStm.Tell();
947 sal_Size nStreamLen = rStm.remainingSize();
948 if (isPCT(rStm, nStreamPos, nStreamLen))
950 bRet = sal_True;
951 nFormat = GFF_PCT;
953 rStm.Seek(nStreamPos);
956 return bRet;
959 sal_Bool GraphicDescriptor::ImpDetectSGF( SvStream& rStm, sal_Bool )
961 sal_Bool bRet = sal_False;
962 if( aPathExt.CompareToAscii( "sgf", 3 ) == COMPARE_EQUAL )
963 bRet = sal_True;
964 else
966 sal_Int32 nStmPos = rStm.Tell();
968 sal_uInt8 nFirst, nSecond;
970 rStm >> nFirst >> nSecond;
972 if( nFirst == 'J' && nSecond == 'J' )
973 bRet = sal_True;
975 rStm.Seek( nStmPos );
978 if( bRet )
979 nFormat = GFF_SGF;
981 return bRet;
984 sal_Bool GraphicDescriptor::ImpDetectSGV( SvStream&, sal_Bool )
986 sal_Bool bRet = aPathExt.CompareToAscii( "sgv", 3 ) == COMPARE_EQUAL;
987 if (bRet)
988 nFormat = GFF_SGV;
990 return bRet;
993 sal_Bool GraphicDescriptor::ImpDetectSVM( SvStream& rStm, sal_Bool bExtendedInfo )
995 sal_uInt32 n32;
996 sal_Bool bRet = sal_False;
997 sal_uInt8 cByte;
999 sal_Int32 nStmPos = rStm.Tell();
1000 rStm.SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
1001 rStm >> n32;
1002 if ( n32 == 0x44475653 )
1004 rStm >> cByte;
1005 if ( cByte == 0x49 )
1007 nFormat = GFF_SVM;
1008 bRet = sal_True;
1010 if ( bExtendedInfo )
1012 sal_uInt32 nTemp32;
1013 sal_uInt16 nTemp16;
1015 rStm.SeekRel( 0x04 );
1017 // width
1018 rStm >> nTemp32;
1019 aLogSize.Width() = nTemp32;
1021 // height
1022 rStm >> nTemp32;
1023 aLogSize.Height() = nTemp32;
1025 // read MapUnit and determine PrefSize
1026 rStm >> nTemp16;
1027 aLogSize = OutputDevice::LogicToLogic( aLogSize,
1028 MapMode( (MapUnit) nTemp16 ),
1029 MapMode( MAP_100TH_MM ) );
1033 else
1035 rStm.SeekRel( -4L );
1036 rStm >> n32;
1038 if( n32 == 0x4D4C4356 )
1040 sal_uInt16 nTmp16;
1042 rStm >> nTmp16;
1044 if( nTmp16 == 0x4654 )
1046 nFormat = GFF_SVM;
1047 bRet = sal_True;
1049 if( bExtendedInfo )
1051 MapMode aMapMode;
1053 rStm.SeekRel( 0x06 );
1054 rStm >> aMapMode;
1055 rStm >> aLogSize;
1056 aLogSize = OutputDevice::LogicToLogic( aLogSize, aMapMode, MapMode( MAP_100TH_MM ) );
1061 rStm.Seek( nStmPos );
1062 return bRet;
1065 sal_Bool GraphicDescriptor::ImpDetectWMF( SvStream&, sal_Bool )
1067 sal_Bool bRet = aPathExt.CompareToAscii( "wmf",3 ) == COMPARE_EQUAL;
1068 if (bRet)
1069 nFormat = GFF_WMF;
1071 return bRet;
1074 sal_Bool GraphicDescriptor::ImpDetectEMF( SvStream&, sal_Bool )
1076 sal_Bool bRet = aPathExt.CompareToAscii( "emf", 3 ) == COMPARE_EQUAL;
1077 if (bRet)
1078 nFormat = GFF_EMF;
1080 return bRet;
1083 sal_Bool GraphicDescriptor::ImpDetectSVG( SvStream& /*rStm*/, sal_Bool /*bExtendedInfo*/ )
1085 sal_Bool bRet = aPathExt.CompareToAscii( "svg", 3 ) == COMPARE_EQUAL;
1086 if (bRet)
1087 nFormat = GFF_SVG;
1089 return bRet;
1092 String GraphicDescriptor::GetImportFormatShortName( sal_uInt16 nFormat )
1094 const char *pKeyName = 0;
1096 switch( nFormat )
1098 case( GFF_BMP ) : pKeyName = "bmp"; break;
1099 case( GFF_GIF ) : pKeyName = "gif"; break;
1100 case( GFF_JPG ) : pKeyName = "jpg"; break;
1101 case( GFF_PCD ) : pKeyName = "pcd"; break;
1102 case( GFF_PCX ) : pKeyName = "pcx"; break;
1103 case( GFF_PNG ) : pKeyName = "png"; break;
1104 case( GFF_XBM ) : pKeyName = "xbm"; break;
1105 case( GFF_XPM ) : pKeyName = "xpm"; break;
1106 case( GFF_PBM ) : pKeyName = "pbm"; break;
1107 case( GFF_PGM ) : pKeyName = "pgm"; break;
1108 case( GFF_PPM ) : pKeyName = "ppm"; break;
1109 case( GFF_RAS ) : pKeyName = "ras"; break;
1110 case( GFF_TGA ) : pKeyName = "tga"; break;
1111 case( GFF_PSD ) : pKeyName = "psd"; break;
1112 case( GFF_EPS ) : pKeyName = "eps"; break;
1113 case( GFF_TIF ) : pKeyName = "tif"; break;
1114 case( GFF_DXF ) : pKeyName = "dxf"; break;
1115 case( GFF_MET ) : pKeyName = "met"; break;
1116 case( GFF_PCT ) : pKeyName = "pct"; break;
1117 case( GFF_SGF ) : pKeyName = "sgf"; break;
1118 case( GFF_SGV ) : pKeyName = "sgv"; break;
1119 case( GFF_SVM ) : pKeyName = "svm"; break;
1120 case( GFF_WMF ) : pKeyName = "wmf"; break;
1121 case( GFF_EMF ) : pKeyName = "emf"; break;
1122 case( GFF_SVG ) : pKeyName = "svg"; break;
1125 return OUString::createFromAscii(pKeyName);
1128 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */