package ij.plugin.frame;
import ij.*;
import ij.process.*;
import ij.gui.*;
import java.awt.*;
import java.awt.image.*;
import java.util.*;
import java.awt.event.*;
import ij.measure.*;
import ij.plugin.*;
import ij.plugin.filter.ThresholdToSelection;


/*	This plugin isolates pixels in an RGB image or stack according to a range of Hue.
	Original PassBand2 by Bob Dougherty. Some code borrowed from ThresholdAdjuster by Wayne Rasband.

	Version 0 5/12/2002.
	Version 1 5/13			Filtered pixels set to foreground color.  Speed improved.
	Version 2 5/13.			Fixed a bug in setting the restore pixels that was causing problems with stacks.
							Explicitly get the foreground color from the toolbar in apply.

	Modifications by G. Landini.
		17/Feb/2004.	The changes are seen as the sliders/checkboxes are adjusted.
				Added hue strip to histogram window, changed histogram scale factor
		19/Feb/2004.	Added Saturation and Brightness histograms,
				Added Pass/Stop checkboxes for each HSB channel.
				Added threshold, added inversion of threshold
				Cleaned some variables. Changed name to Threshold_HSB
		22/Feb/2004	Threshold in RGB or HSB space
				Changed name to Threshold_Colour, changed button names.
				Added thresholding by "sampling". Hue band sampled selection may not'
				always work if there are 0 valued histograms. Thread now finishes properly
		23/Feb/2004	Java 1.4 on Mac OS X bug (thanks Wayne)
		25/Feb/2004	Any type of ROI supported for [Sample]
		26/Feb/2004	Modified ROI handling (thanks Wayne)
		28/Feb/2004	Improved Hue sampling, changed histogram background colour
		29/Feb/2004	Added CIE Lab colour space
		6/Mar/2004	v1.4 Requires ImageJ 1.32c (thanks Wayne)
		8/Mar/2004	v1.5 ColourProcessor bug (thanks Wayne), filter checkboxes detect a new image
		23/Jun/2004	v1.6 Added YUV colour space
		1/May/2006	v1.7 Minor changes to Lab coding, added macro recorder button
		5/Jan/2007	v1.8 added warning and commented lines for back/foreground colours
		2/Feb/2008	v1.9 closing does not apply the filter if Original was being displayed. Thanks for the hint Bob!
 */

