/*
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 * 
 *       http://www.apache.org/licenses/LICENSE-2.0
 * 
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *  under the License.
 */

package org.apache.commons.imaging.formats.xpm;

import java.awt.Dimension;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.awt.image.DataBuffer;
import java.awt.image.DirectColorModel;
import java.awt.image.IndexColorModel;
import java.awt.image.WritableRaster;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Properties;
import java.util.UUID;

import org.apache.commons.imaging.ImageFormat;
import org.apache.commons.imaging.ImageInfo;
import org.apache.commons.imaging.ImageParser;
import org.apache.commons.imaging.ImageReadException;
import org.apache.commons.imaging.ImageWriteException;
import org.apache.commons.imaging.common.BasicCParser;
import org.apache.commons.imaging.common.IImageMetadata;
import org.apache.commons.imaging.common.bytesource.ByteSource;
import org.apache.commons.imaging.palette.PaletteFactory;
import org.apache.commons.imaging.palette.SimplePalette;
import org.apache.commons.imaging.util.Debug;

public class XpmImageParser extends ImageParser
{
    private static Map<String, Integer> colorNames = null;

    public XpmImageParser()
    {
    }

    private synchronized static boolean loadColorNames()
    {
        if (colorNames != null)
            return true;

        BufferedReader reader = null;
        try
        {
            InputStream rgbTxtStream = XpmImageParser.class.getResourceAsStream(
                    "rgb.txt");
            if (rgbTxtStream == null) {
                return false;
            }
            reader = new BufferedReader(new InputStreamReader(rgbTxtStream,
                    "US-ASCII"));
            Map<String, Integer> colors = new HashMap<String, Integer>();
            String line;
            while ((line = reader.readLine()) != null)
            {
                if (line.startsWith("!"))
                    continue;
                try
                {
                    int red = Integer.parseInt(line.substring(0, 3).trim());
                    int green = Integer.parseInt(line.substring(4, 7).trim());
                    int blue = Integer.parseInt(line.substring(8, 11).trim());
                    String colorName = line.substring(11).trim();
                    colors.put(colorName, 0xff000000 |
                            (red << 16) | (green << 8) | blue);
                }
                catch (NumberFormatException nfe)
                {
                }
            }
            colorNames = colors;
            return true;
        }
        catch (IOException ioException)
        {
            Debug.debug(ioException);
            return false;
        }
        finally
        {
            try
            {
                if (reader != null)
                    reader.close();
            }
            catch (IOException ignored)
            {
            }
        }
    }

    @Override
    public String getName()
    {
        return "Xpm-Custom";
    }

    @Override
    public String getDefaultExtension()
    {
        return DEFAULT_EXTENSION;
    }
    private static final String DEFAULT_EXTENSION = ".xpm";
    private static final String ACCEPTED_EXTENSIONS[] =
    {
        ".xpm",
    };

    @Override
    protected String[] getAcceptedExtensions()
    {
        return ACCEPTED_EXTENSIONS;
    }

    @Override
    protected ImageFormat[] getAcceptedTypes()
    {
        return new ImageFormat[]
        {
            ImageFormat.IMAGE_FORMAT_XPM, //
        };
    }

    @Override
    public boolean embedICCProfile(File src, File dst, byte profile[])
    {
        return false;
    }

    @Override
    public IImageMetadata getMetadata(ByteSource byteSource, Map params)
            throws ImageReadException, IOException
    {
        return null;
    }

    @Override
    public ImageInfo getImageInfo(ByteSource byteSource, Map params)
            throws ImageReadException, IOException
    {
        XpmHeader xpmHeader = readXpmHeader(byteSource);
        boolean isTransparent = false;
        int colorType = ImageInfo.COLOR_TYPE_BW;
        for (Iterator<Map.Entry<Object,PaletteEntry>> it = xpmHeader.palette.entrySet().iterator(); it.hasNext();)
        {
            Map.Entry<Object, PaletteEntry> entry = it.next();
            PaletteEntry paletteEntry = entry.getValue();
            if ((paletteEntry.getBestARGB() & 0xff000000) != 0xff000000)
                isTransparent = true;
            if (paletteEntry.haveColor)
                colorType = ImageInfo.COLOR_TYPE_RGB;
            else if (colorType != ImageInfo.COLOR_TYPE_RGB &&
                    (paletteEntry.haveGray || paletteEntry.haveGray4Level))
                colorType = ImageInfo.COLOR_TYPE_GRAYSCALE;
        }
        return new ImageInfo("XPM version 3", xpmHeader.numCharsPerPixel * 8,
                new ArrayList<String>(), ImageFormat.IMAGE_FORMAT_XPM,
                "X PixMap",
                xpmHeader.height, "image/x-xpixmap", 1,
                0, 0, 0, 0,
                xpmHeader.width, false, isTransparent, true,
                colorType,
                ImageInfo.COMPRESSION_ALGORITHM_NONE);
    }

