001/*
002Copyright 2006 Jerry Huxtable
003
004Licensed under the Apache License, Version 2.0 (the "License");
005you may not use this file except in compliance with the License.
006You may obtain a copy of the License at
007
008   http://www.apache.org/licenses/LICENSE-2.0
009
010Unless required by applicable law or agreed to in writing, software
011distributed under the License is distributed on an "AS IS" BASIS,
012WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013See the License for the specific language governing permissions and
014limitations under the License.
015*/
016
017package com.jhlabs.image;
018
019import java.awt.*;
020import java.awt.image.*;
021
022public class Curve {
023        public float[] x;
024        public float[] y;
025        
026        public Curve() {
027                x = new float[] { 0, 1 };
028                y = new float[] { 0, 1 };
029        }
030        
031        public Curve( Curve curve ) {
032                x = (float[])curve.x.clone();
033                y = (float[])curve.y.clone();
034        }
035        
036        public int addKnot( float kx, float ky ) {
037                int pos = -1;
038                int numKnots = x.length;
039                float[] nx = new float[numKnots+1];
040                float[] ny = new float[numKnots+1];
041                int j = 0;
042                for ( int i = 0; i < numKnots; i++ ) {
043                        if ( pos == -1 && x[i] > kx ) {
044                                pos = j;
045                                nx[j] = kx;
046                                ny[j] = ky;
047                                j++;
048                        }
049                        nx[j] = x[i];
050                        ny[j] = y[i];
051                        j++;
052                }
053                if ( pos == -1 ) {
054                        pos = j;
055                        nx[j] = kx;
056                        ny[j] = ky;
057                }
058                x = nx;
059                y = ny;
060                return pos;
061        }
062        
063        public void removeKnot( int n ) {
064                int numKnots = x.length;
065                if ( numKnots <= 2 )
066                        return;
067                float[] nx = new float[numKnots-1];
068                float[] ny = new float[numKnots-1];
069                int j = 0;
070                for ( int i = 0; i < numKnots-1; i++ ) {
071                        if ( i == n )
072                                j++;
073                        nx[i] = x[j];
074                        ny[i] = y[j];
075                        j++;
076                }
077                x = nx;
078                y = ny;
079        }
080
081        private void sortKnots() {
082                int numKnots = x.length;
083                for (int i = 1; i < numKnots-1; i++) {
084                        for (int j = 1; j < i; j++) {
085                                if (x[i] < x[j]) {
086                                        float t = x[i];
087                                        x[i] = x[j];
088                                        x[j] = t;
089                                        t = y[i];
090                                        y[i] = y[j];
091                                        y[j] = t;
092                                }
093                        }
094                }
095        }
096
097        protected int[] makeTable() {
098                int numKnots = x.length;
099                float[] nx = new float[numKnots+2];
100                float[] ny = new float[numKnots+2];
101                System.arraycopy( x, 0, nx, 1, numKnots);
102                System.arraycopy( y, 0, ny, 1, numKnots);
103                nx[0] = nx[1];
104                ny[0] = ny[1];
105                nx[numKnots+1] = nx[numKnots];
106                ny[numKnots+1] = ny[numKnots];
107
108                int[] table = new int[256];
109                for (int i = 0; i < 1024; i++) {
110                        float f = i/1024.0f;
111                        int x = (int)(255 * ImageMath.spline( f, nx.length, nx ) + 0.5f);
112                        int y = (int)(255 * ImageMath.spline( f, nx.length, ny ) + 0.5f);
113                        x = ImageMath.clamp( x, 0, 255 );
114                        y = ImageMath.clamp( y, 0, 255 );
115                        table[x] = y;
116                }
117                return table;
118        }
119}