package king.lib.util;

import java.awt.Image;
import java.awt.Toolkit;
import java.awt.image.MemoryImageSource;
import java.awt.image.PixelGrabber;
import java.io.ByteArrayInputStream; 
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.IOException;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;

/**
 * The image utility to convert images to a byte array and vice versa.  GZIPs the 
 * image to additionally reduce the size.
 *
 @author   Christoph Aschwanden
 @since    March 17, 2007
 */
public final class ImageUtil {

  /**
   * Default constructor without image.
   */
  private ImageUtil() {
    // prevents instantiation.
  }
    
  /**
   * Converts an image to a byte array. GZIPs the image to additionally reduce the size.
   
   @param image  The image to convert.
   @return  The byte array. 
   @throws IOException if something goes wrong.
   */
  public static byte[] imageToByteArray(Image imagethrows IOException {
    // get image size
    int width = image.getWidth(null);
    int height = image.getHeight(null);
    
    // store image data as raw int values
    try {
      int[] imageSource = new int[width * height];
      PixelGrabber pg = new PixelGrabber(image, 00, width, height, imageSource, 0, width);
      pg.grabPixels();
      
      // zip data
      ByteArrayOutputStream byteStream = new ByteArrayOutputStream()
      GZIPOutputStream zippedStream = new GZIPOutputStream(byteStream);
      ObjectOutputStream objectStream = new ObjectOutputStream(zippedStream);
      objectStream.writeShort(width);
      objectStream.writeShort(height);
      objectStream.writeObject(imageSource);
      objectStream.flush();
      objectStream.close();
      return byteStream.toByteArray();
    }
    catch (Exception e) {
      throw new IOException("Error storing image in object: " + e);
    }
  }
  
  /**
   * Converts a byte array to an image that has previously been converted with imageToByteArray(Image image).
   
   @param data  The image.
   @return  The image.
   */
  public static Image byteArrayToImage(byte[] data) {
    try {
      // unzip data
      ByteArrayInputStream byteStream = new ByteArrayInputStream(data);
      GZIPInputStream zippedStream = new GZIPInputStream(byteStream);
      ObjectInputStream objectStream = new ObjectInputStream(zippedStream);
      int width = objectStream.readShort();
      int height = objectStream.readShort();
      int[] imageSource = (int[])objectStream.readObject();
      objectStream.close();

      // create image
      MemoryImageSource mis = new MemoryImageSource(width, height, imageSource, 0, width);
      return Toolkit.getDefaultToolkit().createImage(mis);    
    }
    catch (Exception e) {
      return null;
    }
  }
}