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.Composite; 020 import java.awt.CompositeContext; 021 import java.awt.image.ColorModel; 022 import java.awt.image.Raster; 023 import java.awt.image.WritableRaster; 024 025 public abstract class RGBComposite implements Composite { 026 027 protected float extraAlpha; 028 029 public RGBComposite() { 030 this( 1.0f ); 031 } 032 033 public RGBComposite( float alpha ) { 034 if ( alpha < 0.0f || alpha > 1.0f ) 035 throw new IllegalArgumentException("RGBComposite: alpha must be between 0 and 1"); 036 this.extraAlpha = alpha; 037 } 038 039 public float getAlpha() { 040 return extraAlpha; 041 } 042 043 public int hashCode() { 044 return Float.floatToIntBits(extraAlpha); 045 } 046 047 public boolean equals(Object o) { 048 if (!(o instanceof RGBComposite)) 049 return false; 050 RGBComposite c = (RGBComposite)o; 051 052 if ( extraAlpha != c.extraAlpha ) 053 return false; 054 return true; 055 } 056 057 public abstract static class RGBCompositeContext implements CompositeContext { 058 059 private float alpha; 060 private ColorModel srcColorModel; 061 private ColorModel dstColorModel; 062 063 public RGBCompositeContext( float alpha, ColorModel srcColorModel, ColorModel dstColorModel ) { 064 this.alpha = alpha; 065 this.srcColorModel = srcColorModel; 066 this.dstColorModel = dstColorModel; 067 } 068 069 public void dispose() { 070 } 071 072 // Multiply two numbers in the range 0..255 such that 255*255=255 073 static int multiply255( int a, int b ) { 074 int t = a * b + 0x80; 075 return ((t >> 8) + t) >> 8; 076 } 077 078 static int clamp( int a ) { 079 return a < 0 ? 0 : a > 255 ? 255 : a; 080 } 081 082 public abstract void composeRGB( int[] src, int[] dst, float alpha ); 083 084 public void compose( Raster src, Raster dstIn, WritableRaster dstOut ) { 085 float alpha = this.alpha; 086 087 int[] srcPix = null; 088 int[] dstPix = null; 089 090 int x = dstOut.getMinX(); 091 int w = dstOut.getWidth(); 092 int y0 = dstOut.getMinY(); 093 int y1 = y0 + dstOut.getHeight(); 094 095 for ( int y = y0; y < y1; y++ ) { 096 srcPix = src.getPixels( x, y, w, 1, srcPix ); 097 dstPix = dstIn.getPixels( x, y, w, 1, dstPix ); 098 composeRGB( srcPix, dstPix, alpha ); 099 dstOut.setPixels( x, y, w, 1, dstPix ); 100 } 101 } 102 103 } 104 }