    @Override
    public Dimension getImageSize(ByteSource byteSource,
            Map params)
            throws ImageReadException, IOException
    {
        XpmHeader xpmHeader = readXpmHeader(byteSource);
        return new Dimension(xpmHeader.width, xpmHeader.height);
    }

    @Override
    public byte[] getICCProfileBytes(ByteSource byteSource,
            Map params)
            throws ImageReadException, IOException
    {
        return null;
    }

    private static class XpmHeader
    {
        int width;
        int height;
        int numColors;
        int numCharsPerPixel;
        int xHotSpot = -1;
        int yHotSpot = -1;
        boolean xpmExt;
        
        Map<Object, PaletteEntry> palette = new HashMap<Object, PaletteEntry>();

        public XpmHeader(int width, int height, int numColors,
                int numCharsPerPixel, int xHotSpot, int yHotSpot,
                boolean xpmExt)
        {
            this.width = width;
            this.height = height;
            this.numColors = numColors;
            this.numCharsPerPixel = numCharsPerPixel;
            this.xHotSpot = xHotSpot;
            this.yHotSpot = yHotSpot;
            this.xpmExt = xpmExt;
        }

        public void dump(PrintWriter pw)
        {
            pw.println("XpmHeader");
            pw.println("Width: " + width);
            pw.println("Height: " + height);
            pw.println("NumColors: " + numColors);
            pw.println("NumCharsPerPixel: " + numCharsPerPixel);
            if (xHotSpot != -1 && yHotSpot != -1)
            {
                pw.println("X hotspot: " + xHotSpot);
                pw.println("Y hotspot: " + yHotSpot);
            }
            pw.println("XpmExt: " + xpmExt);
        }
    }

    private static class PaletteEntry
    {
        int index;
        boolean haveColor = false;
        int colorArgb;
        boolean haveGray = false;
        int grayArgb;
        boolean haveGray4Level = false;
        int gray4LevelArgb;
        boolean haveMono = false;
        int monoArgb;
        String symbolicName = null;

        int getBestARGB()
        {
            if (haveColor)
                return colorArgb;
            else if (haveGray)
                return grayArgb;
            else if (haveGray4Level)
                return gray4LevelArgb;
            else if (haveMono)
                return monoArgb;
            else
                return 0x00000000;
        }
    }

    private static class XpmParseResult
    {
        XpmHeader xpmHeader;
        BasicCParser cParser;
    }

    private XpmHeader readXpmHeader(ByteSource byteSource)
            throws ImageReadException, IOException
    {
        XpmParseResult result = parseXpmHeader(byteSource);
        return result.xpmHeader;
    }

    private XpmParseResult parseXpmHeader(ByteSource byteSource)
            throws ImageReadException, IOException
    {
        InputStream is = null;
        try
        {
            is = byteSource.getInputStream();
            StringBuilder firstComment = new StringBuilder();
            ByteArrayOutputStream preprocessedFile = BasicCParser.preprocess(
                    is, firstComment, null);
            if (!firstComment.toString().trim().equals("XPM"))
                throw new ImageReadException("Parsing XPM file failed, " +
                        "signature isn't '/* XPM */'");

            XpmParseResult xpmParseResult = new XpmParseResult();
            xpmParseResult.cParser = new BasicCParser(
                    new ByteArrayInputStream(preprocessedFile.toByteArray()));
            xpmParseResult.xpmHeader = parseXpmHeader(xpmParseResult.cParser);
            return xpmParseResult;
        }
        finally
        {
            try
            {
                if (is != null)
                    is.close();
            }
            catch (IOException ignored)
            {
            }
        }
    }

