Pure Java PNG loader, with efficient & clear code...

probably a good solution but too late now ! I have already started to work on my own, inded the main interrest is learning but it will be also cool to have a full pure java PNG, also deflating inflating seems to not requiere tones of code, I’ve fund a nice flash source code that may help me in this work.

the RGBArrayImage have really nothing fancy, I just did not want fullfill my first post :

import java.awt.image.*;
import java.awt.*;

/**
 * Image RGB dont les pixels peuvents etre lues et modifiés via un tableau d'entier
 */
public class RGBArrayImage 
{
	private static boolean warningMIS=false;
	private int width;
	private int height;
	private int pixels[];
	private Image image;
	private MemoryImageSource mis;

    public RGBArrayImage(int width,int height,boolean alpha) 
    {
    	this.width=width;
    	this.height=height;
    	this.image=null;
    	this.mis=null;
    	this.pixels=null;
    	
    	try
    	{
    		Class c = Class.forName("java.awt.image.BufferedImage");
    		PixelsBufferBI pbi=new PixelsBufferBI(this.width,this.height,alpha);
    		this.pixels=pbi.getPixels();
    		this.image=pbi.getImage();
    	}
    	catch(ClassNotFoundException e) //Old JVM ?
    	{
    		if(!warningMIS)
    			Log.log("Old JVM => using MemoryImageSource");
    		warningMIS=true;
    		this.pixels=new int[this.width*this.height];
    		
    		if(alpha)
    			this.mis=new MemoryImageSource(this.width,this.height,new DirectColorModel(32, 0xff0000, 0xff00, 0xff,0xFF000000), this.pixels, 0, this.width);
    		else
    			this.mis=new MemoryImageSource(this.width,this.height,new DirectColorModel(24, 0xff0000, 0xff00, 0xff), this.pixels, 0, this.width);
    			
    		this.mis.setAnimated(true);
			this.mis.setFullBufferUpdates(true);
			this.image = Toolkit.getDefaultToolkit().createImage(this.mis);	
    	}
    }
    
    public void updateMIS()
    {
    	if(this.isMIS())
    		this.mis.newPixels();
    }
    
    public boolean isMIS()
    {
    	return (this.mis!=null);
    }
    
    public RGBArrayImage(int width,int height) 
    {
    	this(width,height,false);
    }
    
    public Image getImage()
    {
    	return this.image;
    }
    
    public int[] getPixels()
    {
    	return this.pixels;
    }    
    
    
    public RGBArrayImage(Image image)
    {
    	this(image.getWidth(null),image.getHeight(null));
    	PixelGrabber pg=new PixelGrabber(image,0,0,this.width,this.height,this.pixels,0,this.width);
    	try
    	{
    		pg.grabPixels();
    	}
    	catch(InterruptedException ie)
    	{
    		Log.log(ie);
    	}
    }
    
    
    class PixelsBufferBI
	{
		private Image image;
		private int pixels[];
		public PixelsBufferBI(int width,int height,boolean alpha)
		{	
				BufferedImage BIImage;
				if(alpha)
					BIImage = new BufferedImage(width, height,BufferedImage.TYPE_INT_ARGB);
				else
					BIImage = new BufferedImage(width, height,BufferedImage.TYPE_INT_RGB);
				pixels=((DataBufferInt)(BIImage.getRaster().getDataBuffer())).getData(); 
				image=(Image)BIImage;			
		}
		public Image getImage()
		{
			return this.image;
		}
		public int[] getPixels()
		{
			return this.pixels;
		}
	}
    
}

and interresting stuff would be to make it handle other kind of image implementation by ading inner classes and it will chose the best one

little improvment :

  • add of grey & grey alpha
  • replacement of skip by skipFully

and if anyone got some spare time : you’re welcome to make improvment and post them :slight_smile: (here are the spec I’ve used for PNG http://www.w3.org/TR/PNG/#4Concepts.EncodingFiltering )

Missing are :
8 bit Palette Image (should be the next that I’ll do)
Interlace method
16 bit color images ( does it is really requiered ? )
Extended chunks ( boring…)
Custom deflater ( we will see … )

I began a pure java deflater but specs are really unclear (RFC 1951) and I did not got a lot of time to work on it, so it wont be finished soon, but I ll keep this thread up if…