Branch libreoffice-5-0-4
[LibreOffice.git] / vcl / source / filter / graphicfilter2.cxx
blob21d584d6102c1179edf67e8ca852d0030b70b970
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 .
20 #include <string.h>
21 #include <stdio.h>
22 #include <tools/stream.hxx>
23 #include <tools/fract.hxx>
24 #include <vcl/outdev.hxx>
25 #include <vcl/graphicfilter.hxx>
26 #include <unotools/ucbstreamhelper.hxx>
27 #include "graphicfilter_internal.hxx"
29 #define DATA_SIZE 640
31 GraphicDescriptor::GraphicDescriptor( const INetURLObject& rPath ) :
32 pFileStm( ::utl::UcbStreamHelper::CreateStream( rPath.GetMainURL( INetURLObject::NO_DECODE ), StreamMode::READ ) ),
33 aPathExt( rPath.GetFileExtension().toAsciiLowerCase() ),
34 bOwnStream( true )
36 ImpConstruct();
39 GraphicDescriptor::GraphicDescriptor( SvStream& rInStream, const OUString* pPath) :
40 pFileStm ( &rInStream ),
41 bOwnStream ( false )
43 ImpConstruct();
45 if ( pPath )
47 INetURLObject aURL( *pPath );
48 aPathExt = aURL.GetFileExtension().toAsciiLowerCase();
52 GraphicDescriptor::~GraphicDescriptor()
54 if ( bOwnStream )
55 delete pFileStm;
58 bool GraphicDescriptor::Detect( bool bExtendedInfo )
60 bool bRet = false;
61 if ( pFileStm && !pFileStm->GetError() )
63 SvStream& rStm = *pFileStm;
64 SvStreamEndian nOldFormat = rStm.GetEndian();
66 if ( ImpDetectGIF( rStm, bExtendedInfo ) ) bRet = true;
67 else if ( ImpDetectJPG( rStm, bExtendedInfo ) ) bRet = true;
68 else if ( ImpDetectBMP( rStm, bExtendedInfo ) ) bRet = true;
69 else if ( ImpDetectPNG( rStm, bExtendedInfo ) ) bRet = true;
70 else if ( ImpDetectTIF( rStm, bExtendedInfo ) ) bRet = true;
71 else if ( ImpDetectPCX( rStm, bExtendedInfo ) ) bRet = true;
72 else if ( ImpDetectDXF( rStm, bExtendedInfo ) ) bRet = true;
73 else if ( ImpDetectMET( rStm, bExtendedInfo ) ) bRet = true;
74 else if ( ImpDetectSGF( rStm, bExtendedInfo ) ) bRet = true;
75 else if ( ImpDetectSGV( rStm, bExtendedInfo ) ) bRet = true;
76 else if ( ImpDetectSVM( rStm, bExtendedInfo ) ) bRet = true;
77 else if ( ImpDetectWMF( rStm, bExtendedInfo ) ) bRet = true;
78 else if ( ImpDetectEMF( rStm, bExtendedInfo ) ) bRet = true;
79 else if ( ImpDetectSVG( rStm, bExtendedInfo ) ) bRet = true;
80 else if ( ImpDetectPCT( rStm, bExtendedInfo ) ) bRet = true;
81 else if ( ImpDetectXBM( rStm, bExtendedInfo ) ) bRet = true;
82 else if ( ImpDetectXPM( rStm, bExtendedInfo ) ) bRet = true;
83 else if ( ImpDetectPBM( rStm, bExtendedInfo ) ) bRet = true;
84 else if ( ImpDetectPGM( rStm, bExtendedInfo ) ) bRet = true;
85 else if ( ImpDetectPPM( rStm, bExtendedInfo ) ) bRet = true;
86 else if ( ImpDetectRAS( rStm, bExtendedInfo ) ) bRet = true;
87 else if ( ImpDetectTGA( rStm, bExtendedInfo ) ) bRet = true;
88 else if ( ImpDetectPSD( rStm, bExtendedInfo ) ) bRet = true;
89 else if ( ImpDetectEPS( rStm, bExtendedInfo ) ) bRet = true;
90 else if ( ImpDetectPCD( rStm, bExtendedInfo ) ) bRet = true;
92 rStm.SetEndian( nOldFormat );
94 return bRet;
97 void GraphicDescriptor::ImpConstruct()
99 nFormat = GraphicFileFormat::NOT;
100 nBitsPerPixel = 0;
101 nPlanes = 0;
102 bCompressed = false;
105 bool GraphicDescriptor::ImpDetectBMP( SvStream& rStm, bool bExtendedInfo )
107 sal_uInt16 nTemp16 = 0;
108 bool bRet = false;
109 sal_Int32 nStmPos = rStm.Tell();
111 rStm.SetEndian( SvStreamEndian::LITTLE );
112 rStm.ReadUInt16( nTemp16 );
114 // OS/2-BitmapArray
115 if ( nTemp16 == 0x4142 )
117 rStm.SeekRel( 0x0c );
118 rStm.ReadUInt16( nTemp16 );
121 // Bitmap
122 if ( nTemp16 == 0x4d42 )
124 nFormat = GraphicFileFormat::BMP;
125 bRet = true;
127 if ( bExtendedInfo )
129 sal_uInt32 nTemp32;
130 sal_uInt32 nCompression;
132 // up to first info
133 rStm.SeekRel( 0x10 );
135 // Pixel width
136 rStm.ReadUInt32( nTemp32 );
137 aPixSize.Width() = nTemp32;
139 // Pixel height
140 rStm.ReadUInt32( nTemp32 );
141 aPixSize.Height() = nTemp32;
143 // Planes
144 rStm.ReadUInt16( nTemp16 );
145 nPlanes = nTemp16;
147 // BitCount
148 rStm.ReadUInt16( nTemp16 );
149 nBitsPerPixel = nTemp16;
151 // Compression
152 rStm.ReadUInt32( nTemp32 );
153 bCompressed = ( ( nCompression = nTemp32 ) > 0 );
155 // logical width
156 rStm.SeekRel( 4 );
157 rStm.ReadUInt32( nTemp32 );
158 if ( nTemp32 )
159 aLogSize.Width() = ( aPixSize.Width() * 100000 ) / nTemp32;
161 // logical height
162 rStm.ReadUInt32( nTemp32 );
163 if ( nTemp32 )
164 aLogSize.Height() = ( aPixSize.Height() * 100000 ) / nTemp32;
166 // further validation, check for rational values
167 if ( ( nBitsPerPixel > 24 ) || ( nCompression > 3 ) )
169 nFormat = GraphicFileFormat::NOT;
170 bRet = false;
174 rStm.Seek( nStmPos );
175 return bRet;
178 bool GraphicDescriptor::ImpDetectGIF( SvStream& rStm, bool bExtendedInfo )
180 sal_uInt32 n32 = 0;
181 sal_uInt16 n16 = 0;
182 bool bRet = false;
183 sal_uInt8 cByte = 0;
185 sal_Int32 nStmPos = rStm.Tell();
186 rStm.SetEndian( SvStreamEndian::LITTLE );
187 rStm.ReadUInt32( n32 );
189 if ( n32 == 0x38464947 )
191 rStm.ReadUInt16( n16 );
192 if ( ( n16 == 0x6137 ) || ( n16 == 0x6139 ) )
194 nFormat = GraphicFileFormat::GIF;
195 bRet = true;
197 if ( bExtendedInfo )
199 sal_uInt16 nTemp16 = 0;
201 // Pixel width
202 rStm.ReadUInt16( nTemp16 );
203 aPixSize.Width() = nTemp16;
205 // Pixel height
206 rStm.ReadUInt16( nTemp16 );
207 aPixSize.Height() = nTemp16;
209 // Bits/Pixel
210 rStm.ReadUChar( cByte );
211 nBitsPerPixel = ( ( cByte & 112 ) >> 4 ) + 1;
215 rStm.Seek( nStmPos );
216 return bRet;
219 // returns the next jpeg marker, a return value of 0 represents an error
220 sal_uInt8 ImpDetectJPG_GetNextMarker( SvStream& rStm )
222 sal_uInt8 nByte;
227 rStm.ReadUChar( nByte );
228 if ( rStm.IsEof() || rStm.GetError() ) // as 0 is not allowed as marker,
229 return 0; // we can use it as errorcode
231 while ( nByte != 0xff );
234 rStm.ReadUChar( nByte );
235 if ( rStm.IsEof() || rStm.GetError() )
236 return 0;
238 while( nByte == 0xff );
240 while( nByte == 0 ); // 0xff00 represents 0xff and not a marker,
241 // the marker detection has to be restartet.
242 return nByte;
245 bool GraphicDescriptor::ImpDetectJPG( SvStream& rStm, bool bExtendedInfo )
247 sal_uInt32 nTemp32 = 0;
248 bool bRet = false;
250 sal_Int32 nStmPos = rStm.Tell();
252 rStm.SetEndian( SvStreamEndian::BIG );
253 rStm.ReadUInt32( nTemp32 );
255 // compare upper 24 bits
256 if( 0xffd8ff00 == ( nTemp32 & 0xffffff00 ) )
258 nFormat = GraphicFileFormat::JPG;
259 bRet = true;
261 if ( bExtendedInfo )
263 rStm.SeekRel( -2 );
265 sal_uInt32 nError( rStm.GetError() );
267 bool bScanFailure = false;
268 bool bScanFinished = false;
270 while( !bScanFailure && !bScanFinished && !rStm.IsEof() && !rStm.GetError() )
272 sal_uInt8 nMarker = ImpDetectJPG_GetNextMarker( rStm );
273 switch( nMarker )
275 // fixed size marker, not having a two byte length parameter
276 case 0xd0 : // RST0
277 case 0xd1 :
278 case 0xd2 :
279 case 0xd3 :
280 case 0xd4 :
281 case 0xd5 :
282 case 0xd6 :
283 case 0xd7 : // RST7
284 case 0x01 : // TEM
285 break;
287 case 0xd8 : // SOI (has already been checked, there should not be a second one)
288 case 0x00 : // marker is invalid, we should stop now
289 bScanFailure = true;
290 break;
292 case 0xd9 : // EOI
293 bScanFinished = true;
294 break;
296 // per default we assume marker segments conaining a length parameter
297 default :
299 sal_uInt16 nLength = 0;
300 rStm.ReadUInt16( nLength );
302 if ( nLength < 2 )
303 bScanFailure = true;
304 else
306 sal_uInt32 nNextMarkerPos = rStm.Tell() + nLength - 2;
307 switch( nMarker )
309 case 0xe0 : // APP0 Marker
311 if ( nLength == 16 )
313 sal_Int32 nIdentifier = 0;
314 rStm.ReadInt32( nIdentifier );
315 if ( nIdentifier == 0x4a464946 ) // JFIF Identifier
317 sal_uInt8 nStringTerminator = 0;
318 sal_uInt8 nMajorRevision = 0;
319 sal_uInt8 nMinorRevision = 0;
320 sal_uInt8 nUnits = 0;
321 sal_uInt16 nHorizontalResolution = 0;
322 sal_uInt16 nVerticalResolution = 0;
323 sal_uInt8 nHorzThumbnailPixelCount = 0;
324 sal_uInt8 nVertThumbnailPixelCount = 0;
326 rStm.ReadUChar( nStringTerminator )
327 .ReadUChar( nMajorRevision )
328 .ReadUChar( nMinorRevision )
329 .ReadUChar( nUnits )
330 .ReadUInt16( nHorizontalResolution )
331 .ReadUInt16( nVerticalResolution )
332 .ReadUChar( nHorzThumbnailPixelCount )
333 .ReadUChar( nVertThumbnailPixelCount );
335 // setting the logical size
336 if ( nUnits && nHorizontalResolution && nVerticalResolution )
338 MapMode aMap;
339 aMap.SetMapUnit( nUnits == 1 ? MAP_INCH : MAP_CM );
340 aMap.SetScaleX( Fraction( 1, nHorizontalResolution ) );
341 aMap.SetScaleY( Fraction( 1, nVerticalResolution ) );
342 aLogSize = OutputDevice::LogicToLogic( aPixSize, aMap, MapMode( MAP_100TH_MM ) );
347 break;
349 // Start of Frame Markers
350 case 0xc0 : // SOF0
351 case 0xc1 : // SOF1
352 case 0xc2 : // SOF2
353 case 0xc3 : // SOF3
354 case 0xc5 : // SOF5
355 case 0xc6 : // SOF6
356 case 0xc7 : // SOF7
357 case 0xc9 : // SOF9
358 case 0xca : // SOF10
359 case 0xcb : // SOF11
360 case 0xcd : // SOF13
361 case 0xce : // SOF14
362 case 0xcf : // SOF15
364 sal_uInt8 nSamplePrecision = 0;
365 sal_uInt16 nNumberOfLines = 0;
366 sal_uInt16 nSamplesPerLine = 0;
367 sal_uInt8 nNumberOfImageComponents = 0;
368 sal_uInt8 nComponentsIdentifier = 0;
369 sal_uInt8 nHorizontalSamplingFactor = 0;
370 sal_uInt8 nQuantizationTableDestinationSelector = 0;
371 rStm.ReadUChar( nSamplePrecision )
372 .ReadUInt16( nNumberOfLines )
373 .ReadUInt16( nSamplesPerLine )
374 .ReadUChar( nNumberOfImageComponents )
375 .ReadUChar( nComponentsIdentifier )
376 .ReadUChar( nHorizontalSamplingFactor )
377 .ReadUChar( nQuantizationTableDestinationSelector );
378 nHorizontalSamplingFactor >>= 4;
380 aPixSize.Height() = nNumberOfLines;
381 aPixSize.Width() = nSamplesPerLine;
382 nBitsPerPixel = ( nNumberOfImageComponents == 3 ? 24 : nNumberOfImageComponents == 1 ? 8 : 0 );
383 nPlanes = 1;
385 bScanFinished = true;
387 break;
389 rStm.Seek( nNextMarkerPos );
392 break;
395 rStm.SetError( nError );
398 rStm.Seek( nStmPos );
399 return bRet;
402 bool GraphicDescriptor::ImpDetectPCD( SvStream& rStm, bool )
404 bool bRet = false;
406 sal_Int32 nStmPos = rStm.Tell();
407 rStm.SetEndian( SvStreamEndian::LITTLE );
409 sal_uInt32 nTemp32 = 0;
410 sal_uInt16 nTemp16 = 0;
411 sal_uInt8 cByte = 0;
413 rStm.SeekRel( 2048 );
414 rStm.ReadUInt32( nTemp32 );
415 rStm.ReadUInt16( nTemp16 );
416 rStm.ReadUChar( cByte );
418 if ( ( nTemp32 == 0x5f444350 ) &&
419 ( nTemp16 == 0x5049 ) &&
420 ( cByte == 0x49 ) )
422 nFormat = GraphicFileFormat::PCD;
423 bRet = true;
425 rStm.Seek( nStmPos );
426 return bRet;
429 bool GraphicDescriptor::ImpDetectPCX( SvStream& rStm, bool bExtendedInfo )
431 // ! Because 0x0a can be interpreted as LF too ...
432 // we can't be sure that this special sign represent a PCX file only.
433 // Every Ascii file is possible here :-(
434 // We must detect the whole header.
435 bExtendedInfo = true;
437 bool bRet = false;
438 sal_uInt8 cByte = 0;
440 sal_Int32 nStmPos = rStm.Tell();
441 rStm.SetEndian( SvStreamEndian::LITTLE );
442 rStm.ReadUChar( cByte );
444 if ( cByte == 0x0a )
446 nFormat = GraphicFileFormat::PCX;
447 bRet = true;
449 if ( bExtendedInfo )
451 sal_uInt16 nTemp16;
452 sal_uInt16 nXmin;
453 sal_uInt16 nXmax;
454 sal_uInt16 nYmin;
455 sal_uInt16 nYmax;
456 sal_uInt16 nDPIx;
457 sal_uInt16 nDPIy;
459 rStm.SeekRel( 1 );
461 // compression
462 rStm.ReadUChar( cByte );
463 bCompressed = ( cByte > 0 );
465 bRet = (cByte==0 || cByte ==1);
466 if (bRet)
468 // Bits/Pixel
469 rStm.ReadUChar( cByte );
470 nBitsPerPixel = cByte;
472 // image dimensions
473 rStm.ReadUInt16( nTemp16 );
474 nXmin = nTemp16;
475 rStm.ReadUInt16( nTemp16 );
476 nYmin = nTemp16;
477 rStm.ReadUInt16( nTemp16 );
478 nXmax = nTemp16;
479 rStm.ReadUInt16( nTemp16 );
480 nYmax = nTemp16;
482 aPixSize.Width() = nXmax - nXmin + 1;
483 aPixSize.Height() = nYmax - nYmin + 1;
485 // resolution
486 rStm.ReadUInt16( nTemp16 );
487 nDPIx = nTemp16;
488 rStm.ReadUInt16( nTemp16 );
489 nDPIy = nTemp16;
491 // set logical size
492 MapMode aMap( MAP_INCH, Point(),
493 Fraction( 1, nDPIx ), Fraction( 1, nDPIy ) );
494 aLogSize = OutputDevice::LogicToLogic( aPixSize, aMap,
495 MapMode( MAP_100TH_MM ) );
497 // number of color planes
498 cByte = 5; // Illegal value in case of EOF.
499 rStm.SeekRel( 49 );
500 rStm.ReadUChar( cByte );
501 nPlanes = cByte;
503 bRet = (nPlanes<=4);
508 rStm.Seek( nStmPos );
509 return bRet;
512 bool GraphicDescriptor::ImpDetectPNG( SvStream& rStm, bool bExtendedInfo )
514 sal_uInt32 nTemp32 = 0;
515 bool bRet = false;
517 sal_Int32 nStmPos = rStm.Tell();
518 rStm.SetEndian( SvStreamEndian::BIG );
519 rStm.ReadUInt32( nTemp32 );
521 if ( nTemp32 == 0x89504e47 )
523 rStm.ReadUInt32( nTemp32 );
524 if ( nTemp32 == 0x0d0a1a0a )
526 nFormat = GraphicFileFormat::PNG;
527 bRet = true;
529 if ( bExtendedInfo )
531 sal_uInt8 cByte = 0;
533 // IHDR-Chunk
534 rStm.SeekRel( 8 );
536 // width
537 rStm.ReadUInt32( nTemp32 );
538 aPixSize.Width() = nTemp32;
540 // height
541 rStm.ReadUInt32( nTemp32 );
542 aPixSize.Height() = nTemp32;
544 // Bits/Pixel
545 rStm.ReadUChar( cByte );
546 nBitsPerPixel = cByte;
548 // Planes always 1;
549 // compression always
550 nPlanes = 1;
551 bCompressed = true;
553 sal_uInt32 nLen32 = 0;
554 nTemp32 = 0;
556 rStm.SeekRel( 8 );
558 // read up to the pHYs-Chunk or the start of the image
559 rStm.ReadUInt32( nLen32 );
560 rStm.ReadUInt32( nTemp32 );
561 while( ( nTemp32 != 0x70485973 ) && ( nTemp32 != 0x49444154 )
562 && !rStm.IsEof() && !rStm.GetError() )
564 rStm.SeekRel( 4 + nLen32 );
565 rStm.ReadUInt32( nLen32 );
566 rStm.ReadUInt32( nTemp32 );
569 if ( nTemp32 == 0x70485973
570 && !rStm.IsEof() && !rStm.GetError() )
572 sal_uLong nXRes;
573 sal_uLong nYRes;
575 // horizontal resolution
576 nTemp32 = 0;
577 rStm.ReadUInt32( nTemp32 );
578 nXRes = nTemp32;
580 // vertical resolution
581 nTemp32 = 0;
582 rStm.ReadUInt32( nTemp32 );
583 nYRes = nTemp32;
585 // unit
586 cByte = 0;
587 rStm.ReadUChar( cByte );
589 if ( cByte )
591 if ( nXRes )
592 aLogSize.Width() = ( aPixSize.Width() * 100000 ) /
593 nTemp32;
595 if ( nYRes )
596 aLogSize.Height() = ( aPixSize.Height() * 100000 ) /
597 nTemp32;
603 rStm.Seek( nStmPos );
604 return bRet;
607 bool GraphicDescriptor::ImpDetectTIF( SvStream& rStm, bool bExtendedInfo )
609 bool bRet = false;
610 sal_uInt8 cByte1 = 0;
611 sal_uInt8 cByte2 = 1;
613 sal_Int32 nStmPos = rStm.Tell();
614 rStm.ReadUChar( cByte1 );
615 rStm.ReadUChar( cByte2 );
616 if ( cByte1 == cByte2 )
618 bool bDetectOk = false;
620 if ( cByte1 == 0x49 )
622 rStm.SetEndian( SvStreamEndian::LITTLE );
623 bDetectOk = true;
625 else if ( cByte1 == 0x4d )
627 rStm.SetEndian( SvStreamEndian::BIG );
628 bDetectOk = true;
631 if ( bDetectOk )
633 sal_uInt16 nTemp16 = 0;
635 rStm.ReadUInt16( nTemp16 );
636 if ( nTemp16 == 0x2a )
638 nFormat = GraphicFileFormat::TIF;
639 bRet = true;
641 if ( bExtendedInfo )
643 sal_uLong nCount;
644 sal_uLong nMax = DATA_SIZE - 48;
645 sal_uInt32 nTemp32 = 0;
647 // Offset of the first IFD
648 rStm.ReadUInt32( nTemp32 );
649 rStm.SeekRel( ( nCount = ( nTemp32 + 2 ) ) - 0x08 );
651 if ( nCount < nMax )
653 bool bOk = false;
655 // read tags till we find Tag256 ( Width )
656 // do not read more bytes than DATA_SIZE
657 rStm.ReadUInt16( nTemp16 );
658 while ( nTemp16 != 256 )
660 bOk = nCount < nMax;
661 if ( !bOk )
663 break;
665 rStm.SeekRel( 10 );
666 rStm.ReadUInt16( nTemp16 );
667 nCount += 12;
670 if ( bOk )
672 // width
673 rStm.ReadUInt16( nTemp16 );
674 rStm.SeekRel( 4 );
675 if ( nTemp16 == 3 )
677 rStm.ReadUInt16( nTemp16 );
678 aPixSize.Width() = nTemp16;
679 rStm.SeekRel( 2 );
681 else
683 rStm.ReadUInt32( nTemp32 );
684 aPixSize.Width() = nTemp32;
686 nCount += 12;
688 // height
689 rStm.SeekRel( 2 );
690 rStm.ReadUInt16( nTemp16 );
691 rStm.SeekRel( 4 );
692 if ( nTemp16 == 3 )
694 rStm.ReadUInt16( nTemp16 );
695 aPixSize.Height() = nTemp16;
696 rStm.SeekRel( 2 );
698 else
700 rStm.ReadUInt32( nTemp32 );
701 aPixSize.Height() = nTemp32;
703 nCount += 12;
705 // Bits/Pixel
706 rStm.ReadUInt16( nTemp16 );
707 if ( nTemp16 == 258 )
709 rStm.SeekRel( 6 );
710 rStm.ReadUInt16( nTemp16 );
711 nBitsPerPixel = nTemp16;
712 rStm.SeekRel( 2 );
713 nCount += 12;
715 else
716 rStm.SeekRel( -2 );
718 // compression
719 rStm.ReadUInt16( nTemp16 );
720 if ( nTemp16 == 259 )
722 rStm.SeekRel( 6 );
723 rStm.ReadUInt16( nTemp16 );
724 bCompressed = ( nTemp16 > 1 );
725 rStm.SeekRel( 2 );
726 nCount += 12;
728 else
729 rStm.SeekRel( -2 );
736 rStm.Seek( nStmPos );
737 return bRet;
740 bool GraphicDescriptor::ImpDetectXBM( SvStream&, bool )
742 bool bRet = aPathExt.startsWith( "xbm" );
743 if (bRet)
744 nFormat = GraphicFileFormat::XBM;
746 return bRet;
749 bool GraphicDescriptor::ImpDetectXPM( SvStream&, bool )
751 bool bRet = aPathExt.startsWith( "xpm" );
752 if (bRet)
753 nFormat = GraphicFileFormat::XPM;
755 return bRet;
758 bool GraphicDescriptor::ImpDetectPBM( SvStream& rStm, bool )
760 bool bRet = false;
762 // check file extension first, as this trumps the 2 ID bytes
763 if ( aPathExt.startsWith( "pbm" ) )
764 bRet = true;
765 else
767 sal_Int32 nStmPos = rStm.Tell();
768 sal_uInt8 nFirst = 0, nSecond = 0;
769 rStm.ReadUChar( nFirst ).ReadUChar( nSecond );
770 if ( nFirst == 'P' && ( ( nSecond == '1' ) || ( nSecond == '4' ) ) )
771 bRet = true;
772 rStm.Seek( nStmPos );
775 if ( bRet )
776 nFormat = GraphicFileFormat::PBM;
778 return bRet;
781 bool GraphicDescriptor::ImpDetectPGM( SvStream& rStm, bool )
783 bool bRet = false;
785 if ( aPathExt.startsWith( "pgm" ) )
786 bRet = true;
787 else
789 sal_uInt8 nFirst = 0, nSecond = 0;
790 sal_Int32 nStmPos = rStm.Tell();
791 rStm.ReadUChar( nFirst ).ReadUChar( nSecond );
792 if ( nFirst == 'P' && ( ( nSecond == '2' ) || ( nSecond == '5' ) ) )
793 bRet = true;
794 rStm.Seek( nStmPos );
797 if ( bRet )
798 nFormat = GraphicFileFormat::PGM;
800 return bRet;
803 bool GraphicDescriptor::ImpDetectPPM( SvStream& rStm, bool )
805 bool bRet = false;
807 if ( aPathExt.startsWith( "ppm" ) )
808 bRet = true;
809 else
811 sal_uInt8 nFirst = 0, nSecond = 0;
812 sal_Int32 nStmPos = rStm.Tell();
813 rStm.ReadUChar( nFirst ).ReadUChar( nSecond );
814 if ( nFirst == 'P' && ( ( nSecond == '3' ) || ( nSecond == '6' ) ) )
815 bRet = true;
816 rStm.Seek( nStmPos );
819 if ( bRet )
820 nFormat = GraphicFileFormat::PPM;
822 return bRet;
825 bool GraphicDescriptor::ImpDetectRAS( SvStream& rStm, bool )
827 sal_uInt32 nMagicNumber = 0;
828 bool bRet = false;
829 sal_Int32 nStmPos = rStm.Tell();
830 rStm.SetEndian( SvStreamEndian::BIG );
831 rStm.ReadUInt32( nMagicNumber );
832 if ( nMagicNumber == 0x59a66a95 )
834 nFormat = GraphicFileFormat::RAS;
835 bRet = true;
837 rStm.Seek( nStmPos );
838 return bRet;
841 bool GraphicDescriptor::ImpDetectTGA( SvStream&, bool )
843 bool bRet = aPathExt.startsWith( "tga" );
844 if (bRet)
845 nFormat = GraphicFileFormat::TGA;
847 return bRet;
850 bool GraphicDescriptor::ImpDetectPSD( SvStream& rStm, bool bExtendedInfo )
852 bool bRet = false;
854 sal_uInt32 nMagicNumber = 0;
855 sal_Int32 nStmPos = rStm.Tell();
856 rStm.SetEndian( SvStreamEndian::BIG );
857 rStm.ReadUInt32( nMagicNumber );
858 if ( nMagicNumber == 0x38425053 )
860 sal_uInt16 nVersion = 0;
861 rStm.ReadUInt16( nVersion );
862 if ( nVersion == 1 )
864 bRet = true;
865 if ( bExtendedInfo )
867 sal_uInt16 nChannels = 0;
868 sal_uInt32 nRows = 0;
869 sal_uInt32 nColumns = 0;
870 sal_uInt16 nDepth = 0;
871 sal_uInt16 nMode = 0;
872 rStm.SeekRel( 6 ); // Pad
873 rStm.ReadUInt16( nChannels ).ReadUInt32( nRows ).ReadUInt32( nColumns ).ReadUInt16( nDepth ).ReadUInt16( nMode );
874 if ( ( nDepth == 1 ) || ( nDepth == 8 ) || ( nDepth == 16 ) )
876 nBitsPerPixel = ( nDepth == 16 ) ? 8 : nDepth;
877 switch ( nChannels )
879 case 4 :
880 case 3 :
881 nBitsPerPixel = 24;
882 case 2 :
883 case 1 :
884 aPixSize.Width() = nColumns;
885 aPixSize.Height() = nRows;
886 break;
887 default:
888 bRet = false;
891 else
892 bRet = false;
897 if ( bRet )
898 nFormat = GraphicFileFormat::PSD;
899 rStm.Seek( nStmPos );
900 return bRet;
903 bool GraphicDescriptor::ImpDetectEPS( SvStream& rStm, bool )
905 // check the EPS preview and the file extension
906 sal_uInt32 nFirstLong = 0;
907 sal_uInt8 nFirstBytes[20];
908 bool bRet = false;
909 memset(nFirstBytes, 0, sizeof (nFirstBytes));
911 sal_Int32 nStmPos = rStm.Tell();
912 rStm.SetEndian( SvStreamEndian::BIG );
913 rStm.ReadUInt32( nFirstLong );
914 rStm.SeekRel( -4 );
915 rStm.Read( &nFirstBytes, 20 );
917 if ( ( nFirstLong == 0xC5D0D3C6 ) || aPathExt.startsWith( "eps" ) ||
918 ( ImplSearchEntry( nFirstBytes, reinterpret_cast<sal_uInt8 const *>("%!PS-Adobe"), 10, 10 )
919 && ImplSearchEntry( &nFirstBytes[15], reinterpret_cast<sal_uInt8 const *>("EPS"), 3, 3 ) ) )
921 nFormat = GraphicFileFormat::EPS;
922 bRet = true;
924 rStm.Seek( nStmPos );
925 return bRet;
928 bool GraphicDescriptor::ImpDetectDXF( SvStream&, bool )
930 bool bRet = aPathExt.startsWith( "dxf" );
931 if (bRet)
932 nFormat = GraphicFileFormat::DXF;
934 return bRet;
937 bool GraphicDescriptor::ImpDetectMET( SvStream&, bool )
939 bool bRet = aPathExt.startsWith( "met" );
940 if (bRet)
941 nFormat = GraphicFileFormat::MET;
943 return bRet;
946 bool GraphicDescriptor::ImpDetectPCT( SvStream& rStm, bool )
948 bool bRet = aPathExt.startsWith( "pct" );
949 if (bRet)
950 nFormat = GraphicFileFormat::PCT;
951 else
953 sal_Size nStreamPos = rStm.Tell();
954 sal_Size nStreamLen = rStm.remainingSize();
955 if (isPCT(rStm, nStreamPos, nStreamLen))
957 bRet = true;
958 nFormat = GraphicFileFormat::PCT;
960 rStm.Seek(nStreamPos);
963 return bRet;
966 bool GraphicDescriptor::ImpDetectSGF( SvStream& rStm, bool )
968 bool bRet = false;
969 if( aPathExt.startsWith( "sgf" ) )
970 bRet = true;
971 else
973 sal_Int32 nStmPos = rStm.Tell();
975 sal_uInt8 nFirst = 0, nSecond = 0;
977 rStm.ReadUChar( nFirst ).ReadUChar( nSecond );
979 if( nFirst == 'J' && nSecond == 'J' )
980 bRet = true;
982 rStm.Seek( nStmPos );
985 if( bRet )
986 nFormat = GraphicFileFormat::SGF;
988 return bRet;
991 bool GraphicDescriptor::ImpDetectSGV( SvStream&, bool )
993 bool bRet = aPathExt.startsWith( "sgv" );
994 if (bRet)
995 nFormat = GraphicFileFormat::SGV;
997 return bRet;
1000 bool GraphicDescriptor::ImpDetectSVM( SvStream& rStm, bool bExtendedInfo )
1002 sal_uInt32 n32 = 0;
1003 bool bRet = false;
1004 sal_uInt8 cByte = 0;
1006 sal_Int32 nStmPos = rStm.Tell();
1007 rStm.SetEndian( SvStreamEndian::LITTLE );
1008 rStm.ReadUInt32( n32 );
1009 if ( n32 == 0x44475653 )
1011 cByte = 0;
1012 rStm.ReadUChar( cByte );
1013 if ( cByte == 0x49 )
1015 nFormat = GraphicFileFormat::SVM;
1016 bRet = true;
1018 if ( bExtendedInfo )
1020 sal_uInt32 nTemp32;
1021 sal_uInt16 nTemp16;
1023 rStm.SeekRel( 0x04 );
1025 // width
1026 nTemp32 = 0;
1027 rStm.ReadUInt32( nTemp32 );
1028 aLogSize.Width() = nTemp32;
1030 // height
1031 nTemp32 = 0;
1032 rStm.ReadUInt32( nTemp32 );
1033 aLogSize.Height() = nTemp32;
1035 // read MapUnit and determine PrefSize
1036 nTemp16 = 0;
1037 rStm.ReadUInt16( nTemp16 );
1038 aLogSize = OutputDevice::LogicToLogic( aLogSize,
1039 MapMode( (MapUnit) nTemp16 ),
1040 MapMode( MAP_100TH_MM ) );
1044 else
1046 rStm.SeekRel( -4L );
1047 n32 = 0;
1048 rStm.ReadUInt32( n32 );
1050 if( n32 == 0x4D4C4356 )
1052 sal_uInt16 nTmp16 = 0;
1054 rStm.ReadUInt16( nTmp16 );
1056 if( nTmp16 == 0x4654 )
1058 nFormat = GraphicFileFormat::SVM;
1059 bRet = true;
1061 if( bExtendedInfo )
1063 MapMode aMapMode;
1065 rStm.SeekRel( 0x06 );
1066 ReadMapMode( rStm, aMapMode );
1067 ReadPair( rStm, aLogSize );
1068 aLogSize = OutputDevice::LogicToLogic( aLogSize, aMapMode, MapMode( MAP_100TH_MM ) );
1073 rStm.Seek( nStmPos );
1074 return bRet;
1077 bool GraphicDescriptor::ImpDetectWMF( SvStream&, bool )
1079 bool bRet = aPathExt.startsWith( "wmf" );
1080 if (bRet)
1081 nFormat = GraphicFileFormat::WMF;
1083 return bRet;
1086 bool GraphicDescriptor::ImpDetectEMF( SvStream&, bool )
1088 bool bRet = aPathExt.startsWith( "emf" );
1089 if (bRet)
1090 nFormat = GraphicFileFormat::EMF;
1092 return bRet;
1095 bool GraphicDescriptor::ImpDetectSVG( SvStream& /*rStm*/, bool /*bExtendedInfo*/ )
1097 bool bRet = aPathExt.startsWith( "svg" );
1098 if (bRet)
1099 nFormat = GraphicFileFormat::SVG;
1101 return bRet;
1104 OUString GraphicDescriptor::GetImportFormatShortName( GraphicFileFormat nFormat )
1106 const char *pKeyName = 0;
1108 switch( nFormat )
1110 case( GraphicFileFormat::BMP ) : pKeyName = "bmp"; break;
1111 case( GraphicFileFormat::GIF ) : pKeyName = "gif"; break;
1112 case( GraphicFileFormat::JPG ) : pKeyName = "jpg"; break;
1113 case( GraphicFileFormat::PCD ) : pKeyName = "pcd"; break;
1114 case( GraphicFileFormat::PCX ) : pKeyName = "pcx"; break;
1115 case( GraphicFileFormat::PNG ) : pKeyName = "png"; break;
1116 case( GraphicFileFormat::XBM ) : pKeyName = "xbm"; break;
1117 case( GraphicFileFormat::XPM ) : pKeyName = "xpm"; break;
1118 case( GraphicFileFormat::PBM ) : pKeyName = "pbm"; break;
1119 case( GraphicFileFormat::PGM ) : pKeyName = "pgm"; break;
1120 case( GraphicFileFormat::PPM ) : pKeyName = "ppm"; break;
1121 case( GraphicFileFormat::RAS ) : pKeyName = "ras"; break;
1122 case( GraphicFileFormat::TGA ) : pKeyName = "tga"; break;
1123 case( GraphicFileFormat::PSD ) : pKeyName = "psd"; break;
1124 case( GraphicFileFormat::EPS ) : pKeyName = "eps"; break;
1125 case( GraphicFileFormat::TIF ) : pKeyName = "tif"; break;
1126 case( GraphicFileFormat::DXF ) : pKeyName = "dxf"; break;
1127 case( GraphicFileFormat::MET ) : pKeyName = "met"; break;
1128 case( GraphicFileFormat::PCT ) : pKeyName = "pct"; break;
1129 case( GraphicFileFormat::SGF ) : pKeyName = "sgf"; break;
1130 case( GraphicFileFormat::SGV ) : pKeyName = "sgv"; break;
1131 case( GraphicFileFormat::SVM ) : pKeyName = "svm"; break;
1132 case( GraphicFileFormat::WMF ) : pKeyName = "wmf"; break;
1133 case( GraphicFileFormat::EMF ) : pKeyName = "emf"; break;
1134 case( GraphicFileFormat::SVG ) : pKeyName = "svg"; break;
1135 default: assert(false);
1138 return OUString::createFromAscii(pKeyName);
1141 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */