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