/* Implemented by Jauvane C. de Oliveira
   Feel free to send coments to me at jauvane@mcrlab.uottawa.ca

  -------------------------------------------------------------------------
           _/  _/    _/      Jauvane Cavalcante de Oliveira
          _/  _/   _/       University of Ottawa
         _/  _/  _/  _/_/  Electrical and Computer Engineering Department
        _/  _/ _/  _/     Multimedia Communications Research Laboratory
  _/   _/  _/_/   _/     Phone:+1(613)562-5800 Ext.6243/6248 / FAX:562-5175
  _/_/_/  _/      _/_/  Canada        http://www.mcrlab.uottawa.ca/~jauvane
  -------------------------------------------------------------------------
  |                   Bolsista CAPES - Brasilia/Brasil                    |
  -------------------------------------------------------------------------
*/
import java.awt.*;
import java.awt.image.*;
import java.applet.*;
import java.net.*;
import java.io.*;
import java.lang.Cloneable;

public class image extends Applet
{
	Image oImage;
	boolean bShowHistogram[]={true,true};
	Button bList[] = new Button[11];
	int iWidth, iHeight;
	PixelGrabber pelGrabber;
	int viPixel[], viOriginalPixel[];
	int viHistogram[] = new int[256];
	int iMaxHistogram = 0;
	MediaTracker mtTracker;

//	public image()
//	{
//		super(this, "ELG5378 Image Enhancement Algorithms");
//	}

	public void init()
	{
		int i,j;
		boolean bFlag=true;

		oImage = getImage(getDocumentBase(), getParameter("img"));
		mtTracker = new MediaTracker(this);
		mtTracker.addImage(oImage,0);
		try{
			mtTracker.waitForID(0);
		}catch(Exception e){};

		iWidth = oImage.getWidth(null);
		iHeight= oImage.getHeight(null);

		viPixel = new int[iWidth*iHeight];
		viOriginalPixel = new int[iWidth*iHeight];

		try{
			pelGrabber = new PixelGrabber(oImage, 0, 0, iWidth, iHeight, viOriginalPixel, 0, iWidth);
			pelGrabber.grabPixels();
		}catch(Exception e){};

		for(i=j=0; i<iWidth*iHeight; i++)
			viHistogram[(int)(.33*(0xff&(viPixel[i]>>16))+.56*(0xff&(viPixel[i]>>8))+.11*(0xff&viPixel[i]))]++;
		for(i=0; i<256; i++)
			if(viHistogram[i]>iMaxHistogram)
				iMaxHistogram = viHistogram[j=i];

		bList[0] = (Button) add(new Button("Original Image"));
		bList[1] = (Button) add(new Button("Contr. Stretch"));
		bList[2] = (Button) add(new Button("Noise Clipping"));
		bList[3] = (Button) add(new Button("Grey  Reversal"));
		bList[4] = (Button) add(new Button("Window Slicing"));
		bList[5] = (Button) add(new Button("Bit Extraction"));
		bList[6] = (Button) add(new Button("Bit    Removal"));
		bList[7] = (Button) add(new Button("Range Compress"));
		bList[8] = (Button) add(new Button("Add Brightness"));
		bList[9] = (Button) add(new Button("Toggle Histogr"));
		bList[10] =(Button) add(new Button("End  Processing"));

		System.out.println("Picture Size: "+iWidth+" x "+iHeight);
	}

