/* BEGIN_HEADER                                              Java TreeView
*
* $Author: alokito $
* $RCSfile: PpmWriter.java,v $
* $Revision: 1.4 $
* $Date: 2004-12-21 03:28:13 $
* $Name:  $
*
* This file is part of Java TreeView
* Copyright (C) 2001-2014 Alok Saldanha, All Rights Reserved. Modifications Copyright (C) Lawrence Berkeley Lab.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* END_HEADER 
*/
package edu.stanford.genetics.treeview;

import java.awt.Image;
import java.awt.image.PixelGrabber;
import java.io.IOException;
import java.io.OutputStream;

/**
* This is a completely generic and self sufficient static class that writes images to PPM format files.
*/
public class PpmWriter {
	
	public static void writePpm(Image image, OutputStream out) throws java.io.IOException {
		int pixels[][] = getPixels(image);
		int width = pixels.length;
		int height = pixels[0].length;
		//# Each PPM image consists of the following: 
		//# 1) A "magic number" for identifying the file type. A ppm image's magic number is the two characters "P6". 
		out.write(("P6").getBytes());
		//# 2) Whitespace (blanks, TABs, CRs, LFs). 
		out.write(("\n").getBytes());
		//	# 3) A width, formatted as ASCII characters in decimal. 
		out.write(("" + width).getBytes());
		//# 4) Whitespace. 
		out.write(("\n").getBytes());
		//# 5) A height, again in ASCII decimal. 
		out.write(("" + height).getBytes());
		//# 6) Whitespace. 
		out.write(("\n").getBytes());
		//# 7) The maximum color value (Maxval), again in ASCII decimal.  Must be less than 65536. 
		out.write(("255").getBytes());
		//# 8) Newline or other single whitespace character. 
		out.write(("\n").getBytes());
		//# 9) A raster of Height rows, in order from top to bottom.  Each row consists of Width pixels, in order from left # to right.  Each pixel is a triplet of red, green, and blue samples, in that order.  Each sample is represented in pure binary by either 1 or 2 bytes.  If the Maxval is less than 256, it is 1 byte.  Otherwise, it is 2 bytes.  The most significant byte is first. 
		for (int row = 0; row < height; row++) {
			for (int col = 0; col < width; col++) {
				printColor(out, pixels[col][row]);
			}
		}
	}
	public static void printColor(OutputStream out, int val) throws java.io.IOException {
		int blue = val;
		int green = val >> 8;
		int red = val >> 16;
		
		
		out.write(red);
		out.write(green);
		out.write(blue);
	}
	
	/**
	* Snag the pixels from an image.
	*
	* Copied verbatim from com.gurge.amd.TestQuantize by  <a href="http://www.gurge.com/amd/">Adam Doppelt</a>
	*/
	public static int[][] getPixels(Image image) throws IOException {
		int w = image.getWidth(null);
		int h = image.getHeight(null);        
		int pix[] = new int[w * h];
		PixelGrabber grabber = new PixelGrabber(image, 0, 0, w, h, pix, 0, w);
		
		try {
			if (grabber.grabPixels() != true) {
				throw new IOException("Grabber returned false: " +
				grabber.status());
			}
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		
		int pixels[][] = new int[w][h];
		for (int x = w; x-- > 0; ) {
			for (int y = h; y-- > 0; ) {
				pixels[x][y] = pix[y * w + x];
			}
		}
		
		return pixels;
	}
}
