private BufferedImage readXpmImage()

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;
    }