package com.jotuntech.sketcher.common.filter; import com.jotuntech.sketcher.common.Pixels; public class AutoContrastFilter implements Filter { int[] alphaHistogram, colorHistogram; int alphaBlackPoint, alphaWhitePoint, colorBlackPoint, colorWhitePoint, totalPixels, alphaRange, colorRange; float maxBlackFraction, maxWhiteFraction; public AutoContrastFilter() { } public void setSize(int width, int height) { } public void setParameterA(float a) { maxBlackFraction = a; } public void setParameterB(float b) { maxWhiteFraction = b; } public void setParameterC(float c) { } public boolean isPass1ReadOnly() { return true; } public boolean hasPass2() { return true; } public boolean isPass2Reversed() { return false; } public void startPass1() { totalPixels = 0; alphaHistogram = new int[256]; colorHistogram = new int[256]; } public int processPass1Pixel(int pixel) { int alpha = Pixels.getChannel0(pixel); if(alpha > 0) { ++alphaHistogram[alpha]; ++colorHistogram[(Pixels.getChannel1(pixel) + (Pixels.getChannel2(pixel) << 1) + Pixels.getChannel3(pixel)) >> 2]; ++totalPixels; } return pixel; } public void startPass2() { int maxBlackPixels = (int) Math.ceil(maxBlackFraction * totalPixels); int maxWhitePixels = (int) Math.ceil(maxWhiteFraction * totalPixels); alphaBlackPoint = 0; for(int alphaBlackPixels = 0; alphaBlackPixels + alphaHistogram[alphaBlackPoint] <= maxBlackPixels && alphaBlackPoint < alphaHistogram.length; alphaBlackPixels += alphaHistogram[alphaBlackPoint++]) { } alphaWhitePoint = alphaHistogram.length - 1; for(int alphaWhitePixels = 0; alphaWhitePixels + alphaHistogram[alphaWhitePoint] <= maxWhitePixels && alphaWhitePoint >= 0; alphaWhitePixels += alphaHistogram[alphaWhitePoint--]) { } System.err.println("alphaBlackPoint = " + alphaBlackPoint); System.err.println("alphaWhitePoint = " + alphaWhitePoint); alphaRange = alphaWhitePoint - alphaBlackPoint; if(alphaRange <= 0) { alphaBlackPoint = 0; alphaWhitePoint = 255; alphaRange = 255; } colorBlackPoint = 0; for(int colorBlackPixels = 0; colorBlackPixels + colorHistogram[colorBlackPoint] <= maxBlackPixels && colorBlackPoint < colorHistogram.length; colorBlackPixels += colorHistogram[colorBlackPoint++]) { } colorWhitePoint = colorHistogram.length - 1; for(int colorWhitePixels = 0; colorWhitePixels + colorHistogram[colorWhitePoint] <= maxWhitePixels && colorWhitePoint >= 0; colorWhitePixels += colorHistogram[colorWhitePoint--]) { } System.err.println("colorBlackPoint = " + colorBlackPoint); System.err.println("colorWhitePoint = " + colorWhitePoint); colorRange = colorWhitePoint - colorBlackPoint; if(colorRange <= 0) { colorBlackPoint = 0; colorWhitePoint = 255; colorRange = 255; } } public int processPass2Pixel(int pixel) { int alpha = Math.min(255, Math.max(0, Pixels.getChannel0(pixel) - alphaBlackPoint) * 255 / alphaRange); int red = Math.min(255, Math.max(0, Pixels.getChannel1(pixel) - colorBlackPoint) * 255 / colorRange); int green = Math.min(255, Math.max(0, Pixels.getChannel2(pixel) - colorBlackPoint) * 255 / colorRange); int blue = Math.min(255, Math.max(0, Pixels.getChannel3(pixel) - colorBlackPoint) * 255 / colorRange); return Pixels.pack(alpha, red, green, blue); } }