Package org.lwjgl.util

Source Code of org.lwjgl.util.XPMFile

/*
* Copyright (c) 2002-2008 LWJGL Project
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
*   notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
*   notice, this list of conditions and the following disclaimer in the
*   documentation and/or other materials provided with the distribution.
*
* * Neither the name of 'LWJGL' nor the names of
*   its contributors may be used to endorse or promote products derived
*   from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.lwjgl.util;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.LineNumberReader;
import java.util.HashMap;
import java.util.StringTokenizer;

/**
* <p>
* NOTE: This simple XPM reader does not support extensions nor hotspots
* </p>
*
* @author Brian Matzon <brian@matzon.dk>
* @author Jos Hirth
* @version $Revision$
* $Id$
*/

public class XPMFile {

  /** Array of bytes (RGBA) */
  private byte bytes[];

  private static final int WIDTH = 0;

  private static final int HEIGHT = 1;

  private static final int NUMBER_OF_COLORS = 2;

  private static final int CHARACTERS_PER_PIXEL = 3;

  private static int[] format = new int[4];

  /*
   * Private constructor, use load(String filename)
   */
  private XPMFile() {
  }

  /**
   * Loads the XPM file
   *
   * @param file
   *            path to file
   * @return XPMFile loaded, or exception
   * @throws IOException
   *             If any IO exceptions occurs while reading file
   */
  public static XPMFile load(String file) throws IOException {
    return load(new FileInputStream(new File(file)));
  }

  /**
   * Loads the XPM file
   *
   * @param is
   *            InputStream to read file from
   * @return XPMFile loaded, or exception
   */
  public static XPMFile load(InputStream is) {
    XPMFile xFile = new XPMFile();
    xFile.readImage(is);
    return xFile;
  }

  /**
   * @return the height of the image.
   */
  public int getHeight() {
    return format[HEIGHT];
  }

  /**
   * @return the width of the image.
   */
  public int getWidth() {
    return format[WIDTH];
  }

  /**
   * @return The data of the image.
   */
  public byte[] getBytes() {
    return bytes;
  }

  /**
   * Read the image from the specified file.
   */
  private void readImage(InputStream is) {
    try {
      LineNumberReader reader = new LineNumberReader(
          new InputStreamReader(is));
      HashMap<String, Integer> colors = new HashMap<String, Integer>();

      format = parseFormat(nextLineOfInterest(reader));

      // setup color mapping
      for (int i = 0; i < format[NUMBER_OF_COLORS]; i++) {
        Object[] colorDefinition = parseColor(nextLineOfInterest(reader));
        colors.put((String)colorDefinition[0], (Integer)colorDefinition[1]);
      }

      // read actual image (convert to RGBA)
      bytes = new byte[format[WIDTH] * format[HEIGHT] * 4];
      for (int i = 0; i < format[HEIGHT]; i++) {
        parseImageLine(nextLineOfInterest(reader), format, colors, i);
      }
    } catch (Exception e) {
      e.printStackTrace();
      throw new IllegalArgumentException("Unable to parse XPM File");
    }
  }

  /**
   * Finds the next interesting line of text.
   *
   * @param reader
   *            The LineNumberReader to read from
   * @return The next interesting String (with stripped quotes)
   * @throws IOException
   *             If any IO exceptions occurs while reading file
   */
  private static String nextLineOfInterest(LineNumberReader reader)
      throws IOException {
    String ret;
    do {
      ret = reader.readLine();
    } while (!ret.startsWith("\""));
    // lacks sanity check
    return ret.substring(1, ret.lastIndexOf('\"'));
  }

  /**
   * Parses the format of the xpm file given a format string
   *
   * @param format
   *            String to parse
   * @return Array specifying width, height, colors, characters per pixel
   */
  private static int[] parseFormat(String format) {
    // format should look like this:
    // 16 16 122 2

    // tokenize it
    StringTokenizer st = new StringTokenizer(format);

    return new int[] { Integer.parseInt(st.nextToken()), /* width */
    Integer.parseInt(st.nextToken()), /* height */
    Integer.parseInt(st.nextToken()), /* colors */
    Integer.parseInt(st.nextToken()) /* chars per pixel */
    };
  }

