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 }