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.image.*;
020
021/**
022 * A filter for de-interlacing video frames.
023 */
024public class DeinterlaceFilter extends AbstractBufferedImageOp {
025
026    public final static int EVEN = 0;
027    public final static int ODD = 1;
028    public final static int AVERAGE = 2;
029
030    private int mode = EVEN;
031
032        public void setMode(int mode) {
033                this.mode = mode;
034        }
035
036        public int getMode() {
037                return mode;
038        }
039
040    public BufferedImage filter( BufferedImage src, BufferedImage dst ) {
041        int width = src.getWidth();
042        int height = src.getHeight();
043
044        if ( dst == null )
045            dst = createCompatibleDestImage( src, null );
046
047                int[] pixels = null;
048
049        if ( mode == EVEN ) {
050            for ( int y = 0; y < height-1; y += 2 ) {
051                pixels = getRGB( src, 0, y, width, 1, pixels );
052                if ( src != dst )
053                    setRGB( dst, 0, y, width, 1, pixels );
054                setRGB( dst, 0, y+1, width, 1, pixels );
055            }
056        } else if ( mode == ODD ) {
057            for ( int y = 1; y < height; y += 2 ) {
058                pixels = getRGB( src, 0, y, width, 1, pixels );
059                if ( src != dst )
060                    setRGB( dst, 0, y, width, 1, pixels );
061                setRGB( dst, 0, y-1, width, 1, pixels );
062            }
063        } else if ( mode == AVERAGE ) {
064            int[] pixels2 = null;
065            for ( int y = 0; y < height-1; y += 2 ) {
066                pixels = getRGB( src, 0, y, width, 1, pixels );
067                pixels2 = getRGB( src, 0, y+1, width, 1, pixels2 );
068                for ( int x = 0; x < width; x++ ) {
069                    int rgb1 = pixels[x];
070                    int rgb2 = pixels2[x];
071                    int a1 = (rgb1 >> 24) & 0xff;
072                    int r1 = (rgb1 >> 16) & 0xff;
073                    int g1 = (rgb1 >> 8) & 0xff;
074                    int b1 = rgb1 & 0xff;
075                    int a2 = (rgb2 >> 24) & 0xff;
076                    int r2 = (rgb2 >> 16) & 0xff;
077                    int g2 = (rgb2 >> 8) & 0xff;
078                    int b2 = rgb2 & 0xff;
079                    a1 = (a1+a2)/2;
080                    r1 = (r1+r2)/2;
081                    g1 = (g1+g2)/2;
082                    b1 = (b1+b2)/2;
083                    pixels[x] = (a1 << 24) | (r1 << 16) | (g1 << 8) | b1;
084                }
085                setRGB( dst, 0, y, width, 1, pixels );
086                setRGB( dst, 0, y+1, width, 1, pixels );
087            }
088        }
089
090        return dst;
091    }
092
093    public String toString() {
094        return "Video/De-Interlace";
095    }
096}