xref: /trunk/main/vcl/source/gdi/bmpconv.cxx (revision 45fd3b9a)
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