private BufferedImage readXbmImage()

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