/**  Selects pixels according to hsb or rgb components.  */
public class ColorThresholder extends PlugInFrame implements PlugIn, Measurements,
 ActionListener, AdjustmentListener, FocusListener, ItemListener, Runnable{

	private static final int HSB=0, RGB=1, LAB=2, YUV=3;
	private static final String[] colorSpaces = {"HSB", "RGB", "Lab", "YUV"};
	private boolean flag = false;
	private int colorSpace = HSB;
	private Thread thread;
	private static Frame instance;

	private BandPlot plot = new BandPlot();
	private BandPlot splot = new BandPlot();
	private BandPlot bplot = new BandPlot();
	private int sliderRange = 256;
	private Panel panel, panelt;
	private Button  originalB, filteredB, stackB, helpB, sampleB, resetallB, newB, macroB, selectB;
	private Checkbox bandPassH, bandPassS, bandPassB, darkBackground;
	private CheckboxGroup colourMode;
	private Choice colorSpaceChoice, methodChoice, modeChoice;
	private int previousImageID = -1;
	private int previousSlice = -1;
	private ImageJ ij;
	private int minHue = 0, minSat = 0, minBri = 0;
	private int maxHue = 255, maxSat = 255, maxBri = 255;
	private Scrollbar minSlider, maxSlider, minSlider2, maxSlider2, minSlider3, maxSlider3;
	private Label label1, label2, label3, label4, label5, label6, labelh, labels, labelb, labelf;
	private boolean done;
	private byte[] hSource, sSource, bSource;
	private boolean applyingStack;

	private static final int DEFAULT = 0;
	private static String[] methodNames = AutoThresholder.getMethods();
	private static String method = methodNames[DEFAULT];
	private static AutoThresholder thresholder = new AutoThresholder();
	private static final int RED=0, WHITE=1, BLACK=2, BLACK_AND_WHITE=3;
	private static final String[] modes = {"Red", "White", "Black", "B&W"};
	private static int mode = RED;	

	private int numSlices;
	private ImageStack stack;
	private int width, height, numPixels;

	public ColorThresholder() {
		super("Threshold Color");
		if (instance!=null) {
			WindowManager.toFront(instance);
			return;
		}
		thread = new Thread(this, "BandAdjuster");
		WindowManager.addWindow(this);
		instance = this;

		ij = IJ.getInstance();
		Font font = new Font("SansSerif", Font.PLAIN, 10);
		GridBagLayout gridbag = new GridBagLayout();
		GridBagConstraints c = new GridBagConstraints();
		setLayout(gridbag);

		int y = 0;
		c.gridx = 0;
		c.gridy = y;
		c.gridwidth = 1;
		c.weightx = 0;
		c.insets = new Insets(5, 0, 0, 0);
		labelh = new Label("Hue", Label.CENTER);
		add(labelh, c);

		c.gridx = 1;
		c.gridy = y++;
		c.gridwidth = 1;
		c.weightx = 0;
		c.insets = new Insets(7, 0, 0, 0);
		labelf = new Label("", Label.RIGHT);
		add(labelf, c);

		// plot
		c.gridx = 0;
		c.gridy = y;
		c.gridwidth = 1;
		c.fill = c.BOTH;
		c.anchor = c.CENTER;
		c.insets = new Insets(0, 5, 0, 0);
		add(plot, c);

		// checkboxes
		bandPassH = new Checkbox("Pass");
		bandPassH.addItemListener(this);
		bandPassH.setState(true);
		c.gridx = 1;
		c.gridy = y++;
		c.gridwidth = 2;
		c.insets = new Insets(5, 5, 0, 5);
		add(bandPassH, c);

		// minHue slider
		minSlider = new Scrollbar(Scrollbar.HORIZONTAL, 0, 1, 0, sliderRange);
		c.gridx = 0;
		c.gridy = y++;
		c.gridwidth = 1;
		c.weightx = IJ.isMacintosh()?90:100;
		c.fill = c.HORIZONTAL;
		c.insets = new Insets(5, 5, 0, 0);

		add(minSlider, c);
		minSlider.addAdjustmentListener(this);
		minSlider.setUnitIncrement(1);

		// minHue slider label
		c.gridx = 1;
		c.gridwidth = 1;
		c.weightx = IJ.isMacintosh()?10:0;
		c.insets = new Insets(5, 0, 0, 0);
		label1 = new Label("       ", Label.LEFT);
		label1.setFont(font);
		add(label1, c);

		// maxHue sliderHue
		maxSlider = new Scrollbar(Scrollbar.HORIZONTAL, 0, 1, 0, sliderRange);
		c.gridx = 0;
		c.gridy = y;
		c.gridwidth = 1;
		c.weightx = 100;
		c.insets = new Insets(5, 5, 0, 0);
		add(maxSlider, c);
		maxSlider.addAdjustmentListener(this);
		maxSlider.setUnitIncrement(1);

		// maxHue slider label
		c.gridx = 1;
		c.gridwidth = 1;
		c.gridy = y++;
		c.weightx = 0;
		c.insets = new Insets(5, 0, 0, 0);
		label2 = new Label("       ", Label.LEFT);
		label2.setFont(font);
		add(label2, c);

		//=====
		c.gridx = 0;
		c.gridy = y++;
		c.gridwidth = 1;
		c.weightx = 0;
		c.insets = new Insets(10, 0, 0, 0);
		labels = new Label("Saturation", Label.CENTER);
		add(labels, c);

		// plot
		c.gridx = 0;
		c.gridy = y;
		c.gridwidth = 1;
		c.fill = c.BOTH;
		c.anchor = c.CENTER;
		c.insets = new Insets(0, 5, 0, 0);
		add(splot, c);

		// checkboxes
		bandPassS = new Checkbox("Pass");
		bandPassS.addItemListener(this);
		bandPassS.setState(true);
		c.gridx = 1;
		c.gridy = y++;
		c.gridwidth = 2;
		c.insets = new Insets(5, 5, 0, 5);
		add(bandPassS, c);

		// minSat slider
		minSlider2 = new Scrollbar(Scrollbar.HORIZONTAL, 0, 1, 0, sliderRange);
		c.gridx = 0;
		c.gridy = y++;
		c.gridwidth = 1;
		c.weightx = IJ.isMacintosh()?90:100;
		c.fill = c.HORIZONTAL;
		c.insets = new Insets(5, 5, 0, 0);
		add(minSlider2, c);
		minSlider2.addAdjustmentListener(this);
		minSlider2.setUnitIncrement(1);

		// minSat slider label
		c.gridx = 1;
		c.gridwidth = 1;
		c.weightx = IJ.isMacintosh()?10:0;
		c.insets = new Insets(5, 0, 0, 0);
		label3 = new Label("       ", Label.LEFT);
		label3.setFont(font);
		add(label3, c);

		// maxSat slider
		maxSlider2 = new Scrollbar(Scrollbar.HORIZONTAL, 0, 1, 0, sliderRange);
		c.gridx = 0;
		c.gridy = y++;
		c.gridwidth = 1;
		c.weightx = 100;
		c.insets = new Insets(5, 5, 0, 0);
		add(maxSlider2, c);
		maxSlider2.addAdjustmentListener(this);
		maxSlider2.setUnitIncrement(1);

		// maxSat slider label
		c.gridx = 1;
		c.gridwidth = 1;
		c.weightx = 0;
		c.insets = new Insets(5, 0, 0, 0);
		label4 = new Label("       ", Label.LEFT);
		label4.setFont(font);
		add(label4, c);

		//=====
		c.gridx = 0;
		c.gridwidth = 1;
		c.gridy = y++;
		c.weightx = 0;
		c.insets = new Insets(10, 0, 0, 0);
		labelb = new Label("Brightness", Label.CENTER);
		add(labelb, c);

		c.gridx = 0;
		c.gridwidth = 1;
		c.gridy = y;
		c.fill = c.BOTH;
		c.anchor = c.CENTER;
		c.insets = new Insets(0, 5, 0, 0);
		add(bplot, c);

		// checkboxes
		bandPassB = new Checkbox("Pass");
		bandPassB.addItemListener(this);
		bandPassB.setState(true);
		c.gridx = 1;
		c.gridy = y++;
		c.gridwidth = 2;
		c.insets = new Insets(5, 5, 0, 5);
		add(bandPassB, c);

		// minBri slider
		minSlider3 = new Scrollbar(Scrollbar.HORIZONTAL, 0, 1, 0, sliderRange);
		c.gridx = 0;
		c.gridy = y++;
		c.gridwidth = 1;
		c.weightx = IJ.isMacintosh()?90:100;
		c.fill = c.HORIZONTAL;
		c.insets = new Insets(5, 5, 0, 0);
		add(minSlider3, c);
		minSlider3.addAdjustmentListener(this);
		minSlider3.setUnitIncrement(1);

		// minBri slider label
		c.gridx = 1;
		c.gridwidth = 1;
		c.weightx = IJ.isMacintosh()?10:0;
		c.insets = new Insets(5, 0, 0, 0);
		label5 = new Label("       ", Label.LEFT);
		label5.setFont(font);
		add(label5, c);

		// maxBri slider
		maxSlider3 = new Scrollbar(Scrollbar.HORIZONTAL, 0, 1, 0, sliderRange);
		c.gridx = 0;
		c.gridy = y++;
		c.gridwidth = 1;
		c.weightx = 100;
		c.insets = new Insets(5, 5, 0, 0);
		add(maxSlider3, c);
		maxSlider3.addAdjustmentListener(this);
		maxSlider3.setUnitIncrement(1);

		// maxBri slider label
		c.gridx = 1;
		c.gridwidth = 1;
		c.weightx = 0;
		c.insets = new Insets(5, 0, 0, 0);
		label6 = new Label("       ", Label.LEFT);
		label6.setFont(font);
		add(label6, c);

		GridBagLayout gridbag2 = new GridBagLayout();
		GridBagConstraints c2 = new GridBagConstraints();
		int y2 = 0;
		Panel panel = new Panel();
		panel.setLayout(gridbag2);
		
		// threshoding method choice
		c2.gridx = 0; c2.gridy = y2;
		c2.anchor = GridBagConstraints.EAST;
		c2.gridwidth = 1;
		c2.insets = new Insets(5, 0, 0, 0);
		Label theLabel = new Label("Thresholding method:");
		gridbag2.setConstraints(theLabel, c2);
		panel.add(theLabel);
		methodChoice = new Choice();
		for (int i=0; iimaxhue) imaxhue=(hsSource[i]&255);
			if ((hsSource[i]&255)imaxsat) imaxsat=(ssSource[i]&255);
			if ((ssSource[i]&255)imaxbri) imaxbri=(bsSource[i]&255);
			if ((bsSource[i]&255)0){
						gap=1;
						gapst=i;
					}
					else {
						gap++;
					}
					if (gap>maxgap){
						maxgap=gap;
						maxgapst=gapst;
						maxgapen=i;
					}
				}
			}

			for (i = 0; i < 256; i++){
				if (bin[i]>0){
					rangePassL = i;
					break;
				}
			}
			for (i = 255; i >= 0; i--){
				if (bin[i]>0){
					rangePassH = i;
					break;
				}
			}
			if ((rangePassH-rangePassL)maxHue) {
			minHue = maxHue;
			minSlider.setValue((int)minHue);
		}
	}

	void adjustMinSat(int value) {
		minSat = value;
		if (maxSatmaxSat) {
			minSat = maxSat;
			minSlider2.setValue((int)minSat);
		}
	}

	void adjustMinBri(int value) {
		minBri = value;
		if (maxBrimaxBri) {
			minBri = maxBri;
			minSlider3.setValue((int)minBri);
		}
	}

	void apply(ImagePlus imp) {
		if (IJ.debugMode) IJ.log("ColorThresholder.apply");
		ImageProcessor fillMaskIP = (ImageProcessor)imp.getProperty("Mask");
		if (fillMaskIP==null) return;
		byte[] fillMask = (byte[])fillMaskIP.getPixels();
		byte fill = (byte)255;
		byte keep = (byte)0;

		if (bandPassH.getState() && bandPassS.getState() && bandPassB.getState()){ //PPP All pass
			for (int j = 0; j < numPixels; j++){
				int hue = hSource[j]&0xff;
				int sat = sSource[j]&0xff;
				int bri = bSource[j]&0xff;
				if (((hue < minHue)||(hue > maxHue)) || ((sat < minSat)||(sat > maxSat)) || ((bri < minBri)||(bri > maxBri)))
					fillMask[j] = keep;
				else
					fillMask[j] = fill;
			}
		} else if(!bandPassH.getState() && !bandPassS.getState() && !bandPassB.getState()){ //SSS All stop
			for (int j = 0; j < numPixels; j++){
				int hue = hSource[j]&0xff;
				int sat = sSource[j]&0xff;
				int bri = bSource[j]&0xff;
				if (((hue >= minHue)&&(hue <= maxHue)) || ((sat >= minSat)&&(sat <= maxSat)) || ((bri >= minBri)&&(bri <= maxBri)))
					fillMask[j] = keep;
				else
					fillMask[j] = fill;
			}
		} else if(bandPassH.getState() && bandPassS.getState() && !bandPassB.getState()){ //PPS
			for (int j = 0; j < numPixels; j++){
				int hue = hSource[j]&0xff;
				int sat = sSource[j]&0xff;
				int bri = bSource[j]&0xff;
				if (((hue < minHue)||(hue > maxHue)) || ((sat < minSat)||(sat > maxSat)) || ((bri >= minBri) && (bri <= maxBri)))
					fillMask[j] = keep;
				else
					fillMask[j] = fill;
			}
		} else if(!bandPassH.getState() && !bandPassS.getState() && bandPassB.getState()){ //SSP
			for (int j = 0; j < numPixels; j++){
				int hue = hSource[j]&0xff;
				int sat = sSource[j]&0xff;
				int bri = bSource[j]&0xff;
				if (((hue >= minHue) && (hue <= maxHue)) || ((sat >= minSat) && (sat <= maxSat)) || ((bri < minBri) || (bri > maxBri)))
					fillMask[j] = keep;
				else
					fillMask[j] = fill;
			}
		} else if (bandPassH.getState() && !bandPassS.getState() && !bandPassB.getState()){ //PSS
			for (int j = 0; j < numPixels; j++){
				int hue = hSource[j]&0xff;
				int sat = sSource[j]&0xff;
				int bri = bSource[j]&0xff;
				if (((hue < minHue) || (hue > maxHue)) || ((sat >= minSat) && (sat <= maxSat)) || ((bri >= minBri) && (bri <= maxBri)))
					fillMask[j] = keep;
				else
					fillMask[j] = fill;
			}
		} else if(!bandPassH.getState() && bandPassS.getState() && bandPassB.getState()){ //SPP
			for (int j = 0; j < numPixels; j++){
				int hue = hSource[j]&0xff;
				int sat = sSource[j]&0xff;
				int bri = bSource[j]&0xff;
				if (((hue >= minHue) && (hue <= maxHue))|| ((sat < minSat) || (sat > maxSat)) || ((bri < minBri) || (bri > maxBri)))
					fillMask[j] = keep;
				else
					fillMask[j] = fill;
			}
		} else if (!bandPassH.getState() && bandPassS.getState() && !bandPassB.getState()){ //SPS
			for (int j = 0; j < numPixels; j++){
				int hue = hSource[j]&0xff;
				int sat = sSource[j]&0xff;
				int bri = bSource[j]&0xff;
				if (((hue >= minHue)&& (hue <= maxHue)) || ((sat < minSat)||(sat > maxSat)) || ((bri >= minBri) && (bri <= maxBri)))
					fillMask[j] = keep;
				else
					fillMask[j] = fill;
			}
		} else if(bandPassH.getState() && !bandPassS.getState() && bandPassB.getState()){ //PSP
			for (int j = 0; j < numPixels; j++){
				int hue = hSource[j]&0xff;
				int sat = sSource[j]&0xff;
				int bri = bSource[j]&0xff;
				if (((hue < minHue) || (hue > maxHue)) || ((sat >= minSat)&&(sat <= maxSat)) || ((bri < minBri) || (bri > maxBri)))
					fillMask[j] = keep;
				else
					fillMask[j] = fill;
			}
		}

		ImageProcessor ip = imp.getProcessor();
		if (ip==null) return;
		if (mode==BLACK_AND_WHITE) {
			int[] pixels = (int[])ip.getPixels();
			int fcolor = Prefs.blackBackground?0xffffffff:0xff000000;
			int bcolor = Prefs.blackBackground?0xff000000:0xffffffff;
			for (int i=0; i255?255:L1)) & 0xff);
			a[i] = (byte)((int)(a1<0?0:(a1>255?255:a1)) & 0xff);
			b[i] = (byte)((int)(b1<0?0:(b1>255?255:b1)) & 0xff);
		}
	}
		
	public void getYUV(ImageProcessor ip, byte[] Y, byte[] U, byte[] V) {
		// Returns YUV in 3 byte arrays.
		
		//RGB <--> YUV Conversion Formulas from http://www.cse.msu.edu/~cbowen/docs/yuvtorgb.html
		//R = Y + (1.4075 * (V - 128));
		//G = Y - (0.3455 * (U - 128) - (0.7169 * (V - 128));
		//B = Y + (1.7790 * (U - 128);
		//
		//Y = R *  .299 + G *  .587 + B *  .114;
		//U = R * -.169 + G * -.332 + B *  .500 + 128.;
		//V = R *  .500 + G * -.419 + B * -.0813 + 128.;

		int c, x, y, i=0, r, g, b;
		double yf;

		int width=ip.getWidth();
		int height=ip.getHeight();

		for(y=0;y>16);//R
				g = ((c&0x00ff00)>>8);//G
				b = ( c&0x0000ff); //B 

				// Kai's plugin
				yf = (0.299 * r  + 0.587 * g + 0.114 * b);
				Y[i] = (byte)((int)Math.floor(yf + 0.5)) ;
				U[i] = (byte)(128+(int)Math.floor((0.493 *(b - yf))+ 0.5)); 
				V[i] = (byte)(128+(int)Math.floor((0.877 *(r - yf))+ 0.5)); 
				
				//Y[i] = (byte) (Math.floor( 0.299 * r + 0.587 * g + 0.114  * b)+.5);
				//U[i] = (byte) (Math.floor(-0.169 * r - 0.332 * g + 0.500  * b + 128.0)+.5);
				//V[i] = (byte) (Math.floor( 0.500 * r - 0.419 * g - 0.0813 * b + 128.0)+.5);
				
				i++;
			}
		}
	}
	
	/** Converts the current image from RGB to CIE L*a*b* and stores the results 
	* in the same RGB image R=L*, G=a*, B=b*. Values are therfore offset and rescaled.
	*/
	public static void RGBtoLab() {
		ImagePlus imp = IJ.getImage();
		if (imp.getBitDepth()==24)
			imp.setProcessor(RGBtoLab(imp.getProcessor()));
	}
	
	private static ImageProcessor RGBtoLab(ImageProcessor ip) {
		int n = ip.getPixelCount();
		byte[] L = new byte[n];
		byte[] a = new byte[n];
		byte[] b = new byte[n];
		ColorThresholder.getLab(ip, L, a, b);
		ColorProcessor cp = new ColorProcessor(ip.getWidth(),ip.getHeight());
		cp.setRGB(L,a,b);
		return cp;
	}
	
	/** Converts the current image from RGB to YUV and stores 
	* the results in the same RGB image R=Y, G=U, B=V.
	* Author: Gabriel Landini,  G.Landini@bham.ac.uk
	*/
	public static void RGBtoYUV() {
		ImagePlus imp = IJ.getImage();
		if (imp.getBitDepth()==24) {
			RGBtoYUV(imp.getProcessor());
			imp.updateAndDraw();
		}
	}

	static void RGBtoYUV(ImageProcessor ip) {
		int xe = ip.getWidth();
		int ye = ip.getHeight();
		int c, x, y, i=0, Y, U, V, r, g, b;
		double yf;

		ImagePlus imp = WindowManager.getCurrentImage();

		for(y=0;y>16);//R
					g = ((c&0x00ff00)>>8);//G
					b = ( c&0x0000ff); //B 

					// Kai's plugin
					yf = (0.299 * r  + 0.587 * g + 0.114 * b);
					Y = ((int)Math.floor(yf + 0.5)) ;
					U = (128+(int)Math.floor((0.493 *(b - yf))+ 0.5)); 
					V = (128+(int)Math.floor((0.877 *(r - yf))+ 0.5)); 

					ip.putPixel(x,y, (((Y<0?0:Y>255?255:Y) & 0xff) << 16)+
									 (((U<0?0:U>255?255:U) & 0xff) << 8) +
								 	  ((V<0?0:V>255?255:V) & 0xff));
				
				ip.putPixel(x,y, ((Y & 0xff) <<16) + ((U & 0xff) << 8) + ( V & 0xff));
			}
		}
	}


	
	class BandPlot extends Canvas implements Measurements, MouseListener {
	
		final int WIDTH = 256, HEIGHT=64;
		double minHue = 0, minSat=0, minBri=0;
		double maxHue = 255, maxSat= 255, maxBri=255;
		int[] histogram;
		Color[] hColors;
		int hmax;
		Image os;
		Graphics osg;
	
		public BandPlot() {
			addMouseListener(this);
			setSize(WIDTH+1, HEIGHT+1);
		}
	
		/** Overrides Component getPreferredSize(). Added to work
		around a bug in Java 1.4 on Mac OS X.*/
		public Dimension getPreferredSize() {
			return new Dimension(WIDTH+1, HEIGHT+1);
		}
	
		void setHistogram(ImagePlus imp, int j) {
			ImageProcessor ip = imp.getProcessor();
			ImageStatistics stats = ImageStatistics.getStatistics(ip, AREA+MODE, null);
			int maxCount2 = 0;
			histogram = stats.histogram;
			for (int i = 0; i < stats.nBins; i++)
				if ((histogram[i] > maxCount2) ) maxCount2 = histogram[i];
				//if ((histogram[i] > maxCount2) && (i != stats.mode)) maxCount2 = histogram[i];
	
			hmax = (int)(maxCount2 * 1.15);//GL was 1.5
			os = null;
			ColorModel cm = ip.getColorModel();
			if (!(cm instanceof IndexColorModel))
				return;
			IndexColorModel icm = (IndexColorModel)cm;
			int mapSize = icm.getMapSize();
			if (mapSize!=256)
				return;
			byte[] r = new byte[256];
			byte[] g = new byte[256];
			byte[] b = new byte[256];
			icm.getReds(r);
			icm.getGreens(g);
			icm.getBlues(b);
			hColors = new Color[256];
	
			if (colorSpace==RGB){
				if (j==0){
					for (int i=0; i<256; i++)
						hColors[i] = new Color(i&255, 0&255, 0&255);
					}
				else if (j==1){
					for (int i=0; i<256; i++)
						hColors[i] = new Color(0&255, i&255, 0&255);
				}
				else if (j==2){
					for (int i=0; i<256; i++)
						hColors[i] = new Color(0&255, 0&255, i&255);
				}
			}
			else if (colorSpace==HSB){
				if (j==0){
					for (int i=0; i<256; i++)
						hColors[i] = new Color(r[i]&255, g[i]&255, b[i]&255);
				}
				else if (j==1){
					for (int i=0; i<256; i++)
						hColors[i] = new Color(255&255, 255-i&255, 255-i&255);
						//hColors[i] = new Color(192-i/4&255, 192+i/4&255, 192-i/4&255);
				}
				else if (j==2){
					for (int i=0; i<256; i++)
						//hColors[i] = new Color(i&255, i&255, 0&255);
						hColors[i] = new Color(i&255, i&255, i&255);
				}
			}
			else if (colorSpace==LAB){
				if (j==0){
					for (int i=0; i<256; i++)
						hColors[i] = new Color(i&255, i&255, i&255);
				}
				else if (j==1){
					for (int i=0; i<256; i++)
						hColors[i] = new Color(i&255, 255-i&255, 0&255);
				}
				else if (j==2){
					for (int i=0; i<256; i++)
						hColors[i] = new Color(i&255, i&255, 255-i&255);
				}
			}
			else if (colorSpace==YUV){
				if (j==0){
					for (int i=0; i<256; i++)
						hColors[i] = new Color(i&255, i&255, i&255);
				}
				else if (j==1){
					for (int i=0; i<256; i++)
						hColors[i] = new Color((int)(36+(255-i)/1.4)&255, 255-i&255, i&255);
				}
				else if (j==2){
					for (int i=0; i<256; i++)
						hColors[i] = new Color(i&255, 255-i&255, (int)(83+(255-i)/2.87)&255);
				}
			}
			
		}
		
		int[] getHistogram() {
			return histogram;
		}
	
		public void update(Graphics g) {
			paint(g);
		}
	
		public void paint(Graphics g ) {
			int hHist=0;
			if (histogram!=null) {
				if (os==null) {
					os = createImage(WIDTH,HEIGHT);
					osg = os.getGraphics();
					//osg.setColor(Color.white);
					osg.setColor(new Color(140,152,144));
					osg.fillRect(0, 0, WIDTH, HEIGHT);
					for (int i = 0; i < WIDTH; i++) {
						if (hColors!=null) osg.setColor(hColors[i]);
						hHist=HEIGHT - ((int)(HEIGHT * histogram[i])/hmax)-6;
						osg.drawLine(i, HEIGHT, i, hHist);
						osg.setColor(Color.black);
						osg.drawLine(i, hHist, i, hHist);
					}
					osg.dispose();
				}
				if (os!=null) g.drawImage(os, 0, 0, this);
			} else {
				g.setColor(Color.white);
				g.fillRect(0, 0, WIDTH, HEIGHT);
			}
			g.setColor(Color.black);
			g.drawLine(0, HEIGHT -6, 256, HEIGHT-6);
			g.drawRect(0, 0, WIDTH, HEIGHT);
			g.drawRect((int)minHue, 1, (int)(maxHue-minHue), HEIGHT-7);
		}
	
		public void mousePressed(MouseEvent e) {}
		public void mouseReleased(MouseEvent e) {}
		public void mouseExited(MouseEvent e) {}
		public void mouseClicked(MouseEvent e) {}
		public void mouseEntered(MouseEvent e) {}
	} // BandPlot class

} // BandAdjuster class





 

Ads help maintain this website.