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.image.*;
020import com.jhlabs.math.*;
021
022public class TextureFilter extends PointFilter {
023
024        private float scale = 32;
025        private float stretch = 1.0f;
026        private float angle = 0.0f;
027        public float amount = 1.0f;
028        public float turbulence = 1.0f;
029        public float gain = 0.5f;
030        public float bias = 0.5f;
031        public int operation;
032        private float m00 = 1.0f;
033        private float m01 = 0.0f;
034        private float m10 = 0.0f;
035        private float m11 = 1.0f;
036        private Colormap colormap = new Gradient();
037        private Function2D function = new Noise();
038
039        public TextureFilter() {
040        }
041
042        /**
043         * Set the amount of texture.
044         * @param amount the amount
045     * @min-value 0
046     * @max-value 1
047     * @see #getAmount
048         */
049        public void setAmount(float amount) {
050                this.amount = amount;
051        }
052
053        /**
054         * Get the amount of texture.
055         * @return the amount
056     * @see #setAmount
057         */
058        public float getAmount() {
059                return amount;
060        }
061
062        public void setFunction(Function2D function) {
063                this.function = function;
064        }
065
066        public Function2D getFunction() {
067                return function;
068        }
069
070        public void setOperation(int operation) {
071                this.operation = operation;
072        }
073        
074        public int getOperation() {
075                return operation;
076        }
077        
078        /**
079     * Specifies the scale of the texture.
080     * @param scale the scale of the texture.
081     * @min-value 1
082     * @max-value 300+
083     * @see #getScale
084     */
085        public void setScale(float scale) {
086                this.scale = scale;
087        }
088
089        /**
090     * Returns the scale of the texture.
091     * @return the scale of the texture.
092     * @see #setScale
093     */
094        public float getScale() {
095                return scale;
096        }
097
098        /**
099     * Specifies the stretch factor of the texture.
100     * @param stretch the stretch factor of the texture.
101     * @min-value 1
102     * @max-value 50+
103     * @see #getStretch
104     */
105        public void setStretch(float stretch) {
106                this.stretch = stretch;
107        }
108
109        /**
110     * Returns the stretch factor of the texture.
111     * @return the stretch factor of the texture.
112     * @see #setStretch
113     */
114        public float getStretch() {
115                return stretch;
116        }
117
118        /**
119     * Specifies the angle of the texture.
120     * @param angle the angle of the texture.
121     * @angle
122     * @see #getAngle
123     */
124        public void setAngle(float angle) {
125                this.angle = angle;
126                float cos = (float)Math.cos(angle);
127                float sin = (float)Math.sin(angle);
128                m00 = cos;
129                m01 = sin;
130                m10 = -sin;
131                m11 = cos;
132        }
133
134        /**
135     * Returns the angle of the texture.
136     * @return the angle of the texture.
137     * @see #setAngle
138     */
139        public float getAngle() {
140                return angle;
141        }
142
143        /**
144     * Specifies the turbulence of the texture.
145     * @param turbulence the turbulence of the texture.
146     * @min-value 0
147     * @max-value 1
148     * @see #getTurbulence
149     */
150        public void setTurbulence(float turbulence) {
151                this.turbulence = turbulence;
152        }
153
154        /**
155     * Returns the turbulence of the texture.
156     * @return the turbulence of the texture.
157     * @see #setTurbulence
158     */
159        public float getTurbulence() {
160                return turbulence;
161        }
162
163    /**
164     * Set the colormap to be used for the filter.
165     * @param colormap the colormap
166     * @see #getColormap
167     */
168        public void setColormap(Colormap colormap) {
169                this.colormap = colormap;
170        }
171        
172    /**
173     * Get the colormap to be used for the filter.
174     * @return the colormap
175     * @see #setColormap
176     */
177        public Colormap getColormap() {
178                return colormap;
179        }
180        
181        public int filterRGB(int x, int y, int rgb) {
182                float nx = m00*x + m01*y;
183                float ny = m10*x + m11*y;
184                nx /= scale;
185                ny /= scale * stretch;
186                float f = turbulence == 1.0 ? Noise.noise2(nx, ny) : Noise.turbulence2(nx, ny, turbulence);
187                f = (f * 0.5f) + 0.5f;
188                f = ImageMath.gain(f, gain);
189                f = ImageMath.bias(f, bias);
190                f *= amount;
191                int a = rgb & 0xff000000;
192                int v;
193                if (colormap != null)
194                        v = colormap.getColor(f);
195                else {
196                        v = PixelUtils.clamp((int)(f*255));
197                        int r = v << 16;
198                        int g = v << 8;
199                        int b = v;
200                        v = a|r|g|b;
201                }
202                if (operation != PixelUtils.REPLACE)
203                        v = PixelUtils.combinePixels(rgb, v, operation);
204                return v;
205        }
206
207        public String toString() {
208                return "Texture/Noise...";
209        }
210        
211}