
import java.awt.*;
import java.io.*;
import java.awt.*;
import java.awt.image.*;
import java.awt.color.*;
import java.util.*;
import javax.swing.*;

public class RGBImageFactory implements ImageObserver{

   public static void  main(String[] args){
      RGBImageFactory ifact = new RGBImageFactory();
      if(args.length <1) {
         System.out.println("Enter a valid image file name");
         System.exit(0);
      }
      ifact.createRGBBufferedImage(args[0]);
   }

   public Image readImage(String imageName){
       Image image = Toolkit.getDefaultToolkit().getImage(imageName);
       MediaTracker imageTracker = new MediaTracker(new JPanel());
       imageTracker.addImage(image, 0);
       try{
        imageTracker.waitForID(0);
       }catch(InterruptedException e){ return null;}
       return image;
    }

   public boolean imageUpdate(Image img,
                             int infoflags,
                             int x,
                             int y,
                             int width,
                             int height){

       if((infoflags & ImageObserver.ERROR) != 0){
          System.out.println("ERROR in image loading or drawing");
          return false;
       }

       if((infoflags & (ImageObserver.FRAMEBITS | ImageObserver.ALLBITS))!= 0) {
           return false;
       }
       return true;
   }


   public int[] fetchPixels(Image image, int width, int height){
      int pixMap[] = new int[width*height];
      PixelGrabber pg = new PixelGrabber(image, 0,0,width,height, pixMap, 0, width);
      try {
	   pg.grabPixels();
      } catch (InterruptedException e){return null;}
      if((pg.status()  & ImageObserver.ABORT)!=0){
          return null;
      }
      return pixMap;
   }

   public byte[] extractData(int[] pixmap, int numbands) {
      byte data[] = new byte[pixmap.length*numbands];

      for(int i=0;i<pixmap.length;i++){
          int pixel = pixmap[i];
          byte a = (byte)((pixel >> 24) & 0xff);
          byte r  = (byte)((pixel >> 16) & 0xff);
	    byte g = (byte)((pixel >>  8) & 0xff);
	    byte b = (byte)((pixel      ) & 0xff);

          if(numbands == 4){
            data[i*numbands+0] = r;
            data[i*numbands+1] = g;
            data[i*numbands+2]= b;
            data[i*numbands+3] = a;
          } else {
            data[i*numbands+0] = r;
            data[i*numbands+1] = g;
            data[i*numbands+2]= b;
          }
      }
      return data;
   }
   public static void displayImage(BufferedImage img){
       JFrame fr = new JFrame();
       ImagePanel pan = new ImagePanel(img);
       pan.setSize(256,256);
       fr.getContentPane().add(pan);
       fr.pack();
       fr.setSize(256,256);
       fr.show();
   }

   public void createRGBBufferedImage(String filename) {
      Image awtImage = readImage(filename);
      int imageWidth = awtImage.getWidth(this);
      int imageHeight = awtImage.getHeight(this);
      int[] pix = fetchPixels(awtImage, imageWidth, imageHeight);
      byte[] data = extractData(pix, 4);
      BufferedImage image = createInterleavedRGBImage(imageWidth, imageHeight, 8, data,true);
      displayImage(image);
   }


   public static BufferedImage createInterleavedRGBImage(int imageWidth,
                                                          int imageHeight,
                                                          int imageDepth,
                                                          byte data[],
                                                          boolean hasAlpha){
      int pixelStride,transparency ;
      if(hasAlpha) {
         pixelStride = 4;
         transparency = Transparency.BITMASK;
      }
      else {
         pixelStride = 3;
         transparency = Transparency.OPAQUE;
      }
      int[] numBits = new int[pixelStride];
      int[] bandoffsets = new int[pixelStride];

      for(int i=0;i<pixelStride;i++){
          numBits[i] = imageDepth;
          bandoffsets[i] =i;
      }

      ComponentColorModel ccm = new ComponentColorModel(
                          ColorSpace.getInstance(ColorSpace.CS_sRGB),
                          numBits,
                          hasAlpha,
                          false, //Alpha pre-multiplied
                          transparency,
                          DataBuffer.TYPE_BYTE);
      PixelInterleavedSampleModel csm = new PixelInterleavedSampleModel(
                          DataBuffer.TYPE_BYTE,
                          imageWidth, imageHeight,
                          pixelStride,   //Pixel stride
                          imageWidth*pixelStride, // Scanline stride
                          bandoffsets);

      DataBuffer dataBuf = new DataBufferByte(data, imageWidth*imageHeight*pixelStride);
      WritableRaster wr = Raster.createWritableRaster(csm, dataBuf, new Point(0,0));
      Hashtable ht = new Hashtable();
      ht.put("owner", "Lawrence Rodrigues");
      return  new BufferedImage(ccm, wr, false, ht);
   }
 
    static class ImagePanel extends JComponent {
      protected BufferedImage image;
      public ImagePanel(){}
      public ImagePanel(BufferedImage img){ image = img;}

      public void setImage(BufferedImage img){ image = img; }

      public void paintComponent(Graphics g){
         Rectangle rect = this.getBounds();
         if(image != null) {
            g.drawImage(image, 0,0,rect.width, rect.height, this);
         }
      }
   }
}