import java.io.*; import java.util.*; import java.awt.Color; /** * X11 bitmap (xpm) parser * * Parse files of the form: *
* static char * fee_m_pm[] = { * "8 8 2 1 -1 -1", * " s iconColor5 m black c blue", * ". s none m none c none", * " ..", * " ....", * " ....", * " ...", * " .. ..", * " ... .", * "..... ", * "...... "}; ** * @version 1.2 96/02/20 * @author Jan Andersson, Torpa Konsult AB. (janne@torpa.se) */ public class XpmParser { private DataInputStream input; private int lineNo = 0; private int width = 0; private int height = 0; private int nColors = 0; private int charsPerPixel = 0; private int colors[] = null; private Color[] colorTable; private byte[] pixmap = null; private String line; /** * Construct and XpmParser from an InputStream * @param is the imput stream to parse */ public XpmParser(InputStream is) { input = new DataInputStream(is); } /** * Parse input stream. * @return true on success. */ public boolean parse() { try { parseInput(); return true; } catch (Exception e) { System.err.println("XpmParser: " + e.getMessage()); e.printStackTrace(); 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 byte[] getPixmap() { return pixmap; } /** * Get color table. * @return array of used colors. */ public Color[] getColorTable() { return colorTable; } /** * Parse input stream. * @exception Exception on input errors. */ private void parseInput() throws Exception { checkForHeader(); skipLineStartingWith("static char"); readHintsLine(); // allocate color relates tables colors = new int[charsPerPixel * 256]; colorTable = new Color[nColors]; readColorTable(); readPixels(); } /** * Read and check XPM header comment */ private void checkForHeader() throws Exception { readLine(); if (line != null && line.startsWith("/*") && line.endsWith("*/")) { String tmp = line.substring(2); tmp = tmp.trim(); if (!tmp.substring(0, 3).equals("XPM")) System.err.println("XpmParser: warning: Not Xpm version 3."); // read next line readLine(); } } /** * Skip line starting with specified string. */ private void skipLineStartingWith(String skip) throws Exception { if (line == null) throw(new Exception("Invalid Xpm format, line: " + lineNo)); if (line.startsWith(skip)) { // ignore this line; read next readLine(); } } /** * Read XPM hints line. I.e width, height, number of colors and * chars per pixel. */ private void readHintsLine() throws Exception { // skip comment line if (line != null && line.startsWith("/*") && line.endsWith("*/")) readLine(); if (line == null) throw(new Exception("Invalid Xpm format: unexpected EOF, line: " + lineNo)); int start = line.indexOf('"'); int end = line.lastIndexOf('"'); if (start < 0 || end < 0 || end <= start) throw(new Exception("Invalid Xpm format: hints line: " + lineNo)); String tmp = line.substring(start+1, end); StringTokenizer st = new StringTokenizer(tmp); if (st.countTokens() < 4) throw(new Exception("Invalid Xpm format: hints line: " + lineNo)); try { width = Integer.parseInt(st.nextToken()); height = Integer.parseInt(st.nextToken()); nColors = Integer.parseInt(st.nextToken()); charsPerPixel = Integer.parseInt(st.nextToken()); } catch (Exception e) { throw(new Exception("Invalid Xpm format: hints line: " + lineNo)); } if (charsPerPixel > 2) { throw(new Exception("Invalid Xpm format: "+ "Can only handle up to 2 chars per pixels")); } } /** * Read XPM color table. */ private void readColorTable() throws Exception { for (int i=0; i