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 : :
34 : : #define RAS_TYPE_OLD 0x00000000 // supported formats by this filter
35 : : #define RAS_TYPE_STANDARD 0x00000001
36 : : #define RAS_TYPE_BYTE_ENCODED 0x00000002
37 : : #define RAS_TYPE_RGB_FORMAT 0x00000003
38 : :
39 : : #define RAS_COLOR_NO_MAP 0x00000000
40 : : #define RAS_COLOR_RGB_MAP 0x00000001
41 : : #define RAS_COLOR_RAW_MAP 0x00000002
42 : :
43 : : #define SUNRASTER_MAGICNUMBER 0x59a66a95
44 : :
45 : : //============================ RASReader ==================================
46 : :
47 : : class RASReader {
48 : :
49 : : private:
50 : :
51 : : SvStream& m_rRAS; // Die einzulesende RAS-Datei
52 : :
53 : : sal_Bool mbStatus;
54 : : Bitmap maBmp;
55 : : BitmapWriteAccess* mpAcc;
56 : : sal_uInt32 mnWidth, mnHeight; // Bildausmass in Pixeln
57 : : sal_uInt16 mnDstBitsPerPix;
58 : : sal_uInt16 mnDstColors;
59 : : sal_uInt32 mnDepth, mnImageDatSize, mnType;
60 : : sal_uInt32 mnColorMapType, mnColorMapSize;
61 : : sal_uInt8 mnRepCount, mnRepVal; // RLE Decoding
62 : : sal_Bool mbPalette;
63 : :
64 : : sal_Bool ImplReadBody();
65 : : sal_Bool ImplReadHeader();
66 : : sal_uInt8 ImplGetByte();
67 : :
68 : : public:
69 : : RASReader(SvStream &rRAS);
70 : : ~RASReader();
71 : : sal_Bool ReadRAS(Graphic & rGraphic);
72 : : };
73 : :
74 : : //=================== Methoden von RASReader ==============================
75 : :
76 : 0 : RASReader::RASReader(SvStream &rRAS)
77 : : : m_rRAS(rRAS)
78 : : , mbStatus(sal_True)
79 : : , mpAcc(NULL)
80 : : , mnRepCount(0)
81 : 0 : , mbPalette(sal_False)
82 : : {
83 : 0 : }
84 : :
85 : 0 : RASReader::~RASReader()
86 : : {
87 : 0 : }
88 : :
89 : : //----------------------------------------------------------------------------
90 : :
91 : 0 : sal_Bool RASReader::ReadRAS(Graphic & rGraphic)
92 : : {
93 : : sal_uInt32 nMagicNumber;
94 : :
95 : 0 : if ( m_rRAS.GetError() )
96 : 0 : return sal_False;
97 : :
98 : 0 : m_rRAS.SetNumberFormatInt( NUMBERFORMAT_INT_BIGENDIAN );
99 : 0 : m_rRAS >> nMagicNumber;
100 : 0 : if ( nMagicNumber != SUNRASTER_MAGICNUMBER )
101 : 0 : return sal_False;
102 : :
103 : : // Kopf einlesen:
104 : :
105 : 0 : if ( ( mbStatus = ImplReadHeader() ) == sal_False )
106 : 0 : return sal_False;
107 : :
108 : 0 : maBmp = Bitmap( Size( mnWidth, mnHeight ), mnDstBitsPerPix );
109 : 0 : if ( ( mpAcc = maBmp.AcquireWriteAccess() ) == sal_False )
110 : 0 : return sal_False;
111 : :
112 : 0 : if ( mnDstBitsPerPix <= 8 ) // paletten bildchen
113 : : {
114 : 0 : if ( mnColorMapType == RAS_COLOR_RAW_MAP ) // RAW Colormap wird geskipped
115 : : {
116 : 0 : sal_uLong nCurPos = m_rRAS.Tell();
117 : 0 : m_rRAS.Seek( nCurPos + mnColorMapSize );
118 : : }
119 : 0 : else if ( mnColorMapType == RAS_COLOR_RGB_MAP ) // RGB koennen wir auslesen
120 : : {
121 : 0 : mnDstColors = (sal_uInt16)( mnColorMapSize / 3 );
122 : :
123 : 0 : if ( ( 1 << mnDstBitsPerPix ) < mnDstColors )
124 : 0 : return sal_False;
125 : :
126 : 0 : if ( ( mnDstColors >= 2 ) && ( ( mnColorMapSize % 3 ) == 0 ) )
127 : : {
128 : 0 : mpAcc->SetPaletteEntryCount( mnDstColors );
129 : : sal_uInt16 i;
130 : : sal_uInt8 nRed[256], nGreen[256], nBlue[256];
131 : 0 : for ( i = 0; i < mnDstColors; i++ ) m_rRAS >> nRed[ i ];
132 : 0 : for ( i = 0; i < mnDstColors; i++ ) m_rRAS >> nGreen[ i ];
133 : 0 : for ( i = 0; i < mnDstColors; i++ ) m_rRAS >> nBlue[ i ];
134 : 0 : for ( i = 0; i < mnDstColors; i++ )
135 : : {
136 : 0 : mpAcc->SetPaletteColor( i, BitmapColor( nRed[ i ], nGreen[ i ], nBlue[ i ] ) );
137 : : }
138 : 0 : mbPalette = sal_True;
139 : : }
140 : : else
141 : 0 : return sal_False;
142 : :
143 : : }
144 : 0 : else if ( mnColorMapType != RAS_COLOR_NO_MAP ) // alles andere ist kein standard
145 : 0 : return sal_False;
146 : :
147 : 0 : if ( !mbPalette )
148 : : {
149 : 0 : mnDstColors = 1 << mnDstBitsPerPix;
150 : 0 : mpAcc->SetPaletteEntryCount( mnDstColors );
151 : 0 : for ( sal_uInt16 i = 0; i < mnDstColors; i++ )
152 : : {
153 : 0 : sal_uLong nCount = 255 - ( 255 * i / ( mnDstColors - 1 ) );
154 : 0 : mpAcc->SetPaletteColor( i, BitmapColor( (sal_uInt8)nCount, (sal_uInt8)nCount, (sal_uInt8)nCount ) );
155 : : }
156 : : }
157 : : }
158 : : else
159 : : {
160 : 0 : if ( mnColorMapType != RAS_COLOR_NO_MAP ) // when graphic has more then 256 colors and a color map we skip
161 : : { // the colormap
162 : 0 : sal_uLong nCurPos = m_rRAS.Tell();
163 : 0 : m_rRAS.Seek( nCurPos + mnColorMapSize );
164 : : }
165 : : }
166 : :
167 : : // Bitmap-Daten einlesen
168 : 0 : mbStatus = ImplReadBody();
169 : :
170 : 0 : if ( mpAcc )
171 : : {
172 : 0 : maBmp.ReleaseAccess( mpAcc ), mpAcc = NULL;
173 : : }
174 : 0 : if ( mbStatus )
175 : 0 : rGraphic = maBmp;
176 : :
177 : 0 : return mbStatus;
178 : : }
179 : :
180 : : //----------------------------------------------------------------------------
181 : :
182 : 0 : sal_Bool RASReader::ImplReadHeader()
183 : : {
184 : 0 : m_rRAS >> mnWidth >> mnHeight >> mnDepth >> mnImageDatSize >>
185 : 0 : mnType >> mnColorMapType >> mnColorMapSize;
186 : :
187 : 0 : if ( mnWidth == 0 || mnHeight == 0 )
188 : 0 : mbStatus = sal_False;
189 : :
190 : 0 : switch ( mnDepth )
191 : : {
192 : : case 24 :
193 : : case 8 :
194 : : case 1 :
195 : 0 : mnDstBitsPerPix = (sal_uInt16)mnDepth;
196 : 0 : break;
197 : : case 32 :
198 : 0 : mnDstBitsPerPix = 24;
199 : 0 : break;
200 : :
201 : : default :
202 : 0 : mbStatus = sal_False;
203 : : }
204 : :
205 : 0 : switch ( mnType )
206 : : {
207 : : case RAS_TYPE_OLD :
208 : : case RAS_TYPE_STANDARD :
209 : : case RAS_TYPE_RGB_FORMAT :
210 : : case RAS_TYPE_BYTE_ENCODED : // this type will be supported later
211 : 0 : break;
212 : :
213 : : default:
214 : 0 : mbStatus = sal_False;
215 : : }
216 : 0 : return mbStatus;
217 : : }
218 : :
219 : : //----------------------------------------------------------------------------
220 : :
221 : 0 : sal_Bool RASReader::ImplReadBody()
222 : : {
223 : : sal_uLong x, y;
224 : 0 : sal_uInt8 nDat = 0;
225 : : sal_uInt8 nRed, nGreen, nBlue;
226 : 0 : switch ( mnDstBitsPerPix )
227 : : {
228 : : case 1 :
229 : 0 : for ( y = 0; y < mnHeight; y++ )
230 : : {
231 : 0 : for ( x = 0; x < mnWidth; x++ )
232 : : {
233 : 0 : if (!(x & 7))
234 : 0 : nDat = ImplGetByte();
235 : : mpAcc->SetPixel (
236 : : y, x,
237 : : sal::static_int_cast< sal_uInt8 >(
238 : 0 : nDat >> ( ( x & 7 ) ^ 7 )) );
239 : : }
240 : 0 : if (!( ( x - 1 ) & 0x8 ) ) ImplGetByte(); // WORD ALIGNMENT ???
241 : : }
242 : 0 : break;
243 : :
244 : : case 8 :
245 : 0 : for ( y = 0; y < mnHeight; y++ )
246 : : {
247 : 0 : for ( x = 0; x < mnWidth; x++ )
248 : : {
249 : 0 : nDat = ImplGetByte();
250 : 0 : mpAcc->SetPixel ( y, x, nDat );
251 : : }
252 : 0 : if ( x & 1 ) ImplGetByte(); // WORD ALIGNMENT ???
253 : : }
254 : 0 : break;
255 : :
256 : : case 24 :
257 : 0 : switch ( mnDepth )
258 : : {
259 : :
260 : : case 24 :
261 : 0 : for ( y = 0; y < mnHeight; y++ )
262 : : {
263 : 0 : for ( x = 0; x < mnWidth; x++ )
264 : : {
265 : 0 : if ( mnType == RAS_TYPE_RGB_FORMAT )
266 : : {
267 : 0 : nRed = ImplGetByte();
268 : 0 : nGreen = ImplGetByte();
269 : 0 : nBlue = ImplGetByte();
270 : : }
271 : : else
272 : : {
273 : 0 : nBlue = ImplGetByte();
274 : 0 : nGreen = ImplGetByte();
275 : 0 : nRed = ImplGetByte();
276 : : }
277 : 0 : mpAcc->SetPixel ( y, x, BitmapColor( nRed, nGreen, nBlue ) );
278 : : }
279 : 0 : if ( x & 1 ) ImplGetByte(); // WORD ALIGNMENT ???
280 : : }
281 : 0 : break;
282 : :
283 : : case 32 :
284 : 0 : for ( y = 0; y < mnHeight; y++ )
285 : : {
286 : 0 : for ( x = 0; x < mnWidth; x++ )
287 : : {
288 : 0 : nDat = ImplGetByte(); // pad byte > nil
289 : 0 : if ( mnType == RAS_TYPE_RGB_FORMAT )
290 : : {
291 : 0 : nRed = ImplGetByte();
292 : 0 : nGreen = ImplGetByte();
293 : 0 : nBlue = ImplGetByte();
294 : : }
295 : : else
296 : : {
297 : 0 : nBlue = ImplGetByte();
298 : 0 : nGreen = ImplGetByte();
299 : 0 : nRed = ImplGetByte();
300 : : }
301 : 0 : mpAcc->SetPixel ( y, x, BitmapColor( nRed, nGreen, nBlue ) );
302 : : }
303 : : }
304 : 0 : break;
305 : : }
306 : 0 : break;
307 : :
308 : : default:
309 : 0 : mbStatus = sal_False;
310 : 0 : break;
311 : : }
312 : 0 : return mbStatus;
313 : : }
314 : :
315 : : //----------------------------------------------------------------------------
316 : :
317 : 0 : sal_uInt8 RASReader::ImplGetByte()
318 : : {
319 : : sal_uInt8 nRetVal;
320 : 0 : if ( mnType != RAS_TYPE_BYTE_ENCODED )
321 : : {
322 : 0 : m_rRAS >> nRetVal;
323 : 0 : return nRetVal;
324 : : }
325 : : else
326 : : {
327 : 0 : if ( mnRepCount )
328 : : {
329 : 0 : mnRepCount--;
330 : 0 : return mnRepVal;
331 : : }
332 : : else
333 : : {
334 : 0 : m_rRAS >> nRetVal;
335 : 0 : if ( nRetVal != 0x80 )
336 : 0 : return nRetVal;
337 : 0 : m_rRAS >> nRetVal;
338 : 0 : if ( nRetVal == 0 )
339 : 0 : return 0x80;
340 : 0 : mnRepCount = nRetVal ;
341 : 0 : m_rRAS >> mnRepVal;
342 : 0 : return mnRepVal;
343 : : }
344 : : }
345 : : }
346 : :
347 : : //================== GraphicImport - die exportierte Funktion ================
348 : :
349 : : extern "C" SAL_DLLPUBLIC_EXPORT sal_Bool __LOADONCALLAPI
350 : 0 : GraphicImport(SvStream & rStream, Graphic & rGraphic, FilterConfigItem*, sal_Bool)
351 : : {
352 : 0 : RASReader aRASReader(rStream);
353 : :
354 : 0 : return aRASReader.ReadRAS(rGraphic );
355 : : }
356 : :
357 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|