1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_svtools.hxx"
26 
27 #include <svtools/imageresourceaccess.hxx>
28 
29 /** === begin UNO includes === **/
30 #include <com/sun/star/io/NotConnectedException.hpp>
31 #include <com/sun/star/io/XSeekable.hpp>
32 #include <com/sun/star/graphic/XGraphicProvider.hpp>
33 #include <com/sun/star/io/XStream.hpp>
34 /** === end UNO includes === **/
35 #include <unotools/ucbstreamhelper.hxx>
36 #include <tools/stream.hxx>
37 #include <unotools/streamwrap.hxx>
38 #include <cppuhelper/implbase2.hxx>
39 
40 //........................................................................
41 namespace svt
42 {
43 //........................................................................
44 
45     using namespace ::utl;
46     using namespace ::com::sun::star::io;
47     using namespace ::com::sun::star::uno;
48     using namespace ::com::sun::star::lang;
49     using namespace ::com::sun::star::beans;
50     using namespace ::com::sun::star::graphic;
51 
52 	//====================================================================
53 	//= StreamSupplier
54 	//====================================================================
55     typedef ::cppu::WeakImplHelper2 <   XStream
56                                     ,   XSeekable
57                                     >   StreamSupplier_Base;
58     class StreamSupplier : public StreamSupplier_Base
59     {
60     private:
61         Reference< XInputStream >   m_xInput;
62         Reference< XOutputStream >  m_xOutput;
63         Reference< XSeekable >      m_xSeekable;
64 
65     public:
66         StreamSupplier( const Reference< XInputStream >& _rxInput, const Reference< XOutputStream >& _rxOutput );
67 
68     protected:
69         // XStream
70         virtual Reference< XInputStream > SAL_CALL getInputStream(  ) throw (RuntimeException);
71         virtual Reference< XOutputStream > SAL_CALL getOutputStream(  ) throw (RuntimeException);
72 
73         // XSeekable
74         virtual void SAL_CALL seek( ::sal_Int64 location ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
75         virtual ::sal_Int64 SAL_CALL getPosition(  ) throw (::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
76         virtual ::sal_Int64 SAL_CALL getLength(  ) throw (::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
77     };
78 
79 	//--------------------------------------------------------------------
StreamSupplier(const Reference<XInputStream> & _rxInput,const Reference<XOutputStream> & _rxOutput)80     StreamSupplier::StreamSupplier( const Reference< XInputStream >& _rxInput, const Reference< XOutputStream >& _rxOutput )
81         :m_xInput( _rxInput )
82         ,m_xOutput( _rxOutput )
83     {
84         m_xSeekable = m_xSeekable.query( m_xInput );
85         if ( !m_xSeekable.is() )
86             m_xSeekable = m_xSeekable.query( m_xOutput );
87         OSL_ENSURE( m_xSeekable.is(), "StreamSupplier::StreamSupplier: at least one of both must be seekable!" );
88     }
89 
90     //--------------------------------------------------------------------
getInputStream()91     Reference< XInputStream > SAL_CALL StreamSupplier::getInputStream(  ) throw (RuntimeException)
92     {
93         return m_xInput;
94     }
95 
96     //--------------------------------------------------------------------
getOutputStream()97     Reference< XOutputStream > SAL_CALL StreamSupplier::getOutputStream(  ) throw (RuntimeException)
98     {
99         return m_xOutput;
100     }
101 
102     //--------------------------------------------------------------------
seek(::sal_Int64 location)103     void SAL_CALL StreamSupplier::seek( ::sal_Int64 location ) throw (IllegalArgumentException, IOException, RuntimeException)
104     {
105         if ( !m_xSeekable.is() )
106             throw NotConnectedException();
107 
108         m_xSeekable->seek( location );
109     }
110 
111     //--------------------------------------------------------------------
getPosition()112     ::sal_Int64 SAL_CALL StreamSupplier::getPosition(  ) throw (IOException, RuntimeException)
113     {
114         if ( !m_xSeekable.is() )
115             throw NotConnectedException();
116 
117         return m_xSeekable->getPosition();
118     }
119 
120     //--------------------------------------------------------------------
getLength()121     ::sal_Int64 SAL_CALL StreamSupplier::getLength(  ) throw (IOException, RuntimeException)
122     {
123         if ( !m_xSeekable.is() )
124             throw NotConnectedException();
125 
126         return m_xSeekable->getLength();
127     }
128 
129     //====================================================================
130 	//= GraphicAccess
131 	//====================================================================
132 	//--------------------------------------------------------------------
isSupportedURL(const::rtl::OUString & _rURL)133     bool GraphicAccess::isSupportedURL( const ::rtl::OUString& _rURL )
134     {
135         if  (   ( _rURL.indexOfAsciiL( RTL_CONSTASCII_STRINGPARAM( "private:resource/" ) ) == 0 )
136             ||  ( _rURL.indexOfAsciiL( RTL_CONSTASCII_STRINGPARAM( "private:graphicrepository/" ) ) == 0 )
137             ||  ( _rURL.indexOfAsciiL( RTL_CONSTASCII_STRINGPARAM( "private:standardimage/" ) ) == 0 )
138             ||  ( _rURL.indexOfAsciiL( RTL_CONSTASCII_STRINGPARAM( "vnd.sun.star.GraphicObject:" ) ) == 0 )
139             ||  ( _rURL.indexOfAsciiL( RTL_CONSTASCII_STRINGPARAM( "vnd.sun.star.extension://" ) ) == 0 )
140             )
141             return true;
142         return false;
143     }
144 
145 	//--------------------------------------------------------------------
getImageStream(const Reference<XMultiServiceFactory> & _rxORB,const::rtl::OUString & _rImageResourceURL)146     SvStream* GraphicAccess::getImageStream( const Reference< XMultiServiceFactory >& _rxORB, const ::rtl::OUString& _rImageResourceURL )
147     {
148         SvStream* pReturn = NULL;
149 
150         try
151         {
152             // get a GraphicProvider
153             Reference< XGraphicProvider > xProvider;
154             if ( _rxORB.is() )
155                 xProvider = xProvider.query( _rxORB->createInstance( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.graphic.GraphicProvider" ) ) ) );
156             OSL_ENSURE( xProvider.is(), "GraphicAccess::getImageStream: could not create a graphic provider!" );
157 
158             if ( !xProvider.is() )
159                 return pReturn;
160 
161             // let it create a graphic from the given URL
162             Sequence< PropertyValue > aMediaProperties( 1 );
163             aMediaProperties[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "URL" ) );
164             aMediaProperties[0].Value <<= _rImageResourceURL;
165             Reference< XGraphic > xGraphic( xProvider->queryGraphic( aMediaProperties ) );
166             OSL_ENSURE( xGraphic.is(), "GraphicAccess::getImageStream: the provider did not give us a graphic object!" );
167             if ( !xGraphic.is() )
168                 return pReturn;
169 
170             // copy the graphic to a in-memory buffer
171             SvMemoryStream* pMemBuffer = new SvMemoryStream;
172             Reference< XStream > xBufferAccess = new StreamSupplier(
173                 new OSeekableInputStreamWrapper( *pMemBuffer ),
174                 new OSeekableOutputStreamWrapper( *pMemBuffer )
175             );
176 
177             aMediaProperties.realloc( 2 );
178             aMediaProperties[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "OutputStream" ) );
179             aMediaProperties[0].Value <<= xBufferAccess;
180             aMediaProperties[1].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "MimeType" ) );
181             aMediaProperties[1].Value <<= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "image/png" ) );
182             xProvider->storeGraphic( xGraphic, aMediaProperties );
183 
184             pMemBuffer->Seek( 0 );
185             pReturn = pMemBuffer;
186         }
187         catch( const Exception& )
188         {
189         	OSL_ENSURE( sal_False, "GraphicAccess::getImageStream: caught an exception!" );
190         }
191 
192         return pReturn;
193     }
194 
195 	//--------------------------------------------------------------------
getImageXStream(const Reference<XMultiServiceFactory> & _rxORB,const::rtl::OUString & _rImageResourceURL)196     Reference< XInputStream > GraphicAccess::getImageXStream( const Reference< XMultiServiceFactory >& _rxORB, const ::rtl::OUString& _rImageResourceURL )
197     {
198         return new OSeekableInputStreamWrapper( getImageStream( _rxORB, _rImageResourceURL ), sal_True );   // take ownership
199     }
200 
201 //........................................................................
202 } // namespace svt
203 //........................................................................
204 
205