import java.applet.*; import java.awt.*; public class McmTrans extends Applet { //-- date values ---------------------------------------------------------- private float rgb_r, rgb_g, rgb_b; private float lhs_l, lhs_h, lhs_s; private float luv_l, luv_u, luv_v; private float mun_v, mun_h, mun_c; private float xyz_x, xyz_y, xyz_z; private float wmin, wmid, wmax, pos; private int Wmin, Wmid, Wmax, Pos; private boolean wlock, mun_upd; private boolean hsv, hls, hsl; //-- interface layout ----------------------------------------------------- private GridBagLayout gridbagl; private GridBagConstraints gridbagc; //-- interface components ------------------------------------------------- private Label l_rgb; private Label l_rgb_r; private Scrollbar s_rgb_r; private TextField t_rgb_r; private Label l_rgb_g; private Scrollbar s_rgb_g; private TextField t_rgb_g; private Label l_rgb_b; private Scrollbar s_rgb_b; private TextField t_rgb_b; private Label l_rgb_s; private ColorSample rgb_sample; private Label l_glhs; private Label l_glhs_l; private Scrollbar s_glhs_l; private TextField t_glhs_l; private Label l_glhs_h; private HueDial h_glhs_h; private TextField t_glhs_h; private Label l_glhs_s; private Scrollbar s_glhs_s; private TextField t_glhs_s; private Label l_glhs_wgt; private WgtTri w_glhs_wgt; private Checkbox c_glhs_lock; private Checkbox c_glhs_hsv; private Checkbox c_glhs_hls; private Checkbox c_glhs_hsl; private TextField t_glhs_wmin; private Label l_glhs_wmin; private TextField t_glhs_wmid; private Label l_glhs_wmid; private TextField t_glhs_wmax; private Label l_glhs_wmax; private Label l_cie; private Label l_cie_l; private Scrollbar s_cie_l; private TextField t_cie_l; private Label l_cie_u; private Scrollbar s_cie_u; private TextField t_cie_u; private Label l_cie_v; private Scrollbar s_cie_v; private TextField t_cie_v; private Label l_mun; private Label l_mun_v; private Scrollbar s_mun_v; private TextField t_mun_v; private Label l_mun_h; private Scrollbar s_mun_h; private TextField t_mun_h; private Label l_mun_c; private Scrollbar s_mun_c; private TextField t_mun_c; private Label l_mun_upd; private Button b_mun_upd; private Label l_message; private Label a; private Label b; private Label c; private Label d; private Label e; private Label f; private Label g; private Label h; private Label k; public McmTrans() { } public String getAppletInfo() { return "Name: McmTransJ\r\n" + "Author: Alexander Gee\r\n" + "Created with Microsoft Visual J++ Version 1.0"; } // Applet Initialization method //------------------------------------------------------------------------- public void init() { gridbagl = new GridBagLayout(); setLayout( gridbagl ); gridbagc = new GridBagConstraints(); gridbagc.fill = GridBagConstraints.BOTH; l_rgb = new Label( "RGB Color Values", Label.CENTER ); addComp( l_rgb, gridbagl, gridbagc, 0, 0, 10, 1 ); l_rgb_s = new Label( "RGB Color Sample", Label.CENTER ); addComp( l_rgb_s, gridbagl, gridbagc, 11, 0, 10, 1 ); l_glhs = new Label( "GLHS Color Values", Label.CENTER ); addComp( l_glhs, gridbagl, gridbagc, 0, 5, 10, 1 ); l_cie = new Label( "CIE L*u*v* Color Values", Label.CENTER ); addComp( l_cie, gridbagl, gridbagc, 0, 15, 10, 1 ); l_mun = new Label( "Munsell Color Values", Label.CENTER ); addComp( l_mun, gridbagl, gridbagc, 11, 15, 10, 1 ); gridbagc.fill = GridBagConstraints.HORIZONTAL; l_rgb_r = new Label( " R ", Label.LEFT ); addComp( l_rgb_r, gridbagl, gridbagc, 0, 1, 1, 1 ); l_rgb_g = new Label( " G ", Label.LEFT ); addComp( l_rgb_g, gridbagl, gridbagc, 0, 2, 1, 1 ); l_rgb_b = new Label( " B ", Label.LEFT ); addComp( l_rgb_b, gridbagl, gridbagc, 0, 3, 1, 1 ); l_glhs_l = new Label( " L ", Label.LEFT ); addComp( l_glhs_l, gridbagl, gridbagc, 0, 6, 1, 1 ); l_glhs_h = new Label( " H ", Label.LEFT ); addComp( l_glhs_h, gridbagl, gridbagc, 0, 7, 1, 5 ); l_glhs_s = new Label( " S ", Label.LEFT ); addComp( l_glhs_s, gridbagl, gridbagc, 0, 12, 1, 1 ); l_cie_l = new Label( " L* ", Label.LEFT ); addComp( l_cie_l, gridbagl, gridbagc, 0, 16, 1, 1 ); l_cie_u = new Label( " u* ", Label.LEFT ); addComp( l_cie_u, gridbagl, gridbagc, 0, 17, 1, 1 ); l_cie_v = new Label( " v* ", Label.LEFT ); addComp( l_cie_v, gridbagl, gridbagc, 0, 18, 1, 1 ); l_mun_v = new Label( " V ", Label.LEFT ); addComp( l_mun_v, gridbagl, gridbagc, 11, 16, 1, 1 ); l_mun_h = new Label( " H ", Label.LEFT ); addComp( l_mun_h, gridbagl, gridbagc, 11, 17, 1, 1 ); l_mun_c = new Label( " C ", Label.LEFT ); addComp( l_mun_c, gridbagl, gridbagc, 11, 18, 1, 1 ); gridbagc.fill = GridBagConstraints.BOTH; s_rgb_r = new Scrollbar( Scrollbar.HORIZONTAL, 0, 1, 0, 1000 ); addComp( s_rgb_r, gridbagl, gridbagc, 2, 1, 5, 1 ); s_rgb_g = new Scrollbar( Scrollbar.HORIZONTAL, 0, 1, 0, 1000 ); addComp( s_rgb_g, gridbagl, gridbagc, 2, 2, 5, 1 ); s_rgb_b = new Scrollbar( Scrollbar.HORIZONTAL, 0, 1, 0, 1000 ); addComp( s_rgb_b, gridbagl, gridbagc, 2, 3, 5, 1 ); s_glhs_l = new Scrollbar( Scrollbar.HORIZONTAL, 0, 1, 0, 1000 ); addComp( s_glhs_l, gridbagl, gridbagc, 2, 6, 5, 1 ); s_glhs_s = new Scrollbar( Scrollbar.HORIZONTAL, 0, 1, 0, 1000 ); addComp( s_glhs_s, gridbagl, gridbagc, 2, 12, 5, 1 ); s_cie_l = new Scrollbar( Scrollbar.HORIZONTAL, 0, 1, 0, 1000 ); addComp( s_cie_l, gridbagl, gridbagc, 2, 16, 5, 1 ); s_cie_u = new Scrollbar( Scrollbar.HORIZONTAL, 0, 1, -1400, 2300 ); addComp( s_cie_u, gridbagl, gridbagc, 2, 17, 5, 1 ); s_cie_v = new Scrollbar( Scrollbar.HORIZONTAL, 0, 1, -1400, 1400 ); addComp( s_cie_v, gridbagl, gridbagc, 2, 18, 5, 1 ); s_mun_v = new Scrollbar( Scrollbar.HORIZONTAL, 0, 1, 0, 1000 ); addComp( s_mun_v, gridbagl, gridbagc, 12, 16, 6, 1 ); s_mun_h = new Scrollbar( Scrollbar.HORIZONTAL, 0, 1, 0, 1000 ); addComp( s_mun_h, gridbagl, gridbagc, 12, 17, 6, 1 ); s_mun_c = new Scrollbar( Scrollbar.HORIZONTAL, 0, 1, 0, 1400 ); addComp( s_mun_c, gridbagl, gridbagc, 12, 18, 6, 1 ); gridbagc.fill = GridBagConstraints.HORIZONTAL; t_rgb_r = new TextField( "0.000", 4 ); addComp( t_rgb_r, gridbagl, gridbagc, 7, 1, 2, 1 ); t_rgb_g = new TextField( "0.000", 4 ); addComp( t_rgb_g, gridbagl, gridbagc, 7, 2, 2, 1 ); t_rgb_b = new TextField( "0.000", 4 ); addComp( t_rgb_b, gridbagl, gridbagc, 7, 3, 2, 1 ); t_glhs_l = new TextField( "0.000", 4 ); addComp( t_glhs_l, gridbagl, gridbagc, 7, 6, 2, 1 ); t_glhs_h = new TextField( "0.0", 4 ); addComp( t_glhs_h, gridbagl, gridbagc, 7, 7, 2, 5 ); t_glhs_s = new TextField( "0.000", 4 ); addComp( t_glhs_s, gridbagl, gridbagc, 7, 12, 2, 1 ); t_cie_l = new TextField( "0.0", 4 ); addComp( t_cie_l, gridbagl, gridbagc, 7, 16, 2, 1 ); t_cie_u = new TextField( "0.0", 4 ); addComp( t_cie_u, gridbagl, gridbagc, 7, 17, 2, 1 ); t_cie_v = new TextField( "0.0", 4 ); addComp( t_cie_v, gridbagl, gridbagc, 7, 18, 2, 1 ); t_mun_v = new TextField( "0.00", 4 ); addComp( t_mun_v, gridbagl, gridbagc, 18, 16, 2, 1 ); t_mun_h = new TextField( "0.0", 4 ); addComp( t_mun_h, gridbagl, gridbagc, 18, 17, 2, 1 ); t_mun_c = new TextField( "0.00", 4 ); addComp( t_mun_c, gridbagl, gridbagc, 18, 18, 2, 1 ); h_glhs_h = new HueDial( 160, 160 ); gridbagc.gridx = 2; gridbagc.gridy = 7; gridbagc.gridwidth = 5; gridbagc.gridheight = 5; gridbagl.setConstraints( h_glhs_h, gridbagc ); add( h_glhs_h ); w_glhs_wgt = new WgtTri( 180, 180 ); gridbagc.gridx = 11; gridbagc.gridy = 6; gridbagc.gridwidth = 6; gridbagc.gridheight = 6; gridbagl.setConstraints( w_glhs_wgt, gridbagc ); add( w_glhs_wgt ); l_glhs_wgt = new Label( "GLHS Weight Settings", Label.CENTER ); addComp( l_glhs_wgt, gridbagl, gridbagc, 11, 5, 10, 1 ); c_glhs_lock = new Checkbox(); c_glhs_lock.setLabel( "Lock LHS" ); c_glhs_lock.setState( false ); addComp( c_glhs_lock, gridbagl, gridbagc, 17, 6, 4, 2 ); c_glhs_hsv = new Checkbox(); c_glhs_hsv.setLabel( "HSV" ); c_glhs_hsv.setState( false ); addComp( c_glhs_hsv, gridbagl, gridbagc, 17, 8, 4, 1 ); c_glhs_hls = new Checkbox(); c_glhs_hls.setLabel( "HLS" ); c_glhs_hls.setState( false ); addComp( c_glhs_hls, gridbagl, gridbagc, 17, 9, 4, 1 ); c_glhs_hsl = new Checkbox(); c_glhs_hsl.setLabel( "HSL" ); c_glhs_hsl.setState( false ); addComp( c_glhs_hsl, gridbagl, gridbagc, 17, 10, 4, 1 ); t_glhs_wmin = new TextField( "0.00", 4 ); addComp( t_glhs_wmin, gridbagl, gridbagc, 11, 12, 2, 1 ); l_glhs_wmin = new Label( "Wmin", Label.LEFT ); addComp( l_glhs_wmin, gridbagl, gridbagc, 11, 13, 2, 1 ); t_glhs_wmid = new TextField( "0.00", 4 ); addComp( t_glhs_wmid, gridbagl, gridbagc, 13, 12, 2, 1 ); l_glhs_wmid = new Label( "Wmid", Label.LEFT ); addComp( l_glhs_wmid, gridbagl, gridbagc, 13, 13, 2, 1 ); t_glhs_wmax = new TextField( "0.00", 4 ); addComp( t_glhs_wmax, gridbagl, gridbagc, 15, 12, 2, 1 ); l_glhs_wmax = new Label( "Wmax", Label.LEFT ); addComp( l_glhs_wmax, gridbagl, gridbagc, 15, 13, 2, 1 ); l_mun_upd = new Label( "-Munsell settings not current-", Label.CENTER ); addComp( l_mun_upd, gridbagl, gridbagc, 11, 19, 9, 1 ); b_mun_upd = new Button( "Update Munsell" ); addComp( b_mun_upd, gridbagl, gridbagc, 11, 20, 9, 1 ); l_message = new Label( "Multiple Color Model Translation System", Label.LEFT ); addComp( l_message, gridbagl, gridbagc, 0, 21, 21, 1 ); a = new Label( " " ); addComp( a, gridbagl, gridbagc, 10, 0, 1, 21 ); b = new Label( " " ); addComp( b, gridbagl, gridbagc, 0, 4, 10, 1 ); c = new Label( " " ); addComp( c, gridbagl, gridbagc, 11, 4, 10, 1 ); d = new Label( " " ); addComp( d, gridbagl, gridbagc, 0, 13, 10, 2 ); e = new Label( " " ); addComp( e, gridbagl, gridbagc, 11, 14, 10, 1 ); f = new Label( " " ); addComp( f, gridbagl, gridbagc, 17, 11, 4, 3 ); g = new Label( " " ); addComp( g, gridbagl, gridbagc, 0, 19, 10, 2 ); k = new Label( " " ); addComp( k, gridbagl, gridbagc, 21, 0, 1, 22 ); hsv = false; hls = false; hsl = false; wlock = false; mun_upd = false; InitMunsell(); rgb_r = 0.5f; rgb_g = 0.5f; rgb_b = 0.5f; gridbagc.fill = GridBagConstraints.BOTH; rgb_sample = new ColorSample( rgb_r, rgb_g, rgb_b ); gridbagc.gridx = 11; gridbagc.gridy = 1; gridbagc.gridwidth = 10; gridbagc.gridheight = 3; gridbagl.setConstraints( rgb_sample, gridbagc ); add( rgb_sample ); GLHSWgtChange( 0, 1000, 0 ); } public void destroy() { } public void paint(Graphics g) { //g.drawString("Created with Microsoft Visual J++ Version 1.0", 10, 20); } public void start() { } public void stop() { } // handle applet events //------------------------------------------------------------------------- public boolean handleEvent( Event e ) { String str = "0.00"; Float ft; float f = 0.0f; int i = 0; switch( e.id ) { case Event.ACTION_EVENT: if( e.target.equals( t_rgb_r ) ) { str = t_rgb_r.getText(); ft = Float.valueOf( str ); rgb_r = ft.floatValue(); if( rgb_r < 0.0f ) { rgb_r = 0.0f; } else if( rgb_r > 1.0f ) { rgb_r = 1.0f; } s_rgb_r.setValue( (int)(1000.0f*rgb_r) ); RGBChange(); return true; } if( e.target.equals( t_rgb_g ) ) { str = t_rgb_g.getText(); ft = Float.valueOf( str ); rgb_g = ft.floatValue(); if( rgb_g < 0.0f ) { rgb_g = 0.0f; } else if( rgb_g > 1.0f ) { rgb_g = 1.0f; } s_rgb_g.setValue( (int)(1000.0f*rgb_g) ); RGBChange(); return true; } if( e.target.equals( t_rgb_b ) ) { str = t_rgb_b.getText(); ft = Float.valueOf( str ); rgb_b = ft.floatValue(); if( rgb_b < 0.0f ) { rgb_b = 0.0f; } else if( rgb_b > 1.0f ) { rgb_b = 1.0f; } s_rgb_b.setValue( (int)(1000.0f*rgb_b) ); RGBChange(); return true; } if( e.target.equals( t_glhs_l ) ) { str = t_glhs_l.getText(); ft = Float.valueOf( str ); lhs_l = ft.floatValue(); if( lhs_l < 0.0f ) { lhs_l = 0.0f; } else if( lhs_l > 1.0f ) { lhs_l = 1.0f; } s_glhs_l.setValue( (int)(1000.0f*lhs_l) ); LHSChange(); return true; } if( e.target.equals( t_glhs_h ) ) { str = t_glhs_h.getText(); ft = Float.valueOf( str ); lhs_h = ft.floatValue(); if( lhs_h < 0.0f ) { lhs_h += 360.0f; } else if( lhs_h > 360.0f ) { lhs_h -= 360.0f; } h_glhs_h.setValue( lhs_h ); LHSChange(); return true; } if( e.target.equals( t_glhs_s ) ) { str = t_glhs_s.getText(); ft = Float.valueOf( str ); lhs_s = ft.floatValue(); if( lhs_s < 0.0f ) { lhs_s = 0.0f; } else if( lhs_s > 1.0f ) { lhs_s = 1.0f; } s_glhs_s.setValue( (int)(1000.0f*lhs_s) ); LHSChange(); return true; } if( e.target.equals( t_glhs_wmin ) ) { str = t_glhs_wmin.getText(); ft = Float.valueOf( str ); wmin = ft.floatValue(); if( wmin < 0.0f ) { wmin = 0.0f; } else if( wmin > 1.0f ) { wmin = 1.0f; } Wmin = (int)(1000.0f*wmin); c_glhs_hsv.setState( false ); c_glhs_hsl.setState( false ); c_glhs_hls.setState( false ); GLHSWgtChange( Wmin, Wmax, 1 ); return true; } if( e.target.equals( t_glhs_wmid ) ) { // no action taken? return true; } if( e.target.equals( t_glhs_wmax ) ) { str = t_glhs_wmax.getText(); ft = Float.valueOf( str ); wmax = ft.floatValue(); if( wmax < 0.0f ) { wmax = 0.0f; } else if( wmax > 1.0f ) { wmax = 1.0f; } Wmax = (int)(1000.0f*wmax); c_glhs_hsv.setState( false ); c_glhs_hsl.setState( false ); c_glhs_hls.setState( false ); GLHSWgtChange( Wmin, Wmax, 0 ); return true; } if( e.target.equals( t_cie_l ) ) { str = t_cie_l.getText(); ft = Float.valueOf( str ); luv_l = ft.floatValue(); if( luv_l < 0.0f ) { luv_l = 0.0f; } else if( luv_l > 100.0f ) { luv_l = 100.0f; } s_cie_l.setValue( (int)(10.0f*luv_l) ); LUVChange(); return true; } if( e.target.equals( t_cie_u ) ) { str = t_cie_u.getText(); ft = Float.valueOf( str ); luv_u = ft.floatValue(); if( luv_u < -140.0f ) { luv_u = -140.0f; } else if( luv_u > 230.0f ) { luv_u = 230.0f; } s_cie_u.setValue( (int)(10.0f*luv_u) ); LUVChange(); return true; } if( e.target.equals( t_cie_v ) ) { str = t_cie_v.getText(); ft = Float.valueOf( str ); luv_v = ft.floatValue(); if( luv_v < -140.0f ) { luv_v = -140.0f; } else if( luv_v > 140.0f ) { luv_v = 140.0f; } s_cie_v.setValue( (int)(10.0f*luv_v) ); LUVChange(); return true; } if( e.target.equals( t_mun_v ) ) { str = t_mun_v.getText(); ft = Float.valueOf( str ); mun_v = ft.floatValue(); if( mun_v < 0.0f ) { mun_v = 0.0f; } else if( mun_v > 10.0f ) { mun_v = 10.0f; } s_mun_v.setValue( (int)(100.0f*mun_v) ); MUNChange(); return true; } if( e.target.equals( t_mun_h ) ) { str = t_mun_h.getText(); ft = Float.valueOf( str ); mun_h = ft.floatValue(); if( mun_h < 0.0f ) { mun_h = 0.0f; } else if( mun_h > 100.0f ) { mun_h = 100.0f; } s_mun_h.setValue( (int)(10.0f*mun_h) ); MUNChange(); return true; } if( e.target.equals( t_mun_c ) ) { str = t_mun_c.getText(); ft = Float.valueOf( str ); mun_c = ft.floatValue(); if( mun_c < 0.0f ) { mun_c = 0.0f; } else if( mun_c > 14.0f ) { mun_c = 14.0f; } s_mun_c.setValue( (int)(100.0f*mun_c) ); MUNChange(); return true; } if( e.target.equals( c_glhs_lock ) ) { wlock = c_glhs_lock.getState(); GLHSWgtChange( Wmin, Wmax, 0 ); return true; } if( e.target.equals( c_glhs_hsv ) ) { hsv = c_glhs_hsv.getState(); c_glhs_hls.setState( false ); c_glhs_hsl.setState( false ); if( hsv ) { GLHSWgtChange( 0, 1000, 0 ); } return true; } if( e.target.equals( c_glhs_hls ) ) { hls = c_glhs_hls.getState(); c_glhs_hsv.setState( false ); c_glhs_hsl.setState( false ); if( hls ) { GLHSWgtChange( 500, 500, 0 ); } return true; } if( e.target.equals( c_glhs_hsl ) ) { hsl = c_glhs_hsl.getState(); c_glhs_hsv.setState( false ); c_glhs_hls.setState( false ); if( hsl ) { GLHSWgtChange( 334, 333, 0 ); } return true; } if( e.target.equals( b_mun_upd ) ) { MUNChange(); return true; } break; case Event.MOUSE_DOWN: break; case Event.MOUSE_DRAG: if( e.target.equals( h_glhs_h ) ) { lhs_h = h_glhs_h.getValue(); t_glhs_h.setText( Float.toString( lhs_h ) ); return true; } if( e.target.equals( w_glhs_wgt ) ) { Wmin = w_glhs_wgt.getWminValue(); wmin = (float)Wmin/1000.0f; t_glhs_wmin.setText( Float.toString( wmin ) ); Wmid = w_glhs_wgt.getWmidValue(); wmid = (float)Wmid/1000.0f; t_glhs_wmid.setText( Float.toString( wmid ) ); Wmax = w_glhs_wgt.getWmaxValue(); wmax = (float)Wmax/1000.0f; t_glhs_wmax.setText( Float.toString( wmax ) ); c_glhs_hsv.setState( false ); c_glhs_hsl.setState( false ); c_glhs_hls.setState( false ); return true; } break; case Event.MOUSE_ENTER: break; case Event.MOUSE_EXIT: break; case Event.MOUSE_MOVE: break; case Event.MOUSE_UP: if( e.target.equals( h_glhs_h ) ) { lhs_h = h_glhs_h.getValue(); t_glhs_h.setText( Float.toString( lhs_h ) ); LHSChange(); return true; } if( e.target.equals( w_glhs_wgt ) ) { Wmin = w_glhs_wgt.getWminValue(); wmin = (float)Wmin/1000.0f; t_glhs_wmin.setText( Float.toString( wmin ) ); Wmid = w_glhs_wgt.getWmidValue(); wmid = (float)Wmid/1000.0f; t_glhs_wmid.setText( Float.toString( wmid ) ); Wmax = w_glhs_wgt.getWmaxValue(); wmax = (float)Wmax/1000.0f; t_glhs_wmax.setText( Float.toString( wmax ) ); c_glhs_hsv.setState( false ); c_glhs_hsl.setState( false ); c_glhs_hls.setState( false ); GLHSWgtChange( Wmin, Wmax, 0 ); return true; } break; case Event.SCROLL_ABSOLUTE: case Event.SCROLL_LINE_DOWN: case Event.SCROLL_LINE_UP: case Event.SCROLL_PAGE_DOWN: case Event.SCROLL_PAGE_UP: if( e.target.equals( s_rgb_r ) ) { rgb_r = (float)s_rgb_r.getValue()/1000.0f; t_rgb_r.setText( Float.toString( rgb_r ) ); RGBChange(); return true; } if( e.target.equals( s_rgb_g ) ) { rgb_g = (float)s_rgb_g.getValue()/1000.0f; t_rgb_g.setText( Float.toString( rgb_g ) ); RGBChange(); return true; } if( e.target.equals( s_rgb_b ) ) { rgb_b = (float)s_rgb_b.getValue()/1000.0f; t_rgb_b.setText( Float.toString( rgb_b ) ); RGBChange(); return true; } if( e.target.equals( s_glhs_l ) ) { lhs_l = (float)s_glhs_l.getValue()/1000.0f; t_glhs_l.setText( Float.toString( lhs_l ) ); LHSChange(); return true; } if( e.target.equals( s_glhs_s ) ) { lhs_s = (float)s_glhs_s.getValue()/1000.0f; t_glhs_s.setText( Float.toString( lhs_s ) ); LHSChange(); return true; } if( e.target.equals( s_cie_l ) ) { luv_l = (float)s_cie_l.getValue()/10.0f; t_cie_l.setText( Float.toString( luv_l ) ); LUVChange(); return true; } if( e.target.equals( s_cie_u ) ) { luv_u = (float)s_cie_u.getValue()/10.0f; t_cie_u.setText( Float.toString( luv_u ) ); LUVChange(); return true; } if( e.target.equals( s_cie_v ) ) { luv_v = (float)s_cie_v.getValue()/10.0f; t_cie_v.setText( Float.toString( luv_v ) ); LUVChange(); return true; } if( e.target.equals( s_mun_v ) ) { mun_v = (float)s_mun_v.getValue()/100.0f; t_mun_v.setText( Float.toString( mun_v ) ); MUNChange(); return true; } if( e.target.equals( s_mun_h ) ) { mun_h = (float)s_mun_h.getValue()/10.0f; t_mun_h.setText( Float.toString( mun_h ) ); MUNChange(); return true; } if( e.target.equals( s_mun_c ) ) { mun_c = (float)s_mun_c.getValue()/100.0f; t_mun_c.setText( Float.toString( mun_c ) ); MUNChange(); return true; } break; } return super.handleEvent( e ); } // Component setup method //------------------------------------------------------------------------- private void addComp( Component c, GridBagLayout gbl, GridBagConstraints gbc, int x, int y, int w, int h ) { gbc.gridx = x; gbc.gridy = y; gbc.gridwidth = w; gbc.gridheight = h; gbl.setConstraints( c, gbc ); add( c ); } // private color conversion methods //------------------------------------------------------------------------- private void GLHSWgtChange( int newmin, int newmax, int p ) { Wmin = newmin; Wmax = newmax; if( Wmax < 1 ) { Wmax = 1; } if( Wmin < 0 ) { Wmin = 0; } if( Wmax > 1000 ) { Wmax = 1000; } if( Wmin > 1000 ) { Wmin = 1000; } if( p == 0 && Wmax+Wmin > 1000 ) { Wmin = 1000 - Wmax; } if( p == 1 && Wmax+Wmin > 1000 ) { Wmax = 1000 - Wmin; if( Wmax == 0 ) { Wmax++; Wmin--; } } if( Wmax < 1000 && Wmin == 0 ) { Wmin = 1; } Wmid = 1000 - Wmax - Wmin; wmin = (float)Wmin/1000.0f; wmid = (float)Wmid/1000.0f; wmax = (float)Wmax/1000.0f; w_glhs_wgt.setValues( Wmin, Wmid, Wmax ); if( wlock ) { LHSChange(); } else { RGBChange(); } } //------------------------------------------------------------------------- private void ColorChange( int group ) { } // RGB values have changed, or an update should be made from the current // RGB values. // GLHS and L*u*v* values will be changed to reflect current RGB values. // Munsell color settings will be invalidated. //------------------------------------------------------------------------- private void RGBChange() { RGBtoGLHS(); RGBtoXYZ(); XYZtoLUV(); UpdateSliders(); WarnMunsell( true ); } // GLHS values have changed, or an update should be made from the current // GLHS values. // RGB and L*u*v* values will be changed to reflect current GLHS values. // Munsell color settings will be invalidated. //------------------------------------------------------------------------- private void LHSChange() { GLHStoRGB(); RGBtoXYZ(); XYZtoLUV(); UpdateSliders(); WarnMunsell( true ); } // L*u*v* values have changed, or an update should be made from the current // L*u*v* values. // RGB and GLHS values will be changed to reflect current L*u*v* values. // Munsell color settings will be invalidated. //------------------------------------------------------------------------- private void LUVChange() { LUVtoXYZ(); boolean validcolor = XYZtoRGB(); RGBtoGLHS(); UpdateSliders(); WarnMunsell( true ); } // Munsell values have changed, or an update should be made from the current // Munsell values. // RGB, GLHS, and L*u*v* values will be changed to reflect current Munsell // values. // Munsell color settings will be validated. //------------------------------------------------------------------------- private void MUNChange() { if( mun_h >= 100.0f ) { mun_h -= 100.0f; } s_mun_v.setValue( (int)(100.0f*mun_v) ); t_mun_v.setText( Float.toString( mun_v ) ); s_mun_h.setValue( (int)(10.0f*mun_h) ); t_mun_h.setText( Float.toString( mun_h ) ); s_mun_c.setValue( (int)(100.0f*mun_c) ); t_mun_c.setText( Float.toString( mun_c ) ); boolean validchroma = MUNtoXYZ(); XYZtoLUV(); boolean validcolor = XYZtoRGB(); RGBtoGLHS(); UpdateSliders(); WarnMunsell( false ); WarnChroma( !validchroma ); } //------------------------------------------------------------------------- private void WarnMunsell( boolean dowarn ) { if( dowarn ) { l_mun_upd.setText( "-Munsell settings not current-" ); b_mun_upd.enable(); } else { l_mun_upd.setText( "" ); b_mun_upd.disable(); } } //------------------------------------------------------------------------- private void WarnChroma( boolean dowarn ) { // ? } //------------------------------------------------------------------------- private void WarnRGB( int dowarn ) { // ? } //------------------------------------------------------------------------- private void UpdateSliders() { s_rgb_r.setValue( (int)(1000.0f*rgb_r) ); t_rgb_r.setText( Float.toString( rgb_r ) ); s_rgb_g.setValue( (int)(1000.0f*rgb_g) ); t_rgb_g.setText( Float.toString( rgb_g ) ); s_rgb_b.setValue( (int)(1000.0f*rgb_b) ); t_rgb_b.setText( Float.toString( rgb_b ) ); s_glhs_l.setValue( (int)(1000.0f*lhs_l) ); t_glhs_l.setText( Float.toString( lhs_l ) ); h_glhs_h.setValue( lhs_h ); t_glhs_h.setText( Float.toString( lhs_h ) ); s_glhs_s.setValue( (int)(1000.0f*lhs_s) ); t_glhs_s.setText( Float.toString( lhs_s ) ); s_cie_l.setValue( (int)(10.0f*luv_l) ); t_cie_l.setText( Float.toString( luv_l ) ); s_cie_u.setValue( (int)(10.0f*luv_u) ); t_cie_u.setText( Float.toString( luv_u ) ); s_cie_v.setValue( (int)(10.0f*luv_v) ); t_cie_v.setText( Float.toString( luv_v ) ); t_glhs_wmin.setText( Float.toString( wmin ) ); t_glhs_wmid.setText( Float.toString( wmid ) ); t_glhs_wmax.setText( Float.toString( wmax ) ); w_glhs_wgt.setValues( Wmin, Wmid, Wmax ); rgb_sample.setColor( rgb_r, rgb_g, rgb_b ); } // Color Conversion Methods // various color conversion routines. Use of Munsell color conversion // requires a call to InitMunsell() and the presence of the "munsell.asc" // in the current working directory. // // XYZ <---> RGB conversions are based on illuminant C and standard NTSC // phosphors. The Munsell and CIE L*u*v* conversions are also illuminant C // based. // // Conversions available: // MUNtoXYZ Converts Munsell color to CIE XYZ values // MUNtoXYZ_RC Same as MUNtoXYZ except chroma value is normalized // so that 0 represent neutral gray and 1 represents // the maximum saturation for the given value and hue // XYZtoLUV Converts CIE XYZ to CIE L*u*v* // LUVtoXYZ Converts CIE L*u*v* to CIE XYZ // RGBtoXYZ Converts RGB to CIE XYZ // XYZtoRGB Converts CIE XYZ to RGB // GLHStoRGB Converts GLHS lightness, hue, and saturation to // RGB values // RGBtoGLHS Converts RGB to GLHS // // GLHS weight values are set with the SetGLHSWeights routine. Default // values are Wmin = 0, Wmid = 0, Wmax = 1 -- appropriate for HSV color // conversions. // // Generalized Lightness, Hue, and Saturation color model developed by // Haim Levkowitz. Information on CIE L*u*v* color system from Johji // Tajima. Munsell color data provided by Walter Bender. // // GLHS routines provided by Haim Levkowitz, with modifications by Kerry // Shetline. Other routines by Kerry Shetline, 1990. //------------------------------------------------------------------------- private MunsellData MUNdata; private float Y0 = 1.0f; private float u0 = 0.20086f; private float v0 = 0.46097f; private float X_black = 0.0f; private float Z_black = 0.0f; private float X_white = 0.9804f; private float Z_white = 1.1812f; private float Y_scale = 102.568f; private float M_val = 1.0f; private float RGBtolerance = 0.01f; private float w_min = 0.0f; private float w_mid = 0.0f; private float w_max = 1.0f; private float Y_mun[] = new float[12]; private boolean mun_init = false; private int maxChroma[][]= new int[12][40]; private float mun_x[][][] = new float[12][40][15]; private float mun_z[][][] = new float[12][40][15]; // Initializes Munsell color converions. //------------------------------------------------------------------------- private boolean InitMunsell() { int v, h, c, i; float V, H, x, y, Y; MUNdata = new MunsellData(); Y_mun[0] = 0.0f; Y_mun[11] = 1.0f; for( h = 0; h < 40; h++ ) { mun_x[0][h][0] = X_black; mun_z[0][h][0] = Z_black; maxChroma[0][h] = 0; mun_x[11][h][0] = X_white; mun_z[11][h][0] = Z_white; maxChroma[11][h] = 0; } i = 0; for( v = 1; v <= 10; v++ ) { V = v - 0.5f; Y = ( 1.2219f*V - 0.23111f*(float)Math.pow( V, 2.0 ) + 0.23951f*(float)Math.pow( V, 3.0 ) - 0.021009f*(float)Math.pow( V, 4.0 ) + 0.0008404f*(float)Math.pow( V, 5.0 ) )/Y_scale; Y_mun[v] = Y; for( h = 0; h < 40; h++ ) { for( c = 0; c < 15; c++ ) { x = MUNdata.data[i]; i++; y = MUNdata.data[i]; i++; if( x != 0.0f || y != 0.0f ) { mun_x[v][h][c] = x*Y/y; mun_z[v][h][c] = (1.0f-x-y)*Y/y; maxChroma[v][h]= c; } } } } return true; } // Computes a weighted average of a and b based upon the relative // differences between w and wa, and w and wb. A smaller wa difference // favors a, a smaller wb difference favors b. //------------------------------------------------------------------------- private float WgtAvg( float a, float b, float wa, float wb, float w ) { return (a*(wb-w)+b*(w-wa))/(wb-wa); } // Converts Munsell "color" to XYZ values. If the Munsell chroma is within // the lookup table for all hue-value pairs involved in the interpolation // process, return true, otherwise return false. // The method InitMunsell() should be called before using this routine. //------------------------------------------------------------------------- private boolean MUNtoXYZ() { int v, h, h2, mc; int V_index_lo, V_index_hi, H_index_lo, H_index_hi, C_index_lo, C_index_hi; float V_value_lo, V_value_hi, H_value_lo, H_value_hi, C_value_lo, C_value_hi; float Dx[] = {0.0f, 0.0f}; float Dz[] = {0.0f, 0.0f}; float Ex[] = {0.0f, 0.0f}; float Ez[] = {0.0f, 0.0f}; float Fx[] = {0.0f, 0.0f}; float Fz[] = {0.0f, 0.0f}; boolean valid = true; // Determine the indices of table cells that will be involved in the // 8-cell weighted average. if( mun_v < 0.5f ) { V_index_lo = 0; V_index_hi = 1; V_value_lo = 0.0f; V_value_hi = 0.5f; } else if( mun_v < 9.5f ) { V_index_lo = (int)(mun_v + 0.5f); V_index_hi = V_index_lo + 1; V_value_lo = (float)V_index_lo - 0.5f; V_value_hi = V_value_lo + 1.0f; } else { V_index_lo = 10; V_index_hi = 11; V_value_lo = 9.5f; V_value_hi = 10.0f; } H_index_lo = (int)(mun_h/2.5f); H_index_hi = H_index_lo + 1; H_value_lo = (float)H_index_lo*2.5f; H_value_hi = H_value_lo + 2.5f; // Compute the weighted average for( v = V_index_lo; v <= V_index_hi; v++ ) { for( h = H_index_lo; h <= H_index_hi; h++ ) { h2 = h - 40*(int)(h/40); mc = maxChroma[v][h2]; if( mun_c >= mc ){ Ex[h-H_index_lo] = mun_x[v][h2][mc]; Ez[h-H_index_lo] = mun_z[v][h2][mc]; if( mun_c > mc ) { valid = false; } } else { C_index_lo = (int)mun_c; C_index_hi = C_index_lo + 1; C_value_lo = (float)C_index_lo; C_value_hi = C_value_lo + 1.0f; Dx[0] = mun_x[v][h2][C_index_lo]; Dz[0] = mun_z[v][h2][C_index_lo]; Dx[1] = mun_x[v][h2][C_index_hi]; Dz[1] = mun_z[v][h2][C_index_hi]; Ex[h-H_index_lo] = WgtAvg( Dx[0], Dx[1], C_value_lo, C_value_hi, mun_c ); Ez[h-H_index_lo] = WgtAvg( Dz[0], Dz[1], C_value_lo, C_value_hi, mun_c ); } } Fx[v-V_index_lo] = WgtAvg( Ex[0], Ex[1], H_value_lo, H_value_hi, mun_c ); Fz[v-V_index_lo] = WgtAvg( Ez[0], Ez[1], H_value_lo, H_value_hi, mun_c ); } xyz_x = WgtAvg( Fx[0], Fx[1], V_value_lo, V_value_hi, mun_v ); xyz_y = WgtAvg( Y_mun[V_index_lo], Y_mun[V_index_hi], V_value_lo, V_value_hi, mun_v ); xyz_z = WgtAvg( Fz[0], Fz[1], V_value_lo, V_value_hi, mun_v ); return valid; } // Converts Munsell "color" (with normalized boundary-relative chroma) to // XYZ values. // The method InitMunsell() should be called before using this routine. //------------------------------------------------------------------------- private void MUNtoXYZ_RC() { int v, h, h2, mc; int V_index_lo, V_index_hi, H_index_lo, H_index_hi, C_index_lo, C_index_hi; float V_value_lo, V_value_hi, H_value_lo, H_value_hi, C_value_lo, C_value_hi; float absChroma; float Dx[] = {0.0f, 0.0f}; float Dz[] = {0.0f, 0.0f}; float Ex[] = {0.0f, 0.0f}; float Ez[] = {0.0f, 0.0f}; float Fx[] = {0.0f, 0.0f}; float Fz[] = {0.0f, 0.0f}; // Determine the indices of table cells that will be involved in the // 8-cell weighted average. if( mun_v < 0.5 ) { V_index_lo = 0; V_index_hi = 1; V_value_lo = 0.0f; V_value_hi = 0.5f; } else if( mun_v < 9.5 ) { V_index_lo = (int)(mun_v + 0.5f); V_index_hi = V_index_lo + 1; V_value_lo = (float)V_index_lo - 0.5f; V_value_hi = V_value_lo + 1.0f; } else { V_index_lo = 10; V_index_hi = 11; V_value_lo = 9.5f; V_value_hi = 10.0f; } H_index_lo = (int)(mun_h/2.5f); H_index_hi = H_index_lo + 1; H_value_lo = (float)H_index_lo*2.5f; H_value_hi = H_value_lo + 2.5f; // Compute the weighted average for( v = V_index_lo; v <= V_index_hi; v++ ) { for( h = H_index_lo; h <= H_index_hi; h++ ) { h2 = h - 40*(h/40); mc = maxChroma[v][h2]; if( mun_c >= 1.0f || mun_c == mc ){ Ex[h-H_index_lo] = mun_x[v][h2][mc]; Ez[h-H_index_lo] = mun_z[v][h2][mc]; } else { absChroma = mun_c*mc; C_index_lo = (int)absChroma; C_index_hi = C_index_lo + 1; C_value_lo = (float)C_index_lo; C_value_hi = C_value_lo + 1.0f; Dx[0] = mun_x[v][h2][C_index_lo]; Dz[0] = mun_z[v][h2][C_index_lo]; Dx[1] = mun_x[v][h2][C_index_hi]; Dz[1] = mun_z[v][h2][C_index_hi]; Ex[h-H_index_lo] = WgtAvg( Dx[0], Dx[1], C_value_lo, C_value_hi, absChroma ); Ez[h-H_index_lo] = WgtAvg( Dz[0], Dz[1], C_value_lo, C_value_hi, absChroma ); } } Fx[v-V_index_lo] = WgtAvg( Ex[0], Ex[1], H_value_lo, H_value_hi, mun_c ); Fz[v-V_index_lo] = WgtAvg( Ez[0], Ez[1], H_value_lo, H_value_hi, mun_c ); } xyz_x = WgtAvg( Fx[0], Fx[1], V_value_lo, V_value_hi, mun_v ); xyz_y = WgtAvg( Y_mun[V_index_lo], Y_mun[V_index_hi], V_value_lo, V_value_hi, mun_v ); xyz_z = WgtAvg( Fz[0], Fz[1], V_value_lo, V_value_hi, mun_v ); } // CIE XYZ to CIE L*u*v* conversions. //------------------------------------------------------------------------- private void XYZtoLUV() { float yy, d, u1, v1; yy = xyz_y/Y0; if( yy <= 0.008856f ) { luv_l = 903.29f*yy; } else { luv_l = 25.0f*(float)Math.pow( 100.0*yy, 0.333333 ) - 16.0f; } if( luv_l > 100.0f ) { luv_l = 100.0f; } d = xyz_x + 15.0f*xyz_y + 3.0f*xyz_z; if( d != 0.0f ) { u1 = 4.0f*xyz_x/d; v1 = 9.0f*xyz_y/d; } else { u1 = 0.0f; v1 = 0.0f; } luv_u = 13.0f*luv_l*( u1 - u0 ); luv_v = 13.0f*luv_l*( v1 - v0 ); } // CIE L*u*v* to CIE XYZ conversions. //------------------------------------------------------------------------- private void LUVtoXYZ() { if( luv_l <= 8.0f ) { xyz_y = luv_l*Y0/903.29f; } else { xyz_y = 0.01f*Y0*(float)Math.pow( ((double)luv_l+16.0)/25.0, 3.0 ); } xyz_x = 9.0f*(luv_u+13.0f*u0*luv_l)/4.0f/(luv_v+13.0f*v0*luv_l)*xyz_y; xyz_z = (39.0f*luv_l/(luv_v+13.0f*v0*luv_l)-5.0f)*xyz_y-xyz_x/3.0f; } // RGB to CIE XYZ color conversion. NTSC standard phosphors assumed. //------------------------------------------------------------------------- private void RGBtoXYZ() { xyz_x = 0.6067f*rgb_r + 0.1736f*rgb_g + 0.2001f*rgb_b; xyz_y = 0.2988f*rgb_r + 0.5868f*rgb_g + 0.1144f*rgb_b; xyz_z = 0.0661f*rgb_g + 1.1147f*rgb_b; } // CIE XYZ to RGB color conversion. NTSC standard phosphors assumed. If // resulting RGB components are outside of the range [0,1] by more than the // amount specified by RGBtolerance validRGB will be false, otherwise it // will be set to true. After tolerance testing, RGB values are forced // into the [0,1] range. //------------------------------------------------------------------------- private boolean XYZtoRGB() { boolean validRGB = true; rgb_r = 1.9107f*xyz_x-0.5328f*xyz_y-0.2883f*xyz_z; if( rgb_r < 0.0f ) { if( rgb_r < -RGBtolerance ) { validRGB = false; } rgb_r = 0.0f; } else if( rgb_r > 1.0f ) { if( rgb_r > 1.0f+RGBtolerance ) { validRGB = false; } rgb_r = 1.0f; } rgb_g = -0.9843f*xyz_x+1.9986f*xyz_y-0.0284f*xyz_z; if( rgb_g < 0.0f ) { if( rgb_g < -RGBtolerance ) { validRGB = false; } rgb_g = 0.0f; } else if( rgb_g > 1.0f ) { if( rgb_g > 1.0f+RGBtolerance ) { validRGB = false; } rgb_g = 1.0f; } rgb_b = 0.0584f*xyz_x-0.1185f*xyz_y+0.8988f*xyz_z; if( rgb_b < 0.0f ) { if( rgb_b < -RGBtolerance ) { validRGB = false; } rgb_b = 0.0f; } else if( rgb_b > 1.0f ) { if( rgb_b > 1.0f+RGBtolerance ) { validRGB = false; } rgb_b = 1.0f; } return( validRGB ); } // g_min_f_k // Compute the minimum coordinate min_f_k of the point f_k. // Haim Levkowitz, June 23, 1988. //------------------------------------------------------------------------- private float g_min_f_k( float l, int k, float f ) { float M_x_w_max, M_x_w_max_pls_w_mid, f_e_k; M_x_w_max = M_val * wmax; M_x_w_max_pls_w_mid = M_val * (wmax + wmid); if( 0.0f < l && l <= M_x_w_max ) { return( 0.0f ); } else if( M_x_w_max < l && l < M_x_w_max_pls_w_mid ) { if( k == 1 || k == 3 || k == 5 ) { f_e_k = (M_x_w_max_pls_w_mid - l)/(M_val * wmid); if( f >= f_e_k ) { return( (l+M_val*(wmid*(f-1.0f)-wmax))/(wmid*f+wmin)); } else { return( 0.0f ); } } else { f_e_k = (l - M_x_w_max)/(M_val * wmid); if( f <= f_e_k ) { return( (M_val*(wmax+wmid*f)-l)/(wmid*(f-1.0f)-wmin)); } else { return( 0.0f ); } } } else { // M_x_w_max_pls_w_mid <= l <= M if( k == 1 || k == 3 || k == 5 ) { return( (l+M_val*(wmid*(f-1.0f)-wmax))/(wmid*f+wmin)); } else { return( (M_val*(wmax+wmid*f)-l)/(wmid*(f-1.0f)-wmin)); } } } private float mid( float l, float fraction, float min ) { return( (l*fraction+min*(wmax*(1.0f-fraction)-wmin*fraction))/(wmax+wmid*fraction) ); } // GLHS to RGB // Input: l in [0,M] // h in [0,360] or undefined (negative) // s in [0,1] // Output: r in [0,M] // g in [0,M] // b in [0,M] // Haim Levkowitz, June 23, 1988. //------------------------------------------------------------------------- private void GLHStoRGB() { int k = 0; float f, max_odd, max_even, min, mid_odd, mid_even, min_f_k; if( lhs_s == 0.0f || lhs_l == 0.0f || lhs_h < 0.0f ) { // achromatic, no hue (or black or undefined: K.S. mod.) rgb_r = lhs_l; rgb_g = lhs_l; rgb_b = lhs_l; } else { // chromatic color k = (int)(lhs_h/60.0f); // sector number f = lhs_h/60.0f - (float)k; // hue within the sector min_f_k = g_min_f_k( lhs_l, k, f ); min = lhs_l - lhs_s*(lhs_l - min_f_k); mid_odd = mid( lhs_l, 1.0f - f, min ); mid_even = mid( lhs_l, f, min ); max_odd = (lhs_l - (wmid*mid_odd + wmin*min))/wmax; max_even = (lhs_l - (wmid*mid_even + wmin*min))/wmax; switch( k ) { case 0: rgb_r = max_even; rgb_g = mid_even; rgb_b = min; break; case 1: rgb_r = mid_odd; rgb_g = max_odd; rgb_b = min; break; case 2: rgb_r = min; rgb_g = max_even; rgb_b = mid_even; break; case 3: rgb_r = min; rgb_g = mid_odd; rgb_b = max_odd; break; case 4: rgb_r = mid_even; rgb_g = min; rgb_b = max_even; break; case 5: rgb_r = max_odd; rgb_g = min; rgb_b = mid_odd; break; default: break; } } } // RGB to GLHS // Input: r in [0,M] // g in [0,M] // b in [0,M] // wmin in [0,1] // wmid in [0,1] wmin + wmid + wmax = 1 // wmax in [0,1] // Output: l in [0,M] // h in [0,360] // s in [0,1] // if s = 0 then h = -1 (undefined) // Haim Levkowitz, June 23, 1988. //------------------------------------------------------------------------- private void RGBtoGLHS() { int k_c = 0; float max, mid, min, f_c, l_c, f_e_k, M_x_w_max, M_x_w_max_pls_w_mid, min_f_k; M_x_w_max = M_val * wmax; M_x_w_max_pls_w_mid = M_val * (wmax + wmid); max = 0.0f; mid = 0.0f; min = 0.0f; if( rgb_r == rgb_g && rgb_g == rgb_b ) { // achromatic lhs_l = rgb_r; lhs_h = -1.0f; lhs_s = 0.0f; } else { // chromatic if( rgb_r > rgb_g && rgb_g >= rgb_b ) { // r > g >= b, sector 0 max = rgb_r; mid = rgb_g; min = rgb_b; k_c = 0; } else if( rgb_g >= rgb_r && rgb_r > rgb_b ) { // g >= r > b, sector 1 max = rgb_g; mid = rgb_r; min = rgb_b; k_c = 1; } else if( rgb_g > rgb_b && rgb_b >= rgb_r ) { // g > b >= r, sector 2 max = rgb_g; mid = rgb_b; min = rgb_r; k_c = 2; } else if( rgb_b >= rgb_g && rgb_g > rgb_r ) { // b >= g > r, sector 3 max = rgb_b; mid = rgb_g; min = rgb_r; k_c = 3; } else if( rgb_b > rgb_r && rgb_r >= rgb_g ) { // b > r >= g, sector 4 max = rgb_b; mid = rgb_r; min = rgb_g; k_c = 4; } else if( rgb_r >= rgb_b && rgb_b > rgb_g ) { // r >= b > g, sector 5 max = rgb_r; mid = rgb_b; min = rgb_g; k_c = 5; } if( k_c == 1 || k_c == 3 || k_c == 5 ) { f_c = (max - mid)/(max - min); } else { f_c = (mid - min)/(max - min); } lhs_h = ((float)k_c + f_c) * 60.0f; l_c = wmax * max + wmid * mid + wmin * min; lhs_l = l_c; min_f_k = g_min_f_k( l_c, k_c, f_c ); lhs_s = (l_c - min)/(l_c - min_f_k); } } }