LibreOffice Module vcl (master) 1
graphicfilter2.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
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 .
18 */
19
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>
29
31 pFileStm( ::utl::UcbStreamHelper::CreateStream( rPath.GetMainURL( INetURLObject::DecodeMechanism::NONE ), StreamMode::READ ).release() ),
32 aPathExt( rPath.GetFileExtension().toAsciiLowerCase() ),
33 bOwnStream( true )
34{
36}
37
38GraphicDescriptor::GraphicDescriptor( SvStream& rInStream, const OUString* pPath) :
39 pFileStm ( &rInStream ),
40 bOwnStream ( false )
41{
43
44 if ( pPath )
45 {
46 INetURLObject aURL( *pPath );
47 aPathExt = aURL.GetFileExtension().toAsciiLowerCase();
48 }
49}
50
52{
53 if ( bOwnStream )
54 delete pFileStm;
55}
56
57bool GraphicDescriptor::Detect( bool bExtendedInfo )
58{
59 bool bRet = false;
60 if ( pFileStm && !pFileStm->GetError() )
61 {
62 SvStream& rStm = *pFileStm;
63 SvStreamEndian nOldFormat = rStm.GetEndian();
64
65 if ( ImpDetectGIF( rStm, bExtendedInfo ) ) bRet = true;
66 else if ( ImpDetectJPG( rStm, bExtendedInfo ) ) bRet = true;
67 else if ( ImpDetectBMP( rStm, bExtendedInfo ) ) bRet = true;
68 else if ( ImpDetectPNG( rStm, bExtendedInfo ) ) bRet = true;
69 else if ( ImpDetectTIF( rStm, bExtendedInfo ) ) bRet = true;
70 else if ( ImpDetectPCX( rStm ) ) bRet = true;
71 else if ( ImpDetectDXF( rStm, bExtendedInfo ) ) bRet = true;
72 else if ( ImpDetectMET( rStm, bExtendedInfo ) ) bRet = true;
73 else if ( ImpDetectSVM( rStm, bExtendedInfo ) ) bRet = true;
74 else if ( ImpDetectWMF( rStm, bExtendedInfo ) ) bRet = true;
75 else if ( ImpDetectEMF( rStm, bExtendedInfo ) ) bRet = true;
76 else if ( ImpDetectSVG( rStm, bExtendedInfo ) ) bRet = true;
77 else if ( ImpDetectPCT( rStm, bExtendedInfo ) ) bRet = true;
78 else if ( ImpDetectXBM( rStm, bExtendedInfo ) ) bRet = true;
79 else if ( ImpDetectXPM( rStm, bExtendedInfo ) ) bRet = true;
80 else if ( ImpDetectPBM( rStm, bExtendedInfo ) ) bRet = true;
81 else if ( ImpDetectPGM( rStm, bExtendedInfo ) ) bRet = true;
82 else if ( ImpDetectPPM( rStm, bExtendedInfo ) ) bRet = true;
83 else if ( ImpDetectRAS( rStm, bExtendedInfo ) ) bRet = true;
84 else if ( ImpDetectTGA( rStm, bExtendedInfo ) ) bRet = true;
85 else if ( ImpDetectPSD( rStm, bExtendedInfo ) ) bRet = true;
86 else if ( ImpDetectEPS( rStm, bExtendedInfo ) ) bRet = true;
87 else if ( ImpDetectPCD( rStm, bExtendedInfo ) ) bRet = true;
88 else if ( ImpDetectWEBP( rStm, bExtendedInfo ) ) bRet = true;
89
90 rStm.SetEndian( nOldFormat );
91 }
92 return bRet;
93}
94
96{
102 aMetadata.mbIsAlpha = false;
103}
104
105bool GraphicDescriptor::ImpDetectBMP( SvStream& rStm, bool bExtendedInfo )
106{
107 vcl::GraphicFormatDetector aDetector( rStm, aPathExt, bExtendedInfo );
108 bool bRet = aDetector.detect() && aDetector.checkBMP();
109 if ( bRet )
110 aMetadata = aDetector.getMetadata();
111 return bRet;
112}
113
114bool GraphicDescriptor::ImpDetectGIF( SvStream& rStm, bool bExtendedInfo )
115{
116 vcl::GraphicFormatDetector aDetector( rStm, aPathExt, bExtendedInfo );
117 bool bRet = aDetector.detect() && aDetector.checkGIF();
118 if ( bRet )
119 aMetadata = aDetector.getMetadata();
120 return bRet;
121}
122
123// returns the next jpeg marker, a return value of 0 represents an error
125{
126 sal_uInt8 nByte;
127 do
128 {
129 do
130 {
131 rStm.ReadUChar( nByte );
132 if (!rStm.good()) // as 0 is not allowed as marker,
133 return 0; // we can use it as errorcode
134 }
135 while ( nByte != 0xff );
136 do
137 {
138 rStm.ReadUChar( nByte );
139 if (!rStm.good())
140 return 0;
141 }
142 while( nByte == 0xff );
143 }
144 while( nByte == 0 ); // 0xff00 represents 0xff and not a marker,
145 // the marker detection has to be restarted.
146 return nByte;
147}
148
149bool GraphicDescriptor::ImpDetectJPG( SvStream& rStm, bool bExtendedInfo )
150{
151 sal_uInt32 nTemp32 = 0;
152 bool bRet = false;
153
154 sal_Int32 nStmPos = rStm.Tell();
155
156 rStm.SetEndian( SvStreamEndian::BIG );
157 rStm.ReadUInt32( nTemp32 );
158
159 // compare upper 24 bits
160 if( 0xffd8ff00 == ( nTemp32 & 0xffffff00 ) )
161 {
163 bRet = true;
164
165 if ( bExtendedInfo )
166 {
167 rStm.SeekRel( -2 );
168
169 ErrCode nError( rStm.GetError() );
170
171 bool bScanFailure = false;
172 bool bScanFinished = false;
174
175 while (!bScanFailure && !bScanFinished && rStm.good())
176 {
177 sal_uInt8 nMarker = ImpDetectJPG_GetNextMarker( rStm );
178 switch( nMarker )
179 {
180 // fixed size marker, not having a two byte length parameter
181 case 0xd0 : // RST0
182 case 0xd1 :
183 case 0xd2 :
184 case 0xd3 :
185 case 0xd4 :
186 case 0xd5 :
187 case 0xd6 :
188 case 0xd7 : // RST7
189 case 0x01 : // TEM
190 break;
191
192 case 0xd8 : // SOI (has already been checked, there should not be a second one)
193 case 0x00 : // marker is invalid, we should stop now
194 bScanFailure = true;
195 break;
196
197 case 0xd9 : // EOI
198 bScanFinished = true;
199 break;
200
201 // per default we assume marker segments containing a length parameter
202 default :
203 {
204 sal_uInt16 nLength = 0;
205 rStm.ReadUInt16( nLength );
206
207 if ( nLength < 2 )
208 bScanFailure = true;
209 else
210 {
211 sal_uInt32 nNextMarkerPos = rStm.Tell() + nLength - 2;
212 switch( nMarker )
213 {
214 case 0xe0 : // APP0 Marker
215 {
216 if ( nLength == 16 )
217 {
218 sal_Int32 nIdentifier = 0;
219 rStm.ReadInt32( nIdentifier );
220 if ( nIdentifier == 0x4a464946 ) // JFIF Identifier
221 {
222 sal_uInt8 nStringTerminator = 0;
223 sal_uInt8 nMajorRevision = 0;
224 sal_uInt8 nMinorRevision = 0;
225 sal_uInt8 nUnits = 0;
226 sal_uInt16 nHorizontalResolution = 0;
227 sal_uInt16 nVerticalResolution = 0;
228 sal_uInt8 nHorzThumbnailPixelCount = 0;
229 sal_uInt8 nVertThumbnailPixelCount = 0;
230
231 rStm.ReadUChar( nStringTerminator )
232 .ReadUChar( nMajorRevision )
233 .ReadUChar( nMinorRevision )
234 .ReadUChar( nUnits )
235 .ReadUInt16( nHorizontalResolution )
236 .ReadUInt16( nVerticalResolution )
237 .ReadUChar( nHorzThumbnailPixelCount )
238 .ReadUChar( nVertThumbnailPixelCount );
239
240 // setting the logical size
241 if ( nUnits && nHorizontalResolution && nVerticalResolution )
242 {
243 aMap.SetMapUnit( nUnits == 1 ? MapUnit::MapInch : MapUnit::MapCM );
244 aMap.SetScaleX( Fraction( 1, nHorizontalResolution ) );
245 aMap.SetScaleY( Fraction( 1, nVerticalResolution ) );
247 }
248 }
249 }
250 }
251 break;
252
253 // Start of Frame Markers
254 case 0xc0 : // SOF0
255 case 0xc1 : // SOF1
256 case 0xc2 : // SOF2
257 case 0xc3 : // SOF3
258 case 0xc5 : // SOF5
259 case 0xc6 : // SOF6
260 case 0xc7 : // SOF7
261 case 0xc9 : // SOF9
262 case 0xca : // SOF10
263 case 0xcb : // SOF11
264 case 0xcd : // SOF13
265 case 0xce : // SOF14
266 case 0xcf : // SOF15
267 {
268 sal_uInt8 nSamplePrecision = 0;
269 sal_uInt16 nNumberOfLines = 0;
270 sal_uInt16 nSamplesPerLine = 0;
271 sal_uInt8 nNumberOfImageComponents = 0;
272 sal_uInt8 nComponentsIdentifier = 0;
273 sal_uInt8 nSamplingFactor = 0;
274 sal_uInt8 nQuantizationTableDestinationSelector = 0;
275 rStm.ReadUChar( nSamplePrecision )
276 .ReadUInt16( nNumberOfLines )
277 .ReadUInt16( nSamplesPerLine )
278 .ReadUChar( nNumberOfImageComponents )
279 .ReadUChar( nComponentsIdentifier )
280 .ReadUChar( nSamplingFactor )
281 .ReadUChar( nQuantizationTableDestinationSelector );
282 aMetadata.mnNumberOfImageComponents = nNumberOfImageComponents;
283
284 // nSamplingFactor (lower nibble: vertical,
285 // upper nibble: horizontal) is unused
286
287 aMetadata.maPixSize.setHeight( nNumberOfLines );
288 aMetadata.maPixSize.setWidth( nSamplesPerLine );
289 aMetadata.mnBitsPerPixel = ( nNumberOfImageComponents == 3 ? 24 : nNumberOfImageComponents == 1 ? 8 : 0 );
291
292 if (aMap.GetMapUnit() != MapUnit::MapPixel)
293 // We already know the DPI, but the
294 // pixel size arrived later, so do the
295 // conversion again.
297 aMetadata.maPixSize, aMap, MapMode(MapUnit::Map100thMM));
298
299 bScanFinished = true;
300 }
301 break;
302 }
303 rStm.Seek( nNextMarkerPos );
304 }
305 }
306 break;
307 }
308 }
309 rStm.SetError( nError );
310 }
311 }
312 rStm.Seek( nStmPos );
313 return bRet;
314}
315
317{
318 vcl::GraphicFormatDetector aDetector( rStm, aPathExt, false /*bExtendedInfo*/ );
319 bool bRet = aDetector.detect() && aDetector.checkPCD();
320 if ( bRet )
321 aMetadata = aDetector.getMetadata();
322 return bRet;
323}
324
326{
327 vcl::GraphicFormatDetector aDetector( rStm, aPathExt, true /*bExtendedInfo*/ );
328 bool bRet = aDetector.detect() && aDetector.checkPCX();
329 if ( bRet )
330 aMetadata = aDetector.getMetadata();
331 return bRet;
332}
333
334bool GraphicDescriptor::ImpDetectPNG( SvStream& rStm, bool bExtendedInfo )
335{
336 vcl::GraphicFormatDetector aDetector( rStm, aPathExt, bExtendedInfo );
337 bool bRet = aDetector.detect() && aDetector.checkPNG();
338 if ( bRet )
339 aMetadata = aDetector.getMetadata();
340 return bRet;
341}
342
343bool GraphicDescriptor::ImpDetectTIF( SvStream& rStm, bool bExtendedInfo )
344{
345 vcl::GraphicFormatDetector aDetector( rStm, aPathExt, bExtendedInfo );
346 bool bRet = aDetector.detect() && aDetector.checkTIF();
347 if ( bRet )
348 aMetadata = aDetector.getMetadata();
349 return bRet;
350}
351
353{
354 vcl::GraphicFormatDetector aDetector( rStm, aPathExt, false /* bExtendedInfo */ );
355 bool bRet = aDetector.detect() && aDetector.checkXBM();
356 if ( bRet )
357 aMetadata = aDetector.getMetadata();
358 return bRet;
359}
360
362{
363 vcl::GraphicFormatDetector aDetector( rStm, aPathExt, false /* bExtendedInfo */ );
364 bool bRet = aDetector.detect() && aDetector.checkXPM();
365 if ( bRet )
366 aMetadata = aDetector.getMetadata();
367 return bRet;
368}
369
371{
372 vcl::GraphicFormatDetector aDetector( rStm, aPathExt, false /* bExtendedInfo */ );
373 bool bRet = aDetector.detect() && aDetector.checkPBM();
374 if ( bRet )
375 aMetadata = aDetector.getMetadata();
376 return bRet;
377}
378
380{
381 vcl::GraphicFormatDetector aDetector( rStm, aPathExt, false /* bExtendedInfo */ );
382 bool bRet = aDetector.detect() && aDetector.checkPGM();
383 if ( bRet )
384 aMetadata = aDetector.getMetadata();
385 return bRet;
386}
387
389{
390 vcl::GraphicFormatDetector aDetector( rStm, aPathExt, false /* bExtendedInfo */ );
391 bool bRet = aDetector.detect() && aDetector.checkPPM();
392 if ( bRet )
393 aMetadata = aDetector.getMetadata();
394 return bRet;
395}
396
398{
399 vcl::GraphicFormatDetector aDetector( rStm, aPathExt, false /* bExtendedInfo */ );
400 bool bRet = aDetector.detect() && aDetector.checkRAS();
401 if ( bRet )
402 aMetadata = aDetector.getMetadata();
403 return bRet;
404}
405
407{
408 vcl::GraphicFormatDetector aDetector( rStm, aPathExt, false /* bExtendedInfo */ );
409 bool bRet = aDetector.detect() && aDetector.checkTGA();
410 if ( bRet )
411 aMetadata = aDetector.getMetadata();
412 return bRet;
413}
414
415bool GraphicDescriptor::ImpDetectPSD( SvStream& rStm, bool bExtendedInfo )
416{
417 vcl::GraphicFormatDetector aDetector( rStm, aPathExt, bExtendedInfo );
418 bool bRet = aDetector.detect() && aDetector.checkPSD();
419 if ( bRet )
420 aMetadata = aDetector.getMetadata();
421 return bRet;
422}
423
425{
426 vcl::GraphicFormatDetector aDetector( rStm, aPathExt, false /*bExtendedInfo*/ );
427 bool bRet = aDetector.detect() && aDetector.checkEPS();
428 if ( bRet )
429 aMetadata = aDetector.getMetadata();
430 return bRet;
431}
432
434{
435 vcl::GraphicFormatDetector aDetector( rStm, aPathExt, false /*bExtendedInfo*/ );
436 bool bRet = aDetector.detect() && aDetector.checkDXF();
437 if ( bRet )
438 aMetadata = aDetector.getMetadata();
439 return bRet;
440}
441
443{
444 vcl::GraphicFormatDetector aDetector( rStm, aPathExt, false /*bExtendedInfo*/ );
445 bool bRet = aDetector.detect() && aDetector.checkMET();
446 if ( bRet )
447 aMetadata = aDetector.getMetadata();
448 return bRet;
449}
450
452{
453 vcl::GraphicFormatDetector aDetector( rStm, aPathExt, false /*bExtendedInfo*/ );
454 bool bRet = aDetector.detect() && aDetector.checkPCT();
455 if ( bRet )
456 aMetadata = aDetector.getMetadata();
457 return bRet;
458}
459
460bool GraphicDescriptor::ImpDetectSVM( SvStream& rStm, bool bExtendedInfo )
461{
462 vcl::GraphicFormatDetector aDetector( rStm, aPathExt, bExtendedInfo );
463 bool bRet = aDetector.detect() && aDetector.checkSVM();
464 if ( bRet )
465 aMetadata = aDetector.getMetadata();
466 return bRet;
467}
468
469bool GraphicDescriptor::ImpDetectWMF(SvStream& rStm, bool /*bExtendedInfo*/)
470{
471 vcl::GraphicFormatDetector aDetector( rStm, aPathExt, false /*bExtendedInfo*/ );
472 bool bRet = aDetector.detect() && aDetector.checkWMF();
473 if ( bRet )
474 aMetadata = aDetector.getMetadata();
475 return bRet;
476}
477
478bool GraphicDescriptor::ImpDetectEMF(SvStream& rStm, bool bExtendedInfo)
479{
480 vcl::GraphicFormatDetector aDetector( rStm, aPathExt, bExtendedInfo );
481 bool bRet = aDetector.detect() && aDetector.checkEMF();
482 if ( bRet )
483 aMetadata = aDetector.getMetadata();
484 return bRet;
485}
486
487bool GraphicDescriptor::ImpDetectSVG( SvStream& rStm, bool /*bExtendedInfo*/ )
488{
489 vcl::GraphicFormatDetector aDetector( rStm, aPathExt, false /*bExtendedInfo*/ );
490 bool bRet = aDetector.detect() && aDetector.checkSVG();
491 if ( bRet )
492 aMetadata = aDetector.getMetadata();
493 return bRet;
494}
495
496bool GraphicDescriptor::ImpDetectWEBP( SvStream& rStm, bool bExtendedInfo )
497{
498 vcl::GraphicFormatDetector aDetector( rStm, aPathExt, bExtendedInfo );
499 bool bRet = aDetector.detect() && aDetector.checkWEBP();
500 if ( bRet )
501 aMetadata = aDetector.getMetadata();
502 return bRet;
503}
504
506{
507 return vcl::getImportFormatShortName( nFormat );
508}
509
510/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
GraphicFileFormat
bool ImpDetectDXF(SvStream &rStm, bool bExtendedInfo)
bool ImpDetectSVM(SvStream &rStm, bool bExtendedInfo)
bool ImpDetectWMF(SvStream &rStm, bool bExtendedInfo)
bool ImpDetectPNG(SvStream &rStm, bool bExtendedInfo)
bool ImpDetectTIF(SvStream &rStm, bool bExtendedInfo)
bool ImpDetectPGM(SvStream &rStm, bool bExtendedInfo)
GraphicDescriptor(const GraphicDescriptor &)=delete
static OUString GetImportFormatShortName(GraphicFileFormat nFormat)
bool Detect(bool bExtendedInfo=false)
starts the detection
bool ImpDetectMET(SvStream &rStm, bool bExtendedInfo)
bool ImpDetectRAS(SvStream &rStm, bool bExtendedInfo)
bool ImpDetectPCD(SvStream &rStm, bool bExtendedInfo)
GraphicMetadata aMetadata
bool ImpDetectEPS(SvStream &rStm, bool bExtendedInfo)
bool ImpDetectPPM(SvStream &rStm, bool bExtendedInfo)
bool ImpDetectPSD(SvStream &rStm, bool bExtendedInfo)
bool ImpDetectWEBP(SvStream &rStm, bool bExtendedInfo)
bool ImpDetectXPM(SvStream &rStm, bool bExtendedInfo)
bool ImpDetectPBM(SvStream &rStm, bool bExtendedInfo)
bool ImpDetectXBM(SvStream &rStm, bool bExtendedInfo)
bool ImpDetectBMP(SvStream &rStm, bool bExtendedInfo)
bool ImpDetectJPG(SvStream &rStm, bool bExtendedInfo)
bool ImpDetectSVG(SvStream &rStm, bool bExtendedInfo)
bool ImpDetectGIF(SvStream &rStm, bool bExtendedInfo)
bool ImpDetectPCX(SvStream &rStm)
bool ImpDetectEMF(SvStream &rStm, bool bExtendedInfo)
bool ImpDetectTGA(SvStream &rStm, bool bExtendedInfo)
bool ImpDetectPCT(SvStream &rStm, bool bExtendedInfo)
SAL_WARN_UNUSED_RESULT Point LogicToLogic(const Point &rPtSource, const MapMode *pMapModeSource, const MapMode *pMapModeDest) const
Definition: map.cxx:1580
void setWidth(tools::Long nWidth)
void setHeight(tools::Long nHeight)
sal_uInt64 Tell() const
void SetEndian(SvStreamEndian SvStreamEndian)
bool good() const
SvStream & ReadUInt32(sal_uInt32 &rUInt32)
SvStreamEndian GetEndian() const
void SetError(ErrCode nErrorCode)
sal_uInt64 Seek(sal_uInt64 nPos)
SvStream & ReadInt32(sal_Int32 &rInt32)
sal_uInt64 SeekRel(sal_Int64 nPos)
ErrCode GetError() const
SvStream & ReadUInt16(sal_uInt16 &rUInt16)
SvStream & ReadUChar(unsigned char &rChar)
const GraphicMetadata & getMetadata()
URL aURL
static sal_uInt8 ImpDetectJPG_GetNextMarker(SvStream &rStm)
NONE
uno::Reference< io::XStream > CreateStream(uno::Reference< embed::XStorage > const &xStorage, OUString const &rFilename)
READ
static OUString getImportFormatShortName(GraphicFileFormat nFormat)
HashMap_OWString_Interface aMap
StreamMode
SvStreamEndian
GraphicFileFormat mnFormat
sal_uInt16 mnBitsPerPixel
sal_uInt8 mnNumberOfImageComponents
unsigned char sal_uInt8
sal_Int32 nLength