1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_svtools.hxx"
30 
31 #include <svtools/imageresourceaccess.hxx>
32 
33 /** === begin UNO includes === **/
34 #include <com/sun/star/io/NotConnectedException.hpp>
35 #include <com/sun/star/io/XSeekable.hpp>
36 #include <com/sun/star/graphic/XGraphicProvider.hpp>
37 #include <com/sun/star/io/XStream.hpp>
38 /** === end UNO includes === **/
39 #include <unotools/ucbstreamhelper.hxx>
40 #include <tools/stream.hxx>
41 #include <unotools/streamwrap.hxx>
42 #include <cppuhelper/implbase2.hxx>
43 
44 //........................................................................
45 namespace svt
46 {
47 //........................................................................
48 
49     using namespace ::utl;
50     using namespace ::comphelper;
51     using namespace ::com::sun::star::io;
52     using namespace ::com::sun::star::uno;
53     using namespace ::com::sun::star::lang;
54     using namespace ::com::sun::star::beans;
55     using namespace ::com::sun::star::graphic;
56 
57 	//====================================================================
58 	//= StreamSupplier
59 	//====================================================================
60     typedef ::cppu::WeakImplHelper2 <   XStream
61                                     ,   XSeekable
62                                     >   StreamSupplier_Base;
63     class StreamSupplier : public StreamSupplier_Base
64     {
65     private:
66         Reference< XInputStream >   m_xInput;
67         Reference< XOutputStream >  m_xOutput;
68         Reference< XSeekable >      m_xSeekable;
69 
70     public:
71         StreamSupplier( const Reference< XInputStream >& _rxInput, const Reference< XOutputStream >& _rxOutput );
72 
73     protected:
74         // XStream
75         virtual Reference< XInputStream > SAL_CALL getInputStream(  ) throw (RuntimeException);
76         virtual Reference< XOutputStream > SAL_CALL getOutputStream(  ) throw (RuntimeException);
77 
78         // XSeekable
79         virtual void SAL_CALL seek( ::sal_Int64 location ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
80         virtual ::sal_Int64 SAL_CALL getPosition(  ) throw (::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
81         virtual ::sal_Int64 SAL_CALL getLength(  ) throw (::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
82     };
83 
84 	//--------------------------------------------------------------------
85     StreamSupplier::StreamSupplier( const Reference< XInputStream >& _rxInput, const Reference< XOutputStream >& _rxOutput )
86         :m_xInput( _rxInput )
87         ,m_xOutput( _rxOutput )
88     {
89         m_xSeekable = m_xSeekable.query( m_xInput );
90         if ( !m_xSeekable.is() )
91             m_xSeekable = m_xSeekable.query( m_xOutput );
92         OSL_ENSURE( m_xSeekable.is(), "StreamSupplier::StreamSupplier: at least one of both must be seekable!" );
93     }
94 
95     //--------------------------------------------------------------------
96     Reference< XInputStream > SAL_CALL StreamSupplier::getInputStream(  ) throw (RuntimeException)
97     {
98         return m_xInput;
99     }
100 
101     //--------------------------------------------------------------------
102     Reference< XOutputStream > SAL_CALL StreamSupplier::getOutputStream(  ) throw (RuntimeException)
103     {
104         return m_xOutput;
105     }
106 
107     //--------------------------------------------------------------------
108     void SAL_CALL StreamSupplier::seek( ::sal_Int64 location ) throw (IllegalArgumentException, IOException, RuntimeException)
109     {
110         if ( !m_xSeekable.is() )
111             throw NotConnectedException();
112 
113         m_xSeekable->seek( location );
114     }
115 
116     //--------------------------------------------------------------------
117     ::sal_Int64 SAL_CALL StreamSupplier::getPosition(  ) throw (IOException, RuntimeException)
118     {
119         if ( !m_xSeekable.is() )
120             throw NotConnectedException();
121 
122         return m_xSeekable->getPosition();
123     }
124 
125     //--------------------------------------------------------------------
126     ::sal_Int64 SAL_CALL StreamSupplier::getLength(  ) throw (IOException, RuntimeException)
127     {
128         if ( !m_xSeekable.is() )
129             throw NotConnectedException();
130 
131         return m_xSeekable->getLength();
132     }
133 
134     //====================================================================
135 	//= GraphicAccess
136 	//====================================================================
137 	//--------------------------------------------------------------------
138     bool GraphicAccess::isSupportedURL( const ::rtl::OUString& _rURL )
139     {
140         if  (   ( _rURL.indexOfAsciiL( RTL_CONSTASCII_STRINGPARAM( "private:resource/" ) ) == 0 )
141             ||  ( _rURL.indexOfAsciiL( RTL_CONSTASCII_STRINGPARAM( "private:graphicrepository/" ) ) == 0 )
142             ||  ( _rURL.indexOfAsciiL( RTL_CONSTASCII_STRINGPARAM( "private:standardimage/" ) ) == 0 )
143             ||  ( _rURL.indexOfAsciiL( RTL_CONSTASCII_STRINGPARAM( "vnd.sun.star.GraphicObject:" ) ) == 0 )
144             ||  ( _rURL.indexOfAsciiL( RTL_CONSTASCII_STRINGPARAM( "vnd.sun.star.extension://" ) ) == 0 )
145             )
146             return true;
147         return false;
148     }
149 
150 	//--------------------------------------------------------------------
151     SvStream* GraphicAccess::getImageStream( const Reference< XMultiServiceFactory >& _rxORB, const ::rtl::OUString& _rImageResourceURL )
152     {
153         SvStream* pReturn = NULL;
154 
155         try
156         {
157             // get a GraphicProvider
158             Reference< XGraphicProvider > xProvider;
159             if ( _rxORB.is() )
160                 xProvider = xProvider.query( _rxORB->createInstance( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.graphic.GraphicProvider" ) ) ) );
161             OSL_ENSURE( xProvider.is(), "GraphicAccess::getImageStream: could not create a graphic provider!" );
162 
163             if ( !xProvider.is() )
164                 return pReturn;
165 
166             // let it create a graphic from the given URL
167             Sequence< PropertyValue > aMediaProperties( 1 );
168             aMediaProperties[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "URL" ) );
169             aMediaProperties[0].Value <<= _rImageResourceURL;
170             Reference< XGraphic > xGraphic( xProvider->queryGraphic( aMediaProperties ) );
171             OSL_ENSURE( xGraphic.is(), "GraphicAccess::getImageStream: the provider did not give us a graphic object!" );
172             if ( !xGraphic.is() )
173                 return pReturn;
174 
175             // copy the graphic to a in-memory buffer
176             SvMemoryStream* pMemBuffer = new SvMemoryStream;
177             Reference< XStream > xBufferAccess = new StreamSupplier(
178                 new OSeekableInputStreamWrapper( *pMemBuffer ),
179                 new OSeekableOutputStreamWrapper( *pMemBuffer )
180             );
181 
182             aMediaProperties.realloc( 2 );
183             aMediaProperties[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "OutputStream" ) );
184             aMediaProperties[0].Value <<= xBufferAccess;
185             aMediaProperties[1].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "MimeType" ) );
186             aMediaProperties[1].Value <<= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "image/png" ) );
187             xProvider->storeGraphic( xGraphic, aMediaProperties );
188 
189             pMemBuffer->Seek( 0 );
190             pReturn = pMemBuffer;
191         }
192         catch( const Exception& )
193         {
194         	OSL_ENSURE( sal_False, "GraphicAccess::getImageStream: caught an exception!" );
195         }
196 
197         return pReturn;
198     }
199 
200 	//--------------------------------------------------------------------
201     Reference< XInputStream > GraphicAccess::getImageXStream( const Reference< XMultiServiceFactory >& _rxORB, const ::rtl::OUString& _rImageResourceURL )
202     {
203         return new OSeekableInputStreamWrapper( getImageStream( _rxORB, _rImageResourceURL ), sal_True );   // take ownership
204     }
205 
206 //........................................................................
207 } // namespace svt
208 //........................................................................
209 
210