    private boolean parseNextString(BasicCParser cParser, StringBuilder stringBuilder)
            throws IOException, ImageReadException
    {
        stringBuilder.setLength(0);
        String token = cParser.nextToken();
        if (token.charAt(0) != '"')
            throw new ImageReadException("Parsing XPM file failed, " +
                    "no string found where expected");
        BasicCParser.unescapeString(stringBuilder, token);
        for (token = cParser.nextToken(); token.charAt(0) == '"'; token = cParser.nextToken())
        {
            BasicCParser.unescapeString(stringBuilder, token);
        }
        if (token.equals(","))
            return true;
        else if (token.equals("}"))
            return false;
        else
            throw new ImageReadException("Parsing XPM file failed, " +
                    "no ',' or '}' found where expected");
    }

    private XpmHeader parseXpmValuesSection(String row)
            throws ImageReadException
    {
        String[] tokens = BasicCParser.tokenizeRow(row);
        if (tokens.length < 4 && tokens.length > 7)
            throw new ImageReadException("Parsing XPM file failed, " +
                    "<Values> section has incorrect tokens");
        try
        {
            int width = Integer.parseInt(tokens[0]);
            int height = Integer.parseInt(tokens[1]);
            int numColors = Integer.parseInt(tokens[2]);
            int numCharsPerPixel = Integer.parseInt(tokens[3]);
            int xHotSpot = -1;
            int yHotSpot = -1;
            boolean xpmExt = false;
            if (tokens.length >= 6)
            {
                xHotSpot = Integer.parseInt(tokens[4]);
                yHotSpot = Integer.parseInt(tokens[5]);
            }
            if (tokens.length == 5 || tokens.length == 7)
            {
                if (tokens[tokens.length-1].equals("XPMEXT"))
                    xpmExt = true;
                else
                    throw new ImageReadException("Parsing XPM file failed, " +
                            "can't parse <Values> section XPMEXT");
            }
            return new XpmHeader(width, height, numColors, numCharsPerPixel,
                    xHotSpot, yHotSpot, xpmExt);
        }
        catch (NumberFormatException nfe)
        {
            throw new ImageReadException("Parsing XPM file failed, " +
                    "error parsing <Values> section", nfe);
        }
    }

    private int parseColor(String color)
            throws ImageReadException
    {
        if (color.charAt(0) == '#')
        {
            color = color.substring(1);
            if (color.length() == 3)
            {
                int red = Integer.parseInt(color.substring(0, 1), 16);
                int green = Integer.parseInt(color.substring(1, 2), 16);
                int blue = Integer.parseInt(color.substring(2, 3), 16);
                return 0xff000000 | (red << 20) | (green << 12) | (blue << 4);
            }
            else if (color.length() == 6)
                return 0xff000000 | Integer.parseInt(color, 16);
            else if (color.length() == 9)
            {
                int red = Integer.parseInt(color.substring(0, 1), 16);
                int green = Integer.parseInt(color.substring(3, 4), 16);
                int blue = Integer.parseInt(color.substring(6, 7), 16);
                return 0xff000000 | (red << 16) | (green << 8) | blue;
            }
            else if (color.length() == 12)
            {
                int red = Integer.parseInt(color.substring(0, 1), 16);
                int green = Integer.parseInt(color.substring(4, 5), 16);
                int blue = Integer.parseInt(color.substring(8, 9), 16);
                return 0xff000000 | (red << 16) | (green << 8) | blue;
            }
            else
                return 0x00000000;
        }
        else if (color.charAt(0) == '%')
        {
            throw new ImageReadException("HSV colors are not implemented " +
                    "even in the XPM specification!");
        }
        else if (color.equals("None"))
            return 0x00000000;
        else
        {
            if (!loadColorNames())
                return 0x00000000;
            if (colorNames.containsKey(color))
                return (colorNames.get(color)).intValue();
            else
                return 0x00000000;
        }
    }

