Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : :
30 : : #include <vcl/graph.hxx>
31 : : #include <vcl/bmpacc.hxx>
32 : : #include <svtools/fltcall.hxx>
33 : : #include <svtools/FilterConfigItem.hxx>
34 : :
35 : : //============================ RASWriter ==================================
36 : :
37 : : class RASWriter {
38 : :
39 : : private:
40 : :
41 : : SvStream & m_rOStm;
42 : : sal_uInt16 mpOStmOldModus;
43 : :
44 : : sal_Bool mbStatus;
45 : : BitmapReadAccess* mpAcc;
46 : :
47 : : sal_uLong mnWidth, mnHeight;
48 : : sal_uInt16 mnColors, mnDepth;
49 : :
50 : : sal_uLong mnRepCount;
51 : : sal_uInt8 mnRepVal;
52 : :
53 : : com::sun::star::uno::Reference< com::sun::star::task::XStatusIndicator > xStatusIndicator;
54 : :
55 : : void ImplCallback( sal_uLong nCurrentYPos );
56 : : sal_Bool ImplWriteHeader();
57 : : void ImplWritePalette();
58 : : void ImplWriteBody();
59 : : void ImplPutByte( sal_uInt8 ); // RLE decoding
60 : :
61 : : public:
62 : : RASWriter(SvStream &rStream);
63 : : ~RASWriter();
64 : :
65 : : sal_Bool WriteRAS( const Graphic& rGraphic, FilterConfigItem* pFilterConfigItem );
66 : : };
67 : :
68 : : //=================== Methoden von RASWriter ==============================
69 : :
70 : 0 : RASWriter::RASWriter(SvStream &rStream)
71 : : : m_rOStm(rStream)
72 : : , mbStatus(sal_True)
73 : : , mpAcc(NULL)
74 : 0 : , mnRepCount( 0xffffffff )
75 : : {
76 : 0 : }
77 : :
78 : : // ------------------------------------------------------------------------
79 : :
80 : 0 : RASWriter::~RASWriter()
81 : : {
82 : 0 : }
83 : :
84 : : // ------------------------------------------------------------------------
85 : :
86 : 0 : void RASWriter::ImplCallback( sal_uLong nYPos )
87 : : {
88 : 0 : if ( xStatusIndicator.is() )
89 : 0 : xStatusIndicator->setValue( (sal_uInt16)( ( 100 * nYPos ) / mnHeight ) );
90 : 0 : }
91 : :
92 : : // ------------------------------------------------------------------------
93 : :
94 : 0 : sal_Bool RASWriter::WriteRAS( const Graphic& rGraphic, FilterConfigItem* pFilterConfigItem)
95 : : {
96 : 0 : Bitmap aBmp;
97 : :
98 : 0 : if ( pFilterConfigItem )
99 : : {
100 : 0 : xStatusIndicator = pFilterConfigItem->GetStatusIndicator();
101 : 0 : if ( xStatusIndicator.is() )
102 : : {
103 : 0 : rtl::OUString aMsg;
104 : 0 : xStatusIndicator->start( aMsg, 100 );
105 : : }
106 : : }
107 : :
108 : 0 : BitmapEx aBmpEx( rGraphic.GetBitmapEx() );
109 : 0 : aBmp = aBmpEx.GetBitmap();
110 : :
111 : 0 : if ( aBmp.GetBitCount() == 4 )
112 : 0 : aBmp.Convert( BMP_CONVERSION_8BIT_COLORS );
113 : :
114 : 0 : mnDepth = aBmp.GetBitCount();
115 : :
116 : : // export code below only handles three discrete cases
117 : 0 : mnDepth = mnDepth <= 1 ? 1 : mnDepth <= 8 ? 8 : 24;
118 : :
119 : 0 : mpAcc = aBmp.AcquireReadAccess();
120 : 0 : if ( mpAcc )
121 : : {
122 : 0 : mpOStmOldModus = m_rOStm.GetNumberFormatInt();
123 : 0 : m_rOStm.SetNumberFormatInt( NUMBERFORMAT_INT_BIGENDIAN );
124 : :
125 : 0 : if ( ImplWriteHeader() )
126 : : {
127 : 0 : if ( mnDepth <= 8 )
128 : 0 : ImplWritePalette();
129 : 0 : ImplWriteBody();
130 : : }
131 : 0 : aBmp.ReleaseAccess( mpAcc );
132 : : }
133 : : else
134 : 0 : mbStatus = sal_False;
135 : :
136 : 0 : m_rOStm.SetNumberFormatInt( mpOStmOldModus );
137 : :
138 : 0 : if ( xStatusIndicator.is() )
139 : 0 : xStatusIndicator->end();
140 : :
141 : 0 : return mbStatus;
142 : : }
143 : :
144 : : // ------------------------------------------------------------------------
145 : :
146 : 0 : sal_Bool RASWriter::ImplWriteHeader()
147 : : {
148 : 0 : mnWidth = mpAcc->Width();
149 : 0 : mnHeight = mpAcc->Height();
150 : 0 : if ( mnDepth <= 8 )
151 : : {
152 : 0 : mnColors = mpAcc->GetPaletteEntryCount();
153 : 0 : if (mnColors == 0)
154 : 0 : mbStatus = sal_False;
155 : : }
156 : 0 : if ( mbStatus && mnWidth && mnHeight && mnDepth )
157 : : {
158 : 0 : m_rOStm << (sal_uInt32)0x59a66a95 << (sal_uInt32)mnWidth << (sal_uInt32)mnHeight
159 : 0 : << (sal_uInt32)mnDepth
160 : 0 : << (sal_uInt32)(( ( ( ( mnWidth * mnDepth ) + 15 ) >> 4 ) << 1 ) * mnHeight)
161 : 0 : << (sal_uInt32)2;
162 : :
163 : 0 : if ( mnDepth > 8 )
164 : 0 : m_rOStm << (sal_uInt32)0 << (sal_uInt32)0;
165 : : else
166 : : {
167 : :
168 : 0 : m_rOStm << (sal_uInt32)1 << (sal_uInt32)( mnColors * 3 );
169 : : }
170 : : }
171 : 0 : else mbStatus = sal_False;
172 : :
173 : 0 : return mbStatus;
174 : : }
175 : :
176 : : // ------------------------------------------------------------------------
177 : :
178 : 0 : void RASWriter::ImplWritePalette()
179 : : {
180 : : sal_uInt16 i;
181 : :
182 : 0 : for ( i = 0; i < mnColors; m_rOStm << mpAcc->GetPaletteColor( i++ ).GetRed() ) ;
183 : 0 : for ( i = 0; i < mnColors; m_rOStm << mpAcc->GetPaletteColor( i++ ).GetGreen() ) ;
184 : 0 : for ( i = 0; i < mnColors; m_rOStm << mpAcc->GetPaletteColor( i++ ).GetBlue() ) ;
185 : 0 : }
186 : :
187 : : // ------------------------------------------------------------------------
188 : :
189 : 0 : void RASWriter::ImplWriteBody()
190 : : {
191 : : sal_uLong x, y;
192 : :
193 : 0 : if ( mnDepth == 24 )
194 : : {
195 : 0 : for ( y = 0; y < mnHeight; y++ )
196 : : {
197 : 0 : ImplCallback( y ); // processing output
198 : 0 : for ( x = 0; x < mnWidth; x++ )
199 : : {
200 : 0 : BitmapColor aColor( mpAcc->GetPixel( y, x ) );
201 : 0 : ImplPutByte( aColor.GetBlue() ); // Format ist BGR
202 : 0 : ImplPutByte( aColor.GetGreen() );
203 : 0 : ImplPutByte( aColor.GetRed() );
204 : 0 : }
205 : 0 : if ( x & 1 ) ImplPutByte( 0 ); // WORD ALIGNMENT ???
206 : : }
207 : : }
208 : 0 : else if ( mnDepth == 8 )
209 : : {
210 : 0 : for ( y = 0; y < mnHeight; y++ )
211 : : {
212 : 0 : ImplCallback( y ); // processing output
213 : 0 : for ( x = 0; x < mnWidth; x++ )
214 : : {
215 : 0 : ImplPutByte ( mpAcc->GetPixel( y, x ) );
216 : : }
217 : 0 : if ( x & 1 ) ImplPutByte( 0 ); // WORD ALIGNMENT ???
218 : : }
219 : : }
220 : 0 : else if ( mnDepth == 1 )
221 : : {
222 : 0 : sal_uInt8 nDat = 0;
223 : :
224 : 0 : for ( y = 0; y < mnHeight; y++ )
225 : : {
226 : 0 : ImplCallback( y ); // processing output
227 : 0 : for ( x = 0; x < mnWidth; x++ )
228 : : {
229 : 0 : nDat = ( ( nDat << 1 ) | ( mpAcc->GetPixel ( y, x ) & 1 ) );
230 : 0 : if ( ( x & 7 ) == 7 )
231 : 0 : ImplPutByte( nDat );
232 : : }
233 : 0 : if ( x & 7 )
234 : 0 : ImplPutByte( sal::static_int_cast< sal_uInt8 >(nDat << ( ( ( x & 7 ) ^ 7 ) + 1)) );// write remaining bits
235 : 0 : if (!( ( x - 1 ) & 0x8 ) )
236 : 0 : ImplPutByte( 0 ); // WORD ALIGNMENT ???
237 : : }
238 : : }
239 : 0 : ImplPutByte( mnRepVal + 1 ); // end of RLE decoding
240 : 0 : }
241 : :
242 : : // ------------------------------------------------------------------------
243 : :
244 : 0 : void RASWriter::ImplPutByte( sal_uInt8 nPutThis )
245 : : {
246 : 0 : if ( mnRepCount == 0xffffffff )
247 : : {
248 : 0 : mnRepCount = 0;
249 : 0 : mnRepVal = nPutThis;
250 : : }
251 : : else
252 : : {
253 : 0 : if ( ( nPutThis == mnRepVal ) && ( mnRepCount != 0xff ) )
254 : 0 : mnRepCount++;
255 : : else
256 : : {
257 : 0 : if ( mnRepCount == 0 )
258 : : {
259 : 0 : m_rOStm << (sal_uInt8)mnRepVal;
260 : 0 : if ( mnRepVal == 0x80 )
261 : 0 : m_rOStm << (sal_uInt8)0;
262 : : }
263 : : else
264 : : {
265 : 0 : m_rOStm << (sal_uInt8)0x80;
266 : 0 : m_rOStm << (sal_uInt8)mnRepCount;
267 : 0 : m_rOStm << (sal_uInt8)mnRepVal;
268 : : }
269 : 0 : mnRepVal = nPutThis;
270 : 0 : mnRepCount = 0;
271 : : }
272 : : }
273 : 0 : }
274 : :
275 : : // ------------------------------------------------------------------------
276 : :
277 : : // ---------------------
278 : : // - exported function -
279 : : // ---------------------
280 : :
281 : : extern "C" SAL_DLLPUBLIC_EXPORT sal_Bool __LOADONCALLAPI
282 : 0 : GraphicExport(SvStream& rStream, Graphic& rGraphic, FilterConfigItem* pFilterConfigItem, sal_Bool)
283 : : {
284 : 0 : RASWriter aRASWriter(rStream);
285 : :
286 : 0 : return aRASWriter.WriteRAS( rGraphic, pFilterConfigItem );
287 : : }
288 : :
289 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|