xref: /trunk/main/svtools/source/filter/filter2.cxx (revision 01ad09a0)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_svtools.hxx"
26 
27 #include <string.h>
28 #include <stdio.h>
29 #include <tools/stream.hxx>
30 #include <tools/debug.hxx>
31 #include <vcl/outdev.hxx>
32 #include <tools/config.hxx>
33 #include <svtools/filter.hxx>
34 #include "FilterConfigCache.hxx"
35 #include <unotools/ucbstreamhelper.hxx>
36 
37 #define DATA_SIZE			640
38 
39 sal_uInt8* ImplSearchEntry( sal_uInt8* , sal_uInt8* , sal_uLong , sal_uLong  );
40 
41 /*************************************************************************
42 |*
43 |*
44 |*
45 \************************************************************************/
46 
GraphicDescriptor(const INetURLObject & rPath)47 GraphicDescriptor::GraphicDescriptor( const INetURLObject& rPath ) :
48 	pFileStm( ::utl::UcbStreamHelper::CreateStream( rPath.GetMainURL( INetURLObject::NO_DECODE ), STREAM_READ ) ),
49 	aPathExt( rPath.GetFileExtension().toAsciiLowerCase() ),
50 	bOwnStream( sal_True )
51 {
52 	ImpConstruct();
53 }
54 
55 /*************************************************************************
56 |*
57 |*
58 |*
59 \************************************************************************/
60 
GraphicDescriptor(SvStream & rInStream,const String * pPath)61 GraphicDescriptor::GraphicDescriptor( SvStream& rInStream, const String* pPath) :
62 	pFileStm	( &rInStream ),
63 	bOwnStream	( sal_False )
64 {
65 	ImpConstruct();
66 
67 	if ( pPath )
68 	{
69 		INetURLObject aURL( *pPath );
70 		aPathExt = aURL.GetFileExtension().toAsciiLowerCase();
71 	}
72 }
73 
74 /*************************************************************************
75 |*
76 |*
77 |*
78 \************************************************************************/
79 
~GraphicDescriptor()80 GraphicDescriptor::~GraphicDescriptor()
81 {
82 	if ( bOwnStream )
83 		delete pFileStm;
84 }
85 
86 /*************************************************************************
87 |*
88 |*
89 |*
90 \************************************************************************/
91 
Detect(sal_Bool bExtendedInfo)92 sal_Bool GraphicDescriptor::Detect( sal_Bool bExtendedInfo )
93 {
94 	sal_Bool bRet = sal_False;
95 	if ( pFileStm && !pFileStm->GetError() )
96 	{
97 		SvStream&	rStm = *pFileStm;
98 		sal_uInt16		nOldFormat = rStm.GetNumberFormatInt();
99 
100 		if		( ImpDetectGIF( rStm, bExtendedInfo ) )	bRet = sal_True;
101 		else if ( ImpDetectJPG( rStm, bExtendedInfo ) )	bRet = sal_True;
102 		else if	( ImpDetectBMP( rStm, bExtendedInfo ) )	bRet = sal_True;
103 		else if ( ImpDetectPNG( rStm, bExtendedInfo ) )	bRet = sal_True;
104 		else if ( ImpDetectTIF( rStm, bExtendedInfo ) )	bRet = sal_True;
105 		else if ( ImpDetectPCX( rStm, bExtendedInfo ) )	bRet = sal_True;
106 		else if ( ImpDetectDXF( rStm, bExtendedInfo ) )	bRet = sal_True;
107 		else if ( ImpDetectMET( rStm, bExtendedInfo ) )	bRet = sal_True;
108 		else if ( ImpDetectSGF( rStm, bExtendedInfo ) )	bRet = sal_True;
109 		else if ( ImpDetectSGV( rStm, bExtendedInfo ) )	bRet = sal_True;
110 		else if ( ImpDetectSVM( rStm, bExtendedInfo ) )	bRet = sal_True;
111 		else if ( ImpDetectWMF( rStm, bExtendedInfo ) )	bRet = sal_True;
112 		else if ( ImpDetectEMF( rStm, bExtendedInfo ) )	bRet = sal_True;
113 		else if ( ImpDetectSVG( rStm, bExtendedInfo ) )	bRet = sal_True;
114 		else if ( ImpDetectPCT( rStm, bExtendedInfo ) )	bRet = sal_True;
115 		else if ( ImpDetectXBM( rStm, bExtendedInfo ) )	bRet = sal_True;
116 		else if ( ImpDetectXPM( rStm, bExtendedInfo ) )	bRet = sal_True;
117 		else if ( ImpDetectPBM( rStm, bExtendedInfo ) )	bRet = sal_True;
118 		else if ( ImpDetectPGM( rStm, bExtendedInfo ) )	bRet = sal_True;
119 		else if ( ImpDetectPPM( rStm, bExtendedInfo ) )	bRet = sal_True;
120 		else if ( ImpDetectRAS( rStm, bExtendedInfo ) )	bRet = sal_True;
121 		else if ( ImpDetectTGA( rStm, bExtendedInfo ) )	bRet = sal_True;
122 		else if ( ImpDetectPSD( rStm, bExtendedInfo ) )	bRet = sal_True;
123 		else if ( ImpDetectEPS( rStm, bExtendedInfo ) )	bRet = sal_True;
124 		else if ( ImpDetectPCD( rStm, bExtendedInfo ) ) bRet = sal_True;
125 
126 		rStm.SetNumberFormatInt( nOldFormat );
127 	}
128 	return bRet;
129 }
130 
131 /*************************************************************************
132 |*
133 |*
134 |*
135 \************************************************************************/
136 
ImpConstruct()137 void GraphicDescriptor::ImpConstruct()
138 {
139 	nFormat = GFF_NOT;
140 	nBitsPerPixel = 0;
141 	nPlanes = 0;
142 	bCompressed = sal_False;
143 }
144 
145 
146 /*************************************************************************
147 |*
148 |*
149 |*
150 \************************************************************************/
151 
ImpDetectBMP(SvStream & rStm,sal_Bool bExtendedInfo)152 sal_Bool GraphicDescriptor::ImpDetectBMP( SvStream& rStm, sal_Bool bExtendedInfo )
153 {
154 	sal_uInt16	nTemp16;
155 	sal_Bool	bRet = sal_False;
156 	sal_Int32 nStmPos = rStm.Tell();
157 
158 	rStm.SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
159 	rStm >> nTemp16;
160 
161 	// OS/2-BitmapArray
162 	if ( nTemp16 == 0x4142 )
163 	{
164 		rStm.SeekRel( 0x0c );
165 		rStm >> nTemp16;
166 	}
167 
168 	// Bitmap
169 	if ( nTemp16 == 0x4d42 )
170 	{
171 		nFormat = GFF_BMP;
172 		bRet = sal_True;
173 
174 		if ( bExtendedInfo )
175 		{
176 			sal_uInt32	nTemp32;
177 			sal_uInt32	nCompression;
178 
179 			// bis zur ersten Information
180 			rStm.SeekRel( 0x10 );
181 
182 			// PixelBreite auslesen
183 			rStm >> nTemp32;
184 			aPixSize.Width() = nTemp32;
185 
186 			// PixelHoehe auslesen
187 			rStm >> nTemp32;
188 			aPixSize.Height() = nTemp32;
189 
190 			// Planes auslesen
191 			rStm >> nTemp16;
192 			nPlanes = nTemp16;
193 
194 			// BitCount auslesen
195 			rStm >> nTemp16;
196 			nBitsPerPixel = nTemp16;
197 
198 			// Compression auslesen
199 			rStm >> nTemp32;
200 			bCompressed = ( ( nCompression = nTemp32 ) > 0 );
201 
202 			// logische Breite
203 			rStm.SeekRel( 4 );
204 			rStm >> nTemp32;
205 			if ( nTemp32 )
206 				aLogSize.Width() = ( aPixSize.Width() * 100000 ) / nTemp32;
207 
208 			// logische Hoehe
209 			rStm >> nTemp32;
210 			if ( nTemp32 )
211 				aLogSize.Height() = ( aPixSize.Height() * 100000 ) / nTemp32;
212 
213 			// Wir wollen noch etwas feiner differenzieren und
214 			// auf sinnvolle Werte ueberpruefen ( Bug-Id #29001 )
215 			if ( ( nBitsPerPixel > 24 ) || ( nCompression > 3 ) )
216 			{
217 				nFormat = GFF_NOT;
218 				bRet = sal_False;
219 			}
220 		}
221 	}
222 	rStm.Seek( nStmPos );
223 	return bRet;
224 }
225 
226 
227 /*************************************************************************
228 |*
229 |*
230 |*
231 \************************************************************************/
232 
ImpDetectGIF(SvStream & rStm,sal_Bool bExtendedInfo)233 sal_Bool GraphicDescriptor::ImpDetectGIF( SvStream& rStm, sal_Bool bExtendedInfo )
234 {
235 	sal_uInt32	n32;
236 	sal_uInt16	n16;
237 	sal_Bool	bRet = sal_False;
238 	sal_uInt8	cByte;
239 
240 	sal_Int32 nStmPos = rStm.Tell();
241 	rStm.SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
242 	rStm >> n32;
243 
244 	if ( n32 == 0x38464947 )
245 	{
246 		rStm >> n16;
247 		if ( ( n16 == 0x6137 ) || ( n16 == 0x6139 ) )
248 		{
249 			nFormat = GFF_GIF;
250 			bRet = sal_True;
251 
252 			if ( bExtendedInfo )
253 			{
254 				sal_uInt16 nTemp16;
255 
256 				// PixelBreite auslesen
257 				rStm >> nTemp16;
258 				aPixSize.Width() = nTemp16;
259 
260 				// PixelHoehe auslesen
261 				rStm >> nTemp16;
262 				aPixSize.Height() = nTemp16;
263 
264 				// Bits/Pixel auslesen
265 				rStm >> cByte;
266 				nBitsPerPixel = ( ( cByte & 112 ) >> 4 ) + 1;
267 			}
268 		}
269 	}
270 	rStm.Seek( nStmPos );
271 	return bRet;
272 }
273 
274 
275 /*************************************************************************
276 |*
277 |*
278 |*
279 \************************************************************************/
280 
281 // returns the next jpeg marker, a return value of 0 represents an error
ImpDetectJPG_GetNextMarker(SvStream & rStm)282 sal_uInt8 ImpDetectJPG_GetNextMarker( SvStream& rStm )
283 {
284 	sal_uInt8 nByte;
285 	do
286 	{
287 		do
288 		{
289 			rStm >> nByte;
290 			if ( rStm.IsEof() || rStm.GetError() )	// as 0 is not allowed as marker,
291 				return 0;							// we can use it as errorcode
292 		}
293 		while ( nByte != 0xff );
294 		do
295 		{
296 			rStm >> nByte;
297 			if ( rStm.IsEof() || rStm.GetError() )
298 				return 0;
299 		}
300 		while( nByte == 0xff );
301 	}
302 	while( nByte == 0 );		// 0xff00 represents 0xff and not a marker,
303 								// the marker detection has to be restartet.
304 	return nByte;
305 }
306 
ImpDetectJPG(SvStream & rStm,sal_Bool bExtendedInfo)307 sal_Bool GraphicDescriptor::ImpDetectJPG( SvStream& rStm,  sal_Bool bExtendedInfo )
308 {
309 	sal_uInt32	nTemp32;
310 	sal_Bool	bRet = sal_False;
311 
312 	sal_Int32 nStmPos = rStm.Tell();
313 
314 	rStm.SetNumberFormatInt( NUMBERFORMAT_INT_BIGENDIAN );
315 	rStm >> nTemp32;
316 
317 	// compare upper 24 bits
318 	if( 0xffd8ff00 == ( nTemp32 & 0xffffff00 ) )
319 	{
320 		nFormat = GFF_JPG;
321 		bRet = sal_True;
322 
323 		if ( bExtendedInfo )
324 		{
325 			rStm.SeekRel( -2 );
326 
327 			sal_uInt32 nError( rStm.GetError() );
328 
329 			sal_Bool bScanFailure = sal_False;
330 			sal_Bool bScanFinished = sal_False;
331 
332 			while( !bScanFailure && !bScanFinished && !rStm.IsEof() && !rStm.GetError() )
333 			{
334 				sal_uInt8 nMarker = ImpDetectJPG_GetNextMarker( rStm );
335 				switch( nMarker )
336 				{
337 					// fixed size marker, not having a two byte length parameter
338 					case 0xd0 :		// RST0
339 					case 0xd1 :
340 					case 0xd2 :
341 					case 0xd3 :
342 					case 0xd4 :
343 					case 0xd5 :
344 					case 0xd6 :
345 					case 0xd7 :		// RST7
346 					case 0x01 :		// TEM
347 					break;
348 
349 					case 0xd8 :		// SOI (has already been checked, there should not be a second one)
350 					case 0x00 :		// marker is invalid, we should stop now
351 						bScanFailure = sal_True;
352 					break;
353 
354 					case 0xd9 :		// EOI
355 						bScanFinished = sal_True;
356 					break;
357 
358 					// per default we assume marker segments conaining a length parameter
359 					default :
360 					{
361 						sal_uInt16 nLength;
362 						rStm >> nLength;
363 
364 						if ( nLength < 2 )
365 							bScanFailure = sal_True;
366 						else
367 						{
368 							sal_uInt32 nNextMarkerPos = rStm.Tell() + nLength - 2;
369 							switch( nMarker )
370 							{
371 								case 0xe0 :	// APP0 Marker
372 								{
373 									if ( nLength == 16 )
374 									{
375 										sal_Int32 nIdentifier;
376 										rStm >> nIdentifier;
377 										if ( nIdentifier == 0x4a464946 )	// JFIF Identifier
378 										{
379 											sal_uInt8	nStringTerminator;
380 											sal_uInt8	nMajorRevision;
381 											sal_uInt8	nMinorRevision;
382 											sal_uInt8	nUnits;
383 											sal_uInt16	nHorizontalResolution;
384 											sal_uInt16	nVerticalResolution;
385 											sal_uInt8	nHorzThumbnailPixelCount;
386 											sal_uInt8	nVertThumbnailPixelCount;
387 
388 											rStm >> nStringTerminator
389 												 >> nMajorRevision
390 												 >> nMinorRevision
391 												 >> nUnits
392 												 >> nHorizontalResolution
393 												 >> nVerticalResolution
394 												 >> nHorzThumbnailPixelCount
395 												 >> nVertThumbnailPixelCount;
396 
397 											// setting the logical size
398 											if ( nUnits && nHorizontalResolution && nVerticalResolution )
399 											{
400 												MapMode aMap;
401 												aMap.SetMapUnit( nUnits == 1 ? MAP_INCH : MAP_CM );
402 												aMap.SetScaleX( Fraction( 1, nHorizontalResolution ) );
403 												aMap.SetScaleY( Fraction( 1, nVerticalResolution ) );
404 												aLogSize = OutputDevice::LogicToLogic( aPixSize, aMap, MapMode( MAP_100TH_MM ) );
405 											}
406 										}
407 									}
408 								}
409 								break;
410 
411 								// Start of Frame Markers
412 								case 0xc0 :	// SOF0
413 								case 0xc1 :	// SOF1
414 								case 0xc2 :	// SOF2
415 								case 0xc3 :	// SOF3
416 								case 0xc5 :	// SOF5
417 								case 0xc6 :	// SOF6
418 								case 0xc7 :	// SOF7
419 								case 0xc9 : // SOF9
420 								case 0xca : // SOF10
421 								case 0xcb : // SOF11
422 								case 0xcd :	// SOF13
423 								case 0xce :	// SOF14
424 								case 0xcf :	// SOF15
425 								{
426 									sal_uInt8	nSamplePrecision;
427 									sal_uInt16	nNumberOfLines;
428 									sal_uInt16	nSamplesPerLine;
429 									sal_uInt8	nNumberOfImageComponents;
430 									sal_uInt8	nComponentsIdentifier;
431 									sal_uInt8	nHorizontalSamplingFactor;
432 									sal_uInt8	nVerticalSamplingFactor;
433 									sal_uInt8	nQuantizationTableDestinationSelector;
434 									rStm >> nSamplePrecision
435 										 >> nNumberOfLines
436 										 >> nSamplesPerLine
437 										 >> nNumberOfImageComponents
438 										 >> nComponentsIdentifier
439 										 >> nHorizontalSamplingFactor
440 										 >> nQuantizationTableDestinationSelector;
441 									nVerticalSamplingFactor = nHorizontalSamplingFactor & 0xf;
442 									nHorizontalSamplingFactor >>= 4;
443 
444 									aPixSize.Height() = nNumberOfLines;
445 									aPixSize.Width() = nSamplesPerLine;
446 									nBitsPerPixel = ( nNumberOfImageComponents == 3 ? 24 : nNumberOfImageComponents == 1 ? 8 : 0 );
447 									nPlanes = 1;
448 
449 									bScanFinished = sal_True;
450 								}
451 								break;
452 							}
453 							rStm.Seek( nNextMarkerPos );
454 						}
455 					}
456 					break;
457 				}
458 			}
459 			rStm.SetError( nError );
460 		}
461 	}
462 	rStm.Seek( nStmPos );
463 	return bRet;
464 }
465 
466 
467 /*************************************************************************
468 |*
469 |*
470 |*
471 \************************************************************************/
472 
ImpDetectPCD(SvStream & rStm,sal_Bool)473 sal_Bool GraphicDescriptor::ImpDetectPCD( SvStream& rStm, sal_Bool )
474 {
475 	sal_Bool	bRet = sal_False;
476 
477 	sal_Int32 nStmPos = rStm.Tell();
478 	rStm.SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
479 
480 	sal_uInt32	nTemp32;
481 	sal_uInt16	nTemp16;
482 	sal_uInt8	cByte;
483 
484 	rStm.SeekRel( 2048 );
485 	rStm >> nTemp32;
486 	rStm >> nTemp16;
487 	rStm >> cByte;
488 
489 	if ( ( nTemp32 == 0x5f444350 ) &&
490 		 ( nTemp16 == 0x5049 ) &&
491 		 ( cByte == 0x49 ) )
492 	{
493 		nFormat = GFF_PCD;
494 		bRet = sal_True;
495 	}
496 	rStm.Seek( nStmPos );
497 	return bRet;
498 }
499 
500 
501 /*************************************************************************
502 |*
503 |*
504 |*
505 \************************************************************************/
506 
ImpDetectPCX(SvStream & rStm,sal_Bool bExtendedInfo)507 sal_Bool GraphicDescriptor::ImpDetectPCX( SvStream& rStm, sal_Bool bExtendedInfo )
508 {
509 	// ! Because 0x0a can be interpreted as LF too ...
510 	// we can't be sure that this special sign represent a PCX file only.
511 	// Every Ascii file is possible here :-(
512 	// We must detect the whole header.
513 	bExtendedInfo = sal_True;
514 
515 	sal_Bool	bRet = sal_False;
516 	sal_uInt8	cByte;
517 
518 	sal_Int32 nStmPos = rStm.Tell();
519 	rStm.SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
520 	rStm >> cByte;
521 
522 	if ( cByte == 0x0a )
523 	{
524 		nFormat = GFF_PCX;
525 		bRet = sal_True;
526 
527 		if ( bExtendedInfo )
528 		{
529 			sal_uInt16	nTemp16;
530 			sal_uInt16	nXmin;
531 			sal_uInt16	nXmax;
532 			sal_uInt16	nYmin;
533 			sal_uInt16	nYmax;
534 			sal_uInt16	nDPIx;
535 			sal_uInt16	nDPIy;
536 
537 
538 			rStm.SeekRel( 1 );
539 
540 			// Kompression lesen
541 			rStm >> cByte;
542 			bCompressed = ( cByte > 0 );
543 
544 			bRet = (cByte==0 || cByte ==1);
545 
546 			// Bits/Pixel lesen
547 			rStm >> cByte;
548 			nBitsPerPixel = cByte;
549 
550 			// Bildabmessungen
551 			rStm >> nTemp16;
552 			nXmin = nTemp16;
553 			rStm >> nTemp16;
554 			nYmin = nTemp16;
555 			rStm >> nTemp16;
556 			nXmax = nTemp16;
557 			rStm >> nTemp16;
558 			nYmax = nTemp16;
559 
560 			aPixSize.Width() = nXmax - nXmin + 1;
561 			aPixSize.Height() = nYmax - nYmin + 1;
562 
563 			// Aufloesung
564 			rStm >> nTemp16;
565 			nDPIx = nTemp16;
566 			rStm >> nTemp16;
567 			nDPIy = nTemp16;
568 
569 			// logische Groesse setzen
570 			MapMode	aMap( MAP_INCH, Point(),
571 						  Fraction( 1, nDPIx ), Fraction( 1, nDPIy ) );
572 			aLogSize = OutputDevice::LogicToLogic( aPixSize, aMap,
573 												   MapMode( MAP_100TH_MM ) );
574 
575 
576 			// Anzahl Farbebenen
577 			rStm.SeekRel( 49 );
578 			rStm >> cByte;
579 			nPlanes = cByte;
580 
581 			bRet = (nPlanes<=4);
582 		}
583 	}
584 
585 	rStm.Seek( nStmPos );
586 	return bRet;
587 }
588 
589 
590 /*************************************************************************
591 |*
592 |*
593 |*
594 \************************************************************************/
595 
ImpDetectPNG(SvStream & rStm,sal_Bool bExtendedInfo)596 sal_Bool GraphicDescriptor::ImpDetectPNG( SvStream& rStm, sal_Bool bExtendedInfo )
597 {
598 	sal_uInt32	nTemp32;
599 	sal_Bool	bRet = sal_False;
600 
601 	sal_Int32 nStmPos = rStm.Tell();
602 	rStm.SetNumberFormatInt( NUMBERFORMAT_INT_BIGENDIAN );
603 	rStm >> nTemp32;
604 
605 	if ( nTemp32 == 0x89504e47 )
606 	{
607 		rStm >> nTemp32;
608 		if ( nTemp32 == 0x0d0a1a0a )
609 		{
610 			nFormat = GFF_PNG;
611 			bRet = sal_True;
612 
613 			if ( bExtendedInfo )
614 			{
615 				sal_uInt8 cByte;
616 
617 				// IHDR-Chunk
618 				rStm.SeekRel( 8 );
619 
620 				// Breite einlesen
621 				rStm >> nTemp32;
622 				aPixSize.Width() = nTemp32;
623 
624 				// Hoehe einlesen
625 				rStm >> nTemp32;
626 				aPixSize.Height() = nTemp32;
627 
628 				// Bits/Pixel einlesen
629 				rStm >> cByte;
630 				nBitsPerPixel = cByte;
631 
632 				// Planes immer 1;
633 				// Kompression immer
634 				nPlanes = 1;
635 				bCompressed = sal_True;
636 
637 				sal_uInt32	nLen32;
638 
639 				rStm.SeekRel( 8 );
640 
641 				// so lange ueberlesen, bis wir den pHYs-Chunk haben oder
642 				// den Anfang der Bilddaten
643 				rStm >> nLen32;
644 				rStm >> nTemp32;
645 				while( ( nTemp32 != 0x70485973 ) && ( nTemp32 != 0x49444154 ) )
646 				{
647 					rStm.SeekRel( 4 + nLen32 );
648 					rStm >> nLen32;
649 					rStm >> nTemp32;
650 				}
651 
652 				if ( nTemp32 == 0x70485973 )
653 				{
654 					sal_uLong	nXRes;
655 					sal_uLong	nYRes;
656 
657 					// horizontale Aufloesung
658 					rStm >> nTemp32;
659 					nXRes = nTemp32;
660 
661 					// vertikale Aufloesung
662 					rStm >> nTemp32;
663 					nYRes = nTemp32;
664 
665 					// Unit einlesen
666 					rStm >> cByte;
667 
668 					if ( cByte )
669 					{
670 						if ( nXRes )
671 							aLogSize.Width() = ( aPixSize.Width() * 100000 ) /
672 											   nTemp32;
673 
674 						if ( nYRes )
675 							aLogSize.Height() = ( aPixSize.Height() * 100000 ) /
676 												nTemp32;
677 					}
678 				}
679 			}
680 		}
681 	}
682 	rStm.Seek( nStmPos );
683 	return bRet;
684 }
685 
686 
687 /*************************************************************************
688 |*
689 |*
690 |*
691 \************************************************************************/
692 
ImpDetectTIF(SvStream & rStm,sal_Bool bExtendedInfo)693 sal_Bool GraphicDescriptor::ImpDetectTIF( SvStream& rStm, sal_Bool bExtendedInfo )
694 {
695 	sal_Bool	bDetectOk = sal_False;
696 	sal_Bool	bRet = sal_False;
697 	sal_uInt8	cByte1;
698 	sal_uInt8	cByte2;
699 
700 	sal_Int32 nStmPos = rStm.Tell();
701 	rStm >> cByte1;
702 	rStm >> cByte2;
703 	if ( cByte1 == cByte2 )
704 	{
705 		if ( cByte1 == 0x49 )
706 		{
707 			rStm.SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
708 			bDetectOk = sal_True;
709 		}
710 		else if ( cByte1 == 0x4d )
711 		{
712 			rStm.SetNumberFormatInt( NUMBERFORMAT_INT_BIGENDIAN );
713 			bDetectOk = sal_True;
714 		}
715 
716 		if ( bDetectOk )
717 		{
718 			sal_uInt16	nTemp16;
719 
720 			rStm >> nTemp16;
721 			if ( nTemp16 == 0x2a )
722 			{
723 				nFormat = GFF_TIF;
724 				bRet = sal_True;
725 
726 				if ( bExtendedInfo )
727 				{
728 					sal_uLong	nCount;
729 					sal_uLong	nMax = DATA_SIZE - 48;
730 					sal_uInt32	nTemp32;
731 					sal_Bool	bOk = sal_False;
732 
733 					// Offset des ersten IFD einlesen
734 					rStm >> nTemp32;
735 					rStm.SeekRel( ( nCount = ( nTemp32 + 2 ) ) - 0x08 );
736 
737 					if ( nCount < nMax )
738 					{
739 						// Tag's lesen, bis wir auf Tag256 ( Width ) treffen
740 						// nicht mehr Bytes als DATA_SIZE lesen
741 						rStm >> nTemp16;
742 						while ( nTemp16 != 256 )
743 						{
744                             bOk = nCount < nMax;
745                             if ( !bOk )
746                             {
747                                 break;
748                             }
749 							rStm.SeekRel( 10 );
750 							rStm >> nTemp16;
751 							nCount += 12;
752 						}
753 
754 						if ( bOk )
755 						{
756 							// Breite lesen
757 							rStm >> nTemp16;
758 							rStm.SeekRel( 4 );
759 							if ( nTemp16 == 3 )
760 							{
761 								rStm >> nTemp16;
762 								aPixSize.Width() = nTemp16;
763 								rStm.SeekRel( 2 );
764 							}
765 							else
766 							{
767 								rStm >> nTemp32;
768 								aPixSize.Width() = nTemp32;
769 							}
770 							nCount += 12;
771 
772 							// Hoehe lesen
773 							rStm.SeekRel( 2 );
774 							rStm >> nTemp16;
775 							rStm.SeekRel( 4 );
776 							if ( nTemp16 == 3 )
777 							{
778 								rStm >> nTemp16;
779 								aPixSize.Height() = nTemp16;
780 								rStm.SeekRel( 2 );
781 							}
782 							else
783 							{
784 								rStm >> nTemp32;
785 								aPixSize.Height() = nTemp32;
786 							}
787 							nCount += 12;
788 
789 							// ggf. Bits/Pixel lesen
790 							rStm >> nTemp16;
791 							if ( nTemp16 == 258 )
792 							{
793 								rStm.SeekRel( 6 );
794 								rStm >> nTemp16;
795 								nBitsPerPixel = nTemp16;
796 								rStm.SeekRel( 2 );
797 								nCount += 12;
798 							}
799 							else
800 								rStm.SeekRel( -2 );
801 
802 							// ggf. Compression lesen
803 							rStm >> nTemp16;
804 							if ( nTemp16 == 259 )
805 							{
806 								rStm.SeekRel( 6 );
807 								rStm >> nTemp16;
808 								bCompressed = ( nTemp16 > 1 );
809 								rStm.SeekRel( 2 );
810 								nCount += 12;
811 							}
812 							else
813 								rStm.SeekRel( -2 );
814 						}
815 					}
816 				}
817 			}
818 		}
819 	}
820 	rStm.Seek( nStmPos );
821 	return bRet;
822 }
823 
824 
825 /*************************************************************************
826 |*
827 |*
828 |*
829 \************************************************************************/
830 
ImpDetectXBM(SvStream &,sal_Bool)831 sal_Bool GraphicDescriptor::ImpDetectXBM( SvStream&, sal_Bool )
832 {
833 	sal_Bool bRet = aPathExt.CompareToAscii( "xbm", 3 ) == COMPARE_EQUAL;
834 	if (bRet)
835 		nFormat = GFF_XBM;
836 
837 	return bRet;
838 }
839 
840 
841 /*************************************************************************
842 |*
843 |*
844 |*
845 \************************************************************************/
846 
ImpDetectXPM(SvStream &,sal_Bool)847 sal_Bool GraphicDescriptor::ImpDetectXPM( SvStream&, sal_Bool )
848 {
849 	sal_Bool bRet = aPathExt.CompareToAscii( "xpm", 3 ) == COMPARE_EQUAL;
850 	if (bRet)
851 		nFormat = GFF_XPM;
852 
853 	return bRet;
854 }
855 
856 /*************************************************************************
857 |*
858 |*
859 |*
860 \************************************************************************/
861 
ImpDetectPBM(SvStream & rStm,sal_Bool)862 sal_Bool GraphicDescriptor::ImpDetectPBM( SvStream& rStm, sal_Bool )
863 {
864 	sal_Bool bRet = sal_False;
865 
866 	// erst auf Datei Extension pruefen, da diese aussagekraeftiger ist
867 	// als die 2 ID Bytes
868 
869 	if ( aPathExt.CompareToAscii( "pbm", 3 ) == COMPARE_EQUAL )
870 		bRet = sal_True;
871 	else
872 	{
873 		sal_Int32 nStmPos = rStm.Tell();
874 		sal_uInt8	nFirst, nSecond;
875 		rStm >> nFirst >> nSecond;
876 		if ( nFirst == 'P' && ( ( nSecond == '1' ) || ( nSecond == '4' ) ) )
877 			bRet = sal_True;
878 		rStm.Seek( nStmPos );
879 	}
880 
881 	if ( bRet )
882 		nFormat = GFF_PBM;
883 
884 	return bRet;
885 }
886 
887 /*************************************************************************
888 |*
889 |*
890 |*
891 \************************************************************************/
892 
ImpDetectPGM(SvStream & rStm,sal_Bool)893 sal_Bool GraphicDescriptor::ImpDetectPGM( SvStream& rStm, sal_Bool )
894 {
895 	sal_Bool bRet = sal_False;
896 
897 	if ( aPathExt.CompareToAscii( "pgm", 3 ) == COMPARE_EQUAL )
898 		bRet = sal_True;
899 	else
900 	{
901 		sal_uInt8 nFirst, nSecond;
902 		sal_Int32 nStmPos = rStm.Tell();
903 		rStm >> nFirst >> nSecond;
904 		if ( nFirst == 'P' && ( ( nSecond == '2' ) || ( nSecond == '5' ) ) )
905 			bRet = sal_True;
906 		rStm.Seek( nStmPos );
907 	}
908 
909 	if ( bRet )
910 		nFormat = GFF_PGM;
911 
912 	return bRet;
913 }
914 
915 /*************************************************************************
916 |*
917 |*
918 |*
919 \************************************************************************/
920 
ImpDetectPPM(SvStream & rStm,sal_Bool)921 sal_Bool GraphicDescriptor::ImpDetectPPM( SvStream& rStm, sal_Bool )
922 {
923 	sal_Bool bRet = sal_False;
924 
925 	if ( aPathExt.CompareToAscii( "ppm", 3 ) == COMPARE_EQUAL )
926 		bRet = sal_True;
927 	else
928 	{
929 		sal_uInt8	nFirst, nSecond;
930 		sal_Int32 nStmPos = rStm.Tell();
931 		rStm >> nFirst >> nSecond;
932 		if ( nFirst == 'P' && ( ( nSecond == '3' ) || ( nSecond == '6' ) ) )
933 			bRet = sal_True;
934 		rStm.Seek( nStmPos );
935 	}
936 
937 	if ( bRet )
938 		nFormat = GFF_PPM;
939 
940 	return bRet;
941 }
942 
943 /*************************************************************************
944 |*
945 |*
946 |*
947 \************************************************************************/
948 
ImpDetectRAS(SvStream & rStm,sal_Bool)949 sal_Bool GraphicDescriptor::ImpDetectRAS( SvStream& rStm, sal_Bool )
950 {
951 	sal_uInt32 nMagicNumber;
952 	sal_Bool bRet = sal_False;
953 	sal_Int32 nStmPos = rStm.Tell();
954 	rStm.SetNumberFormatInt( NUMBERFORMAT_INT_BIGENDIAN );
955 	rStm >> nMagicNumber;
956 	if ( nMagicNumber == 0x59a66a95 )
957 	{
958 		nFormat = GFF_RAS;
959 		bRet = sal_True;
960 	}
961 	rStm.Seek( nStmPos );
962 	return bRet;
963 }
964 
965 /*************************************************************************
966 |*
967 |*
968 |*
969 \************************************************************************/
970 
ImpDetectTGA(SvStream &,sal_Bool)971 sal_Bool GraphicDescriptor::ImpDetectTGA( SvStream&, sal_Bool )
972 {
973 	sal_Bool bRet = aPathExt.CompareToAscii( "tga", 3 ) == COMPARE_EQUAL;
974 	if (bRet)
975 		nFormat = GFF_TGA;
976 
977 	return bRet;
978 }
979 
980 /*************************************************************************
981 |*
982 |*
983 |*
984 \************************************************************************/
985 
ImpDetectPSD(SvStream & rStm,sal_Bool bExtendedInfo)986 sal_Bool GraphicDescriptor::ImpDetectPSD( SvStream& rStm, sal_Bool bExtendedInfo )
987 {
988 	sal_Bool bRet = sal_False;
989 
990 	sal_uInt32	nMagicNumber;
991 	sal_Int32 nStmPos = rStm.Tell();
992 	rStm.SetNumberFormatInt( NUMBERFORMAT_INT_BIGENDIAN );
993 	rStm >> nMagicNumber;
994 	if ( nMagicNumber == 0x38425053 )
995 	{
996 		sal_uInt16 nVersion;
997 		rStm >> nVersion;
998 		if ( nVersion == 1 )
999 		{
1000 			bRet = sal_True;
1001 			if ( bExtendedInfo )
1002 			{
1003 				sal_uInt16 nChannels;
1004 				sal_uInt32 nRows;
1005 				sal_uInt32 nColumns;
1006 				sal_uInt16 nDepth;
1007 				sal_uInt16 nMode;
1008 				rStm.SeekRel( 6 );	// Pad
1009 				rStm >> nChannels >> nRows >> nColumns >> nDepth >> nMode;
1010 				if ( ( nDepth == 1 ) || ( nDepth == 8 ) || ( nDepth == 16 ) )
1011 				{
1012 					nBitsPerPixel = ( nDepth == 16 ) ? 8 : nDepth;
1013 					switch ( nChannels )
1014 					{
1015 						case 4 :
1016 						case 3 :
1017 							nBitsPerPixel = 24;
1018 						case 2 :
1019 						case 1 :
1020 							aPixSize.Width() = nColumns;
1021 							aPixSize.Height() = nRows;
1022 						break;
1023 						default:
1024 							bRet = sal_False;
1025 					}
1026 				}
1027 				else
1028 					bRet = sal_False;
1029 			}
1030 		}
1031 	}
1032 
1033 	if ( bRet )
1034 		nFormat = GFF_PSD;
1035 	rStm.Seek( nStmPos );
1036 	return bRet;
1037 }
1038 
1039 /*************************************************************************
1040 |*
1041 |*
1042 |*
1043 \************************************************************************/
1044 
ImpDetectEPS(SvStream & rStm,sal_Bool)1045 sal_Bool GraphicDescriptor::ImpDetectEPS( SvStream& rStm, sal_Bool )
1046 {
1047     // es wird die EPS mit Vorschaubild Variante und die Extensionuebereinstimmung
1048     // geprueft
1049 
1050 	sal_uInt32	nFirstLong;
1051 	sal_uInt8	nFirstBytes[20];
1052 	sal_Bool		bRet = sal_False;
1053 
1054 	sal_Int32 nStmPos = rStm.Tell();
1055 	rStm.SetNumberFormatInt( NUMBERFORMAT_INT_BIGENDIAN );
1056 	rStm >> nFirstLong;
1057 	rStm.SeekRel( -4 );
1058 	rStm.Read( &nFirstBytes, 20 );
1059 
1060 	if ( ( nFirstLong == 0xC5D0D3C6 ) || ( aPathExt.CompareToAscii( "eps", 3 ) == COMPARE_EQUAL ) ||
1061 		( ImplSearchEntry( nFirstBytes, (sal_uInt8*)"%!PS-Adobe", 10, 10 )
1062 			&& ImplSearchEntry( &nFirstBytes[15], (sal_uInt8*)"EPS", 3, 3 ) ) )
1063 	{
1064 		nFormat = GFF_EPS;
1065 		bRet = sal_True;
1066 	}
1067 	rStm.Seek( nStmPos );
1068 	return bRet;
1069 }
1070 
1071 /*************************************************************************
1072 |*
1073 |*
1074 |*
1075 \************************************************************************/
1076 
ImpDetectDXF(SvStream &,sal_Bool)1077 sal_Bool GraphicDescriptor::ImpDetectDXF( SvStream&, sal_Bool )
1078 {
1079 	sal_Bool bRet = aPathExt.CompareToAscii( "dxf", 3 ) == COMPARE_EQUAL;
1080 	if (bRet)
1081 		nFormat = GFF_DXF;
1082 
1083 	return bRet;
1084 }
1085 
1086 /*************************************************************************
1087 |*
1088 |*
1089 |*
1090 \************************************************************************/
1091 
ImpDetectMET(SvStream &,sal_Bool)1092 sal_Bool GraphicDescriptor::ImpDetectMET( SvStream&, sal_Bool )
1093 {
1094 	sal_Bool bRet = aPathExt.CompareToAscii( "met", 3 ) == COMPARE_EQUAL;
1095 	if (bRet)
1096 		nFormat = GFF_MET;
1097 
1098 	return bRet;
1099 }
1100 
1101 
1102 /*************************************************************************
1103 |*
1104 |*
1105 |*
1106 \************************************************************************/
1107 
ImpDetectPCT(SvStream & rStm,sal_Bool)1108 sal_Bool GraphicDescriptor::ImpDetectPCT( SvStream& rStm, sal_Bool )
1109 {
1110 	sal_Bool bRet = aPathExt.CompareToAscii( "pct", 3 ) == COMPARE_EQUAL;
1111 	if (bRet)
1112 		nFormat = GFF_PCT;
1113 	else
1114 	{
1115         sal_Int32 nStmPos = rStm.Tell();
1116 
1117 		sal_uInt8 sBuf[4];
1118 
1119 		rStm.SeekRel( 522 );
1120 		rStm.Read( sBuf, 3 );
1121 
1122 		if( !rStm.GetError() )
1123 		{
1124 			if ( ( sBuf[0] == 0x00 ) && ( sBuf[1] == 0x11 ) &&
1125 				 ( ( sBuf[2] == 0x01 ) || ( sBuf[2] == 0x02 ) ) )
1126 			{
1127 				bRet = sal_True;
1128 				nFormat = GFF_PCT;
1129 			}
1130 		}
1131 		rStm.Seek( nStmPos );
1132 	}
1133 
1134 	return bRet;
1135 }
1136 
1137 
1138 /*************************************************************************
1139 |*
1140 |*
1141 |*
1142 \************************************************************************/
1143 
ImpDetectSGF(SvStream & rStm,sal_Bool)1144 sal_Bool GraphicDescriptor::ImpDetectSGF( SvStream& rStm, sal_Bool )
1145 {
1146 	sal_Bool bRet = sal_False;
1147 	if( aPathExt.CompareToAscii( "sgf", 3 ) == COMPARE_EQUAL )
1148 		bRet = sal_True;
1149 	else
1150 	{
1151 		sal_Int32 nStmPos = rStm.Tell();
1152 
1153 		sal_uInt8 nFirst, nSecond;
1154 
1155 		rStm >> nFirst >> nSecond;
1156 
1157         if( nFirst == 'J' && nSecond == 'J' )
1158 			bRet = sal_True;
1159 
1160 		rStm.Seek( nStmPos );
1161 	}
1162 
1163 	if( bRet )
1164 		nFormat = GFF_SGF;
1165 
1166 	return bRet;
1167 }
1168 
1169 
1170 /*************************************************************************
1171 |*
1172 |*
1173 |*
1174 \************************************************************************/
1175 
ImpDetectSGV(SvStream &,sal_Bool)1176 sal_Bool GraphicDescriptor::ImpDetectSGV( SvStream&, sal_Bool )
1177 {
1178 	sal_Bool bRet = aPathExt.CompareToAscii( "sgv", 3 ) == COMPARE_EQUAL;
1179 	if (bRet)
1180 		nFormat = GFF_SGV;
1181 
1182 	return bRet;
1183 }
1184 
1185 
1186 /*************************************************************************
1187 |*
1188 |*
1189 |*
1190 \************************************************************************/
1191 
ImpDetectSVM(SvStream & rStm,sal_Bool bExtendedInfo)1192 sal_Bool GraphicDescriptor::ImpDetectSVM( SvStream& rStm, sal_Bool bExtendedInfo )
1193 {
1194 	sal_uInt32	n32;
1195 	sal_Bool	bRet = sal_False;
1196 	sal_uInt8	cByte;
1197 
1198 	sal_Int32 nStmPos = rStm.Tell();
1199 	rStm.SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
1200 	rStm >> n32;
1201 	if ( n32 == 0x44475653 )
1202 	{
1203 		rStm >> cByte;
1204 		if ( cByte == 0x49 )
1205 		{
1206 			nFormat = GFF_SVM;
1207 			bRet = sal_True;
1208 
1209 			if ( bExtendedInfo )
1210 			{
1211 				sal_uInt32	nTemp32;
1212 				sal_uInt16	nTemp16;
1213 
1214 				rStm.SeekRel( 0x04 );
1215 
1216 				// Breite auslesen
1217 				rStm >> nTemp32;
1218 				aLogSize.Width() = nTemp32;
1219 
1220 				// Hoehe auslesen
1221 				rStm >> nTemp32;
1222 				aLogSize.Height() = nTemp32;
1223 
1224 				// Map-Unit auslesen und PrefSize ermitteln
1225 				rStm >> nTemp16;
1226 				aLogSize = OutputDevice::LogicToLogic( aLogSize,
1227 													   MapMode( (MapUnit) nTemp16 ),
1228 													   MapMode( MAP_100TH_MM ) );
1229 			}
1230 		}
1231 	}
1232 	else
1233 	{
1234 		rStm.SeekRel( -4L );
1235 		rStm >> n32;
1236 
1237 		if( n32 == 0x4D4C4356 )
1238 		{
1239 			sal_uInt16 nTmp16;
1240 
1241 			rStm >> nTmp16;
1242 
1243 			if( nTmp16 == 0x4654 )
1244 			{
1245 				nFormat = GFF_SVM;
1246 				bRet = sal_True;
1247 
1248 				if( bExtendedInfo )
1249 				{
1250 					MapMode aMapMode;
1251 
1252 					rStm.SeekRel( 0x06 );
1253 					rStm >> aMapMode;
1254 					rStm >> aLogSize;
1255 					aLogSize = OutputDevice::LogicToLogic( aLogSize, aMapMode, MapMode( MAP_100TH_MM ) );
1256 				}
1257 			}
1258 		}
1259 	}
1260 	rStm.Seek( nStmPos );
1261 	return bRet;
1262 }
1263 
1264 
1265 /*************************************************************************
1266 |*
1267 |*
1268 |*
1269 \************************************************************************/
1270 
ImpDetectWMF(SvStream &,sal_Bool)1271 sal_Bool GraphicDescriptor::ImpDetectWMF( SvStream&, sal_Bool )
1272 {
1273 	sal_Bool bRet = aPathExt.CompareToAscii( "wmf",3 ) == COMPARE_EQUAL;
1274 	if (bRet)
1275 		nFormat = GFF_WMF;
1276 
1277 	return bRet;
1278 }
1279 
1280 /*************************************************************************
1281 |*
1282 |*
1283 |*
1284 \************************************************************************/
1285 
ImpDetectEMF(SvStream &,sal_Bool)1286 sal_Bool GraphicDescriptor::ImpDetectEMF( SvStream&, sal_Bool )
1287 {
1288 	sal_Bool bRet = aPathExt.CompareToAscii( "emf", 3 ) == COMPARE_EQUAL;
1289 	if (bRet)
1290 		nFormat = GFF_EMF;
1291 
1292 	return bRet;
1293 }
1294 
1295 /*************************************************************************
1296 |*
1297 |*
1298 |*
1299 \************************************************************************/
1300 
ImpDetectSVG(SvStream &,sal_Bool)1301 sal_Bool GraphicDescriptor::ImpDetectSVG( SvStream& /*rStm*/, sal_Bool /*bExtendedInfo*/ )
1302 {
1303 	sal_Bool bRet = aPathExt.CompareToAscii( "svg", 3 ) == COMPARE_EQUAL;
1304 	if (bRet)
1305 		nFormat = GFF_SVG;
1306 
1307 	return bRet;
1308 }
1309 
1310 /*************************************************************************
1311 |*
1312 |*
1313 |*
1314 \************************************************************************/
1315 
GetImportFormatShortName(sal_uInt16 nFormat)1316 String GraphicDescriptor::GetImportFormatShortName( sal_uInt16 nFormat )
1317 {
1318 	ByteString			aKeyName;
1319 
1320 	switch( nFormat )
1321 	{
1322 		case( GFF_BMP ) :	aKeyName = "bmp";	break;
1323 		case( GFF_GIF ) :	aKeyName = "gif";	break;
1324 		case( GFF_JPG ) :	aKeyName = "jpg";	break;
1325 		case( GFF_PCD ) :	aKeyName = "pcd";	break;
1326 		case( GFF_PCX ) :	aKeyName = "pcx";	break;
1327 		case( GFF_PNG ) :	aKeyName = "png";	break;
1328 		case( GFF_XBM ) :	aKeyName = "xbm";	break;
1329 		case( GFF_XPM ) :	aKeyName = "xpm";	break;
1330 		case( GFF_PBM ) :	aKeyName = "pbm";	break;
1331 		case( GFF_PGM ) :	aKeyName = "pgm";	break;
1332 		case( GFF_PPM ) :	aKeyName = "ppm";	break;
1333 		case( GFF_RAS ) :	aKeyName = "ras";	break;
1334 		case( GFF_TGA ) :	aKeyName = "tga";	break;
1335 		case( GFF_PSD ) :	aKeyName = "psd";	break;
1336 		case( GFF_EPS ) :	aKeyName = "eps";	break;
1337 		case( GFF_TIF ) :	aKeyName = "tif";	break;
1338 		case( GFF_DXF ) :	aKeyName = "dxf";	break;
1339 		case( GFF_MET ) :	aKeyName = "met";	break;
1340 		case( GFF_PCT ) :	aKeyName = "pct";	break;
1341 		case( GFF_SGF ) :	aKeyName = "sgf";	break;
1342 		case( GFF_SGV ) :	aKeyName = "sgv";	break;
1343 		case( GFF_SVM ) :	aKeyName = "svm";	break;
1344 		case( GFF_WMF ) :	aKeyName = "wmf";	break;
1345 		case( GFF_EMF ) :	aKeyName = "emf";	break;
1346 		case( GFF_SVG ) :	aKeyName = "svg";	break;
1347 	}
1348 
1349 	return String( aKeyName, RTL_TEXTENCODING_ASCII_US );
1350 }
1351