merge the formfield patch from ooo-build
[ooovba.git] / svtools / source / filter.vcl / ixbm / xbmread.cxx
blobabd8cb9827564afb54429d8a4449f3cebb377d03
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: xbmread.cxx,v $
10 * $Revision: 1.8 $
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
36 #define _XBMPRIVATE
37 #include <ctype.h>
38 #include "xbmread.hxx"
40 // -------------
41 // - XBMReader -
42 // -------------
44 XBMReader::XBMReader( SvStream& rStm ) :
45 rIStm ( rStm ),
46 pAcc1 ( NULL ),
47 nLastPos ( rStm.Tell() ),
48 nWidth ( 0 ),
49 nHeight ( 0 ),
50 bStatus ( TRUE )
52 pHexTable = new short[ 256 ];
53 maUpperName = String::CreateFromAscii( "SVIXBM", 6 );
54 InitTable();
57 // ------------------------------------------------------------------------
59 XBMReader::~XBMReader()
61 delete[] pHexTable;
63 if( pAcc1 )
64 aBmp1.ReleaseAccess( pAcc1 );
67 // ------------------------------------------------------------------------
69 void XBMReader::InitTable()
71 memset( pHexTable, 0, sizeof( short ) );
73 pHexTable['0'] = 0;
74 pHexTable['1'] = 1;
75 pHexTable['2'] = 2;
76 pHexTable['3'] = 3;
77 pHexTable['4'] = 4;
78 pHexTable['5'] = 5;
79 pHexTable['6'] = 6;
80 pHexTable['7'] = 7;
81 pHexTable['8'] = 8;
82 pHexTable['9'] = 9;
83 pHexTable['A'] = 10;
84 pHexTable['B'] = 11;
85 pHexTable['C'] = 12;
86 pHexTable['D'] = 13;
87 pHexTable['E'] = 14;
88 pHexTable['F'] = 15;
89 pHexTable['X'] = 0;
90 pHexTable['a'] = 10;
91 pHexTable['b'] = 11;
92 pHexTable['c'] = 12;
93 pHexTable['d'] = 13;
94 pHexTable['e'] = 14;
95 pHexTable['f'] = 15;
96 pHexTable['x'] = 0;
97 pHexTable[' '] = -1;
98 pHexTable[','] = -1;
99 pHexTable['}'] = -1;
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 )
110 ByteString aRet;
111 long nPos1;
112 long nPos2;
113 long nPos3;
115 bStatus = FALSE;
119 if( !pInStm->ReadLine( aRet ) )
120 break;
122 if( pTok1 )
124 if( ( nPos1 = aRet.Search( pTok1 ) ) != STRING_NOTFOUND )
126 bStatus = TRUE;
128 if( pTok2 )
130 bStatus = FALSE;
132 if( ( ( nPos2 = aRet.Search( pTok2 ) ) != STRING_NOTFOUND ) &&
133 ( nPos2 > nPos1 ) )
135 bStatus = TRUE;
137 if( pTok3 )
139 bStatus = FALSE;
141 if( ( ( nPos3 = aRet.Search( pTok3 ) ) != STRING_NOTFOUND ) && ( nPos3 > nPos2 ) )
142 bStatus = TRUE;
149 while( !bStatus );
151 return aRet;
154 // ------------------------------------------------------------------------
156 long XBMReader::ParseDefine( const sal_Char* pDefine )
158 long nRet = 0;
159 char* pTmp = (char*) pDefine;
160 unsigned char cTmp;
162 // bis zum Ende gehen
163 pTmp += ( strlen( pDefine ) - 1 );
164 cTmp = *pTmp--;
166 // letzte Ziffer suchen
167 while( pHexTable[ cTmp ] == -1 )
168 cTmp = *pTmp--;
170 // bis vor die Zahl laufen
171 while( pHexTable[ cTmp ] != -1 )
172 cTmp = *pTmp--;
174 // auf Anfang der Zahl gehen
175 pTmp += 2;
177 // Hex lesen
178 if( ( pTmp[0] == '0' ) && ( ( pTmp[1] == 'X' ) || ( pTmp[1] == 'x' ) ) )
180 pTmp += 2;
181 cTmp = *pTmp++;
183 while ( pHexTable[ cTmp ] != -1 )
185 nRet = ( nRet << 4 ) + pHexTable[ cTmp ];
186 cTmp = *pTmp++;
189 // Dezimal lesen
190 else
192 cTmp = *pTmp++;
193 while( ( cTmp >= '0' ) && ( cTmp <= '9' ) )
195 nRet = nRet * 10 + ( cTmp - '0' );
196 cTmp = *pTmp++;
200 return nRet;
203 // ------------------------------------------------------------------------
205 BOOL XBMReader::ParseData( SvStream* pInStm, const ByteString& aLastLine, XBMFormat eFormat )
207 ByteString aLine;
208 long nRow = 0;
209 long nCol = 0;
210 long nBits = ( eFormat == XBM10 ) ? 16 : 8;
211 long nBit;
212 USHORT nValue;
213 USHORT nDigits;
214 BOOL bFirstLine = TRUE;
216 while( nRow < nHeight )
218 if( bFirstLine )
220 xub_StrLen nPos;
222 // einfuehrende geschweifte Klammer loeschen
223 if( (nPos = ( aLine = aLastLine ).Search( '{' ) ) != STRING_NOTFOUND )
224 aLine.Erase( 0, nPos + 1 );
226 bFirstLine = FALSE;
228 else if( !pInStm->ReadLine( aLine ) )
229 break;
231 if( aLine.Len() )
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;
251 nDigits++;
252 bProcessed = TRUE;
254 else if( ( nTable < 0 ) && nDigits )
256 bProcessed = TRUE;
257 break;
261 if( bProcessed )
263 while( ( nCol < nWidth ) && ( nBit < nBits ) )
264 pAcc1->SetPixel( nRow, nCol++, ( nValue & ( 1 << nBit++ ) ) ? aBlack : aWhite );
266 if( nCol == nWidth )
267 nCol = 0, nRow++;
273 return TRUE;
276 // ------------------------------------------------------------------------
278 ReadState XBMReader::ReadXBM( Graphic& rGraphic )
280 ReadState eReadState;
281 BYTE cDummy;
283 // sehen, ob wir _alles_ lesen koennen
284 rIStm.Seek( STREAM_SEEK_TO_END );
285 rIStm >> cDummy;
287 // falls wir nicht alles lesen koennen
288 // kehren wir zurueck und warten auf neue Daten
289 if ( rIStm.GetError() != ERRCODE_IO_PENDING )
291 ByteString aLine;
292 int nValue;
294 rIStm.Seek( nLastPos );
295 bStatus = FALSE;
296 aLine = FindTokenLine( &rIStm, "#define", "_width" );
298 if ( bStatus )
300 if ( ( nValue = (int) ParseDefine( aLine.GetBuffer() ) ) > 0 )
302 nWidth = nValue;
303 aLine = FindTokenLine( &rIStm, "#define", "_height" );
305 // Falls die Hoehe nicht folgt, suchen wir noch
306 // einmal vom Anfang der Datei an
307 if ( !bStatus )
309 rIStm.Seek( nLastPos );
310 aLine = FindTokenLine( &rIStm, "#define", "_height" );
313 else
314 bStatus = FALSE;
316 if ( bStatus )
318 if ( ( nValue = (int) ParseDefine( aLine.GetBuffer() ) ) > 0 )
320 nHeight = nValue;
321 aLine = FindTokenLine( &rIStm, "static", "_bits" );
323 if ( bStatus )
325 XBMFormat eFormat = XBM10;
327 if ( aLine.Search( "short" ) != STRING_NOTFOUND )
328 eFormat = XBM10;
329 else if ( aLine.Search( "char" ) != STRING_NOTFOUND )
330 eFormat = XBM11;
331 else
332 bStatus = FALSE;
334 if ( bStatus && nWidth && nHeight )
336 aBmp1 = Bitmap( Size( nWidth, nHeight ), 1 );
337 pAcc1 = aBmp1.AcquireWriteAccess();
339 if( pAcc1 )
341 aWhite = pAcc1->GetBestMatchingColor( Color( COL_WHITE ) );
342 aBlack = pAcc1->GetBestMatchingColor( Color( COL_BLACK ) );
343 bStatus = ParseData( &rIStm, aLine, eFormat );
345 else
346 bStatus = FALSE;
353 if( bStatus )
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;
362 else
363 eReadState = XBMREAD_ERROR;
365 else
367 rIStm.ResetError();
368 eReadState = XBMREAD_NEED_MORE;
371 return eReadState;
374 // -------------
375 // - ImportXBM -
376 // -------------
378 BOOL ImportXBM( SvStream& rStm, Graphic& rGraphic )
380 XBMReader* pXBMReader = (XBMReader*) rGraphic.GetContext();
381 ReadState eReadState;
382 BOOL bRet = TRUE;
384 if( !pXBMReader )
385 pXBMReader = new XBMReader( rStm );
387 rGraphic.SetContext( NULL );
388 eReadState = pXBMReader->ReadXBM( rGraphic );
390 if( eReadState == XBMREAD_ERROR )
392 bRet = FALSE;
393 delete pXBMReader;
395 else if( eReadState == XBMREAD_OK )
396 delete pXBMReader;
397 else
398 rGraphic.SetContext( pXBMReader );
400 return bRet;