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