xref: /trunk/main/vcl/source/gdi/bmpconv.cxx (revision 9f62ea84)
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_vcl.hxx"
26 
27 #include "vcl/bitmap.hxx"
28 #include "vcl/svapp.hxx"
29 #include "vcl/salctype.hxx"
30 #include "vos/mutex.hxx"
31 #include "tools/stream.hxx"
32 #include "com/sun/star/script/XInvocation.hpp"
33 #include "com/sun/star/awt/XBitmap.hpp"
34 #include "cppuhelper/compbase1.hxx"
35 
36 
37 using namespace com::sun::star::uno;
38 using namespace com::sun::star::script;
39 using namespace com::sun::star::beans;
40 using namespace com::sun::star::reflection;
41 using namespace com::sun::star::awt;
42 using namespace rtl;
43 
44 namespace vcl {
45 
46 class BmpTransporter :
47         public cppu::WeakImplHelper1< com::sun::star::awt::XBitmap >
48 {
49     Sequence<sal_Int8>			m_aBM;
50     com::sun::star::awt::Size	m_aSize;
51 public:
52     BmpTransporter( const Bitmap& rBM );
53     virtual  ~BmpTransporter();
54 
55     virtual com::sun::star::awt::Size SAL_CALL getSize() throw();
56     virtual Sequence< sal_Int8 > SAL_CALL getDIB() throw();
57     virtual Sequence< sal_Int8 > SAL_CALL getMaskDIB() throw();
58 };
59 
60 class BmpConverter :
61         public cppu::WeakImplHelper1< com::sun::star::script::XInvocation >
62 {
63 public:
64     BmpConverter();
65     virtual ~BmpConverter();
66 
67     virtual Reference< XIntrospectionAccess > SAL_CALL getIntrospection() throw();
68     virtual void SAL_CALL setValue( const OUString& rProperty, const Any& rValue )
69         throw( UnknownPropertyException );
70     virtual Any SAL_CALL getValue( const OUString& rProperty )
71         throw( UnknownPropertyException );
72     virtual sal_Bool SAL_CALL hasMethod( const OUString& rName ) throw();
73     virtual sal_Bool SAL_CALL hasProperty( const OUString& rProp ) throw();
74 
75     virtual Any SAL_CALL invoke( const OUString& rFunction,
76                                  const Sequence< Any >& rParams,
77                                  Sequence< sal_Int16 >& rOutParamIndex,
78                                  Sequence< Any >& rOutParam
79                                  )
80         throw( CannotConvertException, InvocationTargetException );
81 };
82 
83 }
84 
85 using namespace vcl;
86 
87 Reference< XInvocation > vcl::createBmpConverter()
88 {
89     return static_cast<XInvocation*>(new BmpConverter());
90 }
91 
92 BmpConverter::BmpConverter()
93 {
94 }
95 
96 BmpConverter::~BmpConverter()
97 {
98 }
99 
100 Reference< XIntrospectionAccess > SAL_CALL BmpConverter::getIntrospection() throw()
101 {
102     return Reference< XIntrospectionAccess >();
103 }
104 
105 void SAL_CALL BmpConverter::setValue( const OUString&, const Any& ) throw( UnknownPropertyException )
106 {
107     throw UnknownPropertyException();
108 }
109 
110 Any SAL_CALL BmpConverter::getValue( const OUString& ) throw( UnknownPropertyException )
111 {
112     throw UnknownPropertyException();
113 }
114 
115 sal_Bool SAL_CALL BmpConverter::hasMethod( const OUString& rName ) throw()
116 {
117     return rName.equalsIgnoreAsciiCase( OUString::createFromAscii( "convert-bitmap-depth" ) );
118 }
119 
120 sal_Bool SAL_CALL BmpConverter::hasProperty( const OUString& ) throw()
121 {
122     return sal_False;
123 }
124 
125 Any SAL_CALL BmpConverter::invoke(
126                                   const OUString& rFunction,
127                                   const Sequence< Any >& rParams,
128                                   Sequence< sal_Int16 >&,
129                                   Sequence< Any >& )
130     throw( CannotConvertException, InvocationTargetException )
131 {
132     Any aRet;
133 
134     if( rFunction.equalsIgnoreAsciiCase( OUString::createFromAscii( "convert-bitmap-depth" ) ) )
135     {
136         Reference< XBitmap > xBM;
137         sal_uInt16 nTargetDepth = 0;
138         if( rParams.getLength() != 2 )
139             throw CannotConvertException();
140 
141         if( ! (rParams.getConstArray()[0] >>= xBM ) ||
142             ! ( rParams.getConstArray()[1] >>= nTargetDepth ) )
143             throw CannotConvertException();
144 
145         Sequence< sal_Int8 > aDIB = xBM->getDIB();
146 
147         // call into vcl not thread safe
148         vos::OGuard aGuard( Application::GetSolarMutex() );
149 
150         SvMemoryStream aStream( aDIB.getArray(), aDIB.getLength(), STREAM_READ | STREAM_WRITE );
151         Bitmap aBM;
152         aBM.Read( aStream, sal_True );
153         if( nTargetDepth < 4 )
154             nTargetDepth = 1;
155         else if( nTargetDepth < 8 )
156             nTargetDepth = 4;
157         else if( nTargetDepth >8 && nTargetDepth < 24 )
158             nTargetDepth = 24;
159 
160         if( aBM.GetBitCount() == 24 && nTargetDepth <= 8 )
161             aBM.Dither( BMP_DITHER_FLOYD );
162 
163         if( aBM.GetBitCount() != nTargetDepth )
164         {
165             switch( nTargetDepth )
166             {
167                 case 1:		aBM.Convert( BMP_CONVERSION_1BIT_THRESHOLD );break;
168                 case 4:		aBM.ReduceColors( BMP_CONVERSION_4BIT_COLORS );break;
169                 case 8:		aBM.ReduceColors( BMP_CONVERSION_8BIT_COLORS );break;
170                 case 24:	aBM.Convert( BMP_CONVERSION_24BIT );break;
171             }
172         }
173         xBM = new BmpTransporter( aBM );
174         aRet <<= xBM;
175     }
176     else
177         throw InvocationTargetException();
178 
179     return aRet;
180 }
181 
182 BmpTransporter::BmpTransporter( const Bitmap& rBM )
183 {
184     m_aSize.Width = rBM.GetSizePixel().Width();
185     m_aSize.Height = rBM.GetSizePixel().Height();
186     SvMemoryStream aStream;
187     rBM.Write( aStream, sal_False, sal_True );
188     m_aBM = Sequence<sal_Int8>(static_cast<const sal_Int8*>(aStream.GetData()),
189                 aStream.GetEndOfData());
190 }
191 
192 BmpTransporter::~BmpTransporter()
193 {
194 }
195 
196 com::sun::star::awt::Size SAL_CALL BmpTransporter::getSize() throw()
197 {
198     return m_aSize;
199 }
200 
201 Sequence< sal_Int8 > SAL_CALL BmpTransporter::getDIB() throw()
202 {
203     return m_aBM;
204 }
205 
206 Sequence< sal_Int8 > SAL_CALL BmpTransporter::getMaskDIB() throw()
207 {
208     return Sequence< sal_Int8 >();
209 }
210