import java.io.*; /** * X11 bitmap (xbm) parser class. * * Parse files of the form: *
* #define foo_width w * #define foo_height h * static char foo_bits[] = { * 0xnn,0xnn,0xnn,0xnn,0xnn,0xnn,0xnn,0xnn,0xnn,0xnn,0xnn,0xnn,0xnn,0xnn,0xnn, * 0xnn,0xnn,0xnn,0xnn,0xnn,0xnn,0xnn,0xnn,0xnn,0xnn,0xnn,0xnn,0xnn,0xnn,0xnn, * 0xnn,0xnn,0xnn,0xnn}; ** * @version 1.2 96/02/20 * @author Jan Andersson, Torpa Konsult AB. (janne@torpa.se) */ public class XbmParser { private static final int GET_WIDTH = 0; private static final int GET_HEIGHT = 1; private static final int GET_START = 2; private static final int GET_BYTES = 3; private StreamTokenizer tokenizer; private int width = 0; private int height = 0; private int[] bitmap = null; /** * Construct and XpmParser from an InputStream * @param is the imput stream to parse */ public XbmParser(InputStream is) { tokenizer = new StreamTokenizer(is); tokenizer.slashStarComments(true); tokenizer.ordinaryChar('/'); } /** * Parse input stream. * @return true on success. */ public boolean parse() { try { parseInput(); return true; } catch (Exception e) { return false; } } /** * Get image width. * @return width in pixels. */ public int getWidth() { return width; } /** * Get image height. * @return height in pixels. */ public int getHeight() { return height; } /** * Get pixmap. * @return pixmap array. */ public int[] getBitmap() { return bitmap; } /** * Parse input stream. * @exception Exception on input errors. */ private void parseInput() throws Exception { int state = GET_WIDTH; int token = StreamTokenizer.TT_EOF; int index = 0; token = tokenizer.nextToken(); while (token != StreamTokenizer.TT_EOF) { switch(state) { case GET_WIDTH: if (token == StreamTokenizer.TT_NUMBER) { width = (int) tokenizer.nval; state = GET_HEIGHT; } break; case GET_HEIGHT: if (token == StreamTokenizer.TT_NUMBER) { height = (int) tokenizer.nval; state = GET_START; } break; case GET_START: if (token == '{') { // reset tokinizer to handle bytes resetTokenizer(); // allocate bitmap bitmap = new int[width*height/8]; state = GET_BYTES; } break; case GET_BYTES: // waiting for 0xnn, or '}' if (token == StreamTokenizer.TT_WORD) { if (tokenizer.sval.length() > 2 && tokenizer.sval.charAt(0) == '0' && (tokenizer.sval.charAt(1) == 'x' || tokenizer.sval.charAt(1) == 'x')) { try { int val = Integer.parseInt( tokenizer.sval.substring(2), 16); bitmap[index++] = val; } catch (Exception e) { token = StreamTokenizer.TT_EOF; } } } else if (token == '}') { // done! token = StreamTokenizer.TT_EOF; } } token = tokenizer.nextToken(); } if (width == 0 || height == 0 || index != width*height/8) throw(new Exception()); } /** * Reset input tokenizer to handle hexadecimal values */ private void resetTokenizer() { tokenizer.resetSyntax(); tokenizer.wordChars('a', 'f'); tokenizer.wordChars('A', 'F'); tokenizer.wordChars('0', '9'); tokenizer.wordChars('x', 'x'); tokenizer.wordChars('X', 'X'); tokenizer.whitespaceChars(0, ' '); tokenizer.slashStarComments(true); } }