	public boolean action(Event evtObj, Object objObject)
	{
		int i,j;

		if(evtObj.target instanceof Button)
		{
			if(evtObj.target==bList[0])		//	Return to Original Image
				oImage = createImage(new MemoryImageSource(iWidth, iHeight, viOriginalPixel, 0, iWidth));
			else if(evtObj.target==bList[1])	// Contrast Stretching
			{
				int iA,iB,iVa,iVb;
				float fAlfa, fBeta, fDelta;

				try{
					pelGrabber = new PixelGrabber(oImage, 0, 0, iWidth, iHeight, viPixel, 0, iWidth);
					pelGrabber.grabPixels();
				}catch(Exception e){};

				for(i=j=0; i<iWidth*iHeight; i++)
					viHistogram[(int)(.33*(0xff&(viPixel[i]>>16))+.56*(0xff&(viPixel[i]>>8))+.11*(0xff&viPixel[i]))]++;
				for(i=0; i<256; i++)
					if(viHistogram[i]>iMaxHistogram)
						j = iMaxHistogram = viHistogram[i];

				iA = (int) j/10;
				iB = (int) j*7/10;
				fAlfa = (float) 0.5;
				fBeta = (float) 0.7;
				fDelta= (float) 1.4;
				iVa = 0;
				iVb = 0;
				System.out.println("A="+iA+" B="+iB+" Alfa="+fAlfa+" Beta="+fBeta+" Delta="+fDelta);

				for(i=0;i< iWidth*iHeight; i++)
				{
					int iY, iI, iQ, isR, isG, isB;

					isR = 0xff&(viPixel[i]>>16);
					isG = 0xff&(viPixel[i]>>8);
					isB = 0xff& viPixel[i];

					iY=(int)(.299*isR +  .587*isG +.114*isB);
					iI=(int)(.596*isR - .2746*isG -.322*isB);
					iQ=(int)(.211*isR -.52366*isG -.312*isB);

					if(iY<iA)
						iY=(int)(iY*fAlfa);
					else	if(iY<iB)
						iY=(int)(fBeta*(iY-iA)+iVa);
					else
						iY=(int)(fDelta*(iY-iB)+iVb);

					isR = isG = isB = iY;

					viPixel[i] = 0xff<<24|isR<<16|isG<<8|isB;
				}

				oImage = createImage(new MemoryImageSource(iWidth, iHeight, viPixel, 0, iWidth));
			}
			else if(evtObj.target==bList[2])
			{
				int iA,iB,iVa,iVb;
				float fAlfa, fBeta, fDelta;

				try{
					pelGrabber = new PixelGrabber(oImage, 0, 0, iWidth, iHeight, viPixel, 0, iWidth);
					pelGrabber.grabPixels();
				}catch(Exception e){};

				for(i=j=0; i<iWidth*iHeight; i++)
					viHistogram[(int)(.33*(0xff&(viPixel[i]>>16))+.56*(0xff&(viPixel[i]>>8))+.11*(0xff&viPixel[i]))]++;
				for(i=0; i<256; i++)
					if(viHistogram[i]>iMaxHistogram)
						iMaxHistogram = viHistogram[j=i];

				iA = (int) iMaxHistogram/50;
				iB = (int) iMaxHistogram*37/45;
				fAlfa = 0;
				fBeta = (float) 1.7;
				fDelta= 0;
				iVa = 0;
				iVb = 0;
				System.out.println("A="+iA+" B="+iB+" Alfa="+fAlfa+" Beta="+fBeta+" Delta="+fDelta);

				for(i=0;i< iWidth*iHeight; i++)
				{
					int iY, iI, iQ, isR, isG, isB;

					isR = 0xff&(viPixel[i]>>16);
					isG = 0xff&(viPixel[i]>>8);
					isB = 0xff& viPixel[i];

					iY=(int)(.299*isR +  .587*isG +.114*isB);
					iI=(int)(.596*isR - .2746*isG -.322*isB);
					iQ=(int)(.211*isR -.52366*isG -.312*isB);

					if(iY<iA)
						iY=(int)(iY*fAlfa);
					else	if(iY<iB)
						iY=(int)(fBeta*(iY-iA)+iVa);
					else
						iY=(int)(fDelta*(iY-iB)+iVb);

					isR = isG = isB = iY;

					viPixel[i] = 0xff<<24|isR<<16|isG<<8|isB;
				}

				oImage = createImage(new MemoryImageSource(iWidth, iHeight, viPixel, 0, iWidth));
			}
			else if(evtObj.target==bList[3])
			{
				int isR, isG, isB;
				try{
					pelGrabber = new PixelGrabber(oImage, 0, 0, iWidth, iHeight, viPixel, 0, iWidth);
					pelGrabber.grabPixels();
				}catch(Exception e){};

				for(i=0;i< iWidth*iHeight; i++)
				{
					int iY;

					isR = 0xff&(viPixel[i]>>16);
					isG = 0xff&(viPixel[i]>>8);
					isB = 0xff& viPixel[i];

					iY=(int)(.299*isR +  .587*isG +.114*isB);

					iY = 256-iY;

					isR = isG = isB = iY;

					viPixel[i] = 0xff<<24|isR<<16|isG<<8|isB;
				}

				oImage = createImage(new MemoryImageSource(iWidth, iHeight, viPixel, 0, iWidth));
			}
			else if(evtObj.target==bList[4])
			{
				int isR, isG, isB;
				try{
					pelGrabber = new PixelGrabber(oImage, 0, 0, iWidth, iHeight, viPixel, 0, iWidth);
					pelGrabber.grabPixels();
				}catch(Exception e){};

				for(i=0;i< iWidth*iHeight; i++)
				{
					int iY;

					isR = 0xff&(viPixel[i]>>16);
					isG = 0xff&(viPixel[i]>>8);
					isB = 0xff& viPixel[i];

					iY=(int)(.299*isR +  .587*isG +.114*isB);

					iY = iY>127?256:iY;

					isR = isG = isB = iY;

					viPixel[i] = 0xff<<24|isR<<16|isG<<8|isB;
				}

				oImage = createImage(new MemoryImageSource(iWidth, iHeight, viPixel, 0, iWidth));
			}
			else if(evtObj.target==bList[5])
			{
				int isR, isG, isB;
				try{
					pelGrabber = new PixelGrabber(oImage, 0, 0, iWidth, iHeight, viPixel, 0, iWidth);
					pelGrabber.grabPixels();
				}catch(Exception e){};

				for(i=0;i< iWidth*iHeight; i++)
				{
					int iY;

					isR = 0xff&(viPixel[i]>>16);
					isG = 0xff&(viPixel[i]>>8);
					isB = 0xff& viPixel[i];

					iY=(int)(.299*isR +  .587*isG +.114*isB);

					iY = iY&0xf0;

					isR = isG = isB = iY;

					viPixel[i] = 0xff<<24|isR<<16|isG<<8|isB;
				}

				oImage = createImage(new MemoryImageSource(iWidth, iHeight, viPixel, 0, iWidth));
			}
			else if(evtObj.target==bList[6])
			{
				int isR, isG, isB;
				try{
					pelGrabber = new PixelGrabber(oImage, 0, 0, iWidth, iHeight, viPixel, 0, iWidth);
					pelGrabber.grabPixels();
				}catch(Exception e){};

				for(i=0;i< iWidth*iHeight; i++)
				{
					int iY;

					isR = 0xff&(viPixel[i]>>16);
					isG = 0xff&(viPixel[i]>>8);
					isB = 0xff& viPixel[i];

					iY=(int)(.299*isR +  .587*isG +.114*isB);

					iY = (2*iY)%257;

					isR = isG = isB = iY;

					viPixel[i] = 0xff<<24|isR<<16|isG<<8|isB;
				}

				oImage = createImage(new MemoryImageSource(iWidth, iHeight, viPixel, 0, iWidth));
			}
			else if(evtObj.target==bList[7])
			{
				int isR, isG, isB;
				try{
					pelGrabber = new PixelGrabber(oImage, 0, 0, iWidth, iHeight, viPixel, 0, iWidth);
					pelGrabber.grabPixels();
				}catch(Exception e){};

				for(i=0;i< iWidth*iHeight; i++)
				{
					int iY;

					isR = 0xff&(viPixel[i]>>16);
					isG = 0xff&(viPixel[i]>>8);
					isB = 0xff& viPixel[i];

					iY=(int)(.299*isR +  .587*isG +.114*isB);

					iY = (int) ((256/(Math.log(257)/Math.log(10)))*(Math.log(iY+1)/Math.log(10)));

					isR = isG = isB = iY;

					viPixel[i] = 0xff<<24|isR<<16|isG<<8|isB;
				}

				oImage = createImage(new MemoryImageSource(iWidth, iHeight, viPixel, 0, iWidth));
			}
			else if(evtObj.target==bList[8])
			{
				int isR, isG, isB;
				try{
					pelGrabber = new PixelGrabber(oImage, 0, 0, iWidth, iHeight, viPixel, 0, iWidth);
					pelGrabber.grabPixels();
				}catch(Exception e){};

				for(i=0;i< iWidth*iHeight; i++)
				{
					int iY;

					isR = 0xff&(viPixel[i]>>16);
					isG = 0xff&(viPixel[i]>>8);
					isB = 0xff& viPixel[i];

					iY=(int)(.299*isR +  .587*isG +.114*isB);

					iY = (iY+25)%256;

					isR = isG = isB = iY;

					viPixel[i] = 0xff<<24|isR<<16|isG<<8|isB;
				}

				oImage = createImage(new MemoryImageSource(iWidth, iHeight, viPixel, 0, iWidth));
			}
			else if(evtObj.target==bList[9])
			{
			}
			else if(evtObj.target==bList[10])
			{
				System.out.println("Botao 10");
			}
			repaint();
			return true;
		}
		return false;
	}

	public void paint(Graphics g)
	{
		g.drawImage(oImage,0,70,this);
	}
}
