001/** 002 * 003 * Copyright (c) 2014, the Railo Company Ltd. All rights reserved. 004 * 005 * This library is free software; you can redistribute it and/or 006 * modify it under the terms of the GNU Lesser General Public 007 * License as published by the Free Software Foundation; either 008 * version 2.1 of the License, or (at your option) any later version. 009 * 010 * This library is distributed in the hope that it will be useful, 011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 013 * Lesser General Public License for more details. 014 * 015 * You should have received a copy of the GNU Lesser General Public 016 * License along with this library. If not, see <http://www.gnu.org/licenses/>. 017 * 018 **/ 019/* 020* 021 022Licensed under the Apache License, Version 2.0 (the "License"); 023you may not use this file except in compliance with the License. 024You may obtain a copy of the License at 025 026 http://www.apache.org/licenses/LICENSE-2.0 027 028Unless required by applicable law or agreed to in writing, software 029distributed under the License is distributed on an "AS IS" BASIS, 030WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 031See the License for the specific language governing permissions and 032limitations under the License. 033*/ 034 035package lucee.runtime.img.composite; 036 037import java.awt.Composite; 038import java.awt.CompositeContext; 039import java.awt.image.ColorModel; 040import java.awt.image.Raster; 041import java.awt.image.WritableRaster; 042 043public abstract class RGBComposite implements Composite { 044 045 protected float extraAlpha; 046 047 public RGBComposite() { 048 this( 1.0f ); 049 } 050 051 public RGBComposite( float alpha ) { 052 if ( alpha < 0.0f || alpha > 1.0f ) 053 throw new IllegalArgumentException("RGBComposite: alpha must be between 0 and 1"); 054 this.extraAlpha = alpha; 055 } 056 057 public float getAlpha() { 058 return extraAlpha; 059 } 060 061 public int hashCode() { 062 return Float.floatToIntBits(extraAlpha); 063 } 064 065 public boolean equals(Object o) { 066 if (!(o instanceof RGBComposite)) 067 return false; 068 RGBComposite c = (RGBComposite)o; 069 070 if ( extraAlpha != c.extraAlpha ) 071 return false; 072 return true; 073 } 074 075 public abstract static class RGBCompositeContext implements CompositeContext { 076 077 private float alpha; 078 private ColorModel srcColorModel; 079 private ColorModel dstColorModel; 080 081 public RGBCompositeContext( float alpha, ColorModel srcColorModel, ColorModel dstColorModel ) { 082 this.alpha = alpha; 083 this.srcColorModel = srcColorModel; 084 this.dstColorModel = dstColorModel; 085 } 086 087 public void dispose() { 088 } 089 090 // Multiply two numbers in the range 0..255 such that 255*255=255 091 static int multiply255( int a, int b ) { 092 int t = a * b + 0x80; 093 return ((t >> 8) + t) >> 8; 094 } 095 096 static int clamp( int a ) { 097 return a < 0 ? 0 : a > 255 ? 255 : a; 098 } 099 100 public abstract void composeRGB( int[] src, int[] dst, float alpha ); 101 102 public void compose( Raster src, Raster dstIn, WritableRaster dstOut ) { 103 float alpha = this.alpha; 104 105 int[] srcPix = null; 106 int[] dstPix = null; 107 108 int x = dstOut.getMinX(); 109 int w = dstOut.getWidth(); 110 int y0 = dstOut.getMinY(); 111 int y1 = y0 + dstOut.getHeight(); 112 113 for ( int y = y0; y < y1; y++ ) { 114 srcPix = src.getPixels( x, y, w, 1, srcPix ); 115 dstPix = dstIn.getPixels( x, y, w, 1, dstPix ); 116 composeRGB( srcPix, dstPix, alpha ); 117 dstOut.setPixels( x, y, w, 1, dstPix ); 118 } 119 } 120 121 } 122}