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.image;
018
019import java.awt.*;
020import java.awt.image.*;
021import java.util.*;
022
023/**
024 * A filter which interpolates betwen two images. You can set the interpolation factor outside the range 0 to 1
025 * to extrapolate images.
026 */
027public class InterpolateFilter extends AbstractBufferedImageOp {
028        
029        private BufferedImage destination;
030        private float interpolation;
031
032        public InterpolateFilter() {
033        }
034
035    /**
036     * Set the destination image.
037     * @param destination the destination image
038     * @see #getDestination
039     */
040        public void setDestination( BufferedImage destination ) {
041                this.destination = destination;
042        }
043        
044    /**
045     * Get the destination image.
046     * @return the destination image
047     * @see #setDestination
048     */
049        public BufferedImage getDestination() {
050                return destination;
051        }
052        
053    /**
054     * Set the interpolation factor.
055     * @param interpolation the interpolation factor
056     * @see #getInterpolation
057     */
058        public void setInterpolation( float interpolation ) {
059                this.interpolation = interpolation;
060        }
061        
062    /**
063     * Get the interpolation factor.
064     * @return the interpolation factor
065     * @see #setInterpolation
066     */
067        public float getInterpolation() {
068                return interpolation;
069        }
070        
071    public BufferedImage filter( BufferedImage src, BufferedImage dst ) {
072        int width = src.getWidth();
073        int height = src.getHeight();
074                int type = src.getType();
075                WritableRaster srcRaster = src.getRaster();
076
077        if ( dst == null )
078            dst = createCompatibleDestImage( src, null );
079                WritableRaster dstRaster = dst.getRaster();
080
081        if ( destination != null ) {
082                        width = Math.min( width, destination.getWidth() );
083                        height = Math.min( height, destination.getWidth() );
084                        int[] pixels1 = null;
085                        int[] pixels2 = null;
086
087                        for (int y = 0; y < height; y++) {
088                                pixels1 = getRGB( src, 0, y, width, 1, pixels1 );
089                                pixels2 = getRGB( destination, 0, y, width, 1, pixels2 );
090                                for (int x = 0; x < width; x++) {
091                                        int rgb1 = pixels1[x];
092                                        int rgb2 = pixels2[x];
093                                        int a1 = (rgb1 >> 24) & 0xff;
094                                        int r1 = (rgb1 >> 16) & 0xff;
095                                        int g1 = (rgb1 >> 8) & 0xff;
096                                        int b1 = rgb1 & 0xff;
097                                        int a2 = (rgb2 >> 24) & 0xff;
098                                        int r2 = (rgb2 >> 16) & 0xff;
099                                        int g2 = (rgb2 >> 8) & 0xff;
100                                        int b2 = rgb2 & 0xff;
101                                        r1 = PixelUtils.clamp( ImageMath.lerp( interpolation, r1, r2 ) );
102                                        g1 = PixelUtils.clamp( ImageMath.lerp( interpolation, g1, g2 ) );
103                                        b1 = PixelUtils.clamp( ImageMath.lerp( interpolation, b1, b2 ) );
104                                        pixels1[x] = (a1 << 24) | (r1 << 16) | (g1 << 8) | b1;
105                                }
106                                setRGB( dst, 0, y, width, 1, pixels1 );
107                        }
108        }
109
110        return dst;
111    }
112
113        public String toString() {
114                return "Effects/Interpolate...";
115        }
116}