    private void parsePaletteEntries(XpmHeader xpmHeader, BasicCParser cParser)
            throws IOException, ImageReadException
    {
        StringBuilder row = new StringBuilder();
        for (int i = 0; i < xpmHeader.numColors; i++)
        {
            row.setLength(0);
            boolean hasMore = parseNextString(cParser, row);
            if (!hasMore)
                throw new ImageReadException("Parsing XPM file failed, " +
                        "file ended while reading palette");
            String name = row.substring(0, xpmHeader.numCharsPerPixel);
            String[] tokens = BasicCParser.tokenizeRow(
                    row.substring(xpmHeader.numCharsPerPixel));
            PaletteEntry paletteEntry = new PaletteEntry();
            paletteEntry.index = i;
            int previousKeyIndex = Integer.MIN_VALUE;
            StringBuilder colorBuffer = new StringBuilder();
            for (int j = 0; j < tokens.length; j++)
            {
                String token = tokens[j];
                boolean isKey = false;
                if (previousKeyIndex < (j - 1))
                {
                    if (token.equals("m") || token.equals("g4") ||
                            token.equals("g") || token.equals("c") ||
                            token.equals("s"))
                        isKey = true;
                }
                if (isKey)
                {
                    if (previousKeyIndex >= 0)
                    {
                        String key = tokens[previousKeyIndex];
                        String color = colorBuffer.toString();
                        colorBuffer.setLength(0);
                        if (key.equals("m"))
                        {
                            paletteEntry.monoArgb = parseColor(color);
                            paletteEntry.haveMono = true;
                        }
                        else if (key.equals("g4"))
                        {
                            paletteEntry.gray4LevelArgb = parseColor(color);
                            paletteEntry.haveGray4Level = true;
                        }
                        else if (key.equals("g"))
                        {
                            paletteEntry.grayArgb = parseColor(color);
                            paletteEntry.haveGray = true;
                        }
                        else if (key.equals("s"))
                        {
                            paletteEntry.symbolicName = color;
                            paletteEntry.colorArgb = parseColor(color);
                            paletteEntry.haveColor = true;
                        }
                        else if (key.equals("c"))
                        {
                            paletteEntry.colorArgb = parseColor(color);
                            paletteEntry.haveColor = true;
                        }
                    }
                    previousKeyIndex = j;
                }
                else
                {
                    if (previousKeyIndex < 0)
                        break;
                    if (colorBuffer.length() > 0)
                        colorBuffer.append(' ');
                    colorBuffer.append(token);
                }
            }
            if (previousKeyIndex >= 0 && colorBuffer.length() > 0)
            {
                String key = tokens[previousKeyIndex];
                String color = colorBuffer.toString();
                colorBuffer.setLength(0);
                if (key.equals("m"))
                {
                    paletteEntry.monoArgb = parseColor(color);
                    paletteEntry.haveMono = true;
                }
                else if (key.equals("g4"))
                {
                    paletteEntry.gray4LevelArgb = parseColor(color);
                    paletteEntry.haveGray4Level = true;
                }
                else if (key.equals("g"))
                {
                    paletteEntry.grayArgb = parseColor(color);
                    paletteEntry.haveGray = true;
                }
                else if (key.equals("s"))
                {
                    paletteEntry.symbolicName = color;
                    paletteEntry.colorArgb = parseColor(color);
                    paletteEntry.haveColor = true;
                }
                else if (key.equals("c"))
                {
                    paletteEntry.colorArgb = parseColor(color);
                    paletteEntry.haveColor = true;
                }
            }
            xpmHeader.palette.put(name, paletteEntry);
        }
    }

    private XpmHeader parseXpmHeader(BasicCParser cParser)
            throws ImageReadException, IOException
    {
        String name;
        String token;
        token = cParser.nextToken();
        if (token == null || !token.equals("static"))
            throw new ImageReadException("Parsing XPM file failed, no 'static' token");
        token = cParser.nextToken();
        if (token == null || !token.equals("char"))
            throw new ImageReadException("Parsing XPM file failed, no 'char' token");
        token = cParser.nextToken();
        if (token == null || !token.equals("*"))
            throw new ImageReadException("Parsing XPM file failed, no '*' token");
        name = cParser.nextToken();
        if (name == null)
            throw new ImageReadException("Parsing XPM file failed, no variable name");
        if (name.charAt(0) != '_' && !Character.isLetter(name.charAt(0)))
            throw new ImageReadException("Parsing XPM file failed, variable name " +
                    "doesn't start with letter or underscore");
        for (int i = 0; i < name.length(); i++)
        {
            char c = name.charAt(i);
            if (!Character.isLetterOrDigit(c) && c != '_')
                throw new ImageReadException("Parsing XPM file failed, variable name " +
                        "contains non-letter non-digit non-underscore");
        }
        token = cParser.nextToken();
        if (token == null || !token.equals("["))
            throw new ImageReadException("Parsing XPM file failed, no '[' token");
        token = cParser.nextToken();
        if (token == null || !token.equals("]"))
            throw new ImageReadException("Parsing XPM file failed, no ']' token");
        token = cParser.nextToken();
        if (token == null || !token.equals("="))
            throw new ImageReadException("Parsing XPM file failed, no '=' token");
        token = cParser.nextToken();
        if (token == null || !token.equals("{"))
            throw new ImageReadException("Parsing XPM file failed, no '{' token");

        StringBuilder row = new StringBuilder();
        boolean hasMore = parseNextString(cParser, row);
        if (!hasMore)
            throw new ImageReadException("Parsing XPM file failed, " +
                    "file too short");
        XpmHeader xpmHeader = parseXpmValuesSection(row.toString());
        parsePaletteEntries(xpmHeader, cParser);
        return xpmHeader;
    }

