xref: /trunk/main/vcl/source/gdi/bmpconv.cxx (revision cf6516809c57e1bb0a940545cca99cdad54d4ce2)
19f62ea84SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
39f62ea84SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
49f62ea84SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
59f62ea84SAndrew Rist  * distributed with this work for additional information
69f62ea84SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
79f62ea84SAndrew Rist  * to you under the Apache License, Version 2.0 (the
89f62ea84SAndrew Rist  * "License"); you may not use this file except in compliance
99f62ea84SAndrew Rist  * with the License.  You may obtain a copy of the License at
10cdf0e10cSrcweir  *
119f62ea84SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12cdf0e10cSrcweir  *
139f62ea84SAndrew Rist  * Unless required by applicable law or agreed to in writing,
149f62ea84SAndrew Rist  * software distributed under the License is distributed on an
159f62ea84SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
169f62ea84SAndrew Rist  * KIND, either express or implied.  See the License for the
179f62ea84SAndrew Rist  * specific language governing permissions and limitations
189f62ea84SAndrew Rist  * under the License.
19cdf0e10cSrcweir  *
209f62ea84SAndrew Rist  *************************************************************/
219f62ea84SAndrew Rist 
22cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
23cdf0e10cSrcweir #include "precompiled_vcl.hxx"
24cdf0e10cSrcweir 
25cdf0e10cSrcweir #include "vcl/bitmap.hxx"
26cdf0e10cSrcweir #include "vcl/svapp.hxx"
27cdf0e10cSrcweir #include "vcl/salctype.hxx"
28cdf0e10cSrcweir #include "vos/mutex.hxx"
29cdf0e10cSrcweir #include "tools/stream.hxx"
30cdf0e10cSrcweir #include "com/sun/star/script/XInvocation.hpp"
31cdf0e10cSrcweir #include "com/sun/star/awt/XBitmap.hpp"
32cdf0e10cSrcweir #include "cppuhelper/compbase1.hxx"
33*45fd3b9aSArmin Le Grand #include <vcl/dibtools.hxx>
34cdf0e10cSrcweir 
35cdf0e10cSrcweir using namespace com::sun::star::uno;
36cdf0e10cSrcweir using namespace com::sun::star::script;
37cdf0e10cSrcweir using namespace com::sun::star::beans;
38cdf0e10cSrcweir using namespace com::sun::star::reflection;
39cdf0e10cSrcweir using namespace com::sun::star::awt;
40cdf0e10cSrcweir using namespace rtl;
41cdf0e10cSrcweir 
42cdf0e10cSrcweir namespace vcl {
43cdf0e10cSrcweir 
44cdf0e10cSrcweir class BmpTransporter :
45cdf0e10cSrcweir         public cppu::WeakImplHelper1< com::sun::star::awt::XBitmap >
46cdf0e10cSrcweir {
47cdf0e10cSrcweir     Sequence<sal_Int8>          m_aBM;
48cdf0e10cSrcweir     com::sun::star::awt::Size   m_aSize;
49cdf0e10cSrcweir public:
50cdf0e10cSrcweir     BmpTransporter( const Bitmap& rBM );
51cdf0e10cSrcweir     virtual  ~BmpTransporter();
52cdf0e10cSrcweir 
53cdf0e10cSrcweir     virtual com::sun::star::awt::Size SAL_CALL getSize() throw();
54cdf0e10cSrcweir     virtual Sequence< sal_Int8 > SAL_CALL getDIB() throw();
55cdf0e10cSrcweir     virtual Sequence< sal_Int8 > SAL_CALL getMaskDIB() throw();
56cdf0e10cSrcweir };
57cdf0e10cSrcweir 
58cdf0e10cSrcweir class BmpConverter :
59cdf0e10cSrcweir         public cppu::WeakImplHelper1< com::sun::star::script::XInvocation >
60cdf0e10cSrcweir {
61cdf0e10cSrcweir public:
62cdf0e10cSrcweir     BmpConverter();
63cdf0e10cSrcweir     virtual ~BmpConverter();
64cdf0e10cSrcweir 
65cdf0e10cSrcweir     virtual Reference< XIntrospectionAccess > SAL_CALL getIntrospection() throw();
66cdf0e10cSrcweir     virtual void SAL_CALL setValue( const OUString& rProperty, const Any& rValue )
67cdf0e10cSrcweir         throw( UnknownPropertyException );
68cdf0e10cSrcweir     virtual Any SAL_CALL getValue( const OUString& rProperty )
69cdf0e10cSrcweir         throw( UnknownPropertyException );
70cdf0e10cSrcweir     virtual sal_Bool SAL_CALL hasMethod( const OUString& rName ) throw();
71cdf0e10cSrcweir     virtual sal_Bool SAL_CALL hasProperty( const OUString& rProp ) throw();
72cdf0e10cSrcweir 
73cdf0e10cSrcweir     virtual Any SAL_CALL invoke( const OUString& rFunction,
74cdf0e10cSrcweir                                  const Sequence< Any >& rParams,
75cdf0e10cSrcweir                                  Sequence< sal_Int16 >& rOutParamIndex,
76cdf0e10cSrcweir                                  Sequence< Any >& rOutParam
77cdf0e10cSrcweir                                  )
78cdf0e10cSrcweir         throw( CannotConvertException, InvocationTargetException );
79cdf0e10cSrcweir };
80cdf0e10cSrcweir 
81cdf0e10cSrcweir }
82cdf0e10cSrcweir 
83cdf0e10cSrcweir using namespace vcl;
84cdf0e10cSrcweir 
createBmpConverter()85cdf0e10cSrcweir Reference< XInvocation > vcl::createBmpConverter()
86cdf0e10cSrcweir {
87cdf0e10cSrcweir     return static_cast<XInvocation*>(new BmpConverter());
88cdf0e10cSrcweir }
89cdf0e10cSrcweir 
BmpConverter()90cdf0e10cSrcweir BmpConverter::BmpConverter()
91cdf0e10cSrcweir {
92cdf0e10cSrcweir }
93cdf0e10cSrcweir 
~BmpConverter()94cdf0e10cSrcweir BmpConverter::~BmpConverter()
95cdf0e10cSrcweir {
96cdf0e10cSrcweir }
97cdf0e10cSrcweir 
getIntrospection()98cdf0e10cSrcweir Reference< XIntrospectionAccess > SAL_CALL BmpConverter::getIntrospection() throw()
99cdf0e10cSrcweir {
100cdf0e10cSrcweir     return Reference< XIntrospectionAccess >();
101cdf0e10cSrcweir }
102cdf0e10cSrcweir 
setValue(const OUString &,const Any &)103cdf0e10cSrcweir void SAL_CALL BmpConverter::setValue( const OUString&, const Any& ) throw( UnknownPropertyException )
104cdf0e10cSrcweir {
105cdf0e10cSrcweir     throw UnknownPropertyException();
106cdf0e10cSrcweir }
107cdf0e10cSrcweir 
getValue(const OUString &)108cdf0e10cSrcweir Any SAL_CALL BmpConverter::getValue( const OUString& ) throw( UnknownPropertyException )
109cdf0e10cSrcweir {
110cdf0e10cSrcweir     throw UnknownPropertyException();
111cdf0e10cSrcweir }
112cdf0e10cSrcweir 
hasMethod(const OUString & rName)113cdf0e10cSrcweir sal_Bool SAL_CALL BmpConverter::hasMethod( const OUString& rName ) throw()
114cdf0e10cSrcweir {
115cdf0e10cSrcweir     return rName.equalsIgnoreAsciiCase( OUString::createFromAscii( "convert-bitmap-depth" ) );
116cdf0e10cSrcweir }
117cdf0e10cSrcweir 
hasProperty(const OUString &)118cdf0e10cSrcweir sal_Bool SAL_CALL BmpConverter::hasProperty( const OUString& ) throw()
119cdf0e10cSrcweir {
120cdf0e10cSrcweir     return sal_False;
121cdf0e10cSrcweir }
122cdf0e10cSrcweir 
invoke(const OUString & rFunction,const Sequence<Any> & rParams,Sequence<sal_Int16> &,Sequence<Any> &)123cdf0e10cSrcweir Any SAL_CALL BmpConverter::invoke(
124cdf0e10cSrcweir                                   const OUString& rFunction,
125cdf0e10cSrcweir                                   const Sequence< Any >& rParams,
126cdf0e10cSrcweir                                   Sequence< sal_Int16 >&,
127cdf0e10cSrcweir                                   Sequence< Any >& )
128cdf0e10cSrcweir     throw( CannotConvertException, InvocationTargetException )
129cdf0e10cSrcweir {
130cdf0e10cSrcweir     Any aRet;
131cdf0e10cSrcweir 
132cdf0e10cSrcweir     if( rFunction.equalsIgnoreAsciiCase( OUString::createFromAscii( "convert-bitmap-depth" ) ) )
133cdf0e10cSrcweir     {
134cdf0e10cSrcweir         Reference< XBitmap > xBM;
135cdf0e10cSrcweir         sal_uInt16 nTargetDepth = 0;
136cdf0e10cSrcweir         if( rParams.getLength() != 2 )
137cdf0e10cSrcweir             throw CannotConvertException();
138cdf0e10cSrcweir 
139cdf0e10cSrcweir         if( ! (rParams.getConstArray()[0] >>= xBM ) ||
140cdf0e10cSrcweir             ! ( rParams.getConstArray()[1] >>= nTargetDepth ) )
141cdf0e10cSrcweir             throw CannotConvertException();
142cdf0e10cSrcweir 
143cdf0e10cSrcweir         Sequence< sal_Int8 > aDIB = xBM->getDIB();
144cdf0e10cSrcweir 
145cdf0e10cSrcweir         // call into vcl not thread safe
146cdf0e10cSrcweir         vos::OGuard aGuard( Application::GetSolarMutex() );
147cdf0e10cSrcweir 
148cdf0e10cSrcweir         SvMemoryStream aStream( aDIB.getArray(), aDIB.getLength(), STREAM_READ | STREAM_WRITE );
149cdf0e10cSrcweir         Bitmap aBM;
150*45fd3b9aSArmin Le Grand 
151*45fd3b9aSArmin Le Grand         ReadDIB(aBM, aStream, true);
152*45fd3b9aSArmin Le Grand 
153cdf0e10cSrcweir         if( nTargetDepth < 4 )
154cdf0e10cSrcweir             nTargetDepth = 1;
155cdf0e10cSrcweir         else if( nTargetDepth < 8 )
156cdf0e10cSrcweir             nTargetDepth = 4;
157cdf0e10cSrcweir         else if( nTargetDepth >8 && nTargetDepth < 24 )
158cdf0e10cSrcweir             nTargetDepth = 24;
159cdf0e10cSrcweir 
160cdf0e10cSrcweir         if( aBM.GetBitCount() == 24 && nTargetDepth <= 8 )
161cdf0e10cSrcweir             aBM.Dither( BMP_DITHER_FLOYD );
162cdf0e10cSrcweir 
163cdf0e10cSrcweir         if( aBM.GetBitCount() != nTargetDepth )
164cdf0e10cSrcweir         {
165cdf0e10cSrcweir             switch( nTargetDepth )
166cdf0e10cSrcweir             {
167cdf0e10cSrcweir                 case 1:     aBM.Convert( BMP_CONVERSION_1BIT_THRESHOLD );break;
168cdf0e10cSrcweir                 case 4:     aBM.ReduceColors( BMP_CONVERSION_4BIT_COLORS );break;
169cdf0e10cSrcweir                 case 8:     aBM.ReduceColors( BMP_CONVERSION_8BIT_COLORS );break;
170cdf0e10cSrcweir                 case 24:    aBM.Convert( BMP_CONVERSION_24BIT );break;
171cdf0e10cSrcweir             }
172cdf0e10cSrcweir         }
173cdf0e10cSrcweir         xBM = new BmpTransporter( aBM );
174cdf0e10cSrcweir         aRet <<= xBM;
175cdf0e10cSrcweir     }
176cdf0e10cSrcweir     else
177cdf0e10cSrcweir         throw InvocationTargetException();
178cdf0e10cSrcweir 
179cdf0e10cSrcweir     return aRet;
180cdf0e10cSrcweir }
181cdf0e10cSrcweir 
BmpTransporter(const Bitmap & rBM)182cdf0e10cSrcweir BmpTransporter::BmpTransporter( const Bitmap& rBM )
183cdf0e10cSrcweir {
184cdf0e10cSrcweir     m_aSize.Width = rBM.GetSizePixel().Width();
185cdf0e10cSrcweir     m_aSize.Height = rBM.GetSizePixel().Height();
186*45fd3b9aSArmin Le Grand 
187cdf0e10cSrcweir     SvMemoryStream aStream;
188*45fd3b9aSArmin Le Grand 
189*45fd3b9aSArmin Le Grand     WriteDIB(rBM, aStream, false, true);
190*45fd3b9aSArmin Le Grand 
191cdf0e10cSrcweir     m_aBM = Sequence<sal_Int8>(static_cast<const sal_Int8*>(aStream.GetData()),
192cdf0e10cSrcweir                 aStream.GetEndOfData());
193cdf0e10cSrcweir }
194cdf0e10cSrcweir 
~BmpTransporter()195cdf0e10cSrcweir BmpTransporter::~BmpTransporter()
196cdf0e10cSrcweir {
197cdf0e10cSrcweir }
198cdf0e10cSrcweir 
getSize()199cdf0e10cSrcweir com::sun::star::awt::Size SAL_CALL BmpTransporter::getSize() throw()
200cdf0e10cSrcweir {
201cdf0e10cSrcweir     return m_aSize;
202cdf0e10cSrcweir }
203cdf0e10cSrcweir 
getDIB()204cdf0e10cSrcweir Sequence< sal_Int8 > SAL_CALL BmpTransporter::getDIB() throw()
205cdf0e10cSrcweir {
206cdf0e10cSrcweir     return m_aBM;
207cdf0e10cSrcweir }
208cdf0e10cSrcweir 
getMaskDIB()209cdf0e10cSrcweir Sequence< sal_Int8 > SAL_CALL BmpTransporter::getMaskDIB() throw()
210cdf0e10cSrcweir {
211cdf0e10cSrcweir     return Sequence< sal_Int8 >();
212cdf0e10cSrcweir }
213