Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : :
30 : : #include <osl/file.h>
31 : : #include <tools/vcompat.hxx>
32 : : #include <tools/debug.hxx>
33 : : #include <unotools/ucbstreamhelper.hxx>
34 : : #include <unotools/tempfile.hxx>
35 : : #include <ucbhelper/content.hxx>
36 : : #include <vcl/graph.hxx>
37 : : #include <vcl/gfxlink.hxx>
38 : : #include <vcl/cvtgrf.hxx>
39 : : #include <com/sun/star/ucb/CommandAbortedException.hpp>
40 : :
41 : : // -----------
42 : : // - GfxLink -
43 : : // -----------
44 : :
45 : 62092 : GfxLink::GfxLink() :
46 : : meType ( GFX_LINK_TYPE_NONE ),
47 : : mpBuf ( NULL ),
48 : : mpSwap ( NULL ),
49 : : mnBufSize ( 0 ),
50 : : mnUserId ( 0UL ),
51 [ + - ]: 62092 : mpImpData ( new ImpGfxLink )
52 : : {
53 : 62092 : }
54 : :
55 : : // ------------------------------------------------------------------------
56 : :
57 : 3733 : GfxLink::GfxLink( const GfxLink& rGfxLink ) :
58 [ + - ]: 3733 : mpImpData( new ImpGfxLink )
59 : : {
60 : 3733 : ImplCopy( rGfxLink );
61 : 3733 : }
62 : :
63 : : // ------------------------------------------------------------------------
64 : :
65 : 2107 : GfxLink::GfxLink( sal_uInt8* pBuf, sal_uInt32 nSize, GfxLinkType nType, sal_Bool bOwns ) :
66 [ + - ]: 2107 : mpImpData( new ImpGfxLink )
67 : : {
68 : : DBG_ASSERT( (pBuf != NULL && nSize) || (!bOwns && nSize == 0),
69 : : "GfxLink::GfxLink(): empty/NULL buffer given" );
70 : :
71 : 2107 : meType = nType;
72 : 2107 : mnBufSize = nSize;
73 : 2107 : mpSwap = NULL;
74 : 2107 : mnUserId = 0UL;
75 : :
76 [ + - ]: 2107 : if( bOwns )
77 : 2107 : mpBuf = new ImpBuffer( pBuf );
78 [ # # ]: 0 : else if( nSize )
79 : : {
80 [ # # ]: 0 : mpBuf = new ImpBuffer( nSize );
81 : 0 : memcpy( mpBuf->mpBuffer, pBuf, nSize );
82 : : }
83 : : else
84 : 0 : mpBuf = NULL;
85 : 2107 : }
86 : :
87 : : // ------------------------------------------------------------------------
88 : :
89 : 67687 : GfxLink::~GfxLink()
90 : : {
91 [ + + ][ + + ]: 67687 : if( mpBuf && !( --mpBuf->mnRefCount ) )
[ + + ]
92 [ + - ]: 2110 : delete mpBuf;
93 : :
94 [ + + ][ + + ]: 67687 : if( mpSwap && !( --mpSwap->mnRefCount ) )
[ + + ]
95 [ + - ]: 2095 : delete mpSwap;
96 : :
97 [ + - ]: 67687 : delete mpImpData;
98 : 67687 : }
99 : :
100 : : // ------------------------------------------------------------------------
101 : :
102 : 31178 : GfxLink& GfxLink::operator=( const GfxLink& rGfxLink )
103 : : {
104 [ + - ]: 31178 : if( &rGfxLink != this )
105 : : {
106 [ - + ][ # # ]: 31178 : if ( mpBuf && !( --mpBuf->mnRefCount ) )
[ - + ]
107 [ # # ]: 0 : delete mpBuf;
108 : :
109 [ + + ][ + - ]: 31178 : if( mpSwap && !( --mpSwap->mnRefCount ) )
[ + + ]
110 [ + - ]: 9 : delete mpSwap;
111 : :
112 : 31178 : ImplCopy( rGfxLink );
113 : : }
114 : :
115 : 31178 : return *this;
116 : : }
117 : :
118 : : // ------------------------------------------------------------------------
119 : :
120 : 0 : sal_Bool GfxLink::IsEqual( const GfxLink& rGfxLink ) const
121 : : {
122 : 0 : sal_Bool bIsEqual = sal_False;
123 : :
124 [ # # ][ # # ]: 0 : if ( ( mnBufSize == rGfxLink.mnBufSize ) && ( meType == rGfxLink.meType ) )
125 : : {
126 : 0 : const sal_uInt8* pSource = GetData();
127 : 0 : const sal_uInt8* pDest = rGfxLink.GetData();
128 : 0 : sal_uInt32 nSourceSize = GetDataSize();
129 : 0 : sal_uInt32 nDestSize = rGfxLink.GetDataSize();
130 [ # # ][ # # ]: 0 : if ( pSource && pDest && ( nSourceSize == nDestSize ) )
[ # # ]
131 : : {
132 : 0 : bIsEqual = memcmp( pSource, pDest, nSourceSize ) == 0;
133 : : }
134 [ # # ][ # # ]: 0 : else if ( ( pSource == 0 ) && ( pDest == 0 ) )
135 : 0 : bIsEqual = sal_True;
136 : : }
137 : 0 : return bIsEqual;
138 : : }
139 : :
140 : : // ------------------------------------------------------------------------
141 : :
142 : 34911 : void GfxLink::ImplCopy( const GfxLink& rGfxLink )
143 : : {
144 : 34911 : mnBufSize = rGfxLink.mnBufSize;
145 : 34911 : meType = rGfxLink.meType;
146 : 34911 : mpBuf = rGfxLink.mpBuf;
147 : 34911 : mpSwap = rGfxLink.mpSwap;
148 : 34911 : mnUserId = rGfxLink.mnUserId;
149 : 34911 : *mpImpData = *rGfxLink.mpImpData;
150 : :
151 [ + + ]: 34911 : if( mpBuf )
152 : 2113 : mpBuf->mnRefCount++;
153 : :
154 [ + + ]: 34911 : if( mpSwap )
155 : 1878 : mpSwap->mnRefCount++;
156 : 34911 : }
157 : :
158 : : // ------------------------------------------------------------------------
159 : :
160 : 4687 : GfxLinkType GfxLink::GetType() const
161 : : {
162 : 4687 : return meType;
163 : : }
164 : :
165 : : // ------------------------------------------------------------------------
166 : :
167 : 3489 : sal_Bool GfxLink::IsNative() const
168 : : {
169 [ + + ][ + - ]: 3489 : return( meType >= GFX_LINK_FIRST_NATIVE_ID && meType <= GFX_LINK_LAST_NATIVE_ID );
170 : : }
171 : :
172 : : // ------------------------------------------------------------------------
173 : :
174 : 42 : sal_uInt32 GfxLink::GetDataSize() const
175 : : {
176 : 42 : return mnBufSize;
177 : : }
178 : :
179 : : // ------------------------------------------------------------------------
180 : :
181 : 9 : const sal_uInt8* GfxLink::GetData() const
182 : : {
183 [ + + ]: 9 : if( IsSwappedOut() )
184 : 3 : ( (GfxLink*) this )->SwapIn();
185 : :
186 [ + - ]: 9 : return( mpBuf ? mpBuf->mpBuffer : NULL );
187 : : }
188 : :
189 : : // ------------------------------------------------------------------------
190 : :
191 : 21 : const Size& GfxLink::GetPrefSize() const
192 : : {
193 : 21 : return mpImpData->maPrefSize;
194 : : }
195 : :
196 : : // ------------------------------------------------------------------------
197 : :
198 : 21 : void GfxLink::SetPrefSize( const Size& rPrefSize )
199 : : {
200 : 21 : mpImpData->maPrefSize = rPrefSize;
201 : 21 : mpImpData->mbPrefSizeValid = true;
202 : 21 : }
203 : :
204 : : // ------------------------------------------------------------------------
205 : :
206 : 6 : bool GfxLink::IsPrefSizeValid()
207 : : {
208 : 6 : return mpImpData->mbPrefSizeValid;
209 : : }
210 : :
211 : : // ------------------------------------------------------------------------
212 : :
213 : 21 : const MapMode& GfxLink::GetPrefMapMode() const
214 : : {
215 : 21 : return mpImpData->maPrefMapMode;
216 : : }
217 : :
218 : : // ------------------------------------------------------------------------
219 : :
220 : 21 : void GfxLink::SetPrefMapMode( const MapMode& rPrefMapMode )
221 : : {
222 : 21 : mpImpData->maPrefMapMode = rPrefMapMode;
223 : 21 : mpImpData->mbPrefMapModeValid = true;
224 : 21 : }
225 : :
226 : : // ------------------------------------------------------------------------
227 : :
228 : 6 : bool GfxLink::IsPrefMapModeValid()
229 : : {
230 : 6 : return mpImpData->mbPrefMapModeValid;
231 : : }
232 : :
233 : : // ------------------------------------------------------------------------
234 : :
235 : 6 : sal_Bool GfxLink::LoadNative( Graphic& rGraphic )
236 : : {
237 : 6 : sal_Bool bRet = sal_False;
238 : :
239 [ + - ][ + - ]: 6 : if( IsNative() && mnBufSize )
[ + - ]
240 : : {
241 : 6 : const sal_uInt8* pData = GetData();
242 : :
243 [ + - ]: 6 : if( pData )
244 : : {
245 [ + - ]: 6 : SvMemoryStream aMemStm;
246 : : sal_uLong nCvtType;
247 : :
248 [ + - ]: 6 : aMemStm.SetBuffer( (char*) pData, mnBufSize, sal_False, mnBufSize );
249 : :
250 [ - - + - : 6 : switch( meType )
- - - -
- ]
251 : : {
252 : 0 : case( GFX_LINK_TYPE_NATIVE_GIF ): nCvtType = CVT_GIF; break;
253 : 0 : case( GFX_LINK_TYPE_NATIVE_JPG ): nCvtType = CVT_JPG; break;
254 : 6 : case( GFX_LINK_TYPE_NATIVE_PNG ): nCvtType = CVT_PNG; break;
255 : 0 : case( GFX_LINK_TYPE_NATIVE_TIF ): nCvtType = CVT_TIF; break;
256 : 0 : case( GFX_LINK_TYPE_NATIVE_WMF ): nCvtType = CVT_WMF; break;
257 : 0 : case( GFX_LINK_TYPE_NATIVE_MET ): nCvtType = CVT_MET; break;
258 : 0 : case( GFX_LINK_TYPE_NATIVE_PCT ): nCvtType = CVT_PCT; break;
259 : 0 : case( GFX_LINK_TYPE_NATIVE_SVG ): nCvtType = CVT_SVG; break;
260 : :
261 : 0 : default: nCvtType = CVT_UNKNOWN; break;
262 : : }
263 : :
264 [ + - ][ + - ]: 6 : if( nCvtType && ( GraphicConverter::Import( aMemStm, rGraphic, nCvtType ) == ERRCODE_NONE ) )
[ + - ][ + - ]
265 [ + - ]: 6 : bRet = sal_True;
266 : : }
267 : : }
268 : :
269 : 6 : return bRet;
270 : : }
271 : :
272 : : // ------------------------------------------------------------------------
273 : :
274 : 3437 : void GfxLink::SwapOut()
275 : : {
276 [ + + ][ + - ]: 3437 : if( !IsSwappedOut() && mpBuf )
[ + + ]
277 : : {
278 [ + - ]: 2107 : mpSwap = new ImpSwap( mpBuf->mpBuffer, mnBufSize );
279 : :
280 [ - + ]: 2107 : if( !mpSwap->IsSwapped() )
281 : : {
282 [ # # ]: 0 : delete mpSwap;
283 : 0 : mpSwap = NULL;
284 : : }
285 : : else
286 : : {
287 [ - + ]: 2107 : if( !( --mpBuf->mnRefCount ) )
288 [ # # ]: 0 : delete mpBuf;
289 : :
290 : 2107 : mpBuf = NULL;
291 : : }
292 : : }
293 : 3437 : }
294 : :
295 : : // ------------------------------------------------------------------------
296 : :
297 : 3 : void GfxLink::SwapIn()
298 : : {
299 [ + - ]: 3 : if( IsSwappedOut() )
300 : : {
301 : 3 : mpBuf = new ImpBuffer( mpSwap->GetData() );
302 : :
303 [ - + ]: 3 : if( !( --mpSwap->mnRefCount ) )
304 [ # # ]: 0 : delete mpSwap;
305 : :
306 : 3 : mpSwap = NULL;
307 : : }
308 : 3 : }
309 : :
310 : : // ------------------------------------------------------------------------
311 : :
312 : 9 : sal_Bool GfxLink::ExportNative( SvStream& rOStream ) const
313 : : {
314 [ + - ]: 9 : if( GetDataSize() )
315 : : {
316 [ + - ]: 9 : if( IsSwappedOut() )
317 : 9 : mpSwap->WriteTo( rOStream );
318 [ # # ]: 0 : else if( GetData() )
319 : 0 : rOStream.Write( GetData(), GetDataSize() );
320 : : }
321 : :
322 : 9 : return ( rOStream.GetError() == ERRCODE_NONE );
323 : : }
324 : :
325 : : // ------------------------------------------------------------------------
326 : :
327 : 15 : SvStream& operator<<( SvStream& rOStream, const GfxLink& rGfxLink )
328 : : {
329 [ + - ]: 15 : VersionCompat* pCompat = new VersionCompat( rOStream, STREAM_WRITE, 2 );
330 : :
331 : : // Version 1
332 : 15 : rOStream << (sal_uInt16) rGfxLink.GetType() << rGfxLink.GetDataSize() << rGfxLink.GetUserId();
333 : :
334 : : // Version 2
335 : 15 : rOStream << rGfxLink.GetPrefSize() << rGfxLink.GetPrefMapMode();
336 : :
337 [ + - ]: 15 : delete pCompat;
338 : :
339 [ + - ]: 15 : if( rGfxLink.GetDataSize() )
340 : : {
341 [ + - ]: 15 : if( rGfxLink.IsSwappedOut() )
342 : 15 : rGfxLink.mpSwap->WriteTo( rOStream );
343 [ # # ]: 0 : else if( rGfxLink.GetData() )
344 : 0 : rOStream.Write( rGfxLink.GetData(), rGfxLink.GetDataSize() );
345 : : }
346 : :
347 : 15 : return rOStream;
348 : : }
349 : :
350 : : // ------------------------------------------------------------------------
351 : :
352 : 6 : SvStream& operator>>( SvStream& rIStream, GfxLink& rGfxLink)
353 : : {
354 : 6 : Size aSize;
355 [ + - ]: 6 : MapMode aMapMode;
356 : : sal_uInt32 nSize;
357 : : sal_uInt32 nUserId;
358 : : sal_uInt16 nType;
359 : : sal_uInt8* pBuf;
360 : 6 : bool bMapAndSizeValid( false );
361 [ + - ][ + - ]: 6 : VersionCompat* pCompat = new VersionCompat( rIStream, STREAM_READ );
362 : :
363 : : // Version 1
364 [ + - ][ + - ]: 6 : rIStream >> nType >> nSize >> nUserId;
[ + - ]
365 : :
366 [ + - ]: 6 : if( pCompat->GetVersion() >= 2 )
367 : : {
368 [ + - ][ + - ]: 6 : rIStream >> aSize >> aMapMode;
369 : 6 : bMapAndSizeValid = true;
370 : : }
371 : :
372 [ + - ][ + - ]: 6 : delete pCompat;
373 : :
374 [ + - ]: 6 : pBuf = new sal_uInt8[ nSize ];
375 [ + - ]: 6 : rIStream.Read( pBuf, nSize );
376 : :
377 [ + - ][ + - ]: 6 : rGfxLink = GfxLink( pBuf, nSize, (GfxLinkType) nType, sal_True );
[ + - ]
378 : 6 : rGfxLink.SetUserId( nUserId );
379 : :
380 [ + - ]: 6 : if( bMapAndSizeValid )
381 : : {
382 [ + - ]: 6 : rGfxLink.SetPrefSize( aSize );
383 [ + - ]: 6 : rGfxLink.SetPrefMapMode( aMapMode );
384 : : }
385 : :
386 [ + - ]: 6 : return rIStream;
387 : : }
388 : :
389 : : // -----------
390 : : // - ImpSwap -
391 : : // -----------
392 : :
393 : 2107 : ImpSwap::ImpSwap( sal_uInt8* pData, sal_uLong nDataSize ) :
394 : : mnDataSize( nDataSize ),
395 : 2107 : mnRefCount( 1UL )
396 : : {
397 [ + - ][ + - ]: 2107 : if( pData && mnDataSize )
398 : : {
399 [ + - ]: 2107 : ::utl::TempFile aTempFile;
400 : :
401 [ + - ][ + - ]: 2107 : maURL = aTempFile.GetURL();
[ + - ]
402 [ + - ]: 2107 : if( !maURL.isEmpty() )
403 : : {
404 [ + - ][ + - ]: 2107 : SvStream* pOStm = ::utl::UcbStreamHelper::CreateStream( maURL, STREAM_READWRITE | STREAM_SHARE_DENYWRITE );
[ + - ]
405 [ + - ]: 2107 : if( pOStm )
406 : : {
407 [ + - ]: 2107 : pOStm->Write( pData, mnDataSize );
408 : 2107 : sal_Bool bError = ( ERRCODE_NONE != pOStm->GetError() );
409 [ + - ][ + - ]: 2107 : delete pOStm;
410 : :
411 [ - + ]: 2107 : if( bError )
412 : : {
413 [ # # ]: 0 : osl_removeFile( maURL.pData );
414 [ # # ][ # # ]: 0 : maURL = String();
[ # # ]
415 : : }
416 : : }
417 [ + - ]: 2107 : }
418 : : }
419 : 2107 : }
420 : :
421 : : // ------------------------------------------------------------------------
422 : :
423 : 2104 : ImpSwap::~ImpSwap()
424 : : {
425 [ + - ]: 2104 : if( IsSwapped() )
426 [ + - ]: 2104 : osl_removeFile( maURL.pData );
427 : 2104 : }
428 : :
429 : : // ------------------------------------------------------------------------
430 : :
431 : 27 : sal_uInt8* ImpSwap::GetData() const
432 : : {
433 : : sal_uInt8* pData;
434 : :
435 [ + - ]: 27 : if( IsSwapped() )
436 : : {
437 [ + - ]: 27 : SvStream* pIStm = ::utl::UcbStreamHelper::CreateStream( maURL, STREAM_READWRITE );
438 [ + - ]: 27 : if( pIStm )
439 : : {
440 : 27 : pData = new sal_uInt8[ mnDataSize ];
441 : 27 : pIStm->Read( pData, mnDataSize );
442 : 27 : sal_Bool bError = ( ERRCODE_NONE != pIStm->GetError() );
443 [ + - ]: 27 : delete pIStm;
444 : :
445 [ - + ]: 27 : if( bError )
446 [ # # ]: 0 : delete[] pData, pData = NULL;
447 : : }
448 : : else
449 : 0 : pData = NULL;
450 : : }
451 : : else
452 : 0 : pData = NULL;
453 : :
454 : 27 : return pData;
455 : : }
456 : :
457 : : // ------------------------------------------------------------------------
458 : :
459 : 24 : void ImpSwap::WriteTo( SvStream& rOStm ) const
460 : : {
461 : 24 : sal_uInt8* pData = GetData();
462 : :
463 [ + - ]: 24 : if( pData )
464 : : {
465 : 24 : rOStm.Write( pData, mnDataSize );
466 [ + - ]: 24 : delete[] pData;
467 : : }
468 : 24 : }
469 : :
470 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|