Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*
3 : : * This file is part of the LibreOffice project.
4 : : *
5 : : * This Source Code Form is subject to the terms of the Mozilla Public
6 : : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : : *
9 : : * This file incorporates work covered by the following license notice:
10 : : *
11 : : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : : * contributor license agreements. See the NOTICE file distributed
13 : : * with this work for additional information regarding copyright
14 : : * ownership. The ASF licenses this file to you under the Apache
15 : : * License, Version 2.0 (the "License"); you may not use this file
16 : : * except in compliance with the License. You may obtain a copy of
17 : : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : : */
19 : :
20 : :
21 : : #include <vcl/bmpacc.hxx>
22 : : #include <vcl/graph.hxx>
23 : : #include "rgbtable.hxx"
24 : : #define _XPMPRIVATE
25 : : #include "xpmread.hxx"
26 : :
27 : : // -------------
28 : : // - XPMReader -
29 : : // -------------
30 : :
31 : 0 : XPMReader::XPMReader( SvStream& rStm ) :
32 : : mrIStm ( rStm ),
33 : : mpAcc ( NULL ),
34 : : mpMaskAcc ( NULL ),
35 : 0 : mnLastPos ( rStm.Tell() ),
36 : : mnWidth ( 0 ),
37 : : mnHeight ( 0 ),
38 : : mnColors ( 0 ),
39 : : mnCpp ( 0 ),
40 : : mbTransparent ( sal_False ),
41 : : mbStatus ( sal_True ),
42 : : mnStatus ( 0 ),
43 : : mnIdentifier ( XPMIDENTIFIER ),
44 : : mcThisByte ( 0 ),
45 : : mnTempAvail ( 0 ),
46 : : mpFastColorTable( NULL ),
47 [ # # ][ # # ]: 0 : mpColMap ( NULL )
48 : : {
49 : :
50 : 0 : }
51 : :
52 : : // ------------------------------------------------------------------------
53 : :
54 [ # # ][ # # ]: 0 : XPMReader::~XPMReader()
55 : : {
56 [ # # ]: 0 : if( mpAcc )
57 [ # # ]: 0 : maBmp.ReleaseAccess( mpAcc );
58 [ # # ]: 0 : }
59 : :
60 : : // ------------------------------------------------------------------------
61 : :
62 : : #ifdef _MSC_VER
63 : : #pragma optimize ("",off)
64 : : #endif
65 : :
66 : 0 : ReadState XPMReader::ReadXPM( Graphic& rGraphic )
67 : : {
68 : : ReadState eReadState;
69 : : sal_uInt8 cDummy;
70 : :
71 : : // sehen, ob wir _alles_ lesen koennen
72 [ # # ]: 0 : mrIStm.Seek( STREAM_SEEK_TO_END );
73 [ # # ]: 0 : mrIStm >> cDummy;
74 : :
75 : : // falls wir nicht alles lesen koennen
76 : : // kehren wir zurueck und warten auf neue Daten
77 [ # # ]: 0 : if ( mrIStm.GetError() != ERRCODE_IO_PENDING )
78 : : {
79 [ # # ]: 0 : mrIStm.Seek( mnLastPos );
80 : 0 : mbStatus = sal_True;
81 : :
82 [ # # ]: 0 : if ( mbStatus )
83 : : {
84 [ # # ]: 0 : mpStringBuf = new sal_uInt8 [ XPMSTRINGBUF ];
85 [ # # ]: 0 : mpTempBuf = new sal_uInt8 [ XPMTEMPBUFSIZE ];
86 : :
87 [ # # ][ # # ]: 0 : if ( ( mbStatus = ImplGetString() ) == sal_True )
88 : : {
89 : 0 : mnIdentifier = XPMVALUES; // Bitmap informationen einholen
90 [ # # ]: 0 : mnWidth = ImplGetULONG( 0 );
91 [ # # ]: 0 : mnHeight = ImplGetULONG( 1 );
92 [ # # ]: 0 : mnColors = ImplGetULONG( 2 );
93 [ # # ]: 0 : mnCpp = ImplGetULONG( 3 );
94 : : }
95 [ # # ]: 0 : if ( mnColors > ( SAL_MAX_UINT32 / ( 4 + mnCpp ) ) )
96 : 0 : mbStatus = sal_False;
97 [ # # ]: 0 : if ( ( mnWidth * mnCpp ) >= XPMSTRINGBUF )
98 : 0 : mbStatus = sal_False;
99 [ # # ][ # # ]: 0 : if ( mbStatus && mnWidth && mnHeight && mnColors && mnCpp )
[ # # ][ # # ]
[ # # ]
100 : : {
101 : 0 : mnIdentifier = XPMCOLORS;
102 : :
103 : : // mpColMap beinhaltet fuer jede vorhandene
104 : : // Farbe: ( mnCpp )Byte(s)-> ASCII Eintrag der der Farbe zugeordnet ist
105 : : // 1 Byte -> 0xff wenn Farbe transparent ist
106 : : // 3 Bytes -> RGB Wert der Farbe
107 [ # # ]: 0 : mpColMap = new sal_uInt8[ mnColors * ( 4 + mnCpp ) ];
108 [ # # ]: 0 : if ( mpColMap )
109 : : {
110 [ # # ]: 0 : for ( sal_uLong i = 0; i < mnColors; i++ )
111 : : {
112 [ # # ][ # # ]: 0 : if ( ImplGetColor( i ) == sal_False )
113 : : {
114 : 0 : mbStatus = sal_False;
115 : 0 : break;
116 : : }
117 : : }
118 : : }
119 : : else
120 : 0 : mbStatus = sal_False;
121 : :
122 [ # # ]: 0 : if ( mbStatus )
123 : : {
124 : : // bei mehr als 256 Farben wird eine 24 Bit Grafik erstellt
125 : 0 : sal_uInt16 nBits = 1;
126 [ # # ]: 0 : if ( mnColors > 256 )
127 : 0 : nBits = 24;
128 [ # # ]: 0 : else if ( mnColors > 16 )
129 : 0 : nBits = 8;
130 [ # # ]: 0 : else if ( mnColors > 2 )
131 : 0 : nBits = 4;
132 : : else
133 : 0 : nBits = 1;
134 : :
135 [ # # ][ # # ]: 0 : maBmp = Bitmap( Size( mnWidth, mnHeight ), nBits );
[ # # ]
136 [ # # ]: 0 : mpAcc = maBmp.AcquireWriteAccess();
137 : :
138 : : // mbTransparent ist sal_True wenn mindestens eine Farbe Transparent ist
139 [ # # ]: 0 : if ( mbTransparent )
140 : : {
141 [ # # ][ # # ]: 0 : maMaskBmp = Bitmap( Size( mnWidth, mnHeight ), 1 );
[ # # ]
142 [ # # ][ # # ]: 0 : if ( ( mpMaskAcc = maMaskBmp.AcquireWriteAccess() ) == NULL )
143 : 0 : mbStatus = sal_False;
144 : : }
145 [ # # ][ # # ]: 0 : if( mpAcc && mbStatus )
146 : : {
147 : : sal_uLong i;
148 [ # # ]: 0 : if ( mnColors <=256 ) // palette is only needed by using less than 257
149 : : { // colors
150 : :
151 : 0 : sal_uInt8* pPtr = &mpColMap[mnCpp];
152 : :
153 [ # # ]: 0 : for ( i = 0; i < mnColors; i++ )
154 : : {
155 : 0 : mpAcc->SetPaletteColor( (sal_uInt8)i, Color( pPtr[1], pPtr[2], pPtr[3] ) );
156 : 0 : pPtr += ( mnCpp + 4 );
157 : : }
158 : : // using 2 charakters per pixel and less than 257 Colors we speed up
159 [ # # ]: 0 : if ( mnCpp == 2 ) // by using a 64kb indexing table
160 : : {
161 [ # # ]: 0 : mpFastColorTable = new sal_uInt8[ 256 * 256 ];
162 [ # # ]: 0 : for ( pPtr = mpColMap, i = 0; i < mnColors; i++, pPtr += mnCpp + 4 )
163 : : {
164 : 0 : sal_uLong j = pPtr[ 0 ] << 8;
165 : 0 : j += pPtr[ 1 ];
166 : 0 : mpFastColorTable[ j ] = (sal_uInt8)i;
167 : : }
168 : : }
169 : : }
170 : : // now we get the bitmap data
171 : 0 : mnIdentifier = XPMPIXELS;
172 [ # # ]: 0 : for ( i = 0; i < mnHeight; i++ )
173 : : {
174 [ # # ][ # # ]: 0 : if ( ImplGetScanLine( i ) == sal_False )
175 : : {
176 : 0 : mbStatus = sal_False;
177 : 0 : break;
178 : : }
179 : : }
180 : 0 : mnIdentifier = XPMEXTENSIONS;
181 : : }
182 : : }
183 : : }
184 : :
185 [ # # ]: 0 : delete[] mpFastColorTable;
186 [ # # ]: 0 : delete[] mpColMap;
187 [ # # ]: 0 : delete[] mpStringBuf;
188 [ # # ]: 0 : delete[] mpTempBuf;
189 : :
190 : : }
191 [ # # ]: 0 : if( mbStatus )
192 : : {
193 [ # # ]: 0 : if ( mpMaskAcc )
194 : : {
195 [ # # ]: 0 : maMaskBmp.ReleaseAccess ( mpMaskAcc), mpMaskAcc = NULL;
196 [ # # ]: 0 : maBmp.ReleaseAccess( mpAcc ), mpAcc = NULL;
197 [ # # ][ # # ]: 0 : rGraphic = Graphic( BitmapEx( maBmp, maMaskBmp ) );
[ # # ][ # # ]
[ # # ]
198 : : }
199 : : else
200 : : {
201 [ # # ]: 0 : maBmp.ReleaseAccess( mpAcc ), mpAcc = NULL;
202 [ # # ][ # # ]: 0 : rGraphic = maBmp;
[ # # ]
203 : : }
204 : 0 : eReadState = XPMREAD_OK;
205 : : }
206 : : else
207 : : {
208 [ # # ][ # # ]: 0 : if ( mpMaskAcc ) maMaskBmp.ReleaseAccess ( mpMaskAcc), mpMaskAcc = NULL;
209 [ # # ][ # # ]: 0 : if ( mpAcc ) maBmp.ReleaseAccess( mpAcc ), mpAcc = NULL;
210 : 0 : eReadState = XPMREAD_ERROR;
211 : : }
212 : : }
213 : : else
214 : : {
215 [ # # ]: 0 : mrIStm.ResetError();
216 : 0 : eReadState = XPMREAD_NEED_MORE;
217 : : }
218 : 0 : return eReadState;
219 : : }
220 : :
221 : : #ifdef _MSC_VER
222 : : #pragma optimize ("",on)
223 : : #endif
224 : :
225 : : // ------------------------------------------------------------------------
226 : : // ImplGetColor ermittelt saemtliche Farbwerte,
227 : : // die Rueckgabe ist sal_True wenn saemtliche Farben zugeordnet werden konnten
228 : :
229 : 0 : sal_Bool XPMReader::ImplGetColor( sal_uLong nNumb )
230 : : {
231 : 0 : sal_uInt8* pString = mpStringBuf;
232 : 0 : sal_uInt8* pPtr = ( mpColMap + nNumb * ( 4 + mnCpp ) );
233 : 0 : sal_Bool bStatus = ImplGetString();
234 : :
235 [ # # ]: 0 : if ( bStatus )
236 : : {
237 [ # # ]: 0 : for ( sal_uLong i = 0; i < mnCpp; i++ )
238 : 0 : *pPtr++ = *pString++;
239 : 0 : bStatus = ImplGetColSub ( pPtr );
240 : : }
241 : 0 : return bStatus;
242 : : }
243 : :
244 : : // ------------------------------------------------------------------------
245 : : // ImpGetScanLine liest den String mpBufSize aus und schreibt die Pixel in die
246 : : // Bitmap. Der Parameter nY gibt die horizontale Position an.
247 : :
248 : 0 : sal_Bool XPMReader::ImplGetScanLine( sal_uLong nY )
249 : : {
250 [ # # ]: 0 : sal_Bool bStatus = ImplGetString();
251 : 0 : sal_uInt8* pString = mpStringBuf;
252 : : sal_uInt8* pColor;
253 : 0 : BitmapColor aWhite;
254 : 0 : BitmapColor aBlack;
255 : :
256 [ # # ]: 0 : if ( bStatus )
257 : : {
258 [ # # ]: 0 : if ( mpMaskAcc )
259 : : {
260 [ # # ]: 0 : aWhite = mpMaskAcc->GetBestMatchingColor( Color( COL_WHITE ) );
261 [ # # ]: 0 : aBlack = mpMaskAcc->GetBestMatchingColor( Color( COL_BLACK ) );
262 : : }
263 [ # # ]: 0 : if ( mnStringSize != ( mnWidth * mnCpp ))
264 : 0 : bStatus = sal_False;
265 : : else
266 : : {
267 : : sal_uLong i, j;
268 [ # # ]: 0 : if ( mpFastColorTable )
269 : : {
270 [ # # ]: 0 : for ( i = 0; i < mnWidth; i++ )
271 : : {
272 : 0 : j = (*pString++) << 8;
273 : 0 : j += *pString++;
274 : 0 : sal_uInt8 k = (sal_uInt8)mpFastColorTable[ j ];
275 [ # # ]: 0 : mpAcc->SetPixel( nY, i, BitmapColor( (sal_uInt8)k ) );
276 : :
277 [ # # ]: 0 : if ( mpMaskAcc )
278 : : mpMaskAcc->SetPixel( nY, i,
279 [ # # ][ # # ]: 0 : ( mpColMap[ k * (mnCpp + 4) + mnCpp] ) ? aWhite : aBlack );
280 : : }
281 : : }
282 [ # # ]: 0 : else for ( i = 0; i < mnWidth; i++ )
283 : : {
284 : 0 : pColor = mpColMap;
285 [ # # ]: 0 : for ( j = 0; j < mnColors; j++ )
286 : : {
287 [ # # ]: 0 : if ( ImplCompare( pString, pColor, mnCpp, XPMCASESENSITIVE ) == sal_True )
288 : : {
289 [ # # ]: 0 : if ( mnColors > 256 )
290 [ # # ]: 0 : mpAcc->SetPixel( nY, i, Color ( pColor[3], pColor[4], pColor[5] ) );
291 : : else
292 [ # # ]: 0 : mpAcc->SetPixel( nY, i, BitmapColor( (sal_uInt8) j ) );
293 : :
294 [ # # ]: 0 : if ( mpMaskAcc )
295 : : mpMaskAcc->SetPixel( nY, i, (
296 [ # # ][ # # ]: 0 : pColor[ mnCpp ] ) ? aWhite : aBlack );
297 : :
298 : 0 : break;
299 : : }
300 : 0 : pColor += ( mnCpp + 4 );
301 : : }
302 : 0 : pString += mnCpp;
303 : : }
304 : :
305 : : }
306 : : }
307 : 0 : return bStatus;
308 : : }
309 : :
310 : : // ------------------------------------------------------------------------
311 : : // versucht aus mpStringBuf einen Farbwert zu uebermitteln
312 : : // wurde eine Farbe gefunden wird an pDest[1]..pDest[2] der RGB wert geschrieben
313 : : // pDest[0] enthaelt 0xff wenn die Farbe transparent ist sonst 0
314 : :
315 : 0 : sal_Bool XPMReader::ImplGetColSub( sal_uInt8* pDest )
316 : : {
317 : 0 : unsigned char cTransparent[] = "None";
318 : :
319 : 0 : sal_Bool bColStatus = sal_False;
320 : :
321 [ # # ][ # # ]: 0 : if ( ImplGetColKey( 'c' ) || ImplGetColKey( 'm' ) || ImplGetColKey( 'g' ) )
[ # # ][ # # ]
322 : : {
323 : : // hexentry for RGB or HSV color ?
324 [ # # ]: 0 : if ( *mpPara == '#' )
325 : : {
326 : 0 : *pDest++ = 0;
327 : 0 : bColStatus = sal_True;
328 [ # # # # ]: 0 : switch ( mnParaSize )
329 : : {
330 : : case 25 :
331 : 0 : ImplGetRGBHex ( pDest, 6 );
332 : 0 : break;
333 : : case 13 :
334 : 0 : ImplGetRGBHex ( pDest, 2 );
335 : 0 : break;
336 : : case 7 :
337 : 0 : ImplGetRGBHex ( pDest, 0 );
338 : 0 : break;
339 : : default:
340 : 0 : bColStatus = sal_False;
341 : 0 : break;
342 : : }
343 : : }
344 : : // maybe pixel is transparent
345 [ # # ]: 0 : else if ( ImplCompare( &cTransparent[0], mpPara, 4 ))
346 : : {
347 : 0 : *pDest++ = 0xff;
348 : 0 : bColStatus = sal_True;
349 : 0 : mbTransparent = sal_True;
350 : : }
351 : : // last we will try to get the colorname
352 [ # # ]: 0 : else if ( mnParaSize > 2 ) // name must enlarge the minimum size
353 : : {
354 : 0 : sal_uLong i = 0;
355 : 0 : while ( sal_True )
356 : : {
357 [ # # ]: 0 : if ( pRGBTable[ i ].name == NULL )
358 : 0 : break;
359 [ # # ]: 0 : if ( pRGBTable[ i ].name[ mnParaSize ] == 0 )
360 : : {
361 [ # # ]: 0 : if ( ImplCompare ( (unsigned char*)pRGBTable[ i ].name,
362 : 0 : mpPara, mnParaSize, XPMCASENONSENSITIVE ) )
363 : : {
364 : 0 : bColStatus = sal_True;
365 : 0 : *pDest++ = 0;
366 : 0 : *pDest++ = pRGBTable[ i ].red;
367 : 0 : *pDest++ = pRGBTable[ i ].green;
368 : 0 : *pDest++ = pRGBTable[ i ].blue;
369 : : }
370 : : }
371 : 0 : i++;
372 : : }
373 : : }
374 : : }
375 : 0 : return bColStatus;
376 : : }
377 : :
378 : : // ------------------------------------------------------------------------
379 : : // ImplGetColKey durchsuch den String mpStringBuf nach einem Parameter 'nKey'
380 : : // und gibt einen sal_Bool zurueck. ( wenn sal_True werden mpPara und mnParaSize gesetzt )
381 : :
382 : 0 : sal_Bool XPMReader::ImplGetColKey( sal_uInt8 nKey )
383 : : {
384 : 0 : sal_uInt8 nTemp, nPrev = ' ';
385 : :
386 : 0 : mpPara = mpStringBuf + mnCpp + 1;
387 : 0 : mnParaSize = 0;
388 : :
389 [ # # ]: 0 : while ( *mpPara != 0 )
390 : : {
391 [ # # ]: 0 : if ( *mpPara == nKey )
392 : : {
393 : 0 : nTemp = *( mpPara + 1 );
394 [ # # ][ # # ]: 0 : if ( nTemp == ' ' || nTemp == 0x09 )
395 : : {
396 [ # # ][ # # ]: 0 : if ( nPrev == ' ' || nPrev == 0x09 )
397 : 0 : break;
398 : : }
399 : : }
400 : 0 : nPrev = *mpPara;
401 : 0 : mpPara++;
402 : : }
403 [ # # ]: 0 : if ( *mpPara )
404 : : {
405 : 0 : mpPara++;
406 [ # # ][ # # ]: 0 : while ( (*mpPara == ' ') || (*mpPara == 0x09) )
[ # # ]
407 : : {
408 : 0 : mpPara++;
409 : : }
410 [ # # ]: 0 : if ( *mpPara != 0 )
411 : : {
412 [ # # ][ # # ]: 0 : while ( *(mpPara+mnParaSize) != ' ' && *(mpPara+mnParaSize) != 0x09 &&
[ # # ][ # # ]
413 : 0 : *(mpPara+mnParaSize) != 0 )
414 : : {
415 : 0 : mnParaSize++;
416 : : }
417 : : }
418 : : }
419 [ # # ]: 0 : return ( mnParaSize ) ? sal_True : sal_False;
420 : : }
421 : :
422 : : // ------------------------------------------------------------------------
423 : : // ImplGetRGBHex uebersetzt den ASCII-Hexadezimalwert der sich bei mpPara befindet
424 : : // in einen RGB wert und schreibt diesen nach pDest
425 : : // folgende Formate muessen sich bei mpPara befinden:
426 : : // wenn nAdd = 0 : '#12ab12' -> RGB = 0x12, 0xab, 0x12
427 : : // 2 : '#1234abcd1234' " " " "
428 : : // 6 : '#12345678abcdefab12345678' " " " "
429 : :
430 : :
431 : 0 : void XPMReader::ImplGetRGBHex( sal_uInt8* pDest,sal_uLong nAdd )
432 : : {
433 : 0 : sal_uInt8* pPtr = mpPara+1;
434 : : sal_uInt8 nHex, nTemp;
435 : :
436 [ # # ]: 0 : for ( sal_uLong i = 0; i < 3; i++ )
437 : : {
438 : 0 : nHex = (*pPtr++) - '0';
439 [ # # ]: 0 : if ( nHex > 9 )
440 : 0 : nHex = ((nHex - 'A' + '0') & 7) + 10;
441 : :
442 : 0 : nTemp = (*pPtr++) - '0';
443 [ # # ]: 0 : if ( nTemp > 9 )
444 : 0 : nTemp = ((nTemp - 'A' + '0') & 7) + 10;
445 : 0 : nHex = ( nHex << 4 ) + nTemp;
446 : :
447 : 0 : pPtr += nAdd;
448 : 0 : *pDest++ = (sal_uInt8)nHex;
449 : : }
450 : 0 : }
451 : :
452 : : // ------------------------------------------------------------------------
453 : : // ImplGetUlong gibt den wert einer bis zu 6stelligen ASCII-Dezimalzahl zurueck.
454 : :
455 : 0 : sal_uLong XPMReader::ImplGetULONG( sal_uLong nPara )
456 : : {
457 [ # # ]: 0 : if ( ImplGetPara ( nPara ) )
458 : : {
459 : 0 : sal_uLong nRetValue = 0;
460 : 0 : sal_uInt8* pPtr = mpPara;
461 : :
462 [ # # ][ # # ]: 0 : if ( ( mnParaSize > 6 ) || ( mnParaSize == 0 ) ) return 0;
463 [ # # ]: 0 : for ( sal_uLong i = 0; i < mnParaSize; i++ )
464 : : {
465 : 0 : sal_uInt8 j = (*pPtr++) - 48;
466 [ # # ]: 0 : if ( j > 9 ) return 0; // ascii is invalid
467 : 0 : nRetValue*=10;
468 : 0 : nRetValue+=j;
469 : : }
470 : 0 : return nRetValue;
471 : : }
472 : 0 : else return 0;
473 : : }
474 : :
475 : : // ------------------------------------------------------------------------
476 : :
477 : 0 : sal_Bool XPMReader::ImplCompare( sal_uInt8* pSource, sal_uInt8* pDest, sal_uLong nSize, sal_uLong nMode )
478 : : {
479 : 0 : sal_Bool bRet = sal_True;
480 : :
481 [ # # ]: 0 : if ( nMode == XPMCASENONSENSITIVE )
482 : : {
483 [ # # ]: 0 : for ( sal_uLong i = 0; i < nSize; i++ )
484 : : {
485 [ # # ]: 0 : if ( ( pSource[i]&~0x20 ) != ( pDest[i]&~0x20 ) )
486 : : {
487 : 0 : bRet = sal_False;
488 : 0 : break;
489 : : }
490 : : }
491 : : }
492 : : else
493 : : {
494 [ # # ]: 0 : for ( sal_uLong i = 0; i < nSize; i++ )
495 : : {
496 [ # # ]: 0 : if ( pSource[i] != pDest[i] )
497 : : {
498 : 0 : bRet = sal_False;
499 : 0 : break;
500 : : }
501 : : }
502 : : }
503 : 0 : return bRet;
504 : : }
505 : :
506 : : // ------------------------------------------------------------------------
507 : : // ImplGetPara versucht den nNumb ( 0...x ) Parameter aus mpStringBuf zu ermitteln.
508 : : // Ein Parameter ist durch Spaces oder Tabs von den anderen getrennt.
509 : : // Konnte der Parameter gefunden werden ist der Rueckgabewert sal_True und mpPara + mnParaSize
510 : : // werden gesetzt.
511 : :
512 : 0 : sal_Bool XPMReader::ImplGetPara ( sal_uLong nNumb )
513 : : {
514 : : sal_uInt8 nByte;
515 : 0 : sal_uLong pSize = 0;
516 : 0 : sal_uInt8* pPtr = mpStringBuf;
517 : 0 : sal_uLong nCount = 0;
518 : :
519 [ # # ][ # # ]: 0 : if ( ( *pPtr != ' ' ) && ( *pPtr != 0x09 ) )
520 : : {
521 : 0 : mpPara = pPtr;
522 : 0 : mnParaSize = 0;
523 : 0 : nCount = 0;
524 : : }
525 : : else
526 : : {
527 : 0 : mpPara = NULL;
528 : 0 : nCount = 0xffffffff;
529 : : }
530 : :
531 [ # # ]: 0 : while ( pSize < mnStringSize )
532 : : {
533 : 0 : nByte = *pPtr;
534 : :
535 [ # # ]: 0 : if ( mpPara )
536 : : {
537 [ # # ][ # # ]: 0 : if ( ( nByte == ' ' ) || ( nByte == 0x09 ) )
538 : : {
539 [ # # ]: 0 : if ( nCount == nNumb )
540 : 0 : break;
541 : : else
542 : 0 : mpPara = NULL;
543 : : }
544 : : else
545 : 0 : mnParaSize++;
546 : : }
547 : : else
548 : : {
549 [ # # ][ # # ]: 0 : if ( ( nByte != ' ' ) && ( nByte != 0x09 ) )
550 : : {
551 : 0 : mpPara = pPtr;
552 : 0 : mnParaSize = 1;
553 : 0 : nCount++;
554 : : }
555 : : }
556 : 0 : pSize++;
557 : 0 : pPtr++;
558 : : }
559 [ # # ][ # # ]: 0 : return ( ( nCount == nNumb ) && ( mpPara ) ) ? sal_True : sal_False;
560 : : }
561 : :
562 : : // ------------------------------------------------------------------------
563 : : // Der naechste String wird ausgelesen und in mpStringBuf (mit 0 abgeschlossen) abgelegt;
564 : : // mnStringSize enthaelt die Groesse des gelesenen Strings.
565 : : // Bemerkungen wie '//' und '/*.....*/' werden uebersprungen.
566 : :
567 : 0 : sal_Bool XPMReader::ImplGetString( void )
568 : : {
569 : 0 : sal_uInt8 sID[] = "/* XPM */";
570 : 0 : sal_uInt8* pString = mpStringBuf;
571 : :
572 : 0 : mnStringSize = 0;
573 : 0 : mpStringBuf[0] = 0;
574 : :
575 [ # # ][ # # ]: 0 : while( mbStatus && ( mnStatus != XPMFINISHED ) )
[ # # ]
576 : : {
577 [ # # ]: 0 : if ( mnTempAvail == 0 )
578 : : {
579 [ # # ]: 0 : mnTempAvail = mrIStm.Read( mpTempBuf, XPMTEMPBUFSIZE );
580 [ # # ]: 0 : if ( mnTempAvail == 0 )
581 : 0 : break;
582 : :
583 : 0 : mpTempPtr = mpTempBuf;
584 : :
585 [ # # ]: 0 : if ( mnIdentifier == XPMIDENTIFIER )
586 : : {
587 [ # # ]: 0 : if ( mnTempAvail <= 50 )
588 : : {
589 : 0 : mbStatus = sal_False; // file is too short to be a correct XPM format
590 : 0 : break;
591 : : }
592 [ # # ]: 0 : for ( int i = 0; i < 9; i++ ) // searching for "/* XPM */"
593 [ # # ]: 0 : if ( *mpTempPtr++ != sID[i] )
594 : : {
595 : 0 : mbStatus = sal_False;
596 : 0 : break;
597 : : }
598 : 0 : mnTempAvail-=9;
599 : 0 : mnIdentifier++;
600 : : }
601 : : }
602 : 0 : mcLastByte = mcThisByte;
603 : 0 : mcThisByte = *mpTempPtr++;
604 : 0 : mnTempAvail--;
605 : :
606 [ # # ]: 0 : if ( mnStatus & XPMDOUBLE )
607 : : {
608 [ # # ]: 0 : if ( mcThisByte == 0x0a )
609 : 0 : mnStatus &=~XPMDOUBLE;
610 : 0 : continue;
611 : : }
612 [ # # ]: 0 : if ( mnStatus & XPMREMARK )
613 : : {
614 [ # # ][ # # ]: 0 : if ( ( mcThisByte == '/' ) && ( mcLastByte == '*' ) )
615 : 0 : mnStatus &=~XPMREMARK;
616 : 0 : continue;
617 : : }
618 [ # # ]: 0 : if ( mnStatus & XPMSTRING ) // characters in string
619 : : {
620 [ # # ]: 0 : if ( mcThisByte == '"' )
621 : : {
622 : 0 : mnStatus &=~XPMSTRING; // end of parameter by eol
623 : 0 : break;
624 : : }
625 [ # # ]: 0 : if ( mnStringSize >= ( XPMSTRINGBUF - 1 ) )
626 : : {
627 : 0 : mbStatus = sal_False;
628 : 0 : break;
629 : : }
630 : 0 : *pString++ = mcThisByte;
631 : 0 : pString[0] = 0;
632 : 0 : mnStringSize++;
633 : 0 : continue;
634 : : }
635 : : else
636 : : { // characters beside string
637 [ # # # # : 0 : switch ( mcThisByte )
# # ]
638 : : {
639 : : case '*' :
640 [ # # ]: 0 : if ( mcLastByte == '/' ) mnStatus |= XPMREMARK;
641 : 0 : break;
642 : : case '/' :
643 [ # # ]: 0 : if ( mcLastByte == '/' ) mnStatus |= XPMDOUBLE;
644 : 0 : break;
645 : 0 : case '"' : mnStatus |= XPMSTRING;
646 : 0 : break;
647 : : case '{' :
648 [ # # ]: 0 : if ( mnIdentifier == XPMDEFINITION )
649 : 0 : mnIdentifier++;
650 : 0 : break;
651 : : case '}' :
652 [ # # ]: 0 : if ( mnIdentifier == XPMENDEXT )
653 : 0 : mnStatus = XPMFINISHED;
654 : 0 : break;
655 : : }
656 : : }
657 : : }
658 : 0 : return mbStatus;
659 : : }
660 : :
661 : : // -------------
662 : : // - ImportXPM -
663 : : // -------------
664 : :
665 : 0 : sal_Bool ImportXPM( SvStream& rStm, Graphic& rGraphic )
666 : : {
667 : 0 : XPMReader* pXPMReader = (XPMReader*) rGraphic.GetContext();
668 : : ReadState eReadState;
669 : 0 : sal_Bool bRet = sal_True;
670 : :
671 [ # # ]: 0 : if( !pXPMReader )
672 [ # # ]: 0 : pXPMReader = new XPMReader( rStm );
673 : :
674 : 0 : rGraphic.SetContext( NULL );
675 : 0 : eReadState = pXPMReader->ReadXPM( rGraphic );
676 : :
677 [ # # ]: 0 : if( eReadState == XPMREAD_ERROR )
678 : : {
679 : 0 : bRet = sal_False;
680 [ # # ]: 0 : delete pXPMReader;
681 : : }
682 [ # # ]: 0 : else if( eReadState == XPMREAD_OK )
683 [ # # ]: 0 : delete pXPMReader;
684 : : else
685 : 0 : rGraphic.SetContext( pXPMReader );
686 : :
687 : 0 : return bRet;
688 : : }
689 : :
690 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|