package uk.co.mmscomputing.imageio.ppm;
import java.io.IOException;
import java.nio.ByteOrder;
import java.util.Iterator;
import java.util.ArrayList;
import java.awt.image.*;
import javax.imageio.*;
import javax.imageio.spi.*;
import javax.imageio.stream.*;
import javax.imageio.metadata.*;
import uk.co.mmscomputing.image.operators.*;
public class PBMImageWriter extends ImageWriter implements PPMConstants{
protected PBMImageWriter(ImageWriterSpi originatingProvider){
super(originatingProvider);
}
public IIOMetadata convertImageMetadata(IIOMetadata inData, ImageTypeSpecifier imageType, ImageWriteParam param){
return null;
}
public IIOMetadata convertStreamMetadata(IIOMetadata inData,ImageWriteParam param){
return null;
}
public IIOMetadata getDefaultImageMetadata(ImageTypeSpecifier imageType,ImageWriteParam param){
return null;
}
public IIOMetadata getDefaultStreamMetadata(ImageWriteParam param){
return null;
}
public boolean canInsertImage(int imageIndex)throws IOException{
super.canInsertImage(imageIndex);
return (imageIndex==0); // can deal only with one image
}
public void pbm(ImageOutputStream out, BufferedImage image)throws IOException{
int width = image.getWidth();
int height = image.getHeight();
PixelGrabber grabber = new PixelGrabber(image, 0, 0, width, height, false);
try{
grabber.grabPixels();
}catch(InterruptedException e){
throw new IOException(getClass().getName()+".pbm: couldn't grab pixels from image !");
}
int bpl=((width%8)==0)?width>>3:(width+8)>>3; // bytes per line
// String header="P4\n"+(bpl<<3)+" "+height+"\n";
String header="P4\n"+width+" "+height+"\n";
out.write(header.getBytes());
WritableRaster raster=image.getRaster();
int k=0; byte b; int pixel;
byte[] bitmap = new byte[bpl*height];
for(int y=0;y<height;y++){
for(int x=0;(x<width)&&(k<bitmap.length);){
b=0; // all white
for(int bit=7;(bit>=0)&&(x<width);bit--){
pixel=raster.getSample(x++,y,0);
if(pixel==0){ b|=(1<<bit);} // if black set bit
}
bitmap[k++]=b;
}
}
out.write(bitmap);
}
public void write(IIOMetadata streamMetadata,IIOImage img,ImageWriteParam param)throws IOException{
ImageOutputStream out=(ImageOutputStream)getOutput();
if(!(img.getRenderedImage() instanceof BufferedImage)){
throw new IOException(getClass().getName()+"write: Can only write BufferedImage objects");
}
BufferedImage image=(BufferedImage)img.getRenderedImage();
switch(image.getType()){
case BufferedImage.TYPE_BYTE_BINARY: // 1, 2, 4 bit possible; expect 1 bit
break;
case BufferedImage.TYPE_BYTE_GRAY:
image=new Binarization().filter(image);
break;
default:
image=new GrayScale().filter(image);
image=new Binarization().filter(image);
break;
}
pbm(out,image);
}
public ImageWriteParam getDefaultWriteParam(){
return new ImageWriteParam(getLocale());
}
}