/* JWildfire - an image and animation processor written in Java Copyright (C) 1995-2017 Andreas Maschke This is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this software; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ package org.jwildfire.create.tina.render; import java.io.Serializable; import org.jwildfire.base.mathlib.MathLib; import org.jwildfire.create.tina.base.Flame; import org.jwildfire.create.tina.render.filter.FilterKernel; import org.jwildfire.create.tina.render.filter.FilterKernelType; public class FilterHolder implements Serializable { protected double filter[][]; protected int noiseFilterSize; protected int noiseFilterSizeHalve; protected final FilterKernel filterKernel; private final FilterKernelType filterKernelType; protected final int oversample; private final double intensity; private FilterIndicator filterIndicator = FilterIndicator.GREY; public FilterHolder(Flame pFlame) { this(pFlame.getSpatialFilterKernel(), pFlame.getSpatialOversampling(), pFlame.getSpatialFilterRadius()); } public FilterHolder(FilterKernelType pSpatialFilterKernel, int pSpatialOversampling, double pSpatialFilterRadius) { oversample = pSpatialOversampling; filterKernelType = pSpatialFilterKernel; filterKernel = filterKernelType.createFilterInstance(); noiseFilterSize = filterKernel.getFilterSize(pSpatialFilterRadius, oversample); noiseFilterSizeHalve = noiseFilterSize / 2 - 1; intensity = pSpatialFilterRadius; filter = new double[noiseFilterSize][noiseFilterSize]; initFilter(pSpatialFilterRadius, noiseFilterSize, filter); } private void initFilter(double pFilterRadius, int pFilterSize, double[][] pFilter) { double adjust = filterKernel.getFilterAdjust(pFilterRadius, oversample); double sum = 0.0; for (int i = 0; i < pFilterSize; i++) { for (int j = 0; j < pFilterSize; j++) { double ii = ((2.0 * i + 1.0) / pFilterSize - 1.0) * adjust; double jj = ((2.0 * j + 1.0) / pFilterSize - 1.0) * adjust; double f = filterKernel.getFilterCoeff(MathLib.sqrt(ii * ii + jj * jj)); // double f = filterKernel.getFilterCoeff(ii) * filterKernel.getFilterCoeff(jj); sum += f; pFilter[i][j] = f; } } // normalize { for (int i = 0; i < pFilterSize; i++) { for (int j = 0; j < pFilterSize; j++) { pFilter[i][j] = pFilter[i][j] / sum * oversample * oversample; } } } } public int getNoiseFilterSize() { return noiseFilterSize; } public double[][] getFilter() { return filter; } public boolean isEmpty() { return noiseFilterSize <= 1; } public FilterIndicator getFilterIndicator() { return filterIndicator; } public void setFilterIndicator(FilterIndicator filterIndicator) { this.filterIndicator = filterIndicator; } public double getIntensity() { return intensity; } public FilterKernelType getFilterKernelType() { return filterKernelType; } }