1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: xbmread.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_svtools.hxx"
34 #define XBMMINREAD 512
38 #include "xbmread.hxx"
44 XBMReader::XBMReader( SvStream
& rStm
) :
47 nLastPos ( rStm
.Tell() ),
52 pHexTable
= new short[ 256 ];
53 maUpperName
= String::CreateFromAscii( "SVIXBM", 6 );
57 // ------------------------------------------------------------------------
59 XBMReader::~XBMReader()
64 aBmp1
.ReleaseAccess( pAcc1
);
67 // ------------------------------------------------------------------------
69 void XBMReader::InitTable()
71 memset( pHexTable
, 0, sizeof( short ) );
100 pHexTable
['\n'] = -1;
101 pHexTable
['\t'] = -1;
102 pHexTable
['\0'] = -1;
105 // ------------------------------------------------------------------------
107 ByteString
XBMReader::FindTokenLine( SvStream
* pInStm
, const char* pTok1
,
108 const char* pTok2
, const char* pTok3
)
119 if( !pInStm
->ReadLine( aRet
) )
124 if( ( nPos1
= aRet
.Search( pTok1
) ) != STRING_NOTFOUND
)
132 if( ( ( nPos2
= aRet
.Search( pTok2
) ) != STRING_NOTFOUND
) &&
141 if( ( ( nPos3
= aRet
.Search( pTok3
) ) != STRING_NOTFOUND
) && ( nPos3
> nPos2
) )
154 // ------------------------------------------------------------------------
156 long XBMReader::ParseDefine( const sal_Char
* pDefine
)
159 char* pTmp
= (char*) pDefine
;
162 // bis zum Ende gehen
163 pTmp
+= ( strlen( pDefine
) - 1 );
166 // letzte Ziffer suchen
167 while( pHexTable
[ cTmp
] == -1 )
170 // bis vor die Zahl laufen
171 while( pHexTable
[ cTmp
] != -1 )
174 // auf Anfang der Zahl gehen
178 if( ( pTmp
[0] == '0' ) && ( ( pTmp
[1] == 'X' ) || ( pTmp
[1] == 'x' ) ) )
183 while ( pHexTable
[ cTmp
] != -1 )
185 nRet
= ( nRet
<< 4 ) + pHexTable
[ cTmp
];
193 while( ( cTmp
>= '0' ) && ( cTmp
<= '9' ) )
195 nRet
= nRet
* 10 + ( cTmp
- '0' );
203 // ------------------------------------------------------------------------
205 BOOL
XBMReader::ParseData( SvStream
* pInStm
, const ByteString
& aLastLine
, XBMFormat eFormat
)
210 long nBits
= ( eFormat
== XBM10
) ? 16 : 8;
214 BOOL bFirstLine
= TRUE
;
216 while( nRow
< nHeight
)
222 // einfuehrende geschweifte Klammer loeschen
223 if( (nPos
= ( aLine
= aLastLine
).Search( '{' ) ) != STRING_NOTFOUND
)
224 aLine
.Erase( 0, nPos
+ 1 );
228 else if( !pInStm
->ReadLine( aLine
) )
233 const USHORT nCount
= aLine
.GetTokenCount( ',' );
235 for( USHORT i
= 0; ( i
< nCount
) && ( nRow
< nHeight
); i
++ )
237 const ByteString
aToken( aLine
.GetToken( i
, ',' ) );
238 const xub_StrLen nLen
= aToken
.Len();
239 BOOL bProcessed
= FALSE
;
241 nBit
= nDigits
= nValue
= 0;
243 for( xub_StrLen n
= 0UL; n
< nLen
; n
++ )
245 const unsigned char cChar
= aToken
.GetChar( n
);
246 const short nTable
= pHexTable
[ cChar
];
248 if( isxdigit( cChar
) || !nTable
)
250 nValue
= ( nValue
<< 4 ) + nTable
;
254 else if( ( nTable
< 0 ) && nDigits
)
263 while( ( nCol
< nWidth
) && ( nBit
< nBits
) )
264 pAcc1
->SetPixel( nRow
, nCol
++, ( nValue
& ( 1 << nBit
++ ) ) ? aBlack
: aWhite
);
276 // ------------------------------------------------------------------------
278 ReadState
XBMReader::ReadXBM( Graphic
& rGraphic
)
280 ReadState eReadState
;
283 // sehen, ob wir _alles_ lesen koennen
284 rIStm
.Seek( STREAM_SEEK_TO_END
);
287 // falls wir nicht alles lesen koennen
288 // kehren wir zurueck und warten auf neue Daten
289 if ( rIStm
.GetError() != ERRCODE_IO_PENDING
)
294 rIStm
.Seek( nLastPos
);
296 aLine
= FindTokenLine( &rIStm
, "#define", "_width" );
300 if ( ( nValue
= (int) ParseDefine( aLine
.GetBuffer() ) ) > 0 )
303 aLine
= FindTokenLine( &rIStm
, "#define", "_height" );
305 // Falls die Hoehe nicht folgt, suchen wir noch
306 // einmal vom Anfang der Datei an
309 rIStm
.Seek( nLastPos
);
310 aLine
= FindTokenLine( &rIStm
, "#define", "_height" );
318 if ( ( nValue
= (int) ParseDefine( aLine
.GetBuffer() ) ) > 0 )
321 aLine
= FindTokenLine( &rIStm
, "static", "_bits" );
325 XBMFormat eFormat
= XBM10
;
327 if ( aLine
.Search( "short" ) != STRING_NOTFOUND
)
329 else if ( aLine
.Search( "char" ) != STRING_NOTFOUND
)
334 if ( bStatus
&& nWidth
&& nHeight
)
336 aBmp1
= Bitmap( Size( nWidth
, nHeight
), 1 );
337 pAcc1
= aBmp1
.AcquireWriteAccess();
341 aWhite
= pAcc1
->GetBestMatchingColor( Color( COL_WHITE
) );
342 aBlack
= pAcc1
->GetBestMatchingColor( Color( COL_BLACK
) );
343 bStatus
= ParseData( &rIStm
, aLine
, eFormat
);
355 Bitmap
aBlackBmp( Size( pAcc1
->Width(), pAcc1
->Height() ), 1 );
357 aBmp1
.ReleaseAccess( pAcc1
), pAcc1
= NULL
;
358 aBlackBmp
.Erase( Color( COL_BLACK
) );
359 rGraphic
= BitmapEx( aBlackBmp
, aBmp1
);
360 eReadState
= XBMREAD_OK
;
363 eReadState
= XBMREAD_ERROR
;
368 eReadState
= XBMREAD_NEED_MORE
;
378 BOOL
ImportXBM( SvStream
& rStm
, Graphic
& rGraphic
)
380 XBMReader
* pXBMReader
= (XBMReader
*) rGraphic
.GetContext();
381 ReadState eReadState
;
385 pXBMReader
= new XBMReader( rStm
);
387 rGraphic
.SetContext( NULL
);
388 eReadState
= pXBMReader
->ReadXBM( rGraphic
);
390 if( eReadState
== XBMREAD_ERROR
)
395 else if( eReadState
== XBMREAD_OK
)
398 rGraphic
.SetContext( pXBMReader
);