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.composite;
018    
019    import java.awt.Color;
020    import java.awt.CompositeContext;
021    import java.awt.RenderingHints;
022    import java.awt.image.ColorModel;
023    
024    public final class SaturationComposite extends RGBComposite {
025    
026            public SaturationComposite( float alpha ) {
027            super( alpha );
028            }
029    
030            public CompositeContext createContext( ColorModel srcColorModel, ColorModel dstColorModel, RenderingHints hints ) {
031                    return new Context( extraAlpha, srcColorModel, dstColorModel );
032            }
033    
034        static class Context extends RGBCompositeContext {
035                    private float[] sHSB = new float[3];
036            private float[] dHSB = new float[3];
037    
038            public Context( float alpha, ColorModel srcColorModel, ColorModel dstColorModel ) {
039                super( alpha, srcColorModel, dstColorModel );
040            }
041    
042            public void composeRGB( int[] src, int[] dst, float alpha ) {
043                int w = src.length;
044    
045                for ( int i = 0; i < w; i += 4 ) {
046                    int sr = src[i];
047                    int dir = dst[i];
048                    int sg = src[i+1];
049                    int dig = dst[i+1];
050                    int sb = src[i+2];
051                    int dib = dst[i+2];
052                    int sa = src[i+3];
053                    int dia = dst[i+3];
054                    int dor, dog, dob;
055    
056                    Color.RGBtoHSB( sr, sg, sb, sHSB );
057                    Color.RGBtoHSB( dir, dig, dib, dHSB );
058    
059                    dHSB[1] = sHSB[1];
060    
061                    int doRGB = Color.HSBtoRGB( dHSB[0], dHSB[1], dHSB[2] );
062                    dor = (doRGB & 0xff0000) >> 16;
063                    dog = (doRGB & 0xff00) >> 8;
064                    dob = (doRGB & 0xff);
065    
066                    float a = alpha*sa/255f;
067                    float ac = 1-a;
068    
069                    dst[i] = (int)(a*dor + ac*dir);
070                    dst[i+1] = (int)(a*dog + ac*dig);
071                    dst[i+2] = (int)(a*dob + ac*dib);
072                    dst[i+3] = (int)(sa*alpha + dia*ac);
073                }
074            }
075        }
076    
077    }