in src/main/java/org/apache/commons/imaging/formats/xbm/XbmImageParser.java [231:343]
private BufferedImage readXbmImage(final XbmHeader xbmHeader, final BasicCParser cParser)
throws ImagingException, IOException {
String token;
token = cParser.nextToken();
if (!"static".equals(token)) {
throw new ImagingException(
"Parsing XBM file failed, no 'static' token");
}
token = cParser.nextToken();
if (token == null) {
throw new ImagingException(
"Parsing XBM file failed, no 'unsigned' "
+ "or 'char' or 'short' token");
}
if ("unsigned".equals(token)) {
token = cParser.nextToken();
}
final int inputWidth;
final int hexWidth;
if ("char".equals(token)) {
inputWidth = 8;
hexWidth = 4; // 0xab
} else if ("short".equals(token)) {
inputWidth = 16;
hexWidth = 6; // 0xabcd
} else {
throw new ImagingException(
"Parsing XBM file failed, no 'char' or 'short' token");
}
final String name = cParser.nextToken();
if (name == null) {
throw new ImagingException(
"Parsing XBM file failed, no variable name");
}
if (name.charAt(0) != '_' && !Character.isLetter(name.charAt(0))) {
throw new ImagingException(
"Parsing XBM file failed, variable name "
+ "doesn't start with letter or underscore");
}
for (int i = 0; i < name.length(); i++) {
final char c = name.charAt(i);
if (!Character.isLetterOrDigit(c) && c != '_') {
throw new ImagingException(
"Parsing XBM file failed, variable name "
+ "contains non-letter non-digit non-underscore");
}
}
token = cParser.nextToken();
if (!"[".equals(token)) {
throw new ImagingException(
"Parsing XBM file failed, no '[' token");
}
token = cParser.nextToken();
if (!"]".equals(token)) {
throw new ImagingException(
"Parsing XBM file failed, no ']' token");
}
token = cParser.nextToken();
if (!"=".equals(token)) {
throw new ImagingException(
"Parsing XBM file failed, no '=' token");
}
token = cParser.nextToken();
if (!"{".equals(token)) {
throw new ImagingException(
"Parsing XBM file failed, no '{' token");
}
final int rowLength = (xbmHeader.width + 7) / 8;
final byte[] imageData = Allocator.byteArray(rowLength * xbmHeader.height);
int i = 0;
for (int y = 0; y < xbmHeader.height; y++) {
for (int x = 0; x < xbmHeader.width; x += inputWidth) {
token = cParser.nextToken();
if (token == null || !token.startsWith("0x")) {
throw new ImagingException("Parsing XBM file failed, "
+ "hex value missing");
}
if (token.length() > hexWidth) {
throw new ImagingException("Parsing XBM file failed, "
+ "hex value too long");
}
final int value = Integer.parseInt(token.substring(2), 16);
final int flipped = Integer.reverse(value) >>> (32 - inputWidth);
if (inputWidth == 16) {
imageData[i++] = (byte) (flipped >>> 8);
if ((x + 8) < xbmHeader.width) {
imageData[i++] = (byte) flipped;
}
} else {
imageData[i++] = (byte) flipped;
}
token = cParser.nextToken();
if (token == null) {
throw new ImagingException("Parsing XBM file failed, "
+ "premature end of file");
}
if (!",".equals(token)
&& ((i < imageData.length) || !"}".equals(token))) {
throw new ImagingException("Parsing XBM file failed, "
+ "punctuation error");
}
}
}
final int[] palette = { 0xffffff, 0x000000 };
final ColorModel colorModel = new IndexColorModel(1, 2, palette, 0, false, -1, DataBuffer.TYPE_BYTE);
final DataBufferByte dataBuffer = new DataBufferByte(imageData, imageData.length);
final WritableRaster raster = Raster.createPackedRaster(dataBuffer, xbmHeader.width, xbmHeader.height, 1, null);
return new BufferedImage(colorModel, raster, colorModel.isAlphaPremultiplied(), new Properties());
}