LCOV - code coverage report
Current view: top level - vcl/source/filter/ixpm - xpmread.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 0 315 0.0 %
Date: 2015-06-13 12:38:46 Functions: 0 14 0.0 %
Legend: Lines: hit not hit

          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             : #include <vcl/bmpacc.hxx>
      21             : #include <vcl/graph.hxx>
      22             : #include "rgbtable.hxx"
      23             : #define _XPMPRIVATE
      24             : #include "xpmread.hxx"
      25             : #include <cstring>
      26             : 
      27           0 : XPMReader::XPMReader(SvStream& rStm)
      28             :     : mrIStm(rStm)
      29             :     , mpAcc(NULL)
      30             :     , mpMaskAcc(NULL)
      31           0 :     , mnLastPos(rStm.Tell())
      32             :     , mnWidth(0)
      33             :     , mnHeight(0)
      34             :     , mnColors(0)
      35             :     , mnCpp(0)
      36             :     , mbTransparent(false)
      37             :     , mbStatus(true)
      38             :     , mnStatus( 0 )
      39             :     , mnIdentifier(XPMIDENTIFIER)
      40             :     , mcThisByte(0)
      41             :     , mcLastByte(0)
      42             :     , mnTempAvail(0)
      43             :     , mpTempBuf(NULL)
      44             :     , mpTempPtr(NULL)
      45             :     , mpFastColorTable(NULL)
      46             :     , mpColMap(NULL)
      47             :     , mnStringSize(0)
      48             :     , mpStringBuf(NULL)
      49             :     , mnParaSize(0)
      50           0 :     , mpPara(NULL)
      51             : {
      52           0 : }
      53             : 
      54           0 : XPMReader::~XPMReader()
      55             : {
      56           0 :     if( mpAcc )
      57           0 :         Bitmap::ReleaseAccess( mpAcc );
      58           0 : }
      59             : 
      60           0 : ReadState XPMReader::ReadXPM( Graphic& rGraphic )
      61             : {
      62             :     ReadState   eReadState;
      63             :     sal_uInt8       cDummy;
      64             : 
      65             :     // check if we can real ALL
      66           0 :     mrIStm.Seek( STREAM_SEEK_TO_END );
      67           0 :     mrIStm.ReadUChar( cDummy );
      68             : 
      69             :     // if we could not read all
      70             :     // return and wait for new data
      71           0 :     if ( mrIStm.GetError() != ERRCODE_IO_PENDING )
      72             :     {
      73           0 :         mrIStm.Seek( mnLastPos );
      74           0 :         mbStatus = true;
      75             : 
      76           0 :         if ( mbStatus )
      77             :         {
      78           0 :             mpStringBuf = new sal_uInt8 [ XPMSTRINGBUF ];
      79           0 :             mpTempBuf = new sal_uInt8 [ XPMTEMPBUFSIZE ];
      80             : 
      81           0 :             if ( ( mbStatus = ImplGetString() ) )
      82             :             {
      83           0 :                 mnIdentifier = XPMVALUES;           // fetch Bitmap information
      84           0 :                 mnWidth = ImplGetULONG( 0 );
      85           0 :                 mnHeight = ImplGetULONG( 1 );
      86           0 :                 mnColors = ImplGetULONG( 2 );
      87           0 :                 mnCpp = ImplGetULONG( 3 );
      88             :             }
      89           0 :             if ( mnColors > ( SAL_MAX_UINT32 / ( 4 + mnCpp ) ) )
      90           0 :                 mbStatus = false;
      91           0 :             if ( ( mnWidth * mnCpp ) >= XPMSTRINGBUF )
      92           0 :                 mbStatus = false;
      93           0 :             if ( mbStatus && mnWidth && mnHeight && mnColors && mnCpp )
      94             :             {
      95           0 :                 mnIdentifier = XPMCOLORS;
      96             : 
      97             :                 // mpColMap constitutes for all available
      98             :                 // colour:   ( mnCpp )Byte(s)-> ASCII entry assigned to the colour
      99             :                 //              1    Byte   -> 0xFF if colour is transparent
     100             :                 //              3    Bytes  -> RGB value of the colour
     101           0 :                 mpColMap = new sal_uInt8[ mnColors * ( 4 + mnCpp ) ];
     102           0 :                 for ( sal_uLong i = 0; i < mnColors; i++ )
     103             :                 {
     104           0 :                     if ( !ImplGetColor( i ) )
     105             :                     {
     106           0 :                         mbStatus = false;
     107           0 :                         break;
     108             :                     }
     109             :                 }
     110             : 
     111           0 :                 if ( mbStatus )
     112             :                 {
     113             :                     // create a 24bit graphic when more as 256 colours present
     114           0 :                     sal_uInt16  nBits = 1;
     115           0 :                     if ( mnColors > 256 )
     116           0 :                         nBits = 24;
     117           0 :                     else if ( mnColors > 16 )
     118           0 :                         nBits = 8;
     119           0 :                     else if ( mnColors > 2 )
     120           0 :                         nBits = 4;
     121             :                     else
     122           0 :                         nBits = 1;
     123             : 
     124           0 :                     maBmp = Bitmap( Size( mnWidth, mnHeight ), nBits );
     125           0 :                     mpAcc = maBmp.AcquireWriteAccess();
     126             : 
     127             :                     // mbTransparent is TRUE if at least one colour is transparent
     128           0 :                     if ( mbTransparent )
     129             :                     {
     130           0 :                         maMaskBmp = Bitmap( Size( mnWidth, mnHeight ), 1 );
     131           0 :                         if ( ( mpMaskAcc = maMaskBmp.AcquireWriteAccess() ) == NULL )
     132           0 :                             mbStatus = false;
     133             :                     }
     134           0 :                     if( mpAcc && mbStatus )
     135             :                     {
     136             :                         sal_uLong   i;
     137           0 :                         if ( mnColors <=256 )   // palette is only needed by using less than 257
     138             :                         {                       // colors
     139             : 
     140           0 :                             sal_uInt8*  pPtr = &mpColMap[mnCpp];
     141             : 
     142           0 :                             for ( i = 0; i < mnColors; i++ )
     143             :                             {
     144           0 :                                 mpAcc->SetPaletteColor( (sal_uInt8)i, Color( pPtr[1], pPtr[2], pPtr[3] ) );
     145           0 :                                 pPtr += ( mnCpp + 4 );
     146             :                             }
     147             :                             // using 2 charakters per pixel and less than 257 Colors we speed up
     148           0 :                             if ( mnCpp == 2 )   // by using a 64kb indexing table
     149             :                             {
     150           0 :                                 mpFastColorTable = new sal_uInt8[ 256 * 256 ];
     151           0 :                                 for ( pPtr = mpColMap, i = 0; i < mnColors; i++, pPtr += mnCpp + 4 )
     152             :                                 {
     153           0 :                                     sal_uLong   j =  pPtr[ 0 ] << 8;
     154           0 :                                             j += pPtr[ 1 ];
     155           0 :                                     mpFastColorTable[ j ] = (sal_uInt8)i;
     156             :                                 }
     157             :                             }
     158             :                         }
     159             :                         // now we get the bitmap data
     160           0 :                         mnIdentifier = XPMPIXELS;
     161           0 :                         for ( i = 0; i < mnHeight; i++ )
     162             :                         {
     163           0 :                             if ( !ImplGetScanLine( i ) )
     164             :                             {
     165           0 :                                 mbStatus = false;
     166           0 :                                 break;
     167             :                             }
     168             :                         }
     169           0 :                         mnIdentifier = XPMEXTENSIONS;
     170             :                     }
     171             :                 }
     172             :             }
     173             : 
     174           0 :             delete[] mpFastColorTable;
     175           0 :             delete[] mpColMap;
     176           0 :             delete[] mpStringBuf;
     177           0 :             delete[] mpTempBuf;
     178             : 
     179             :         }
     180           0 :         if( mbStatus )
     181             :         {
     182           0 :             if ( mpMaskAcc )
     183             :             {
     184           0 :                 Bitmap::ReleaseAccess ( mpMaskAcc), mpMaskAcc = NULL;
     185           0 :                 Bitmap::ReleaseAccess( mpAcc ), mpAcc = NULL;
     186           0 :                 rGraphic = Graphic( BitmapEx( maBmp, maMaskBmp ) );
     187             :             }
     188             :             else
     189             :             {
     190           0 :                 Bitmap::ReleaseAccess( mpAcc ), mpAcc = NULL;
     191           0 :                 rGraphic = maBmp;
     192             :             }
     193           0 :             eReadState = XPMREAD_OK;
     194             :         }
     195             :         else
     196             :         {
     197           0 :             if ( mpMaskAcc ) Bitmap::ReleaseAccess ( mpMaskAcc), mpMaskAcc = NULL;
     198           0 :             if ( mpAcc ) Bitmap::ReleaseAccess( mpAcc ), mpAcc = NULL;
     199           0 :             eReadState = XPMREAD_ERROR;
     200             :         }
     201             :     }
     202             :     else
     203             :     {
     204           0 :         mrIStm.ResetError();
     205           0 :         eReadState = XPMREAD_NEED_MORE;
     206             :     }
     207           0 :     return eReadState;
     208             : }
     209             : 
     210             : // ImplGetColor returns variouls colour values,
     211             : // returns TRUE if various colours could be assigned
     212             : 
     213           0 : bool XPMReader::ImplGetColor( sal_uLong nNumb )
     214             : {
     215           0 :     sal_uInt8*  pString = mpStringBuf;
     216           0 :     sal_uInt8*  pPtr =  ( mpColMap + nNumb * ( 4 + mnCpp ) );
     217           0 :     bool    bStatus = ImplGetString();
     218             : 
     219           0 :     if ( bStatus )
     220             :     {
     221           0 :         for ( sal_uLong i = 0; i < mnCpp; i++ )
     222           0 :             *pPtr++ = *pString++;
     223           0 :         bStatus = ImplGetColSub ( pPtr );
     224             :     }
     225           0 :     return bStatus;
     226             : }
     227             : 
     228             : // ImpGetScanLine reads the string mpBufSize and writes the pixel in the
     229             : // Bitmap. Parameter nY is the horizontal position.
     230             : 
     231           0 : bool XPMReader::ImplGetScanLine( sal_uLong nY )
     232             : {
     233           0 :     bool    bStatus = ImplGetString();
     234           0 :     sal_uInt8*  pString = mpStringBuf;
     235             :     sal_uInt8*  pColor;
     236           0 :     BitmapColor     aWhite;
     237           0 :     BitmapColor     aBlack;
     238             : 
     239           0 :     if ( bStatus )
     240             :     {
     241           0 :         if ( mpMaskAcc )
     242             :         {
     243           0 :             aWhite = mpMaskAcc->GetBestMatchingColor( Color( COL_WHITE ) );
     244           0 :             aBlack = mpMaskAcc->GetBestMatchingColor( Color( COL_BLACK ) );
     245             :         }
     246           0 :         if ( mnStringSize != ( mnWidth * mnCpp ))
     247           0 :             bStatus = false;
     248             :         else
     249             :         {
     250             :             sal_uLong i, j;
     251           0 :             if ( mpFastColorTable )
     252             :             {
     253           0 :                 for ( i = 0; i < mnWidth; i++ )
     254             :                 {
     255           0 :                     j = (*pString++) << 8;
     256           0 :                     j += *pString++;
     257           0 :                     sal_uInt8 k = (sal_uInt8)mpFastColorTable[ j ];
     258           0 :                     mpAcc->SetPixel( nY, i, BitmapColor( (sal_uInt8)k ) );
     259             : 
     260           0 :                     if ( mpMaskAcc )
     261             :                         mpMaskAcc->SetPixel( nY, i,
     262           0 :                             ( mpColMap[ k * (mnCpp + 4) + mnCpp] ) ? aWhite : aBlack );
     263             :                 }
     264             :             }
     265           0 :             else for ( i = 0; i < mnWidth; i++ )
     266             :             {
     267           0 :                 pColor = mpColMap;
     268           0 :                 for ( j = 0; j < mnColors; j++ )
     269             :                 {
     270           0 :                     if ( ImplCompare( pString, pColor, mnCpp, XPMCASESENSITIVE ) )
     271             :                     {
     272           0 :                         if ( mnColors > 256 )
     273           0 :                             mpAcc->SetPixel( nY, i, Color ( pColor[3], pColor[4], pColor[5] ) );
     274             :                         else
     275           0 :                             mpAcc->SetPixel( nY, i, BitmapColor( (sal_uInt8) j ) );
     276             : 
     277           0 :                         if ( mpMaskAcc )
     278             :                             mpMaskAcc->SetPixel( nY, i, (
     279           0 :                                 pColor[ mnCpp ] ) ? aWhite : aBlack );
     280             : 
     281           0 :                         break;
     282             :                     }
     283           0 :                     pColor += ( mnCpp + 4 );
     284             :                 }
     285           0 :                 pString += mnCpp;
     286             :             }
     287             : 
     288             :         }
     289             :     }
     290           0 :     return bStatus;
     291             : }
     292             : 
     293             : // tries to determine a colour value from mpStringBuf
     294             : // if a colour was found the RGB value is written a pDest[1]..pDest[2]
     295             : // pDest[0] contains 0xFF if the colour is transparent otherwise 0
     296             : 
     297           0 : bool XPMReader::ImplGetColSub( sal_uInt8* pDest )
     298             : {
     299           0 :     unsigned char cTransparent[] = "None";
     300             : 
     301           0 :     bool bColStatus = false;
     302             : 
     303           0 :     if ( ImplGetColKey( 'c' ) || ImplGetColKey( 'm' ) || ImplGetColKey( 'g' ) )
     304             :     {
     305             :         // hexentry for RGB or HSV color ?
     306           0 :         if ( *mpPara == '#' )
     307             :         {
     308           0 :                 *pDest++ = 0;
     309           0 :                 bColStatus = true;
     310           0 :                 switch ( mnParaSize )
     311             :                 {
     312             :                     case 25 :
     313           0 :                         ImplGetRGBHex ( pDest, 6 );
     314           0 :                         break;
     315             :                     case 13 :
     316           0 :                         ImplGetRGBHex ( pDest, 2 );
     317           0 :                         break;
     318             :                     case  7 :
     319           0 :                         ImplGetRGBHex ( pDest, 0 );
     320           0 :                         break;
     321             :                     default:
     322           0 :                         bColStatus = false;
     323           0 :                         break;
     324             :                 }
     325             :         }
     326             :         // maybe pixel is transparent
     327           0 :         else if ( ImplCompare( &cTransparent[0], mpPara, 4 ))
     328             :         {
     329           0 :             *pDest++ = 0xff;
     330           0 :             bColStatus = true;
     331           0 :             mbTransparent = true;
     332             :         }
     333             :         // last we will try to get the colorname
     334           0 :         else if ( mnParaSize > 2 )  // name must enlarge the minimum size
     335             :         {
     336           0 :             sal_uLong i = 0;
     337             :             while ( true )
     338             :             {
     339           0 :                 if ( pRGBTable[ i ].name == NULL )
     340           0 :                     break;
     341           0 :                 if ( std::strlen(pRGBTable[i].name) > mnParaSize &&
     342           0 :                         pRGBTable[ i ].name[ mnParaSize ] == 0 )
     343             :                 {
     344           0 :                     if ( ImplCompare ( reinterpret_cast<unsigned char const *>(pRGBTable[ i ].name),
     345           0 :                             mpPara, mnParaSize, XPMCASENONSENSITIVE ) )
     346             :                     {
     347           0 :                         bColStatus = true;
     348           0 :                         *pDest++ = 0;
     349           0 :                         *pDest++ = pRGBTable[ i ].red;
     350           0 :                         *pDest++ = pRGBTable[ i ].green;
     351           0 :                         *pDest++ = pRGBTable[ i ].blue;
     352             :                     }
     353             :                 }
     354           0 :                 i++;
     355           0 :             }
     356             :         }
     357             :     }
     358           0 :     return bColStatus;
     359             : }
     360             : 
     361             : // ImplGetColKey searches string mpStringBuf for a parameter 'nKey'
     362             : // and returns a boolean. (if TRUE mpPara and mnParaSize will be set)
     363             : 
     364           0 : bool XPMReader::ImplGetColKey( sal_uInt8 nKey )
     365             : {
     366           0 :     sal_uInt8 nTemp, nPrev = ' ';
     367             : 
     368           0 :     mpPara = mpStringBuf + mnCpp + 1;
     369           0 :     mnParaSize = 0;
     370             : 
     371           0 :     while ( *mpPara != 0 )
     372             :     {
     373           0 :         if ( *mpPara == nKey )
     374             :         {
     375           0 :             nTemp = *( mpPara + 1 );
     376           0 :             if ( nTemp == ' ' || nTemp == 0x09 )
     377             :             {
     378           0 :                 if ( nPrev == ' ' || nPrev == 0x09 )
     379             :                     break;
     380             :             }
     381             :         }
     382           0 :         nPrev = *mpPara;
     383           0 :         mpPara++;
     384             :     }
     385           0 :     if ( *mpPara )
     386             :     {
     387           0 :         mpPara++;
     388           0 :         while ( (*mpPara == ' ') || (*mpPara == 0x09) )
     389             :         {
     390           0 :             mpPara++;
     391             :         }
     392           0 :         if ( *mpPara != 0 )
     393             :         {
     394           0 :             while ( *(mpPara+mnParaSize) != ' ' && *(mpPara+mnParaSize) != 0x09 &&
     395           0 :                         *(mpPara+mnParaSize) != 0 )
     396             :             {
     397           0 :                 mnParaSize++;
     398             :             }
     399             :         }
     400             :     }
     401           0 :     return mnParaSize != 0;
     402             : }
     403             : 
     404             : // ImplGetRGBHex translates the ASCII-Hexadecimalvalue belonging to mpPara
     405             : // in a RGB value and writes this to pDest
     406             : // below formats should be contained in mpPara:
     407             : // if nAdd = 0 : '#12ab12'                    -> RGB = 0x12, 0xab, 0x12
     408             : //           2 : '#1234abcd1234'                  "      "     "     "
     409             : //           6 : '#12345678abcdefab12345678'      "      "     "     "
     410             : 
     411           0 : void XPMReader::ImplGetRGBHex( sal_uInt8* pDest,sal_uLong  nAdd )
     412             : {
     413           0 :     sal_uInt8*  pPtr = mpPara+1;
     414             :     sal_uInt8   nHex, nTemp;
     415             : 
     416           0 :     for ( sal_uLong i = 0; i < 3; i++ )
     417             :     {
     418           0 :         nHex = (*pPtr++) - '0';
     419           0 :         if ( nHex > 9 )
     420           0 :             nHex = ((nHex - 'A' + '0') & 7) + 10;
     421             : 
     422           0 :         nTemp = (*pPtr++) - '0';
     423           0 :         if ( nTemp > 9 )
     424           0 :             nTemp = ((nTemp - 'A' + '0') & 7) + 10;
     425           0 :         nHex = ( nHex << 4 ) + nTemp;
     426             : 
     427           0 :         pPtr += nAdd;
     428           0 :         *pDest++ = (sal_uInt8)nHex;
     429             :     }
     430           0 : }
     431             : 
     432             : // ImplGetUlong returns the value of a up to 6-digit long ASCII-decimal number.
     433             : 
     434           0 : sal_uLong XPMReader::ImplGetULONG( sal_uLong nPara )
     435             : {
     436           0 :     if ( ImplGetPara ( nPara ) )
     437             :     {
     438           0 :         sal_uLong nRetValue = 0;
     439           0 :         sal_uInt8* pPtr = mpPara;
     440             : 
     441           0 :         if ( ( mnParaSize > 6 ) || ( mnParaSize == 0 ) ) return 0;
     442           0 :         for ( sal_uLong i = 0; i < mnParaSize; i++ )
     443             :         {
     444           0 :             sal_uInt8 j = (*pPtr++) - 48;
     445           0 :             if ( j > 9 ) return 0;              // ascii is invalid
     446           0 :             nRetValue*=10;
     447           0 :             nRetValue+=j;
     448             :         }
     449           0 :         return nRetValue;
     450             :     }
     451           0 :     else return 0;
     452             : }
     453             : 
     454           0 : bool XPMReader::ImplCompare( sal_uInt8 const * pSource, sal_uInt8 const * pDest, sal_uLong nSize, sal_uLong nMode )
     455             : {
     456           0 :     bool bRet = true;
     457             : 
     458           0 :     if ( nMode == XPMCASENONSENSITIVE )
     459             :     {
     460           0 :         for ( sal_uLong i = 0; i < nSize; i++ )
     461             :         {
     462           0 :             if ( ( pSource[i]&~0x20 ) != ( pDest[i]&~0x20 ) )
     463             :             {
     464           0 :                 bRet = false;
     465           0 :                 break;
     466             :             }
     467             :         }
     468             :     }
     469             :     else
     470             :     {
     471           0 :         for ( sal_uLong i = 0; i < nSize; i++ )
     472             :         {
     473           0 :             if ( pSource[i] != pDest[i] )
     474             :             {
     475           0 :                 bRet = false;
     476           0 :                 break;
     477             :             }
     478             :         }
     479             :     }
     480           0 :     return bRet;
     481             : }
     482             : 
     483             : // ImplGetPara tries to retrieve nNumb (0...x) parameters from mpStringBuf.
     484             : // Parameters are separated by spaces or tabs.
     485             : // If a parameter was found then the return value is TRUE and mpPara + mnParaSize
     486             : // are set.
     487             : 
     488           0 : bool XPMReader::ImplGetPara ( sal_uLong nNumb )
     489             : {
     490             :     sal_uInt8   nByte;
     491           0 :     sal_uLong   pSize = 0;
     492           0 :     sal_uInt8*  pPtr = mpStringBuf;
     493           0 :     sal_uLong   nCount = 0;
     494             : 
     495           0 :     if ( ( *pPtr != ' ' ) && ( *pPtr != 0x09 ) )
     496             :     {
     497           0 :         mpPara = pPtr;
     498           0 :         mnParaSize = 0;
     499           0 :         nCount = 0;
     500             :     }
     501             :     else
     502             :     {
     503           0 :         mpPara = NULL;
     504           0 :         nCount = 0xffffffff;
     505             :     }
     506             : 
     507           0 :     while ( pSize < mnStringSize )
     508             :     {
     509           0 :         nByte = *pPtr;
     510             : 
     511           0 :         if ( mpPara )
     512             :         {
     513           0 :             if ( ( nByte == ' ' ) || ( nByte == 0x09 ) )
     514             :             {
     515           0 :                 if ( nCount == nNumb )
     516           0 :                     break;
     517             :                 else
     518           0 :                     mpPara = NULL;
     519             :             }
     520             :             else
     521           0 :                 mnParaSize++;
     522             :         }
     523             :         else
     524             :         {
     525           0 :             if ( ( nByte != ' ' ) && ( nByte != 0x09 ) )
     526             :             {
     527           0 :                 mpPara = pPtr;
     528           0 :                 mnParaSize = 1;
     529           0 :                 nCount++;
     530             :             }
     531             :         }
     532           0 :         pSize++;
     533           0 :         pPtr++;
     534             :     }
     535           0 :     return ( ( nCount == nNumb ) && ( mpPara ) );
     536             : }
     537             : 
     538             : // The next string is read and stored in mpStringBuf (terminated with 0);
     539             : // mnStringSize contains the size of the string read.
     540             : // Comments like '//' and '/*....*/' are skipped.
     541             : 
     542           0 : bool XPMReader::ImplGetString()
     543             : {
     544           0 :     sal_uInt8       sID[] = "/* XPM */";
     545           0 :     sal_uInt8*      pString = mpStringBuf;
     546             : 
     547           0 :     mnStringSize = 0;
     548           0 :     mpStringBuf[0] = 0;
     549             : 
     550           0 :     while( mbStatus && ( mnStatus != XPMFINISHED ) )
     551             :     {
     552           0 :         if ( mnTempAvail == 0 )
     553             :         {
     554           0 :             mnTempAvail = mrIStm.Read( mpTempBuf, XPMTEMPBUFSIZE );
     555           0 :             if ( mnTempAvail == 0 )
     556           0 :                 break;
     557             : 
     558           0 :             mpTempPtr = mpTempBuf;
     559             : 
     560           0 :             if ( mnIdentifier == XPMIDENTIFIER )
     561             :             {
     562           0 :                 if ( mnTempAvail <= 50 )
     563             :                 {
     564           0 :                     mbStatus = false;   // file is too short to be a correct XPM format
     565           0 :                     break;
     566             :                 }
     567           0 :                 for ( int i = 0; i < 9; i++ )   // searching for "/* XPM */"
     568           0 :                     if ( *mpTempPtr++ != sID[i] )
     569             :                     {
     570           0 :                         mbStatus = false;
     571           0 :                         break;
     572             :                     }
     573           0 :                 mnTempAvail-=9;
     574           0 :                 mnIdentifier++;
     575             :             }
     576             :         }
     577           0 :         mcLastByte = mcThisByte;
     578           0 :         mcThisByte = *mpTempPtr++;
     579           0 :         mnTempAvail--;
     580             : 
     581           0 :         if ( mnStatus & XPMDOUBLE )
     582             :         {
     583           0 :             if ( mcThisByte == 0x0a )
     584           0 :                 mnStatus &=~XPMDOUBLE;
     585           0 :             continue;
     586             :         }
     587           0 :         if ( mnStatus & XPMREMARK )
     588             :         {
     589           0 :             if ( ( mcThisByte == '/' )  && ( mcLastByte == '*' ) )
     590           0 :                 mnStatus &=~XPMREMARK;
     591           0 :             continue;
     592             :         }
     593           0 :         if ( mnStatus & XPMSTRING )             // characters in string
     594             :         {
     595           0 :             if ( mcThisByte == '"' )
     596             :             {
     597           0 :                 mnStatus &=~XPMSTRING;          // end of parameter by eol
     598           0 :                 break;
     599             :             }
     600           0 :             if ( mnStringSize >= ( XPMSTRINGBUF - 1 ) )
     601             :             {
     602           0 :                 mbStatus = false;
     603           0 :                 break;
     604             :             }
     605           0 :             *pString++ = mcThisByte;
     606           0 :             pString[0] = 0;
     607           0 :             mnStringSize++;
     608           0 :             continue;
     609             :         }
     610             :         else
     611             :         {                                           // characters beside string
     612           0 :             switch ( mcThisByte )
     613             :             {
     614             :                 case '*' :
     615           0 :                     if ( mcLastByte == '/' ) mnStatus |= XPMREMARK;
     616           0 :                     break;
     617             :                 case '/' :
     618           0 :                     if ( mcLastByte == '/' ) mnStatus |= XPMDOUBLE;
     619           0 :                     break;
     620           0 :                 case '"' : mnStatus |= XPMSTRING;
     621           0 :                     break;
     622             :                 case '{' :
     623           0 :                     if ( mnIdentifier == XPMDEFINITION )
     624           0 :                         mnIdentifier++;
     625           0 :                     break;
     626             :                 case '}' :
     627           0 :                     if ( mnIdentifier == XPMENDEXT )
     628           0 :                         mnStatus = XPMFINISHED;
     629           0 :                     break;
     630             :             }
     631             :         }
     632             :     }
     633           0 :     return mbStatus;
     634             : }
     635             : 
     636             : // - ImportXPM -
     637             : 
     638           0 : bool ImportXPM( SvStream& rStm, Graphic& rGraphic )
     639             : {
     640           0 :     XPMReader*  pXPMReader = static_cast<XPMReader*>(rGraphic.GetContext());
     641             :     ReadState   eReadState;
     642           0 :     bool        bRet = true;
     643             : 
     644           0 :     if( !pXPMReader )
     645           0 :         pXPMReader = new XPMReader( rStm );
     646             : 
     647           0 :     rGraphic.SetContext( NULL );
     648           0 :     eReadState = pXPMReader->ReadXPM( rGraphic );
     649             : 
     650           0 :     if( eReadState == XPMREAD_ERROR )
     651             :     {
     652           0 :         bRet = false;
     653           0 :         delete pXPMReader;
     654             :     }
     655           0 :     else if( eReadState == XPMREAD_OK )
     656           0 :         delete pXPMReader;
     657             :     else
     658           0 :         rGraphic.SetContext( pXPMReader );
     659             : 
     660           0 :     return bRet;
     661             : }
     662             : 
     663             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11