in src/main/java/org/apache/commons/imaging/formats/xpm/XpmImageParser.java [520:600]
private BufferedImage readXpmImage(final XpmHeader xpmHeader, final BasicCParser cParser) throws ImagingException, IOException {
final ColorModel colorModel;
final WritableRaster raster;
final int bpp;
if (xpmHeader.palette.size() <= 1 << 8) {
final int[] palette = Allocator.intArray(xpmHeader.palette.size());
for (final Entry<Object, PaletteEntry> entry : xpmHeader.palette.entrySet()) {
final PaletteEntry paletteEntry = entry.getValue();
palette[paletteEntry.index] = paletteEntry.getBestArgb();
}
colorModel = new IndexColorModel(8, xpmHeader.palette.size(), palette, 0, true, -1, DataBuffer.TYPE_BYTE);
// Check allocation
final int bands = 1;
final int scanlineStride = xpmHeader.width * bands;
final int pixelStride = bands;
final int size = scanlineStride * (xpmHeader.height - 1) + // first (h - 1) scans
pixelStride * xpmHeader.width; // last scan
Allocator.check(Byte.SIZE, size);
raster = Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE, xpmHeader.width, xpmHeader.height, bands, null);
bpp = 8;
} else if (xpmHeader.palette.size() <= 1 << 16) {
final int[] palette = Allocator.intArray(xpmHeader.palette.size());
for (final Entry<Object, PaletteEntry> entry : xpmHeader.palette.entrySet()) {
final PaletteEntry paletteEntry = entry.getValue();
palette[paletteEntry.index] = paletteEntry.getBestArgb();
}
colorModel = new IndexColorModel(16, xpmHeader.palette.size(), palette, 0, true, -1, DataBuffer.TYPE_USHORT);
// Check allocation
final int bands = 1;
final int scanlineStride = xpmHeader.width * bands;
final int pixelStride = bands;
final int size = scanlineStride * (xpmHeader.height - 1) + // first (h - 1) scans
pixelStride * xpmHeader.width; // last scan
Allocator.check(Short.SIZE, size);
raster = Raster.createInterleavedRaster(DataBuffer.TYPE_USHORT, xpmHeader.width, xpmHeader.height, bands, null);
bpp = 16;
} else {
colorModel = new DirectColorModel(32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000);
Allocator.check(Integer.SIZE, xpmHeader.width * xpmHeader.height);
raster = Raster.createPackedRaster(DataBuffer.TYPE_INT, xpmHeader.width, xpmHeader.height,
new int[] { 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000 }, null);
bpp = 32;
}
final BufferedImage image = new BufferedImage(colorModel, raster, colorModel.isAlphaPremultiplied(), new Properties());
final DataBuffer dataBuffer = raster.getDataBuffer();
final StringBuilder row = new StringBuilder();
boolean hasMore = true;
for (int y = 0; y < xpmHeader.height; y++) {
row.setLength(0);
hasMore = parseNextString(cParser, row);
if (y < xpmHeader.height - 1 && !hasMore) {
throw new ImagingException("Parsing XPM file failed, " + "insufficient image rows in file");
}
final int rowOffset = y * xpmHeader.width;
for (int x = 0; x < xpmHeader.width; x++) {
final String index = row.substring(x * xpmHeader.numCharsPerPixel, (x + 1) * xpmHeader.numCharsPerPixel);
final PaletteEntry paletteEntry = xpmHeader.palette.get(index);
if (paletteEntry == null) {
throw new ImagingException("No palette entry was defined " + "for " + index);
}
if (bpp <= 16) {
dataBuffer.setElem(rowOffset + x, paletteEntry.index);
} else {
dataBuffer.setElem(rowOffset + x, paletteEntry.getBestArgb());
}
}
}
while (hasMore) {
row.setLength(0);
hasMore = parseNextString(cParser, row);
}
final String token = cParser.nextToken();
if (!";".equals(token)) {
throw new ImagingException("Last token wasn't ';'");
}
return image;
}