1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 .
22 #include <tools/vcompat.hxx>
23 #include <tools/debug.hxx>
24 #include <unotools/ucbstreamhelper.hxx>
25 #include <unotools/tempfile.hxx>
26 #include <ucbhelper/content.hxx>
27 #include <vcl/graph.hxx>
28 #include <vcl/gfxlink.hxx>
29 #include <vcl/cvtgrf.hxx>
30 #include <com/sun/star/ucb/CommandAbortedException.hpp>
33 meType ( GFX_LINK_TYPE_NONE
),
38 mpImpData ( new ImpGfxLink
)
42 GfxLink::GfxLink( const GfxLink
& rGfxLink
) :
43 mpImpData( new ImpGfxLink
)
48 GfxLink::GfxLink( sal_uInt8
* pBuf
, sal_uInt32 nSize
, GfxLinkType nType
, sal_Bool bOwns
) :
49 mpImpData( new ImpGfxLink
)
51 DBG_ASSERT( (pBuf
!= NULL
&& nSize
) || (!bOwns
&& nSize
== 0),
52 "GfxLink::GfxLink(): empty/NULL buffer given" );
60 mpBuf
= new ImpBuffer( pBuf
);
63 mpBuf
= new ImpBuffer( nSize
);
64 memcpy( mpBuf
->mpBuffer
, pBuf
, nSize
);
72 if( mpBuf
&& !( --mpBuf
->mnRefCount
) )
75 if( mpSwap
&& !( --mpSwap
->mnRefCount
) )
81 GfxLink
& GfxLink::operator=( const GfxLink
& rGfxLink
)
83 if( &rGfxLink
!= this )
85 if ( mpBuf
&& !( --mpBuf
->mnRefCount
) )
88 if( mpSwap
&& !( --mpSwap
->mnRefCount
) )
97 sal_Bool
GfxLink::IsEqual( const GfxLink
& rGfxLink
) const
99 sal_Bool bIsEqual
= sal_False
;
101 if ( ( mnBufSize
== rGfxLink
.mnBufSize
) && ( meType
== rGfxLink
.meType
) )
103 const sal_uInt8
* pSource
= GetData();
104 const sal_uInt8
* pDest
= rGfxLink
.GetData();
105 sal_uInt32 nSourceSize
= GetDataSize();
106 sal_uInt32 nDestSize
= rGfxLink
.GetDataSize();
107 if ( pSource
&& pDest
&& ( nSourceSize
== nDestSize
) )
109 bIsEqual
= memcmp( pSource
, pDest
, nSourceSize
) == 0;
111 else if ( ( pSource
== 0 ) && ( pDest
== 0 ) )
117 void GfxLink::ImplCopy( const GfxLink
& rGfxLink
)
119 mnBufSize
= rGfxLink
.mnBufSize
;
120 meType
= rGfxLink
.meType
;
121 mpBuf
= rGfxLink
.mpBuf
;
122 mpSwap
= rGfxLink
.mpSwap
;
123 mnUserId
= rGfxLink
.mnUserId
;
124 *mpImpData
= *rGfxLink
.mpImpData
;
130 mpSwap
->mnRefCount
++;
133 GfxLinkType
GfxLink::GetType() const
138 sal_Bool
GfxLink::IsNative() const
140 return( meType
>= GFX_LINK_FIRST_NATIVE_ID
&& meType
<= GFX_LINK_LAST_NATIVE_ID
);
143 sal_uInt32
GfxLink::GetDataSize() const
148 const sal_uInt8
* GfxLink::GetData() const
151 ( (GfxLink
*) this )->SwapIn();
153 return( mpBuf
? mpBuf
->mpBuffer
: NULL
);
156 const Size
& GfxLink::GetPrefSize() const
158 return mpImpData
->maPrefSize
;
161 void GfxLink::SetPrefSize( const Size
& rPrefSize
)
163 mpImpData
->maPrefSize
= rPrefSize
;
164 mpImpData
->mbPrefSizeValid
= true;
167 bool GfxLink::IsPrefSizeValid()
169 return mpImpData
->mbPrefSizeValid
;
172 const MapMode
& GfxLink::GetPrefMapMode() const
174 return mpImpData
->maPrefMapMode
;
177 void GfxLink::SetPrefMapMode( const MapMode
& rPrefMapMode
)
179 mpImpData
->maPrefMapMode
= rPrefMapMode
;
180 mpImpData
->mbPrefMapModeValid
= true;
183 bool GfxLink::IsPrefMapModeValid()
185 return mpImpData
->mbPrefMapModeValid
;
188 sal_Bool
GfxLink::LoadNative( Graphic
& rGraphic
)
190 sal_Bool bRet
= sal_False
;
192 if( IsNative() && mnBufSize
)
194 const sal_uInt8
* pData
= GetData();
198 SvMemoryStream aMemStm
;
201 aMemStm
.SetBuffer( (char*) pData
, mnBufSize
, sal_False
, mnBufSize
);
205 case( GFX_LINK_TYPE_NATIVE_GIF
): nCvtType
= CVT_GIF
; break;
206 case( GFX_LINK_TYPE_NATIVE_JPG
): nCvtType
= CVT_JPG
; break;
207 case( GFX_LINK_TYPE_NATIVE_PNG
): nCvtType
= CVT_PNG
; break;
208 case( GFX_LINK_TYPE_NATIVE_TIF
): nCvtType
= CVT_TIF
; break;
209 case( GFX_LINK_TYPE_NATIVE_WMF
): nCvtType
= CVT_WMF
; break;
210 case( GFX_LINK_TYPE_NATIVE_MET
): nCvtType
= CVT_MET
; break;
211 case( GFX_LINK_TYPE_NATIVE_PCT
): nCvtType
= CVT_PCT
; break;
212 case( GFX_LINK_TYPE_NATIVE_SVG
): nCvtType
= CVT_SVG
; break;
214 default: nCvtType
= CVT_UNKNOWN
; break;
217 if( nCvtType
&& ( GraphicConverter::Import( aMemStm
, rGraphic
, nCvtType
) == ERRCODE_NONE
) )
225 void GfxLink::SwapOut()
227 if( !IsSwappedOut() && mpBuf
)
229 mpSwap
= new ImpSwap( mpBuf
->mpBuffer
, mnBufSize
);
231 if( !mpSwap
->IsSwapped() )
238 if( !( --mpBuf
->mnRefCount
) )
246 void GfxLink::SwapIn()
250 mpBuf
= new ImpBuffer( mpSwap
->GetData() );
252 if( !( --mpSwap
->mnRefCount
) )
259 sal_Bool
GfxLink::ExportNative( SvStream
& rOStream
) const
264 mpSwap
->WriteTo( rOStream
);
266 rOStream
.Write( GetData(), GetDataSize() );
269 return ( rOStream
.GetError() == ERRCODE_NONE
);
272 SvStream
& operator<<( SvStream
& rOStream
, const GfxLink
& rGfxLink
)
274 VersionCompat
* pCompat
= new VersionCompat( rOStream
, STREAM_WRITE
, 2 );
277 rOStream
<< (sal_uInt16
) rGfxLink
.GetType() << rGfxLink
.GetDataSize() << rGfxLink
.GetUserId();
280 rOStream
<< rGfxLink
.GetPrefSize() << rGfxLink
.GetPrefMapMode();
284 if( rGfxLink
.GetDataSize() )
286 if( rGfxLink
.IsSwappedOut() )
287 rGfxLink
.mpSwap
->WriteTo( rOStream
);
288 else if( rGfxLink
.GetData() )
289 rOStream
.Write( rGfxLink
.GetData(), rGfxLink
.GetDataSize() );
295 SvStream
& operator>>( SvStream
& rIStream
, GfxLink
& rGfxLink
)
303 bool bMapAndSizeValid( false );
304 VersionCompat
* pCompat
= new VersionCompat( rIStream
, STREAM_READ
);
307 rIStream
>> nType
>> nSize
>> nUserId
;
309 if( pCompat
->GetVersion() >= 2 )
311 rIStream
>> aSize
>> aMapMode
;
312 bMapAndSizeValid
= true;
317 pBuf
= new sal_uInt8
[ nSize
];
318 rIStream
.Read( pBuf
, nSize
);
320 rGfxLink
= GfxLink( pBuf
, nSize
, (GfxLinkType
) nType
, sal_True
);
321 rGfxLink
.SetUserId( nUserId
);
323 if( bMapAndSizeValid
)
325 rGfxLink
.SetPrefSize( aSize
);
326 rGfxLink
.SetPrefMapMode( aMapMode
);
332 ImpSwap::ImpSwap( sal_uInt8
* pData
, sal_uLong nDataSize
) :
333 mnDataSize( nDataSize
),
336 if( pData
&& mnDataSize
)
338 ::utl::TempFile aTempFile
;
340 maURL
= aTempFile
.GetURL();
341 if( !maURL
.isEmpty() )
343 SvStream
* pOStm
= ::utl::UcbStreamHelper::CreateStream( maURL
, STREAM_READWRITE
| STREAM_SHARE_DENYWRITE
);
346 pOStm
->Write( pData
, mnDataSize
);
347 bool bError
= ( ERRCODE_NONE
!= pOStm
->GetError() );
352 osl_removeFile( maURL
.pData
);
363 osl_removeFile( maURL
.pData
);
366 sal_uInt8
* ImpSwap::GetData() const
372 SvStream
* pIStm
= ::utl::UcbStreamHelper::CreateStream( maURL
, STREAM_READWRITE
);
375 pData
= new sal_uInt8
[ mnDataSize
];
376 pIStm
->Read( pData
, mnDataSize
);
377 bool bError
= ( ERRCODE_NONE
!= pIStm
->GetError() );
378 sal_Size nActReadSize
= pIStm
->Tell();
379 if (nActReadSize
!= mnDataSize
)
386 delete[] pData
, pData
= NULL
;
397 void ImpSwap::WriteTo( SvStream
& rOStm
) const
399 sal_uInt8
* pData
= GetData();
403 rOStm
.Write( pData
, mnDataSize
);
408 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */