24#include <rtl/character.hxx>
51 std::unique_ptr<short[]>
61 OString FindTokenLine(
SvStream* pInStm,
const char* pTok1,
const char* pTok2 );
62 int ParseDefine(
const char* pDefine );
63 void ParseData(
SvStream* pInStm,
const OString& aLastLine, XBMFormat eFormat );
67 explicit XBMReader(
SvStream& rStm );
74XBMReader::XBMReader(
SvStream& rStm ) :
76 nLastPos ( rStm.Tell() ),
81 pHexTable.reset(
new short[ 256 ] );
82 maUpperName =
"SVIXBM";
86void XBMReader::InitTable()
88 memset( pHexTable.get(), 0,
sizeof(
short ) * 256 );
90 pHexTable[
int(
'0')] = 0;
91 pHexTable[
int(
'1')] = 1;
92 pHexTable[
int(
'2')] = 2;
93 pHexTable[
int(
'3')] = 3;
94 pHexTable[
int(
'4')] = 4;
95 pHexTable[
int(
'5')] = 5;
96 pHexTable[
int(
'6')] = 6;
97 pHexTable[
int(
'7')] = 7;
98 pHexTable[
int(
'8')] = 8;
99 pHexTable[
int(
'9')] = 9;
100 pHexTable[
int(
'A')] = 10;
101 pHexTable[
int(
'B')] = 11;
102 pHexTable[
int(
'C')] = 12;
103 pHexTable[
int(
'D')] = 13;
104 pHexTable[
int(
'E')] = 14;
105 pHexTable[
int(
'F')] = 15;
106 pHexTable[
int(
'X')] = 0;
107 pHexTable[
int(
'a')] = 10;
108 pHexTable[
int(
'b')] = 11;
109 pHexTable[
int(
'c')] = 12;
110 pHexTable[
int(
'd')] = 13;
111 pHexTable[
int(
'e')] = 14;
112 pHexTable[
int(
'f')] = 15;
113 pHexTable[
int(
'x')] = 0;
114 pHexTable[
int(
' ')] = -1;
115 pHexTable[
int(
',')] = -1;
116 pHexTable[
int(
'}')] = -1;
117 pHexTable[
int(
'\n')] = -1;
118 pHexTable[
int(
'\t')] = -1;
119 pHexTable[
int(
'\0')] = -1;
122OString XBMReader::FindTokenLine(
SvStream* pInStm,
const char* pTok1,
126 sal_Int32 nPos1, nPos2;
137 if( ( nPos1 = aRet.indexOf( pTok1 ) ) != -1 )
145 nPos2 = aRet.indexOf( pTok2 );
146 if( ( nPos2 != -1 ) && ( nPos2 > nPos1 ) )
159int XBMReader::ParseDefine(
const char* pDefine )
162 const char* pTmp = pDefine;
166 pTmp += ( strlen( pDefine ) - 1 );
170 while (pHexTable[ cTmp ] == -1 && pTmp >= pDefine)
174 while (pHexTable[ cTmp ] != -1 && pTmp >= pDefine)
181 if( ( pTmp[0] ==
'0' ) && ( ( pTmp[1] ==
'X' ) || ( pTmp[1] ==
'x' ) ) )
184 nRet = OString(pTmp, strlen(pTmp)).toInt32(16);
188 nRet = OString(pTmp, strlen(pTmp)).toInt32();
194void XBMReader::ParseData(
SvStream* pInStm,
const OString& aLastLine, XBMFormat eFormat )
203 bool bFirstLine =
true;
205 while( nRow < nHeight )
213 nPos = aLine.indexOf(
'{');
215 aLine = aLine.copy(nPos + 1);
219 else if( !pInStm->
ReadLine( aLine ) )
222 if (!aLine.isEmpty())
225 const sal_Int32 nLen {aLine.getLength()};
226 while (nRow<nHeight && nIndex<nLen)
228 bool bProcessed =
false;
234 const unsigned char cChar = aLine[
nIndex];
240 const short nTable = pHexTable[ cChar ];
242 if( rtl::isAsciiHexDigit( cChar ) || !nTable )
248 else if( ( nTable < 0 ) && nDigits )
257 Scanline pScanline = pAcc1->GetScanline(nRow);
258 while( ( nCol < nWidth ) && (
nBit < nBits ) )
259 pAcc1->SetPixelOnData(pScanline, nCol++, ( nValue & ( 1 << nBit++ ) ) ? aBlack : aWhite);
278 rIStm.Seek( STREAM_SEEK_TO_END );
279 rIStm.ReadUChar( cDummy );
283 if ( rIStm.GetError() != ERRCODE_IO_PENDING )
285 rIStm.Seek( nLastPos );
287 OString aLine = FindTokenLine( &rIStm,
"#define",
"_width" );
292 if ( ( nValue = ParseDefine( aLine.getStr() ) ) > 0 )
295 aLine = FindTokenLine( &rIStm,
"#define",
"_height" );
301 rIStm.Seek( nLastPos );
302 aLine = FindTokenLine( &rIStm,
"#define",
"_height" );
310 if ( ( nValue = ParseDefine( aLine.getStr() ) ) > 0 )
313 aLine = FindTokenLine( &rIStm,
"static",
"_bits" );
317 XBMFormat eFormat = XBM10;
319 if (aLine.indexOf(
"short") != -1)
321 else if (aLine.indexOf(
"char") != -1)
328 if (rIStm.remainingSize() < (
static_cast<sal_uInt64
>(nWidth) * nHeight) / 8)
331 if ( bStatus && nWidth && nHeight )
338 aWhite = pAcc1->GetBestMatchingColor( COL_WHITE );
339 aBlack = pAcc1->GetBestMatchingColor( COL_BLACK );
340 ParseData( &rIStm, aLine, eFormat );
350 if (bStatus && pAcc1)
355 aBlackBmp.Erase( COL_BLACK );
356 rGraphic =
BitmapEx( aBlackBmp, aBmp1 );
357 eReadState = XBMREAD_OK;
360 eReadState = XBMREAD_ERROR;
365 eReadState = XBMREAD_NEED_MORE;
375 XBMReader* pXBMReader =
dynamic_cast<XBMReader*
>( pContext.get() );
378 pContext = std::make_shared<XBMReader>( rStm );
379 pXBMReader =
static_cast<XBMReader*
>( pContext.get() );
384 ReadState eReadState = pXBMReader->ReadXBM( rGraphic );
386 if( eReadState == XBMREAD_ERROR )
390 else if( eReadState == XBMREAD_NEED_MORE )
vcl::ScopedBitmapAccess< BitmapWriteAccess, Bitmap, &Bitmap::AcquireWriteAccess > BitmapScopedWriteAccess
static const BitmapPalette & GetGreyPalette(int nEntries)
void SetReaderContext(const std::shared_ptr< GraphicReader > &pReader)
std::shared_ptr< GraphicReader > & GetReaderContext()
bool ReadLine(OStringBuffer &rStr, sal_Int32 nMaxBytesToRead=0xFFFE)
This template handles BitmapAccess the RAII way.
const wchar_t *typedef int(__stdcall *DllNativeUnregProc)(int
VCL_DLLPUBLIC bool ImportXBM(SvStream &rStm, Graphic &rGraphic)