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