xref: /trunk/main/vcl/source/gdi/bmpconv.cxx (revision cdf0e10c)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_vcl.hxx"
30 
31 #include "vcl/bitmap.hxx"
32 #include "vcl/svapp.hxx"
33 #include "vcl/salctype.hxx"
34 #include "vos/mutex.hxx"
35 #include "tools/stream.hxx"
36 #include "com/sun/star/script/XInvocation.hpp"
37 #include "com/sun/star/awt/XBitmap.hpp"
38 #include "cppuhelper/compbase1.hxx"
39 
40 
41 using namespace com::sun::star::uno;
42 using namespace com::sun::star::script;
43 using namespace com::sun::star::beans;
44 using namespace com::sun::star::reflection;
45 using namespace com::sun::star::awt;
46 using namespace rtl;
47 
48 namespace vcl {
49 
50 class BmpTransporter :
51         public cppu::WeakImplHelper1< com::sun::star::awt::XBitmap >
52 {
53     Sequence<sal_Int8>			m_aBM;
54     com::sun::star::awt::Size	m_aSize;
55 public:
56     BmpTransporter( const Bitmap& rBM );
57     virtual  ~BmpTransporter();
58 
59     virtual com::sun::star::awt::Size SAL_CALL getSize() throw();
60     virtual Sequence< sal_Int8 > SAL_CALL getDIB() throw();
61     virtual Sequence< sal_Int8 > SAL_CALL getMaskDIB() throw();
62 };
63 
64 class BmpConverter :
65         public cppu::WeakImplHelper1< com::sun::star::script::XInvocation >
66 {
67 public:
68     BmpConverter();
69     virtual ~BmpConverter();
70 
71     virtual Reference< XIntrospectionAccess > SAL_CALL getIntrospection() throw();
72     virtual void SAL_CALL setValue( const OUString& rProperty, const Any& rValue )
73         throw( UnknownPropertyException );
74     virtual Any SAL_CALL getValue( const OUString& rProperty )
75         throw( UnknownPropertyException );
76     virtual sal_Bool SAL_CALL hasMethod( const OUString& rName ) throw();
77     virtual sal_Bool SAL_CALL hasProperty( const OUString& rProp ) throw();
78 
79     virtual Any SAL_CALL invoke( const OUString& rFunction,
80                                  const Sequence< Any >& rParams,
81                                  Sequence< sal_Int16 >& rOutParamIndex,
82                                  Sequence< Any >& rOutParam
83                                  )
84         throw( CannotConvertException, InvocationTargetException );
85 };
86 
87 }
88 
89 using namespace vcl;
90 
91 Reference< XInvocation > vcl::createBmpConverter()
92 {
93     return static_cast<XInvocation*>(new BmpConverter());
94 }
95 
96 BmpConverter::BmpConverter()
97 {
98 }
99 
100 BmpConverter::~BmpConverter()
101 {
102 }
103 
104 Reference< XIntrospectionAccess > SAL_CALL BmpConverter::getIntrospection() throw()
105 {
106     return Reference< XIntrospectionAccess >();
107 }
108 
109 void SAL_CALL BmpConverter::setValue( const OUString&, const Any& ) throw( UnknownPropertyException )
110 {
111     throw UnknownPropertyException();
112 }
113 
114 Any SAL_CALL BmpConverter::getValue( const OUString& ) throw( UnknownPropertyException )
115 {
116     throw UnknownPropertyException();
117 }
118 
119 sal_Bool SAL_CALL BmpConverter::hasMethod( const OUString& rName ) throw()
120 {
121     return rName.equalsIgnoreAsciiCase( OUString::createFromAscii( "convert-bitmap-depth" ) );
122 }
123 
124 sal_Bool SAL_CALL BmpConverter::hasProperty( const OUString& ) throw()
125 {
126     return sal_False;
127 }
128 
129 Any SAL_CALL BmpConverter::invoke(
130                                   const OUString& rFunction,
131                                   const Sequence< Any >& rParams,
132                                   Sequence< sal_Int16 >&,
133                                   Sequence< Any >& )
134     throw( CannotConvertException, InvocationTargetException )
135 {
136     Any aRet;
137 
138     if( rFunction.equalsIgnoreAsciiCase( OUString::createFromAscii( "convert-bitmap-depth" ) ) )
139     {
140         Reference< XBitmap > xBM;
141         sal_uInt16 nTargetDepth = 0;
142         if( rParams.getLength() != 2 )
143             throw CannotConvertException();
144 
145         if( ! (rParams.getConstArray()[0] >>= xBM ) ||
146             ! ( rParams.getConstArray()[1] >>= nTargetDepth ) )
147             throw CannotConvertException();
148 
149         Sequence< sal_Int8 > aDIB = xBM->getDIB();
150 
151         // call into vcl not thread safe
152         vos::OGuard aGuard( Application::GetSolarMutex() );
153 
154         SvMemoryStream aStream( aDIB.getArray(), aDIB.getLength(), STREAM_READ | STREAM_WRITE );
155         Bitmap aBM;
156         aBM.Read( aStream, sal_True );
157         if( nTargetDepth < 4 )
158             nTargetDepth = 1;
159         else if( nTargetDepth < 8 )
160             nTargetDepth = 4;
161         else if( nTargetDepth >8 && nTargetDepth < 24 )
162             nTargetDepth = 24;
163 
164         if( aBM.GetBitCount() == 24 && nTargetDepth <= 8 )
165             aBM.Dither( BMP_DITHER_FLOYD );
166 
167         if( aBM.GetBitCount() != nTargetDepth )
168         {
169             switch( nTargetDepth )
170             {
171                 case 1:		aBM.Convert( BMP_CONVERSION_1BIT_THRESHOLD );break;
172                 case 4:		aBM.ReduceColors( BMP_CONVERSION_4BIT_COLORS );break;
173                 case 8:		aBM.ReduceColors( BMP_CONVERSION_8BIT_COLORS );break;
174                 case 24:	aBM.Convert( BMP_CONVERSION_24BIT );break;
175             }
176         }
177         xBM = new BmpTransporter( aBM );
178         aRet <<= xBM;
179     }
180     else
181         throw InvocationTargetException();
182 
183     return aRet;
184 }
185 
186 BmpTransporter::BmpTransporter( const Bitmap& rBM )
187 {
188     m_aSize.Width = rBM.GetSizePixel().Width();
189     m_aSize.Height = rBM.GetSizePixel().Height();
190     SvMemoryStream aStream;
191     rBM.Write( aStream, sal_False, sal_True );
192     m_aBM = Sequence<sal_Int8>(static_cast<const sal_Int8*>(aStream.GetData()),
193                 aStream.GetEndOfData());
194 }
195 
196 BmpTransporter::~BmpTransporter()
197 {
198 }
199 
200 com::sun::star::awt::Size SAL_CALL BmpTransporter::getSize() throw()
201 {
202     return m_aSize;
203 }
204 
205 Sequence< sal_Int8 > SAL_CALL BmpTransporter::getDIB() throw()
206 {
207     return m_aBM;
208 }
209 
210 Sequence< sal_Int8 > SAL_CALL BmpTransporter::getMaskDIB() throw()
211 {
212     return Sequence< sal_Int8 >();
213 }
214