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: */
|