xref: /AOO41X/main/svtools/source/filter/filter2.cxx (revision 5900e8ec128faec89519683efce668ccd8cc6084)
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 cant be shure 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