    private BufferedImage readXpmImage(XpmHeader xpmHeader, BasicCParser cParser)
            throws ImageReadException, IOException
    {
        ColorModel colorModel;
        WritableRaster raster;
        int bpp;
        if (xpmHeader.palette.size() <= (1 << 8))
        {
            int[] palette = new int[xpmHeader.palette.size()];
            for (Iterator<Map.Entry<Object,PaletteEntry>> it = xpmHeader.palette.entrySet().iterator(); it.hasNext();)
            {
                Map.Entry<Object, PaletteEntry> entry = it.next();
                PaletteEntry paletteEntry = entry.getValue();
                palette[paletteEntry.index] = paletteEntry.getBestARGB();
            }
            colorModel = new IndexColorModel(8, xpmHeader.palette.size(),
                    palette, 0, true, -1, DataBuffer.TYPE_BYTE);
            raster = WritableRaster.createInterleavedRaster(DataBuffer.TYPE_BYTE,
                    xpmHeader.width, xpmHeader.height, 1, null);
            bpp = 8;
        }
        else if (xpmHeader.palette.size() <= (1 << 16))
        {
            int[] palette = new int[xpmHeader.palette.size()];
            for (Iterator<Map.Entry<Object,PaletteEntry>> it = xpmHeader.palette.entrySet().iterator(); it.hasNext();)
            {
                Map.Entry<Object, PaletteEntry> entry = it.next();
                PaletteEntry paletteEntry = entry.getValue();
                palette[paletteEntry.index] = paletteEntry.getBestARGB();
            }
            colorModel = new IndexColorModel(16, xpmHeader.palette.size(),
                    palette, 0, true, -1, DataBuffer.TYPE_USHORT);
            raster = WritableRaster.createInterleavedRaster(DataBuffer.TYPE_USHORT,
                    xpmHeader.width, xpmHeader.height, 1, null);
            bpp = 16;
        }
        else
        {
            colorModel = new DirectColorModel(32, 0x00ff0000, 0x0000ff00,
                    0x000000ff, 0xff000000);
            raster = WritableRaster.createPackedRaster(DataBuffer.TYPE_INT,
                    xpmHeader.width, xpmHeader.height,
                    new int[]{0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000}, null);
            bpp = 32;
        }

        BufferedImage image = new BufferedImage(colorModel, raster,
                colorModel.isAlphaPremultiplied(), new Properties());
        DataBuffer dataBuffer = raster.getDataBuffer();
        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 ImageReadException("Parsing XPM file failed, " +
                        "insufficient image rows in file");
            int rowOffset = y*xpmHeader.width;
            for (int x = 0; x < xpmHeader.width; x++)
            {
                String index = row.substring(x*xpmHeader.numCharsPerPixel,
                        (x + 1)*xpmHeader.numCharsPerPixel);
                PaletteEntry paletteEntry = xpmHeader.palette.get(index);
                if (paletteEntry == null) {
                    throw new ImageReadException("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);
        }
        
        String token = cParser.nextToken();
        if (!token.equals(";"))
            throw new ImageReadException("Last token wasn't ';'");
        
        return image;
    }

    @Override
    public boolean dumpImageFile(PrintWriter pw, ByteSource byteSource)
            throws ImageReadException, IOException
    {
        readXpmHeader(byteSource).dump(pw);
        return true;
    }

    @Override
    public final BufferedImage getBufferedImage(ByteSource byteSource,
            Map params) throws ImageReadException, IOException
    {
        XpmParseResult result = parseXpmHeader(byteSource);
        return readXpmImage(result.xpmHeader, result.cParser);
    }

    private String randomName()
    {
        UUID uuid = UUID.randomUUID();
        StringBuilder stringBuilder = new StringBuilder("a");
        long bits = uuid.getMostSignificantBits();
        // Long.toHexString() breaks for very big numbers
        for (int i = 64 - 8; i >= 0; i -= 8)
            stringBuilder.append(Integer.toHexString((int)((bits >> i) & 0xff)));
        bits = uuid.getLeastSignificantBits();
        for (int i = 64 - 8; i >= 0; i -= 8)
            stringBuilder.append(Integer.toHexString((int)((bits >> i) & 0xff)));
        return stringBuilder.toString();
    }

    private String pixelsForIndex(int index, int charsPerPixel)
    {
        StringBuilder stringBuilder = new StringBuilder();
        int highestPower = 1;
        for (int i = 1; i < charsPerPixel; i++)
            highestPower *= writePalette.length;
        for (int i = 0; i < charsPerPixel; i++)
        {
            int multiple = index / highestPower;
            index  -= (multiple * highestPower);
            highestPower /= writePalette.length;
            stringBuilder.append(writePalette[multiple]);
        }
        return stringBuilder.toString();
    }

    private String toColor(int color)
    {
        String hex = Integer.toHexString(color);
        if (hex.length() < 6)
        {
            char zeroes[] = new char[6 - hex.length()];
            Arrays.fill(zeroes, '0');
            return "#" + new String(zeroes) + hex;
        }
        else
            return "#" + hex;
    }

    @Override
    public void writeImage(BufferedImage src, OutputStream os, Map params)
            throws ImageWriteException, IOException
    {
        // make copy of params; we'll clear keys as we consume them.
        params = (params == null) ? new HashMap() : new HashMap(params);

        // clear format key.
        if (params.containsKey(PARAM_KEY_FORMAT))
            params.remove(PARAM_KEY_FORMAT);

        if (params.size() > 0)
        {
            Object firstKey = params.keySet().iterator().next();
            throw new ImageWriteException("Unknown parameter: " + firstKey);
        }

        PaletteFactory paletteFactory = new PaletteFactory();
        boolean hasTransparency = false;
        if (paletteFactory.hasTransparency(src, 1))
            hasTransparency = true;
        SimplePalette palette = null;
        int maxColors = writePalette.length;
        int charsPerPixel = 1;
        for (; palette == null; )
        {
            palette = paletteFactory.makePaletteSimple(src,
                    hasTransparency ? maxColors - 1 : maxColors);
            if (palette == null)
            {
                maxColors *= writePalette.length;
                charsPerPixel++;
            }
        }
        int colors = palette.length();
        if (hasTransparency)
            ++colors;

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

        for (int i = 0; i < colors; i++)
        {
            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("US-ASCII"));
        }

        String separator = "";
        for (int y = 0; y < src.getHeight(); y++)
        {
            os.write(separator.getBytes("US-ASCII"));
            separator = ",\n";
            line = "\"";
            os.write(line.getBytes("US-ASCII"));
            for (int x = 0; x < src.getWidth(); x++)
            {
                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("US-ASCII"));
            }
            line = "\"";
            os.write(line.getBytes("US-ASCII"));
        }

        line = "\n};\n";
        os.write(line.getBytes("US-ASCII"));
    }

