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