001// License: GPL. For details, see LICENSE file.
002package org.openstreetmap.josm.gui.layer.imagery;
003
004import java.util.Arrays;
005import java.util.List;
006import java.util.concurrent.CopyOnWriteArrayList;
007
008import org.openstreetmap.josm.gui.layer.ImageProcessor;
009
010/**
011 * This class holds the filter settings for an imagery layer.
012 * @author Michael Zangl
013 * @since 10547
014 */
015public class ImageryFilterSettings {
016
017    protected GammaImageProcessor gammaImageProcessor = new GammaImageProcessor();
018    protected SharpenImageProcessor sharpenImageProcessor = new SharpenImageProcessor();
019    protected ColorfulImageProcessor collorfulnessImageProcessor = new ColorfulImageProcessor();
020    private final List<FilterChangeListener> filterChangeListeners = new CopyOnWriteArrayList<>();
021
022    /**
023     * Returns the currently set gamma value.
024     * @return the currently set gamma value
025     */
026    public double getGamma() {
027        return gammaImageProcessor.getGamma();
028    }
029
030    /**
031     * Sets a new gamma value, {@code 1} stands for no correction.
032     * @param gamma new gamma value
033     */
034    public void setGamma(double gamma) {
035        gammaImageProcessor.setGamma(gamma);
036        fireListeners();
037    }
038
039    /**
040     * Gets the current sharpen level.
041     * @return The sharpen level.
042     */
043    public double getSharpenLevel() {
044        return sharpenImageProcessor.getSharpenLevel();
045    }
046
047    /**
048     * Sets the sharpen level for the layer.
049     * <code>1</code> means no change in sharpness.
050     * Values in range 0..1 blur the image.
051     * Values above 1 are used to sharpen the image.
052     * @param sharpenLevel The sharpen level.
053     */
054    public void setSharpenLevel(double sharpenLevel) {
055        sharpenImageProcessor.setSharpenLevel((float) sharpenLevel);
056        fireListeners();
057    }
058
059    /**
060     * Gets the colorfulness of this image.
061     * @return The colorfulness
062     */
063    public double getColorfulness() {
064        return collorfulnessImageProcessor.getColorfulness();
065    }
066
067    /**
068     * Sets the colorfulness of this image.
069     * 0 means grayscale.
070     * 1 means normal colorfulness.
071     * Values greater than 1 are allowed.
072     * @param colorfulness The colorfulness.
073     */
074    public void setColorfulness(double colorfulness) {
075        collorfulnessImageProcessor.setColorfulness(colorfulness);
076        fireListeners();
077    }
078
079    /**
080     * Gets the image processors for this setting.
081     * @return The processors in the order in which they should be applied.
082     */
083    public List<ImageProcessor> getProcessors() {
084        return Arrays.asList(collorfulnessImageProcessor, gammaImageProcessor, sharpenImageProcessor);
085    }
086
087    /**
088     * Adds a filter change listener
089     * @param l The listener
090     */
091    public void addFilterChangeListener(FilterChangeListener l) {
092        filterChangeListeners.add(l);
093    }
094
095    /**
096     * Removes a filter change listener
097     * @param l The listener
098     */
099    public void removeFilterChangeListener(FilterChangeListener l) {
100        filterChangeListeners.remove(l);
101    }
102
103    private void fireListeners() {
104        for (FilterChangeListener l : filterChangeListeners) {
105            l.filterChanged();
106        }
107    }
108
109    /**
110     * A listener that listens to filter changes
111     * @author Michael Zangl
112     * @since 10600 (functional interface)
113     */
114    @FunctionalInterface
115    public interface FilterChangeListener {
116        /**
117         * Invoked when the filter is changed.
118         */
119        void filterChanged();
120    }
121}