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