scalingfilter.java

来自「Sony Ericsson手机上的Facebook客户端全套代码」· Java 代码 · 共 393 行

JAVA
393
字号
// Decompiled by Jad v1.5.7g. Copyright 2000 Pavel Kouznetsov.
// Jad home page: http://www.geocities.com/SiliconValley/Bridge/8617/jad.html
// Decompiler options: packimports(3) 
// Source File Name:   ScalingFilter.java

package se.southend.drops.pixelfilter;

import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.Image;
import se.southend.drops.scene.Node;

// Referenced classes of package se.southend.drops.pixelfilter:
//            Filter, RGBTools

public class ScalingFilter
    implements Filter
{

    public ScalingFilter()
    {
        filtering = 0;
        width = 0;
        height = 0;
    }

    public ScalingFilter(Image fromImage)
    {
        filtering = 0;
        width = 0;
        height = 0;
        setImage(fromImage);
    }

    public void setImage(Image fromImage)
    {
        if(fromImage == null)
        {
            return;
        } else
        {
            int width = fromImage.getWidth();
            int height = fromImage.getHeight();
            int fromRGB[] = new int[width * height];
            fromImage.getRGB(fromRGB, 0, width, 0, 0, width, height);
            setRGB(fromRGB, width, height);
            return;
        }
    }

    public void setRGB(int fromRGB[], int width, int height)
    {
        this.fromRGB = fromRGB;
        srcWidth = width;
        srcHeight = height;
        if(this.width == 0 || this.height == 0)
            setSize(width, height);
    }

    public Image getImage()
    {
        return Image.createRGBImage(getRGB(), getWidth(), getHeight(), true);
    }

    public int[] getRGB()
    {
        return rgb;
    }

    public int getWidth()
    {
        return width;
    }

    public int getHeight()
    {
        return height;
    }

    public void setMaxMemoryUsage(int maxUsage)
    {
        this.maxUsage = maxUsage;
    }

    public int getMemoryUsage()
    {
        int fromRGBLength = fromRGB == null ? 0 : fromRGB.length << 2;
        int rgbLength = rgb == null ? 0 : rgb.length << 2;
        return fromRGBLength + rgbLength;
    }

    public void setOutputRGB(int outRGB[])
    {
        this.outRGB = outRGB;
        rgb = outRGB;
    }

    public void setFiltering(int filtering)
    {
        this.filtering = filtering;
        needsRender = true;
    }

    public void setSize(int width, int height)
    {
        if(width == this.width && height == this.height)
        {
            return;
        } else
        {
            this.width = width;
            this.height = height;
            needsRender = true;
            return;
        }
    }

    public void render()
    {
        if(filtering == 1)
        {
            if(outRGB == null)
                rgb = new int[width * height];
            rgb = scaleLinear(fromRGB, srcWidth, srcHeight, rgb, width, height);
        } else
        if(filtering == 2)
        {
            int srcRGB[] = fromRGB;
            int currWidth = srcWidth;
            int currHeight = srcHeight;
            if(width < srcWidth >>> 1 && height < srcHeight >>> 1)
            {
                int midWidth = currWidth >> 1;
                int midHeight;
                for(midHeight = currHeight >> 1; midWidth > width && midHeight > height; midHeight >>>= 1)
                {
                    rgb = srcRGB;
                    srcRGB = new int[midWidth * midHeight];
                    srcRGB = scaleToHalf(rgb, srcRGB, currWidth, currHeight);
                    currWidth >>>= 1;
                    currHeight >>>= 1;
                    midWidth >>>= 1;
                }

                if(outRGB == null)
                    rgb = new int[width * height];
                rgb = scaleLinear(srcRGB, midWidth << 1, midHeight << 1, rgb, width, height);
            } else
            {
                if(outRGB == null)
                    rgb = new int[width * height];
                rgb = scaleLinear(srcRGB, srcWidth, srcHeight, rgb, width, height);
            }
        } else
        {
            if(outRGB == null)
                rgb = new int[width * height];
            rgb = scaleNearest(fromRGB, srcWidth, srcHeight, rgb, width, height);
        }
        needsRender = false;
    }

    public void paintAt(Graphics graphics, int x, int y)
    {
        if(!segmentedPaintAt(graphics, x, y))
        {
            if(needsRender)
                render();
            graphics.drawRGB(rgb, 0, width, x, y, width, height, true);
        }
    }

    public boolean segmentedPaintAt(Graphics graphics, int x, int y)
    {
        if(filtering != 0)
            return false;
        if(maxUsage > 0)
        {
            int xBeg = x <= 0 ? 0 : x;
            int xEnd = x + width >= Node.SCREEN_WIDTH ? Node.SCREEN_WIDTH : x + width;
            int segmentWidth = xEnd - xBeg;
            if(segmentWidth <= 0)
                return true;
            segmentHeight = (maxUsage - (fromRGB.length << 2)) / segmentWidth >> 2;
            if(segmentHeight < height)
            {
                if(segmentHeight < 1)
                    segmentHeight = 1;
                int yBeg = y <= 0 ? 0 : y;
                int yEnd = y + height >= Node.SCREEN_HEIGHT ? Node.SCREEN_HEIGHT : y + height;
                rgb = new int[segmentWidth * segmentHeight];
                for(int segmentBeg = yBeg; segmentBeg < yEnd; segmentBeg += segmentHeight)
                {
                    int segmentEnd = segmentBeg + segmentHeight;
                    if(segmentEnd > yEnd)
                        segmentEnd = yEnd;
                    if(filtering == 1)
                    {
                        if(segmentHeight < height - segmentBeg)
                            segmentBeg--;
                    } else
                    {
                        rgb = scaleRegionNearest(fromRGB, srcWidth, srcHeight, rgb, width, height, 0, 0, xBeg - x, segmentBeg - y, segmentWidth, segmentEnd - segmentBeg);
                    }
                    graphics.drawRGB(rgb, 0, segmentWidth, xBeg, segmentBeg, segmentWidth, segmentEnd - segmentBeg, true);
                }

                return true;
            }
        }
        return false;
    }

    public static final int[] scaleToHalf(int src[], int dest[], int srcWidth, int srcHeight)
    {
        int width = srcWidth >> 1;
        int height = srcHeight >> 1;
        for(int y = 0; y < height; y++)
        {
            int y_width = y * width;
            int y_srcWidth = y * srcWidth;
            for(int x = 0; x < width; x++)
            {
                int srcPos = x + y_srcWidth << 1;
                dest[x + y_width] = (src[srcPos] >> 2 & 0x3f3f3f3f) + (src[srcPos + 1] >> 2 & 0x3f3f3f3f) + (src[srcPos + srcWidth] >> 2 & 0x3f3f3f3f) + (src[srcPos + srcWidth + 1] >> 2 & 0x3f3f3f3f);
            }

        }

        return dest;
    }

    public static final int[] scaleToDouble(int src[], int dest[], int srcWidth, int srcHeight)
    {
        int width = srcWidth << 1;
        for(int y = 1; y < srcHeight - 1; y++)
        {
            int y_width = y * width;
            int y_srcWidth = y * srcWidth;
            for(int x = 1; x < srcWidth - 1; x++)
            {
                int srcPos = x + y_srcWidth;
                int destPos = x + y_width << 1;
                dest[destPos] = src[srcPos];
                dest[destPos + 1] = src[srcPos];
                dest[destPos + width] = src[srcPos];
                dest[destPos + width + 1] = src[srcPos];
            }

        }

        return dest;
    }

    public static final int[] scaleLinear(int src[], int srcWidth, int srcHeight, int dest[], int width, int height)
    {
        int mid[] = new int[width * srcHeight];
        int dx = (srcWidth - 1 << 16) / width;
        int dy = (srcHeight - 1 << 16) / height;
        int xBeg = (srcWidth << 16) - dx * width >> 1;
        int yBeg = (srcHeight << 16) - dy * height >> 1;
        int destWidth = width - 1;
        int destHeight = height - 1;
        for(int y = 0; y < srcHeight; y++)
        {
            int xSrc = xBeg;
            int y_width = y * width;
            int y_srcWidth = y * srcWidth;
            for(int x = 0; x < destWidth; x++)
            {
                int xSrcInteger = xSrc >> 16;
                mid[x + y_width] = RGBTools.blend16(src[xSrcInteger + y_srcWidth], src[xSrcInteger + 1 + y_srcWidth], xSrc - (xSrcInteger << 16) >> 12);
                xSrc += dx;
            }

        }

        int ySrc = yBeg;
        for(int y = 0; y < destHeight; y++)
        {
            int y_width = y * width;
            int ySrcInteger = ySrc >> 16;
            int ySrcInteger_width = ySrcInteger * width;
            for(int x = 0; x < width; x++)
                dest[x + y_width] = RGBTools.blend16(mid[x + ySrcInteger_width], mid[x + ySrcInteger_width + width], ySrc - (ySrcInteger << 16) >> 12);

            ySrc += dy;
        }

        return dest;
    }

    public static final int[] scaleNearest(int src[], int srcWidth, int srcHeight, int dest[], int width, int height)
    {
        int dx = (srcWidth << 16) / width;
        int dy = (srcHeight << 16) / height;
        int ySrc = dy >> 1;
        for(int y = 0; y < height; y++)
        {
            int xSrc = dx >> 1;
            int y_width = y * width;
            int ySrcInteger_srcWidth = (ySrc >> 16) * srcWidth;
            for(int x = 0; x < width; x++)
            {
                int xSrcInteger = xSrc >> 16;
                dest[x + y_width] = src[xSrcInteger + ySrcInteger_srcWidth];
                xSrc += dx;
            }

            ySrc += dy;
        }

        return dest;
    }

    public static final int[] scaleRegionLinear(int src[], int srcWidth, int srcHeight, int dest[], int width, int height, int xDest, int yDest, 
            int regionX, int regionY, int regionWidth, int regionHeight)
    {
        int mid[] = new int[regionWidth * regionHeight];
        int dx = (srcWidth - 2 << 16) / width;
        int dy = (srcHeight - 2 << 16) / height;
        int ySrc = regionY * dy + 127;
        for(int y = 0; y < regionHeight - 1; y++)
        {
            int y_srcWidth = y * srcWidth;
            int ySrcInteger = ySrc >> 16;
            int ySrcInteger_srcWidth = ySrcInteger * srcWidth;
            for(int x = 0; x < srcWidth; x++)
                mid[x + y_srcWidth] = RGBTools.blend16(src[x + ySrcInteger_srcWidth], src[x + ySrcInteger_srcWidth + srcWidth], ySrc - (ySrcInteger << 16) >> 12);

            ySrc += dy;
        }

        for(int y = 0; y < regionHeight; y++)
        {
            int xSrc = 127;
            int y_width = y * width;
            int y_srcWidth = y * srcWidth;
            for(int x = 0; x < width - 1; x++)
            {
                int xSrcInteger = xSrc >> 8;
                dest[x + y_width] = RGBTools.blend16(mid[xSrcInteger + y_srcWidth], mid[xSrcInteger + 1 + y_srcWidth], xSrc - (xSrcInteger << 16) >> 12);
                xSrc += dx;
            }

        }

        return dest;
    }

    public static final int[] scaleRegionNearest(int src[], int srcWidth, int srcHeight, int dest[], int width, int height, int xDest, int yDest, 
            int regionX, int regionY, int regionWidth, int regionHeight)
    {
        int xBeg = xDest <= 0 ? 0 : xDest;
        int yBeg = yDest <= 0 ? 0 : yDest;
        int xEnd = xDest + regionWidth >= width ? width : xDest + regionWidth;
        int yEnd = yDest + regionHeight >= height ? height : yDest + regionHeight;
        int dx = (srcWidth << 16) / width;
        int dy = (srcHeight << 16) / height;
        int ySrc = regionY * dy;
        for(int y = yBeg; y < yEnd; y++)
        {
            int xSrc = regionX * dx;
            int y_width = y * regionWidth;
            int ySrcInteger_srcWidth = (ySrc >> 16) * srcWidth;
            for(int x = xBeg; x < xEnd; x++)
            {
                int xSrcInteger = xSrc >> 16;
                dest[x + y_width] = src[xSrcInteger + ySrcInteger_srcWidth];
                xSrc += dx;
            }

            ySrc += dy;
        }

        return dest;
    }

    public static final int FILTER_NEAREST = 0;
    public static final int FILTER_LINEAR = 1;
    public static final int FILTER_MIPMAP = 2;
    private int filtering;
    protected int fromRGB[];
    protected int rgb[];
    protected int width;
    protected int height;
    protected int srcWidth;
    protected int srcHeight;
    private int outRGB[];
    private int maxUsage;
    private int segmentHeight;
    private boolean needsRender;
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?