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 ::com::sun::star::io;
51     using namespace ::com::sun::star::uno;
52     using namespace ::com::sun::star::lang;
53     using namespace ::com::sun::star::beans;
54     using namespace ::com::sun::star::graphic;
55 
56 	//====================================================================
57 	//= StreamSupplier
58 	//====================================================================
59     typedef ::cppu::WeakImplHelper2 <   XStream
60                                     ,   XSeekable
61                                     >   StreamSupplier_Base;
62     class StreamSupplier : public StreamSupplier_Base
63     {
64     private:
65         Reference< XInputStream >   m_xInput;
66         Reference< XOutputStream >  m_xOutput;
67         Reference< XSeekable >      m_xSeekable;
68 
69     public:
70         StreamSupplier( const Reference< XInputStream >& _rxInput, const Reference< XOutputStream >& _rxOutput );
71 
72     protected:
73         // XStream
74         virtual Reference< XInputStream > SAL_CALL getInputStream(  ) throw (RuntimeException);
75         virtual Reference< XOutputStream > SAL_CALL getOutputStream(  ) throw (RuntimeException);
76 
77         // XSeekable
78         virtual void SAL_CALL seek( ::sal_Int64 location ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
79         virtual ::sal_Int64 SAL_CALL getPosition(  ) throw (::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
80         virtual ::sal_Int64 SAL_CALL getLength(  ) throw (::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException);
81     };
82 
83 	//--------------------------------------------------------------------
84     StreamSupplier::StreamSupplier( const Reference< XInputStream >& _rxInput, const Reference< XOutputStream >& _rxOutput )
85         :m_xInput( _rxInput )
86         ,m_xOutput( _rxOutput )
87     {
88         m_xSeekable = m_xSeekable.query( m_xInput );
89         if ( !m_xSeekable.is() )
90             m_xSeekable = m_xSeekable.query( m_xOutput );
91         OSL_ENSURE( m_xSeekable.is(), "StreamSupplier::StreamSupplier: at least one of both must be seekable!" );
92     }
93 
94     //--------------------------------------------------------------------
95     Reference< XInputStream > SAL_CALL StreamSupplier::getInputStream(  ) throw (RuntimeException)
96     {
97         return m_xInput;
98     }
99 
100     //--------------------------------------------------------------------
101     Reference< XOutputStream > SAL_CALL StreamSupplier::getOutputStream(  ) throw (RuntimeException)
102     {
103         return m_xOutput;
104     }
105 
106     //--------------------------------------------------------------------
107     void SAL_CALL StreamSupplier::seek( ::sal_Int64 location ) throw (IllegalArgumentException, IOException, RuntimeException)
108     {
109         if ( !m_xSeekable.is() )
110             throw NotConnectedException();
111 
112         m_xSeekable->seek( location );
113     }
114 
115     //--------------------------------------------------------------------
116     ::sal_Int64 SAL_CALL StreamSupplier::getPosition(  ) throw (IOException, RuntimeException)
117     {
118         if ( !m_xSeekable.is() )
119             throw NotConnectedException();
120 
121         return m_xSeekable->getPosition();
122     }
123 
124     //--------------------------------------------------------------------
125     ::sal_Int64 SAL_CALL StreamSupplier::getLength(  ) throw (IOException, RuntimeException)
126     {
127         if ( !m_xSeekable.is() )
128             throw NotConnectedException();
129 
130         return m_xSeekable->getLength();
131     }
132 
133     //====================================================================
134 	//= GraphicAccess
135 	//====================================================================
136 	//--------------------------------------------------------------------
137     bool GraphicAccess::isSupportedURL( const ::rtl::OUString& _rURL )
138     {
139         if  (   ( _rURL.indexOfAsciiL( RTL_CONSTASCII_STRINGPARAM( "private:resource/" ) ) == 0 )
140             ||  ( _rURL.indexOfAsciiL( RTL_CONSTASCII_STRINGPARAM( "private:graphicrepository/" ) ) == 0 )
141             ||  ( _rURL.indexOfAsciiL( RTL_CONSTASCII_STRINGPARAM( "private:standardimage/" ) ) == 0 )
142             ||  ( _rURL.indexOfAsciiL( RTL_CONSTASCII_STRINGPARAM( "vnd.sun.star.GraphicObject:" ) ) == 0 )
143             ||  ( _rURL.indexOfAsciiL( RTL_CONSTASCII_STRINGPARAM( "vnd.sun.star.extension://" ) ) == 0 )
144             )
145             return true;
146         return false;
147     }
148 
149 	//--------------------------------------------------------------------
150     SvStream* GraphicAccess::getImageStream( const Reference< XMultiServiceFactory >& _rxORB, const ::rtl::OUString& _rImageResourceURL )
151     {
152         SvStream* pReturn = NULL;
153 
154         try
155         {
156             // get a GraphicProvider
157             Reference< XGraphicProvider > xProvider;
158             if ( _rxORB.is() )
159                 xProvider = xProvider.query( _rxORB->createInstance( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.graphic.GraphicProvider" ) ) ) );
160             OSL_ENSURE( xProvider.is(), "GraphicAccess::getImageStream: could not create a graphic provider!" );
161 
162             if ( !xProvider.is() )
163                 return pReturn;
164 
165             // let it create a graphic from the given URL
166             Sequence< PropertyValue > aMediaProperties( 1 );
167             aMediaProperties[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "URL" ) );
168             aMediaProperties[0].Value <<= _rImageResourceURL;
169             Reference< XGraphic > xGraphic( xProvider->queryGraphic( aMediaProperties ) );
170             OSL_ENSURE( xGraphic.is(), "GraphicAccess::getImageStream: the provider did not give us a graphic object!" );
171             if ( !xGraphic.is() )
172                 return pReturn;
173 
174             // copy the graphic to a in-memory buffer
175             SvMemoryStream* pMemBuffer = new SvMemoryStream;
176             Reference< XStream > xBufferAccess = new StreamSupplier(
177                 new OSeekableInputStreamWrapper( *pMemBuffer ),
178                 new OSeekableOutputStreamWrapper( *pMemBuffer )
179             );
180 
181             aMediaProperties.realloc( 2 );
182             aMediaProperties[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "OutputStream" ) );
183             aMediaProperties[0].Value <<= xBufferAccess;
184             aMediaProperties[1].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "MimeType" ) );
185             aMediaProperties[1].Value <<= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "image/png" ) );
186             xProvider->storeGraphic( xGraphic, aMediaProperties );
187 
188             pMemBuffer->Seek( 0 );
189             pReturn = pMemBuffer;
190         }
191         catch( const Exception& )
192         {
193         	OSL_ENSURE( sal_False, "GraphicAccess::getImageStream: caught an exception!" );
194         }
195 
196         return pReturn;
197     }
198 
199 	//--------------------------------------------------------------------
200     Reference< XInputStream > GraphicAccess::getImageXStream( const Reference< XMultiServiceFactory >& _rxORB, const ::rtl::OUString& _rImageResourceURL )
201     {
202         return new OSeekableInputStreamWrapper( getImageStream( _rxORB, _rImageResourceURL ), sal_True );   // take ownership
203     }
204 
205 //........................................................................
206 } // namespace svt
207 //........................................................................
208 
209