001    /*
002    *
003    
004    Licensed under the Apache License, Version 2.0 (the "License");
005    you may not use this file except in compliance with the License.
006    You may obtain a copy of the License at
007    
008       http://www.apache.org/licenses/LICENSE-2.0
009    
010    Unless required by applicable law or agreed to in writing, software
011    distributed under the License is distributed on an "AS IS" BASIS,
012    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013    See the License for the specific language governing permissions and
014    limitations under the License.
015    */
016    
017    package railo.runtime.img.filter;
018    /**
019     * A class for calulating the colors of the spectrum.
020     */
021    public class Spectrum {
022    
023            private static int adjust(float color, float factor, float gamma) {
024                    if (color == 0.0)
025                            return 0;
026                    return (int)Math.round(255 * Math.pow(color * factor, gamma));
027            }
028            
029            /**
030         * Convert a wavelength to an RGB value.
031             * @param wavelength wavelength in nanometres
032         * @return the RGB value
033             */
034            public static int wavelengthToRGB(float wavelength) {
035                    float gamma = 0.80f;
036                    float r, g, b, factor;
037    
038                    int w = (int)wavelength;
039                    if (w < 380) {
040                            r = 0.0f;
041                            g = 0.0f;
042                            b = 0.0f;
043                    } else if (w < 440) {
044                            r = -(wavelength - 440) / (440 - 380);
045                            g = 0.0f;
046                            b = 1.0f;
047                    } else if (w < 490) {
048                            r = 0.0f;
049                            g = (wavelength - 440) / (490 - 440);
050                            b = 1.0f;
051                    } else if (w < 510) {
052                            r = 0.0f;
053                            g = 1.0f;
054                            b = -(wavelength - 510) / (510 - 490);
055                    } else if (w < 580) {
056                            r = (wavelength - 510) / (580 - 510);
057                            g = 1.0f;
058                            b = 0.0f;
059                    } else if (w < 645) {
060                            r = 1.0f;
061                            g = -(wavelength - 645) / (645 - 580);
062                            b = 0.0f;
063                    } else if (w <= 780) {
064                            r = 1.0f;
065                            g = 0.0f;
066                            b = 0.0f;
067                    } else {
068                            r = 0.0f;
069                            g = 0.0f;
070                            b = 0.0f;
071                    }
072    
073                    // Let the intensity fall off near the vision limits
074                    if (380 <= w && w <= 419)
075                            factor = 0.3f + 0.7f*(wavelength - 380) / (420 - 380);
076                    else if (420 <= w && w <= 700)
077                            factor = 1.0f;
078                    else if (701 <= w && w <= 780)
079                            factor = 0.3f + 0.7f*(780 - wavelength) / (780 - 700);
080                    else
081                            factor = 0.0f;
082    
083                    int ir = adjust(r, factor, gamma);
084                    int ig = adjust(g, factor, gamma);
085                    int ib = adjust(b, factor, gamma);
086    
087                    return 0xff000000 | (ir << 16) | (ig << 8) | ib;
088            }
089    
090    }