MultitoneOp.java 6.17 KB
/*
 * Decompiled with CFR 0_118.
 */
package com.day.image;

import com.day.image.AbstractBufferedImageOp;
import com.day.image.ColorCurve;
import java.awt.Color;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.awt.image.ByteLookupTable;
import java.awt.image.LookupOp;
import java.awt.image.LookupTable;
import java.awt.image.ShortLookupTable;
import java.awt.image.WritableRaster;

public class MultitoneOp
extends AbstractBufferedImageOp {
    private static final LookupTableHelper tableHelper;
    private final ColorCurve[] colorCurves;
    private final float maxAlpha;

    public MultitoneOp(Color color, RenderingHints hints) {
        this(new Color[]{color}, hints);
    }

    public MultitoneOp(Color[] colors, RenderingHints hints) {
        super(hints);
        if (colors == null) {
            throw new NullPointerException("colors");
        }
        this.colorCurves = new ColorCurve[colors.length];
        for (int i = 0; i < colors.length; ++i) {
            if (colors[i] == null) {
                throw new NullPointerException("colors[" + i + "]");
            }
            this.colorCurves[i] = new ColorCurve(colors[i]);
        }
        this.maxAlpha = this.calculateMaxAlpha();
    }

    public MultitoneOp(ColorCurve[] colorCurves, RenderingHints hints) {
        super(hints);
        if (colorCurves == null) {
            throw new NullPointerException("colorCurves");
        }
        this.colorCurves = new ColorCurve[colorCurves.length];
        for (int i = 0; i < colorCurves.length; ++i) {
            if (colorCurves[i] == null) {
                throw new NullPointerException("colorCurves" + i + "]");
            }
            this.colorCurves[i] = new ColorCurve(colorCurves[i]);
        }
        this.maxAlpha = this.calculateMaxAlpha();
    }

    public BufferedImage filter(BufferedImage src, BufferedImage dst) {
        if (src != null && src == dst) {
            this.doFilter(src, dst);
            return dst;
        }
        return super.filter(src, dst);
    }

    protected void doFilter(BufferedImage src, BufferedImage dst) {
        int numcols = this.colorCurves.length;
        float[][] cols = new float[numcols][4];
        for (int i = 0; i < numcols; ++i) {
            this.colorCurves[i].getColor().getColorComponents(cols[i]);
        }
        LookupTableHelper helper = tableHelper.getInstance();
        for (int i2 = 0; i2 < 256; ++i2) {
            float alpha = 0.0f;
            float red = 0.0f;
            float green = 0.0f;
            float blue = 0.0f;
            for (int j = 0; j < numcols; ++j) {
                float coljalpha = this.colorCurves[j].getLevel(i2);
                alpha += (coljalpha /= this.maxAlpha);
                red += cols[j][0] * coljalpha;
                green += cols[j][1] * coljalpha;
                blue += cols[j][2] * coljalpha;
            }
            if (alpha < 1.0f) {
                alpha = 1.0f - alpha * 1.3f;
                red += alpha;
                green += alpha;
                blue += alpha;
            }
            if (red > 1.0f) {
                red = 1.0f;
            } else if (red < 0.0f) {
                red = 0.0f;
            }
            if (green > 1.0f) {
                green = 1.0f;
            } else if (green < 0.0f) {
                green = 0.0f;
            }
            if (blue > 1.0f) {
                blue = 1.0f;
            } else if (blue < 0.0f) {
                blue = 0.0f;
            }
            helper.addMapping(255 - i2, 255.0f * red, 255.0f * green, 255.0f * blue, 255.0f);
        }
        int w = src.getWidth();
        int h = src.getHeight();
        int[] srcAlpha = src.getRaster().getSamples(0, 0, w, h, 3, (int[])null);
        LookupOp lop = new LookupOp(helper.getLookupTable(), this.getRenderingHints());
        lop.filter(src, dst);
        dst.getRaster().setSamples(0, 0, w, h, 3, srcAlpha);
    }

    private float calculateMaxAlpha() {
        float maxAlpha = 0.0f;
        for (int i = 0; i < 256; ++i) {
            float alpha = 0.0f;
            for (int j = 0; j < this.colorCurves.length; ++j) {
                alpha += this.colorCurves[j].getLevel(i);
            }
            if (alpha <= maxAlpha) continue;
            maxAlpha = alpha;
        }
        return maxAlpha;
    }

    static {
        String os = System.getProperty("os.name", "-").toLowerCase();
        tableHelper = os.indexOf("linux") >= 0 ? new ShortLookupTableHelper(null) : new ByteLookupTableHelper(null);
    }

    private static class ShortLookupTableHelper
    implements LookupTableHelper {
        private final short[][] table;

        private ShortLookupTableHelper(short[][] table) {
            this.table = table;
        }

        public LookupTableHelper getInstance() {
            return new ShortLookupTableHelper(new short[4][256]);
        }

        public void addMapping(int index, float red, float green, float blue, float alpha) {
            this.table[0][index] = (short)red;
            this.table[1][index] = (short)green;
            this.table[2][index] = (short)blue;
            this.table[3][index] = (short)alpha;
        }

        public LookupTable getLookupTable() {
            return new ShortLookupTable(0, this.table);
        }
    }

    private static class ByteLookupTableHelper
    implements LookupTableHelper {
        private final byte[][] table;

        private ByteLookupTableHelper(byte[][] table) {
            this.table = table;
        }

        public LookupTableHelper getInstance() {
            return new ByteLookupTableHelper(new byte[4][256]);
        }

        public void addMapping(int index, float red, float green, float blue, float alpha) {
            this.table[0][index] = (byte)red;
            this.table[1][index] = (byte)green;
            this.table[2][index] = (byte)blue;
            this.table[3][index] = (byte)alpha;
        }

        public LookupTable getLookupTable() {
            return new ByteLookupTable(0, this.table);
        }
    }

    private static interface LookupTableHelper {
        public LookupTableHelper getInstance();

        public void addMapping(int var1, float var2, float var3, float var4, float var5);

        public LookupTable getLookupTable();
    }

}