  /**
   * Given a line defining a color/pixel, parses this into an array containing
   * a key and a color
   *
   * @param line
   *            Line to parse
   * @return Array containing a key (String) and a color (Integer)
   */
  private static Object[] parseColor(String line) {
    // line should look like this:
    // # c #0A0A0A

    // NOTE: will break if the color is something like "black" or "gray50"
    // etc (instead of #rrggbb).

    String key = line.substring(0, format[CHARACTERS_PER_PIXEL]);
    // since we always assume color as type we dont need to read it
    // String type = line.substring(format[CHARACTERS_PER_PIXEL] + 1,
    // format[CHARACTERS_PER_PIXEL] + 2);
    String color = line.substring(format[CHARACTERS_PER_PIXEL] + 4);

    // we always assume type is color, and supplied as #<r><g><b>
    return new Object[] { key, Integer.parseInt(color, 16) };
  }

  /**
   * Parses an Image line into its byte values
   *
   * @param line
   *            Line of chars to parse
   * @param format
   *            Format to expext it in
   * @param colors
   *            Colors to lookup
   * @param index
   *            current index into lines, we've reached
   */
  private void parseImageLine(String line, int[] format, HashMap<String, Integer> colors,
      int index) {
    // offset for next line
    int offset = index * 4 * format[WIDTH];

    // read <format[CHARACTERS_PER_PIXEL]> characters <format[WIDTH]> times,
    // each iteration equals one pixel
    for (int i = 0; i < format[WIDTH]; i++) {
      String key = line
          .substring(
              i * format[CHARACTERS_PER_PIXEL],
              (i * format[CHARACTERS_PER_PIXEL] + format[CHARACTERS_PER_PIXEL]));
      int color = colors.get(key);
      bytes[offset + (i * 4)] = (byte) ((color & 0x00ff0000) >> 16);
      bytes[offset + ((i * 4) + 1)] = (byte) ((color & 0x0000ff00) >> 8);
      bytes[offset + ((i * 4) + 2)] = (byte) ((color & 0x000000ff) >> 0); // looks
      // better
      // :)
      bytes[offset + ((i * 4) + 3)] = (byte) 0xff; // always 0xff alpha
    }
  }

  /**
   * @param args
   */
  public static void main(String[] args) {
    if (args.length != 1) {
      System.out.println("usage:\nXPMFile <file>");
    }

    try {
      String out = args[0].substring(0, args[0].indexOf(".")) + ".raw";
      XPMFile file = XPMFile.load(args[0]);
      BufferedOutputStream bos = new BufferedOutputStream(
          new FileOutputStream(new File(out)));
      bos.write(file.getBytes());
      bos.close();

      // showResult(file.getBytes());
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
  /*
  private static void showResult(byte[] bytes) {
    final BufferedImage i = new BufferedImage(16, 16, BufferedImage.TYPE_INT_ARGB);
    int c = 0;
    for (int y = 0; y < 16; y++) {
      for (int x = 0; x < 16; x++) {
        i.setRGB(x, y, (bytes[c] << 16) + (bytes[c + 1] << 8) + (bytes[c + 2] << 0) + (bytes[c + 3] << 24));//+(128<<24));//
        c += 4;
      }
    }

    final Frame frame = new Frame("XPM Result");
    frame.add(new Canvas() {

      public void paint(Graphics g) {
        g.drawImage(i, 0, 0, frame);
      }
    });

    frame.addWindowListener(new WindowAdapter() {

      public void windowClosing(WindowEvent e) {
        frame.dispose();
      }

    });

    frame.setSize(100, 100);
    frame.setVisible(true);
  }*/
}
TOP

Related Classes of org.lwjgl.util.XPMFile

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.