gt: 		byte[] palette = new byte[768];	
context: /*
   * Copyright (c) 1997 by Sun Microsystems, Inc.
   * 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
   * All rights reserved.
   *
   * This software is the confidential and proprietary information
   * of Sun Microsystems, Inc. ("Confidential Information").  You
   * shall not disclose such Confidential Information and shall use
   * it only in accordance with the terms of the license agreement
   * you entered into with Sun.
   */
  
  
  /**
   * Save an image in a PCX format.
   *
   * @author Max Hrabrov
   * @version	1.0
   */
  
  package com.sun.jimi.core.encoder.pcx;
  
  import java.lang.*;
  import java.io.*;
  import java.util.*;
  import java.awt.*;
  import java.awt.image.*;
  
  import com.sun.jimi.core.compat.*;
  import com.sun.jimi.core.Jimi;
  import com.sun.jimi.core.JimiException;
  import com.sun.jimi.core.JimiImage;
  import com.sun.jimi.core.util.LEDataOutputStream;
  
  
  public class PCXEncoder extends JimiEncoderBase  //  implements JimiEncoder
  {
      
  	OutputStream myOut;
  	RLEOutputStreamForPCX dataOut;
  	LEDataOutputStream LEDOut;
  	private int nState;	         // encoder return state
  
  	int nBitsPerPixel = 8;		 /** default to 8 bits per pixel **/
  	int nBitPlanes = 1;			 /** default to 1 bit plane (for a 256 color image) **/
  	int nBytesPerLine = 0;
  	int nPaletteType = 1;		 /** 1 or 2 , default to 1 (color/grayscale) **/
  	int nVersion = 5;			 
  
  	AdaptiveRasterImage myJimiImage;
  
  	protected int COLOR_MODEL = 0;    // 0 = IndexColorModel  1 = DirectColorModel 	
  		
  	
  	
  	public void initSpecificEncoder(OutputStream anOutputStream, AdaptiveRasterImage aJimiImage) throws JimiException
  	{
  			nState = 0;
  			myOut = anOutputStream;
  			if (aJimiImage.getColorModel() instanceof DirectColorModel) 
  			{
  				nBitPlanes = 3;				// store as a 24-bit image
  				COLOR_MODEL = 1;
  			}
  
  			/** RLE compression is theoretically an option, but in reality _always_ used **/
  
  			LEDOut = new LEDataOutputStream(new BufferedOutputStream(myOut));
  			dataOut = new RLEOutputStreamForPCX(LEDOut);
  	}	
  	
  	
      public void writePcxHeader(LEDataOutputStream aDataOutStream, AdaptiveRasterImage aJimiImage)
  	{
  	
  	    byte[] padding = new byte[54]; 
  		byte[] palette = new byte[48];
  		byte[] zero = new byte[2];
  		
  		int Xstart = 0;				// x of left upper corner
  		int Ystart = 0;				// y of left upper corner	
  		int Xend = 0;				// x of bottom right corner
  		int Yend = 0;				// y of bottom right corner		
  		
      	// first get some required information from JimiImage
  	  	
  		int nWidth = aJimiImage.getWidth();
  		int nHeight = aJimiImage.getHeight();
  		
  		int nBytesPerLine = nWidth;
  		
  		Xend = Xstart + nWidth - 1;
  		Yend = Xstart + nHeight - 1;
  		
  		
  		try
  		{
  
  		// now write the header for the PCX file
  
  			aDataOutStream.write(0x0A); 	  				// PCX id number	
  			aDataOutStream.write((byte)(nVersion));		    // version number
  			aDataOutStream.write((byte)(1));				// encoding format - RLE 
  			aDataOutStream.write((byte)(nBitsPerPixel));	// Bits per pixel 
  			aDataOutStream.writeShort(0);		    		// x of left upper corner
  			aDataOutStream.writeShort(0);		    		// y of left upper corner
  
  			aDataOutStream.writeShort(Xend);				// x of bottom right corner
  			aDataOutStream.writeShort(Yend);				// y of bottom right corner
  			aDataOutStream.writeShort(nWidth);				// horisontal res
  			aDataOutStream.writeShort(nHeight);				// vertical res
  			
  			/** an EGA palette is only used for 16 color images or worse. Larger (256 c) palettes
  			 are appended at the end of the PCX file.  You can always include a 
  			 16 color EGA Palette anyway, though, as long as the image is an IndexColorModel  **/
  
  			if (COLOR_MODEL == 0)  {
  				IndexColorModel icm = (IndexColorModel)aJimiImage.getColorModel();
  				palette = makePalette(icm, 16);			    // 16 Color EGA Palette 
  			}
  			aDataOutStream.write(palette);					// zero's if DirectColorModel
  
  			aDataOutStream.write(0x00);						// reserved - always 0
  			aDataOutStream.write((byte)(nBitPlanes));		// number of bit planes 
  			aDataOutStream.writeShort(nBytesPerLine);		// Bytes per Scan-line	
  			// palette type
  
  			aDataOutStream.writeShort(nPaletteType);		
  
  			/** the next 2 values are the screen rez at which the image was created.  JimiImage cannot currently 
  			provide this information, so the current screen size of the host computer is being stored.  **/
  
  			Toolkit MyToolkit = Toolkit.getDefaultToolkit();
  
  			aDataOutStream.writeShort(MyToolkit.getScreenSize().width);
  			aDataOutStream.writeShort(MyToolkit.getScreenSize().height);
  
  			// that's it for the header - just need to fill out the rest of the 128 byte space (54 bytes) with // 0's.
  
  			aDataOutStream.write(padding);	
  			aDataOutStream.flush();			
  		}		
  		catch (IOException e){
  			nState = ERROR;
  		}
  			
   	}
  	
  	public byte[] makePalette (IndexColorModel icm, int nColors) 
  	
  	/**  this method creates and writes a palette with nColors number of colors. It only gets called for
  	IndexColorModel images.  **/
  	
  	{
  
  		int paletteSize = nColors * 3;  
  		byte[] palette = new byte[paletteSize];
  
  		ByteArrayOutputStream localOut = new ByteArrayOutputStream(paletteSize); 
  		// output stream to write to palette byte array
  	
  		int count = icm.getMapSize();		
  				
  		byte[] red = new byte[count];
  		byte[] green = new byte[count];
  		byte[] blue = new byte[count];
  
  		int my_count;
  		
  		icm.getReds(red);
  		icm.getGreens(green);
  		icm.getBlues(blue);
  				
  		try
  		{
  			/** write out as many colors as are available as long as <= nColors
  			 otherwise write nColors colors.   **/
  
  			if (nColors < count){
  				my_count = nColors;
  			} else {
  				my_count = count;
  			}
  
  			for (int i = 0; i < my_count; i++)
  			{
  				localOut.write(red[i]);
  				localOut.write(green[i]);
  				localOut.write(blue[i]);
  			}
  
  			// fill the rest with 0's, up to nColors
  
  			if (nColors > count) {
  				for (int i = 0; i < nColors - my_count; ++i) {
  					localOut.write(0x00);
  					localOut.write(0x00);
  					localOut.write(0x00);
      			}	
  			}
  
  			// now write out to palette[] and return
  
  			palette = localOut.toByteArray();
  			localOut.close();
  			localOut = null;   					// deallocate
  		}
  		catch (IOException e)
  		{
  			nState = ERROR;
  		}			
  		return palette;
  	}
  
  
  	public void writePcxImage(RLEOutputStreamForPCX aDataOutStream, AdaptiveRasterImage aJimiImage) throws JimiException
  	{
  
     	int nWidth = aJimiImage.getWidth();
  	int nHeight = aJimiImage.getHeight();
  	nBytesPerLine = (nWidth + 1);  			  // RLE encoder will run from 0 to nWidth - 1
  				
  				
  	byte buffer[] = new byte[nBytesPerLine];	
  					
  	try {
  	
  			for (int i = 0; i < nHeight; i++)  {
  				if (COLOR_MODEL == 0)        // IndexColorModel
  				{		
  					/** If a palette is being used (all cases except 24 bit color or monochrome) 
  					get pixel value of JimiImage in the form R,G,B.   **/
  
  					aJimiImage.getChannel(0, i, buffer, 0);   // this is a row of pixels in the form we need.
  					aDataOutStream.write(buffer);
  				}
  				else  			/** DirectColorModel - 24 bit color **/
  				{
  					aJimiImage.setRGBDefault(true);
  					aJimiImage.getChannel(1, i, buffer, 0);
  					aDataOutStream.write(buffer);
  					aJimiImage.getChannel(2, i , buffer, 0);
  					aDataOutStream.write(buffer);
  					aJimiImage.getChannel(3, i, buffer, 0);
  					aDataOutStream.write(buffer);
  				}
  				setProgress((i * 100) / nHeight);
  			}
  		}
  		catch (IOException e) {
  			nState = ERROR;
  		}	
      }	
  	
  	
      public void writePcxFooter(LEDataOutputStream aDataOutStream, AdaptiveRasterImage aJimiImage)
  	{
  	/** if a VGA palette at the end is required, write it.  **/
  