    private static final char writePalette[] = {
        ' ',
        '.',
        'X',
        'o',
        'O',
        '+',
        '@',
        '#',
        '$',
        '%',
        '&',
        '*',
        '=',
        '-',
        ';',
        ':',
        '>',
        ',',
        '<',
        '1',
        '2',
        '3',
        '4',
        '5',
        '6',
        '7',
        '8',
        '9',
        '0',
        'q',
        'w',
        'e',
        'r',
        't',
        'y',
        'u',
        'i',
        'p',
        'a',
        's',
        'd',
        'f',
        'g',
        'h',
        'j',
        'k',
        'l',
        'z',
        'x',
        'c',
        'v',
        'b',
        'n',
        'm',
        'M',
        'N',
        'B',
        'V',
        'C',
        'Z',
        'A',
        'S',
        'D',
        'F',
        'G',
        'H',
        'J',
        'K',
        'L',
        'P',
        'I',
        'U',
        'Y',
        'T',
        'R',
        'E',
        'W',
        'Q',
        '!',
        '~',
        '^',
        '/',
        '(',
        ')',
        '_',
        '`',
        '\'',
        ']',
        '[',
        '{',
        '}',
        '|',
    };

    /**
     * Extracts embedded XML metadata as XML string.
     * <p>
     *
     * @param byteSource
     *            File containing image data.
     * @param params
     *            Map of optional parameters, defined in SanselanConstants.
     * @return Xmp Xml as String, if present.  Otherwise, returns null.
     */
    @Override
    public String getXmpXml(ByteSource byteSource, Map params)
            throws ImageReadException, IOException
    {
        return null;
    }
}
