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 // MARKER(update_precomp.py): autogen include statement, do not remove
23 #include "precompiled_vcl.hxx"
24
25 #include "vcl/bitmap.hxx"
26 #include "vcl/svapp.hxx"
27 #include "vcl/salctype.hxx"
28 #include "vos/mutex.hxx"
29 #include "tools/stream.hxx"
30 #include "com/sun/star/script/XInvocation.hpp"
31 #include "com/sun/star/awt/XBitmap.hpp"
32 #include "cppuhelper/compbase1.hxx"
33 #include <vcl/dibtools.hxx>
34
35 using namespace com::sun::star::uno;
36 using namespace com::sun::star::script;
37 using namespace com::sun::star::beans;
38 using namespace com::sun::star::reflection;
39 using namespace com::sun::star::awt;
40 using namespace rtl;
41
42 namespace vcl {
43
44 class BmpTransporter :
45 public cppu::WeakImplHelper1< com::sun::star::awt::XBitmap >
46 {
47 Sequence<sal_Int8> m_aBM;
48 com::sun::star::awt::Size m_aSize;
49 public:
50 BmpTransporter( const Bitmap& rBM );
51 virtual ~BmpTransporter();
52
53 virtual com::sun::star::awt::Size SAL_CALL getSize() throw();
54 virtual Sequence< sal_Int8 > SAL_CALL getDIB() throw();
55 virtual Sequence< sal_Int8 > SAL_CALL getMaskDIB() throw();
56 };
57
58 class BmpConverter :
59 public cppu::WeakImplHelper1< com::sun::star::script::XInvocation >
60 {
61 public:
62 BmpConverter();
63 virtual ~BmpConverter();
64
65 virtual Reference< XIntrospectionAccess > SAL_CALL getIntrospection() throw();
66 virtual void SAL_CALL setValue( const OUString& rProperty, const Any& rValue )
67 throw( UnknownPropertyException );
68 virtual Any SAL_CALL getValue( const OUString& rProperty )
69 throw( UnknownPropertyException );
70 virtual sal_Bool SAL_CALL hasMethod( const OUString& rName ) throw();
71 virtual sal_Bool SAL_CALL hasProperty( const OUString& rProp ) throw();
72
73 virtual Any SAL_CALL invoke( const OUString& rFunction,
74 const Sequence< Any >& rParams,
75 Sequence< sal_Int16 >& rOutParamIndex,
76 Sequence< Any >& rOutParam
77 )
78 throw( CannotConvertException, InvocationTargetException );
79 };
80
81 }
82
83 using namespace vcl;
84
createBmpConverter()85 Reference< XInvocation > vcl::createBmpConverter()
86 {
87 return static_cast<XInvocation*>(new BmpConverter());
88 }
89
BmpConverter()90 BmpConverter::BmpConverter()
91 {
92 }
93
~BmpConverter()94 BmpConverter::~BmpConverter()
95 {
96 }
97
getIntrospection()98 Reference< XIntrospectionAccess > SAL_CALL BmpConverter::getIntrospection() throw()
99 {
100 return Reference< XIntrospectionAccess >();
101 }
102
setValue(const OUString &,const Any &)103 void SAL_CALL BmpConverter::setValue( const OUString&, const Any& ) throw( UnknownPropertyException )
104 {
105 throw UnknownPropertyException();
106 }
107
getValue(const OUString &)108 Any SAL_CALL BmpConverter::getValue( const OUString& ) throw( UnknownPropertyException )
109 {
110 throw UnknownPropertyException();
111 }
112
hasMethod(const OUString & rName)113 sal_Bool SAL_CALL BmpConverter::hasMethod( const OUString& rName ) throw()
114 {
115 return rName.equalsIgnoreAsciiCase( OUString::createFromAscii( "convert-bitmap-depth" ) );
116 }
117
hasProperty(const OUString &)118 sal_Bool SAL_CALL BmpConverter::hasProperty( const OUString& ) throw()
119 {
120 return sal_False;
121 }
122
invoke(const OUString & rFunction,const Sequence<Any> & rParams,Sequence<sal_Int16> &,Sequence<Any> &)123 Any SAL_CALL BmpConverter::invoke(
124 const OUString& rFunction,
125 const Sequence< Any >& rParams,
126 Sequence< sal_Int16 >&,
127 Sequence< Any >& )
128 throw( CannotConvertException, InvocationTargetException )
129 {
130 Any aRet;
131
132 if( rFunction.equalsIgnoreAsciiCase( OUString::createFromAscii( "convert-bitmap-depth" ) ) )
133 {
134 Reference< XBitmap > xBM;
135 sal_uInt16 nTargetDepth = 0;
136 if( rParams.getLength() != 2 )
137 throw CannotConvertException();
138
139 if( ! (rParams.getConstArray()[0] >>= xBM ) ||
140 ! ( rParams.getConstArray()[1] >>= nTargetDepth ) )
141 throw CannotConvertException();
142
143 Sequence< sal_Int8 > aDIB = xBM->getDIB();
144
145 // call into vcl not thread safe
146 vos::OGuard aGuard( Application::GetSolarMutex() );
147
148 SvMemoryStream aStream( aDIB.getArray(), aDIB.getLength(), STREAM_READ | STREAM_WRITE );
149 Bitmap aBM;
150
151 ReadDIB(aBM, aStream, true);
152
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
BmpTransporter(const Bitmap & rBM)182 BmpTransporter::BmpTransporter( const Bitmap& rBM )
183 {
184 m_aSize.Width = rBM.GetSizePixel().Width();
185 m_aSize.Height = rBM.GetSizePixel().Height();
186
187 SvMemoryStream aStream;
188
189 WriteDIB(rBM, aStream, false, true);
190
191 m_aBM = Sequence<sal_Int8>(static_cast<const sal_Int8*>(aStream.GetData()),
192 aStream.GetEndOfData());
193 }
194
~BmpTransporter()195 BmpTransporter::~BmpTransporter()
196 {
197 }
198
getSize()199 com::sun::star::awt::Size SAL_CALL BmpTransporter::getSize() throw()
200 {
201 return m_aSize;
202 }
203
getDIB()204 Sequence< sal_Int8 > SAL_CALL BmpTransporter::getDIB() throw()
205 {
206 return m_aBM;
207 }
208
getMaskDIB()209 Sequence< sal_Int8 > SAL_CALL BmpTransporter::getMaskDIB() throw()
210 {
211 return Sequence< sal_Int8 >();
212 }
213