tdf#130857 qt weld: Support mail merge "Server Auth" dialog
[LibreOffice.git] / vcl / source / filter / graphicfilter2.cxx
blobd1a84c7b1ad9fb1c421d003294f8985aa8997020
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <string.h>
21 #include <tools/stream.hxx>
22 #include <tools/fract.hxx>
23 #include <tools/urlobj.hxx>
24 #include <tools/zcodec.hxx>
25 #include <vcl/outdev.hxx>
26 #include <vcl/graphicfilter.hxx>
27 #include <unotools/ucbstreamhelper.hxx>
28 #include <graphic/GraphicFormatDetector.hxx>
30 GraphicDescriptor::GraphicDescriptor( const INetURLObject& rPath ) :
31 pFileStm( ::utl::UcbStreamHelper::CreateStream( rPath.GetMainURL( INetURLObject::DecodeMechanism::NONE ), StreamMode::READ ).release() ),
32 aPathExt( rPath.GetFileExtension().toAsciiLowerCase() ),
33 bOwnStream( true )
37 GraphicDescriptor::GraphicDescriptor( SvStream& rInStream, const OUString* pPath) :
38 pFileStm ( &rInStream ),
39 bOwnStream ( false )
41 if ( pPath )
43 INetURLObject aURL( *pPath );
44 aPathExt = aURL.GetFileExtension().toAsciiLowerCase();
48 GraphicDescriptor::~GraphicDescriptor()
50 if ( bOwnStream )
51 delete pFileStm;
54 bool GraphicDescriptor::Detect( bool bExtendedInfo )
56 bool bRet = false;
57 if ( pFileStm && !pFileStm->GetError() )
59 SvStream& rStm = *pFileStm;
60 SvStreamEndian nOldFormat = rStm.GetEndian();
62 if ( ImpDetectGIF( rStm, bExtendedInfo ) ) bRet = true;
63 else if ( ImpDetectJPG( rStm, bExtendedInfo ) ) bRet = true;
64 else if ( ImpDetectBMP( rStm, bExtendedInfo ) ) bRet = true;
65 else if ( ImpDetectPNG( rStm, bExtendedInfo ) ) bRet = true;
66 else if ( ImpDetectTIF( rStm, bExtendedInfo ) ) bRet = true;
67 else if ( ImpDetectPCX( rStm ) ) bRet = true;
68 else if ( ImpDetectDXF( rStm, bExtendedInfo ) ) bRet = true;
69 else if ( ImpDetectMET( rStm, bExtendedInfo ) ) bRet = true;
70 else if ( ImpDetectSVM( rStm, bExtendedInfo ) ) bRet = true;
71 else if ( ImpDetectWMF( rStm, bExtendedInfo ) ) bRet = true;
72 else if ( ImpDetectEMF( rStm, bExtendedInfo ) ) bRet = true;
73 else if ( ImpDetectSVG( rStm, bExtendedInfo ) ) bRet = true;
74 else if ( ImpDetectPCT( rStm, bExtendedInfo ) ) bRet = true;
75 else if ( ImpDetectXBM( rStm, bExtendedInfo ) ) bRet = true;
76 else if ( ImpDetectXPM( rStm, bExtendedInfo ) ) bRet = true;
77 else if ( ImpDetectPBM( rStm, bExtendedInfo ) ) bRet = true;
78 else if ( ImpDetectPGM( rStm, bExtendedInfo ) ) bRet = true;
79 else if ( ImpDetectPPM( rStm, bExtendedInfo ) ) bRet = true;
80 else if ( ImpDetectRAS( rStm, bExtendedInfo ) ) bRet = true;
81 else if ( ImpDetectTGA( rStm, bExtendedInfo ) ) bRet = true;
82 else if ( ImpDetectPSD( rStm, bExtendedInfo ) ) bRet = true;
83 else if ( ImpDetectEPS( rStm, bExtendedInfo ) ) bRet = true;
84 else if ( ImpDetectPCD( rStm, bExtendedInfo ) ) bRet = true;
85 else if ( ImpDetectWEBP( rStm, bExtendedInfo ) ) bRet = true;
87 rStm.SetEndian( nOldFormat );
89 return bRet;
92 bool GraphicDescriptor::ImpDetectBMP( SvStream& rStm, bool bExtendedInfo )
94 vcl::GraphicFormatDetector aDetector( rStm, aPathExt, bExtendedInfo );
95 bool bRet = aDetector.detect() && aDetector.checkBMP();
96 if ( bRet )
97 aMetadata = aDetector.getMetadata();
98 return bRet;
101 bool GraphicDescriptor::ImpDetectGIF( SvStream& rStm, bool bExtendedInfo )
103 vcl::GraphicFormatDetector aDetector( rStm, aPathExt, bExtendedInfo );
104 bool bRet = aDetector.detect() && aDetector.checkGIF();
105 if ( bRet )
106 aMetadata = aDetector.getMetadata();
107 return bRet;
110 // returns the next jpeg marker, a return value of 0 represents an error
111 static sal_uInt8 ImpDetectJPG_GetNextMarker( SvStream& rStm )
113 sal_uInt8 nByte;
118 rStm.ReadUChar( nByte );
119 if (!rStm.good()) // as 0 is not allowed as marker,
120 return 0; // we can use it as errorcode
122 while ( nByte != 0xff );
125 rStm.ReadUChar( nByte );
126 if (!rStm.good())
127 return 0;
129 while( nByte == 0xff );
131 while( nByte == 0 ); // 0xff00 represents 0xff and not a marker,
132 // the marker detection has to be restarted.
133 return nByte;
136 bool GraphicDescriptor::ImpDetectJPG( SvStream& rStm, bool bExtendedInfo )
138 sal_uInt32 nTemp32 = 0;
139 bool bRet = false;
141 sal_uInt64 nStmPos = rStm.Tell();
143 rStm.SetEndian( SvStreamEndian::BIG );
144 rStm.ReadUInt32( nTemp32 );
146 // compare upper 24 bits
147 if( 0xffd8ff00 == ( nTemp32 & 0xffffff00 ) )
149 aMetadata.mnFormat = GraphicFileFormat::JPG;
150 bRet = true;
152 if ( bExtendedInfo )
154 rStm.SeekRel( -2 );
156 ErrCode nError( rStm.GetError() );
158 bool bScanFailure = false;
159 bool bScanFinished = false;
160 MapMode aMap;
162 while (!bScanFailure && !bScanFinished && rStm.good())
164 sal_uInt8 nMarker = ImpDetectJPG_GetNextMarker( rStm );
165 switch( nMarker )
167 // fixed size marker, not having a two byte length parameter
168 case 0xd0 : // RST0
169 case 0xd1 :
170 case 0xd2 :
171 case 0xd3 :
172 case 0xd4 :
173 case 0xd5 :
174 case 0xd6 :
175 case 0xd7 : // RST7
176 case 0x01 : // TEM
177 break;
179 case 0xd8 : // SOI (has already been checked, there should not be a second one)
180 case 0x00 : // marker is invalid, we should stop now
181 bScanFailure = true;
182 break;
184 case 0xd9 : // EOI
185 bScanFinished = true;
186 break;
188 // per default we assume marker segments containing a length parameter
189 default :
191 sal_uInt16 nLength = 0;
192 rStm.ReadUInt16( nLength );
194 if ( nLength < 2 )
195 bScanFailure = true;
196 else
198 sal_uInt64 nNextMarkerPos = rStm.Tell() + nLength - 2;
199 switch( nMarker )
201 case 0xe0 : // APP0 Marker
203 if ( nLength == 16 )
205 sal_Int32 nIdentifier = 0;
206 rStm.ReadInt32( nIdentifier );
207 if ( nIdentifier == 0x4a464946 ) // JFIF Identifier
209 sal_uInt8 nStringTerminator = 0;
210 sal_uInt8 nMajorRevision = 0;
211 sal_uInt8 nMinorRevision = 0;
212 sal_uInt8 nUnits = 0;
213 sal_uInt16 nHorizontalResolution = 0;
214 sal_uInt16 nVerticalResolution = 0;
215 sal_uInt8 nHorzThumbnailPixelCount = 0;
216 sal_uInt8 nVertThumbnailPixelCount = 0;
218 rStm.ReadUChar( nStringTerminator )
219 .ReadUChar( nMajorRevision )
220 .ReadUChar( nMinorRevision )
221 .ReadUChar( nUnits )
222 .ReadUInt16( nHorizontalResolution )
223 .ReadUInt16( nVerticalResolution )
224 .ReadUChar( nHorzThumbnailPixelCount )
225 .ReadUChar( nVertThumbnailPixelCount );
227 // setting the logical size
228 if ( nUnits && nHorizontalResolution && nVerticalResolution )
230 aMap.SetMapUnit( nUnits == 1 ? MapUnit::MapInch : MapUnit::MapCM );
231 aMap.SetScaleX( Fraction( 1, nHorizontalResolution ) );
232 aMap.SetScaleY( Fraction( 1, nVerticalResolution ) );
233 aMetadata.maLogSize = OutputDevice::LogicToLogic( aMetadata.maPixSize, aMap, MapMode( MapUnit::Map100thMM ) );
238 break;
240 // Start of Frame Markers
241 case 0xc0 : // SOF0
242 case 0xc1 : // SOF1
243 case 0xc2 : // SOF2
244 case 0xc3 : // SOF3
245 case 0xc5 : // SOF5
246 case 0xc6 : // SOF6
247 case 0xc7 : // SOF7
248 case 0xc9 : // SOF9
249 case 0xca : // SOF10
250 case 0xcb : // SOF11
251 case 0xcd : // SOF13
252 case 0xce : // SOF14
253 case 0xcf : // SOF15
255 sal_uInt8 nSamplePrecision = 0;
256 sal_uInt16 nNumberOfLines = 0;
257 sal_uInt16 nSamplesPerLine = 0;
258 sal_uInt8 nNumberOfImageComponents = 0;
259 sal_uInt8 nComponentsIdentifier = 0;
260 sal_uInt8 nSamplingFactor = 0;
261 sal_uInt8 nQuantizationTableDestinationSelector = 0;
262 rStm.ReadUChar( nSamplePrecision )
263 .ReadUInt16( nNumberOfLines )
264 .ReadUInt16( nSamplesPerLine )
265 .ReadUChar( nNumberOfImageComponents )
266 .ReadUChar( nComponentsIdentifier )
267 .ReadUChar( nSamplingFactor )
268 .ReadUChar( nQuantizationTableDestinationSelector );
269 aMetadata.mnNumberOfImageComponents = nNumberOfImageComponents;
271 // nSamplingFactor (lower nibble: vertical,
272 // upper nibble: horizontal) is unused
274 aMetadata.maPixSize.setHeight( nNumberOfLines );
275 aMetadata.maPixSize.setWidth( nSamplesPerLine );
276 aMetadata.mnBitsPerPixel = ( nNumberOfImageComponents == 3 ? 24 : nNumberOfImageComponents == 1 ? 8 : 0 );
277 aMetadata.mnPlanes = 1;
279 if (aMap.GetMapUnit() != MapUnit::MapPixel)
280 // We already know the DPI, but the
281 // pixel size arrived later, so do the
282 // conversion again.
283 aMetadata.maLogSize = OutputDevice::LogicToLogic(
284 aMetadata.maPixSize, aMap, MapMode(MapUnit::Map100thMM));
286 bScanFinished = true;
288 break;
290 rStm.Seek( nNextMarkerPos );
293 break;
296 rStm.SetError( nError );
299 rStm.Seek( nStmPos );
300 return bRet;
303 bool GraphicDescriptor::ImpDetectPCD( SvStream& rStm, bool )
305 vcl::GraphicFormatDetector aDetector( rStm, aPathExt, false /*bExtendedInfo*/ );
306 bool bRet = aDetector.detect() && aDetector.checkPCD();
307 if ( bRet )
308 aMetadata = aDetector.getMetadata();
309 return bRet;
312 bool GraphicDescriptor::ImpDetectPCX( SvStream& rStm )
314 vcl::GraphicFormatDetector aDetector( rStm, aPathExt, true /*bExtendedInfo*/ );
315 bool bRet = aDetector.detect() && aDetector.checkPCX();
316 if ( bRet )
317 aMetadata = aDetector.getMetadata();
318 return bRet;
321 bool GraphicDescriptor::ImpDetectPNG( SvStream& rStm, bool bExtendedInfo )
323 vcl::GraphicFormatDetector aDetector( rStm, aPathExt, bExtendedInfo );
324 bool bRet = aDetector.detect() && aDetector.checkPNG();
325 if ( bRet )
326 aMetadata = aDetector.getMetadata();
327 return bRet;
330 bool GraphicDescriptor::ImpDetectTIF( SvStream& rStm, bool bExtendedInfo )
332 vcl::GraphicFormatDetector aDetector( rStm, aPathExt, bExtendedInfo );
333 bool bRet = aDetector.detect() && aDetector.checkTIF();
334 if ( bRet )
335 aMetadata = aDetector.getMetadata();
336 return bRet;
339 bool GraphicDescriptor::ImpDetectXBM( SvStream& rStm, bool )
341 vcl::GraphicFormatDetector aDetector( rStm, aPathExt, false /* bExtendedInfo */ );
342 bool bRet = aDetector.detect() && aDetector.checkXBM();
343 if ( bRet )
344 aMetadata = aDetector.getMetadata();
345 return bRet;
348 bool GraphicDescriptor::ImpDetectXPM( SvStream& rStm, bool )
350 vcl::GraphicFormatDetector aDetector( rStm, aPathExt, false /* bExtendedInfo */ );
351 bool bRet = aDetector.detect() && aDetector.checkXPM();
352 if ( bRet )
353 aMetadata = aDetector.getMetadata();
354 return bRet;
357 bool GraphicDescriptor::ImpDetectPBM( SvStream& rStm, bool )
359 vcl::GraphicFormatDetector aDetector( rStm, aPathExt, false /* bExtendedInfo */ );
360 bool bRet = aDetector.detect() && aDetector.checkPBM();
361 if ( bRet )
362 aMetadata = aDetector.getMetadata();
363 return bRet;
366 bool GraphicDescriptor::ImpDetectPGM( SvStream& rStm, bool )
368 vcl::GraphicFormatDetector aDetector( rStm, aPathExt, false /* bExtendedInfo */ );
369 bool bRet = aDetector.detect() && aDetector.checkPGM();
370 if ( bRet )
371 aMetadata = aDetector.getMetadata();
372 return bRet;
375 bool GraphicDescriptor::ImpDetectPPM( SvStream& rStm, bool )
377 vcl::GraphicFormatDetector aDetector( rStm, aPathExt, false /* bExtendedInfo */ );
378 bool bRet = aDetector.detect() && aDetector.checkPPM();
379 if ( bRet )
380 aMetadata = aDetector.getMetadata();
381 return bRet;
384 bool GraphicDescriptor::ImpDetectRAS( SvStream& rStm, bool )
386 vcl::GraphicFormatDetector aDetector( rStm, aPathExt, false /* bExtendedInfo */ );
387 bool bRet = aDetector.detect() && aDetector.checkRAS();
388 if ( bRet )
389 aMetadata = aDetector.getMetadata();
390 return bRet;
393 bool GraphicDescriptor::ImpDetectTGA( SvStream& rStm, bool )
395 vcl::GraphicFormatDetector aDetector( rStm, aPathExt, false /* bExtendedInfo */ );
396 bool bRet = aDetector.detect() && aDetector.checkTGA();
397 if ( bRet )
398 aMetadata = aDetector.getMetadata();
399 return bRet;
402 bool GraphicDescriptor::ImpDetectPSD( SvStream& rStm, bool bExtendedInfo )
404 vcl::GraphicFormatDetector aDetector( rStm, aPathExt, bExtendedInfo );
405 bool bRet = aDetector.detect() && aDetector.checkPSD();
406 if ( bRet )
407 aMetadata = aDetector.getMetadata();
408 return bRet;
411 bool GraphicDescriptor::ImpDetectEPS( SvStream& rStm, bool )
413 vcl::GraphicFormatDetector aDetector( rStm, aPathExt, false /*bExtendedInfo*/ );
414 bool bRet = aDetector.detect() && aDetector.checkEPS();
415 if ( bRet )
416 aMetadata = aDetector.getMetadata();
417 return bRet;
420 bool GraphicDescriptor::ImpDetectDXF( SvStream& rStm, bool )
422 vcl::GraphicFormatDetector aDetector( rStm, aPathExt, false /*bExtendedInfo*/ );
423 bool bRet = aDetector.detect() && aDetector.checkDXF();
424 if ( bRet )
425 aMetadata = aDetector.getMetadata();
426 return bRet;
429 bool GraphicDescriptor::ImpDetectMET( SvStream& rStm, bool )
431 vcl::GraphicFormatDetector aDetector( rStm, aPathExt, false /*bExtendedInfo*/ );
432 bool bRet = aDetector.detect() && aDetector.checkMET();
433 if ( bRet )
434 aMetadata = aDetector.getMetadata();
435 return bRet;
438 bool GraphicDescriptor::ImpDetectPCT( SvStream& rStm, bool )
440 vcl::GraphicFormatDetector aDetector( rStm, aPathExt, false /*bExtendedInfo*/ );
441 bool bRet = aDetector.detect() && aDetector.checkPCT();
442 if ( bRet )
443 aMetadata = aDetector.getMetadata();
444 return bRet;
447 bool GraphicDescriptor::ImpDetectSVM( SvStream& rStm, bool bExtendedInfo )
449 vcl::GraphicFormatDetector aDetector( rStm, aPathExt, bExtendedInfo );
450 bool bRet = aDetector.detect() && aDetector.checkSVM();
451 if ( bRet )
452 aMetadata = aDetector.getMetadata();
453 return bRet;
456 bool GraphicDescriptor::ImpDetectWMF(SvStream& rStm, bool /*bExtendedInfo*/)
458 vcl::GraphicFormatDetector aDetector( rStm, aPathExt, false /*bExtendedInfo*/ );
459 bool bRet = aDetector.detect() && aDetector.checkWMF();
460 if ( bRet )
461 aMetadata = aDetector.getMetadata();
462 return bRet;
465 bool GraphicDescriptor::ImpDetectEMF(SvStream& rStm, bool bExtendedInfo)
467 vcl::GraphicFormatDetector aDetector( rStm, aPathExt, bExtendedInfo );
468 bool bRet = aDetector.detect() && aDetector.checkEMF();
469 if ( bRet )
470 aMetadata = aDetector.getMetadata();
471 return bRet;
474 bool GraphicDescriptor::ImpDetectSVG( SvStream& rStm, bool /*bExtendedInfo*/ )
476 vcl::GraphicFormatDetector aDetector( rStm, aPathExt, false /*bExtendedInfo*/ );
477 bool bRet = aDetector.detect() && aDetector.checkSVG();
478 if ( bRet )
479 aMetadata = aDetector.getMetadata();
480 return bRet;
483 bool GraphicDescriptor::ImpDetectWEBP( SvStream& rStm, bool bExtendedInfo )
485 vcl::GraphicFormatDetector aDetector( rStm, aPathExt, bExtendedInfo );
486 bool bRet = aDetector.detect() && aDetector.checkWEBP();
487 if ( bRet )
488 aMetadata = aDetector.getMetadata();
489 return bRet;
492 OUString GraphicDescriptor::GetImportFormatShortName( GraphicFileFormat nFormat )
494 return vcl::getImportFormatShortName( nFormat );
497 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */