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 virtual Any SAL_CALL getValue( const OUString& rProperty );
68 virtual sal_Bool SAL_CALL hasMethod( const OUString& rName ) throw();
69 virtual sal_Bool SAL_CALL hasProperty( const OUString& rProp ) throw();
70
71 virtual Any SAL_CALL invoke( const OUString& rFunction,
72 const Sequence< Any >& rParams,
73 Sequence< sal_Int16 >& rOutParamIndex,
74 Sequence< Any >& rOutParam
75 );
76 };
77
78 }
79
80 using namespace vcl;
81
createBmpConverter()82 Reference< XInvocation > vcl::createBmpConverter()
83 {
84 return static_cast<XInvocation*>(new BmpConverter());
85 }
86
BmpConverter()87 BmpConverter::BmpConverter()
88 {
89 }
90
~BmpConverter()91 BmpConverter::~BmpConverter()
92 {
93 }
94
getIntrospection()95 Reference< XIntrospectionAccess > SAL_CALL BmpConverter::getIntrospection() throw()
96 {
97 return Reference< XIntrospectionAccess >();
98 }
99
setValue(const OUString &,const Any &)100 void SAL_CALL BmpConverter::setValue( const OUString&, const Any& )
101 {
102 throw UnknownPropertyException();
103 }
104
getValue(const OUString &)105 Any SAL_CALL BmpConverter::getValue( const OUString& )
106 {
107 throw UnknownPropertyException();
108 }
109
hasMethod(const OUString & rName)110 sal_Bool SAL_CALL BmpConverter::hasMethod( const OUString& rName ) throw()
111 {
112 return rName.equalsIgnoreAsciiCase( OUString::createFromAscii( "convert-bitmap-depth" ) );
113 }
114
hasProperty(const OUString &)115 sal_Bool SAL_CALL BmpConverter::hasProperty( const OUString& ) throw()
116 {
117 return sal_False;
118 }
119
invoke(const OUString & rFunction,const Sequence<Any> & rParams,Sequence<sal_Int16> &,Sequence<Any> &)120 Any SAL_CALL BmpConverter::invoke(
121 const OUString& rFunction,
122 const Sequence< Any >& rParams,
123 Sequence< sal_Int16 >&,
124 Sequence< Any >& )
125 {
126 Any aRet;
127
128 if( rFunction.equalsIgnoreAsciiCase( OUString::createFromAscii( "convert-bitmap-depth" ) ) )
129 {
130 Reference< XBitmap > xBM;
131 sal_uInt16 nTargetDepth = 0;
132 if( rParams.getLength() != 2 )
133 throw CannotConvertException();
134
135 if( ! (rParams.getConstArray()[0] >>= xBM ) ||
136 ! ( rParams.getConstArray()[1] >>= nTargetDepth ) )
137 throw CannotConvertException();
138
139 Sequence< sal_Int8 > aDIB = xBM->getDIB();
140
141 // call into vcl not thread safe
142 vos::OGuard aGuard( Application::GetSolarMutex() );
143
144 SvMemoryStream aStream( aDIB.getArray(), aDIB.getLength(), STREAM_READ | STREAM_WRITE );
145 Bitmap aBM;
146
147 ReadDIB(aBM, aStream, true);
148
149 if( nTargetDepth < 4 )
150 nTargetDepth = 1;
151 else if( nTargetDepth < 8 )
152 nTargetDepth = 4;
153 else if( nTargetDepth >8 && nTargetDepth < 24 )
154 nTargetDepth = 24;
155
156 if( aBM.GetBitCount() == 24 && nTargetDepth <= 8 )
157 aBM.Dither( BMP_DITHER_FLOYD );
158
159 if( aBM.GetBitCount() != nTargetDepth )
160 {
161 switch( nTargetDepth )
162 {
163 case 1: aBM.Convert( BMP_CONVERSION_1BIT_THRESHOLD );break;
164 case 4: aBM.ReduceColors( BMP_CONVERSION_4BIT_COLORS );break;
165 case 8: aBM.ReduceColors( BMP_CONVERSION_8BIT_COLORS );break;
166 case 24: aBM.Convert( BMP_CONVERSION_24BIT );break;
167 }
168 }
169 xBM = new BmpTransporter( aBM );
170 aRet <<= xBM;
171 }
172 else
173 throw InvocationTargetException();
174
175 return aRet;
176 }
177
BmpTransporter(const Bitmap & rBM)178 BmpTransporter::BmpTransporter( const Bitmap& rBM )
179 {
180 m_aSize.Width = rBM.GetSizePixel().Width();
181 m_aSize.Height = rBM.GetSizePixel().Height();
182
183 SvMemoryStream aStream;
184
185 WriteDIB(rBM, aStream, false, true);
186
187 m_aBM = Sequence<sal_Int8>(static_cast<const sal_Int8*>(aStream.GetData()),
188 aStream.GetEndOfData());
189 }
190
~BmpTransporter()191 BmpTransporter::~BmpTransporter()
192 {
193 }
194
getSize()195 com::sun::star::awt::Size SAL_CALL BmpTransporter::getSize() throw()
196 {
197 return m_aSize;
198 }
199
getDIB()200 Sequence< sal_Int8 > SAL_CALL BmpTransporter::getDIB() throw()
201 {
202 return m_aBM;
203 }
204
getMaskDIB()205 Sequence< sal_Int8 > SAL_CALL BmpTransporter::getMaskDIB() throw()
206 {
207 return Sequence< sal_Int8 >();
208 }
209