@Override
    public void writeImage(final BufferedImage src, final OutputStream os, final XpmImagingParameters params) throws ImagingException, IOException {
        final PaletteFactory paletteFactory = new PaletteFactory();
        final boolean hasTransparency = paletteFactory.hasTransparency(src, 1);
        SimplePalette palette = null;
        int maxColors = WRITE_PALETTE.length;
        int charsPerPixel = 1;
        while (palette == null) {
            palette = paletteFactory.makeExactRgbPaletteSimple(src, hasTransparency ? maxColors - 1 : maxColors);

            // leave the loop if numbers would go beyond Integer.MAX_VALUE to avoid infinite loops
            // test every operation from below if it would increase an int value beyond Integer.MAX_VALUE
            final long nextMaxColors = maxColors * WRITE_PALETTE.length;
            final long nextCharsPerPixel = charsPerPixel + 1;
            if (nextMaxColors > Integer.MAX_VALUE) {
                throw new ImagingException("Xpm: Can't write images with more than Integer.MAX_VALUE colors.");
            }
            if (nextCharsPerPixel > Integer.MAX_VALUE) {
                throw new ImagingException("Xpm: Can't write images with more than Integer.MAX_VALUE chars per pixel.");
            }
            // the code above makes sure that we never go beyond Integer.MAX_VALUE here
            if (palette == null) {
                maxColors *= WRITE_PALETTE.length;
                charsPerPixel++;
            }
        }
        int colors = palette.length();
        if (hasTransparency) {
            ++colors;
        }

        String line = "/* XPM */\n";
        os.write(line.getBytes(StandardCharsets.US_ASCII));
        line = "static char *" + randomName() + "[] = {\n";
        os.write(line.getBytes(StandardCharsets.US_ASCII));
        line = "\"" + src.getWidth() + " " + src.getHeight() + " " + colors + " " + charsPerPixel + "\",\n";
        os.write(line.getBytes(StandardCharsets.US_ASCII));

        for (int i = 0; i < colors; i++) {
            final String color;
            if (i < palette.length()) {
                color = toColor(palette.getEntry(i));
            } else {
                color = "None";
            }
            line = "\"" + pixelsForIndex(i, charsPerPixel) + " c " + color + "\",\n";
            os.write(line.getBytes(StandardCharsets.US_ASCII));
        }

        String separator = "";
        for (int y = 0; y < src.getHeight(); y++) {
            os.write(separator.getBytes(StandardCharsets.US_ASCII));
            separator = ",\n";
            line = "\"";
            os.write(line.getBytes(StandardCharsets.US_ASCII));
            for (int x = 0; x < src.getWidth(); x++) {
                final int argb = src.getRGB(x, y);
                if ((argb & 0xff000000) == 0) {
                    line = pixelsForIndex(palette.length(), charsPerPixel);
                } else {
                    line = pixelsForIndex(palette.getPaletteIndex(0xffffff & argb), charsPerPixel);
                }
                os.write(line.getBytes(StandardCharsets.US_ASCII));
            }
            line = "\"";
            os.write(line.getBytes(StandardCharsets.US_ASCII));
        }

        line = "\n};\n";
        os.write(line.getBytes(StandardCharsets.US_ASCII));
    }
Constructs a new instance with the big-endian byte order.
src/main/java/org/apache/commons/imaging/formats/xpm/XpmImageParser.java