001/* 002Copyright 2006 Jerry Huxtable 003 004Licensed under the Apache License, Version 2.0 (the "License"); 005you may not use this file except in compliance with the License. 006You may obtain a copy of the License at 007 008 http://www.apache.org/licenses/LICENSE-2.0 009 010Unless required by applicable law or agreed to in writing, software 011distributed under the License is distributed on an "AS IS" BASIS, 012WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013See the License for the specific language governing permissions and 014limitations under the License. 015*/ 016 017package com.jhlabs.composite; 018 019import java.awt.*; 020import java.awt.image.*; 021 022public abstract class RGBComposite implements Composite { 023 024 protected float extraAlpha; 025 026 public RGBComposite() { 027 this( 1.0f ); 028 } 029 030 public RGBComposite( float alpha ) { 031 if ( alpha < 0.0f || alpha > 1.0f ) 032 throw new IllegalArgumentException("RGBComposite: alpha must be between 0 and 1"); 033 this.extraAlpha = alpha; 034 } 035 036 public float getAlpha() { 037 return extraAlpha; 038 } 039 040 public int hashCode() { 041 return Float.floatToIntBits(extraAlpha); 042 } 043 044 public boolean equals(Object o) { 045 if (!(o instanceof RGBComposite)) 046 return false; 047 RGBComposite c = (RGBComposite)o; 048 049 if ( extraAlpha != c.extraAlpha ) 050 return false; 051 return true; 052 } 053 054 public abstract static class RGBCompositeContext implements CompositeContext { 055 056 private float alpha; 057 private ColorModel srcColorModel; 058 private ColorModel dstColorModel; 059 060 public RGBCompositeContext( float alpha, ColorModel srcColorModel, ColorModel dstColorModel ) { 061 this.alpha = alpha; 062 this.srcColorModel = srcColorModel; 063 this.dstColorModel = dstColorModel; 064 } 065 066 public void dispose() { 067 } 068 069 // Multiply two numbers in the range 0..255 such that 255*255=255 070 static int multiply255( int a, int b ) { 071 int t = a * b + 0x80; 072 return ((t >> 8) + t) >> 8; 073 } 074 075 static int clamp( int a ) { 076 return a < 0 ? 0 : a > 255 ? 255 : a; 077 } 078 079 public abstract void composeRGB( int[] src, int[] dst, float alpha ); 080 081 public void compose( Raster src, Raster dstIn, WritableRaster dstOut ) { 082 float alpha = this.alpha; 083 084 int[] srcPix = null; 085 int[] dstPix = null; 086 087 int x = dstOut.getMinX(); 088 int w = dstOut.getWidth(); 089 int y0 = dstOut.getMinY(); 090 int y1 = y0 + dstOut.getHeight(); 091 092 for ( int y = y0; y < y1; y++ ) { 093 srcPix = src.getPixels( x, y, w, 1, srcPix ); 094 dstPix = dstIn.getPixels( x, y, w, 1, dstPix ); 095 composeRGB( srcPix, dstPix, alpha ); 096 dstOut.setPixels( x, y, w, 1, dstPix ); 097 } 098 } 099 100 } 101}