#pragma once
/*
 *  $Id: filters.h 29624 2026-03-19 18:44:31Z yeti-dn $
 *  Copyright (C) 2003-2026 David Necas (Yeti), Petr Klapetek.
 *  E-mail: yeti@gwyddion.net, klapetek@gwyddion.net.
 *
 *  This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public
 *  License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any
 *  later version.
 *
 *  This program 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 General Public License for more
 *  details.
 *
 *  You should have received a copy of the GNU General Public License along with this program; if not, write to the
 *  Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 */

#ifndef __GWY_FILTERS_H__
#define __GWY_FILTERS_H__

#include <libgwyddion/field.h>
#include <libgwyddion/nield.h>
#include <libgwyddion/enums.h>

G_BEGIN_DECLS

typedef enum {
    GWY_DERIVATIVE_FILTER_XDER     = 0,
    GWY_DERIVATIVE_FILTER_YDER     = 1,
    GWY_DERIVATIVE_FILTER_DER      = 2,
    GWY_DERIVATIVE_FILTER_HPREWITT = 4,
    GWY_DERIVATIVE_FILTER_VPREWITT = 5,
    GWY_DERIVATIVE_FILTER_PREWITT  = 6,
    GWY_DERIVATIVE_FILTER_HSOBEL   = 8,
    GWY_DERIVATIVE_FILTER_VSOBEL   = 9,
    GWY_DERIVATIVE_FILTER_SOBEL    = 10,
    GWY_DERIVATIVE_FILTER_HSCHARR  = 12,
    GWY_DERIVATIVE_FILTER_VSCHARR  = 13,
    GWY_DERIVATIVE_FILTER_SCHARR   = 14,
    GWY_DERIVATIVE_FILTER_XDER2    = 16,
    GWY_DERIVATIVE_FILTER_YDER2    = 17,
    GWY_DERIVATIVE_FILTER_XYDER    = 18,
    GWY_DERIVATIVE_FILTER_SXDER2   = 19,
    GWY_DERIVATIVE_FILTER_SYDER2   = 20,
    GWY_DERIVATIVE_FILTER_DET2DER  = 21,
    GWY_DERIVATIVE_FILTER_LAPLACE  = 22,
} GwyDerivativeFilterType;

typedef enum {
    GWY_ENHANCE_FILTER_KUWAHARA     = 0,
    GWY_ENHANCE_FILTER_MLV          = 1,
    GWY_ENHANCE_FILTER_DECHECKER    = 2,
} GwyEnhanceFilterType;

typedef enum {
    GWY_MIN_MAX_FILTER_MINIMUM       = 0,
    GWY_MIN_MAX_FILTER_EROSION       = 0,
    GWY_MIN_MAX_FILTER_FROSION       = 1,
    GWY_MIN_MAX_FILTER_MAXIMUM       = 2,
    GWY_MIN_MAX_FILTER_DILATION      = 3,
    GWY_MIN_MAX_FILTER_OPENING       = 4,
    GWY_MIN_MAX_FILTER_CLOSING       = 5,
    GWY_MIN_MAX_FILTER_RANGE         = 6,
    GWY_MIN_MAX_FILTER_NORMALIZATION = 7,
} GwyMinMaxFilterType;

void     gwy_field_normalize                        (GwyField *field);
void     gwy_field_renormalize                      (GwyField *field,
                                                     gdouble range,
                                                     gdouble offset);
void     gwy_field_area_renormalize                 (GwyField *field,
                                                     gint col,
                                                     gint row,
                                                     gint width,
                                                     gint height,
                                                     gdouble range,
                                                     gdouble offset);
gsize    gwy_field_threshold                        (GwyField *field,
                                                     gdouble threshold,
                                                     gdouble below,
                                                     gdouble above);
gsize    gwy_field_area_threshold                   (GwyField *field,
                                                     gint col,
                                                     gint row,
                                                     gint width,
                                                     gint height,
                                                     gdouble threshold,
                                                     gdouble below,
                                                     gdouble above);
gsize    gwy_field_clamp                            (GwyField *field,
                                                     gdouble bottom,
                                                     gdouble top);
gsize    gwy_field_area_clamp                       (GwyField *field,
                                                     GwyNield *mask,
                                                     GwyMaskingType masking,
                                                     gint col,
                                                     gint row,
                                                     gint width,
                                                     gint height,
                                                     gdouble bottom,
                                                     gdouble top);
void     gwy_field_area_gather                      (GwyField *field,
                                                     GwyField *result,
                                                     GwyField *buffer,
                                                     gint hsize,
                                                     gint vsize,
                                                     gboolean average,
                                                     gint col,
                                                     gint row,
                                                     gint width,
                                                     gint height);
void     gwy_field_area_filter_3x3                  (GwyField *field,
                                                     GwyField *target,
                                                     GwyNield *mask,
                                                     GwyMaskingType masking,
                                                     gint col,
                                                     gint row,
                                                     gint width,
                                                     gint height,
                                                     const gdouble *kernel);
void     gwy_field_filter_3x3                       (GwyField *field,
                                                     GwyField *target,
                                                     const gdouble *kernel);
void     gwy_field_area_enhance_filter              (GwyField *field,
                                                     GwyField *target,
                                                     GwyNield *mask,
                                                     GwyMaskingType masking,
                                                     gint col,
                                                     gint row,
                                                     gint width,
                                                     gint height,
                                                     GwyEnhanceFilterType filter_type);
void     gwy_field_enhance_filter                   (GwyField *field,
                                                     GwyField *target,
                                                     GwyEnhanceFilterType filter_type);
void     gwy_field_derivative_filter                (GwyField *field,
                                                     GwyField *target,
                                                     GwyDerivativeFilterType filter_type,
                                                     gboolean as_derivative);
void     gwy_field_convolve                         (GwyField *field,
                                                     GwyField *kernel_field);
void     gwy_field_area_convolve                    (GwyField *field,
                                                     GwyField *kernel_field,
                                                     gint col,
                                                     gint row,
                                                     gint width,
                                                     gint height);
void     gwy_field_fft_convolve                     (GwyField *field,
                                                     GwyField *kernel_field);
void     gwy_field_area_ext_convolve                (GwyField *field,
                                                     guint col,
                                                     guint row,
                                                     guint width,
                                                     guint height,
                                                     GwyField *target,
                                                     GwyField *kernel,
                                                     GwyExteriorType exterior,
                                                     gdouble fill_value,
                                                     gboolean as_integral);
void     gwy_field_convolve_1d                      (GwyField *field,
                                                     GwyLine *kernel_line,
                                                     GwyOrientation orientation);
void     gwy_field_area_convolve_1d                 (GwyField *field,
                                                     GwyLine *kernel_line,
                                                     GwyOrientation orientation,
                                                     gint col,
                                                     gint row,
                                                     gint width,
                                                     gint height);
void     gwy_field_area_ext_row_convolve            (GwyField *field,
                                                     guint col,
                                                     guint row,
                                                     guint width,
                                                     guint height,
                                                     GwyField *target,
                                                     GwyLine *kernel,
                                                     GwyExteriorType exterior,
                                                     gdouble fill_value,
                                                     gboolean as_integral);
void     gwy_field_filter_median                    (GwyField *field,
                                                     gint size);
void     gwy_field_area_filter_median               (GwyField *field,
                                                     gint size,
                                                     gint col,
                                                     gint row,
                                                     gint width,
                                                     gint height);
void     gwy_field_filter_mean                      (GwyField *field,
                                                     gint size);
void     gwy_field_area_filter_mean                 (GwyField *field,
                                                     gint size,
                                                     gint col,
                                                     gint row,
                                                     gint width,
                                                     gint height);
void     gwy_field_filter_conservative              (GwyField *field,
                                                     gint size);
void     gwy_field_area_filter_conservative         (GwyField *field,
                                                     gint size,
                                                     gint col,
                                                     gint row,
                                                     gint width,
                                                     gint height);
void     gwy_field_laplacian_of_gaussians           (GwyField *field,
                                                     GwyField *target);
void     gwy_field_filter_gauss_step                (GwyField *field,
                                                     GwyField *target,
                                                     gdouble sigma);
void     gwy_field_filter_gaussian                  (GwyField *field,
                                                     gdouble sigma);
void     gwy_field_area_filter_gaussian             (GwyField *field,
                                                     gdouble sigma,
                                                     gint col,
                                                     gint row,
                                                     gint width,
                                                     gint height);
void     gwy_field_row_gaussian                     (GwyField *field,
                                                     gdouble sigma);
void     gwy_field_column_gaussian                  (GwyField *field,
                                                     gdouble sigma);
void     gwy_field_filter_minimum                   (GwyField *field,
                                                     gint size);
void     gwy_field_area_filter_minimum              (GwyField *field,
                                                     gint size,
                                                     gint col,
                                                     gint row,
                                                     gint width,
                                                     gint height);
void     gwy_field_filter_maximum                   (GwyField *field,
                                                     gint size);
void     gwy_field_area_filter_maximum              (GwyField *field,
                                                     gint size,
                                                     gint col,
                                                     gint row,
                                                     gint width,
                                                     gint height);
void     gwy_field_filter_min_max                   (GwyField *field,
                                                     GwyNield *kernel,
                                                     GwyMinMaxFilterType filtertype);
void     gwy_field_area_filter_min_max              (GwyField *field,
                                                     GwyNield *kernel,
                                                     GwyMinMaxFilterType filtertype,
                                                     gint col,
                                                     gint row,
                                                     gint width,
                                                     gint height);
void     gwy_field_area_filter_disc_asf             (GwyField *field,
                                                     gint radius,
                                                     gboolean closing,
                                                     gint col,
                                                     gint row,
                                                     gint width,
                                                     gint height);
void     gwy_nield_filter_min_max                   (GwyNield *nield,
                                                     GwyNield *kernel,
                                                     GwyMinMaxFilterType filtertype);
void     gwy_nield_area_filter_min_max              (GwyNield *nield,
                                                     GwyNield *kernel,
                                                     GwyMinMaxFilterType filtertype,
                                                     gint col,
                                                     gint row,
                                                     gint width,
                                                     gint height);
void     gwy_nield_area_filter_disc_asf             (GwyNield *nield,
                                                     gint radius,
                                                     gboolean closing,
                                                     gint col,
                                                     gint row,
                                                     gint width,
                                                     gint height);
gboolean gwy_field_area_filter_kth_rank             (GwyField *field,
                                                     GwyNield *kernel,
                                                     gint col,
                                                     gint row,
                                                     gint width,
                                                     gint height,
                                                     gint k,
                                                     GwySetFractionFunc set_fraction);
void     gwy_line_part_filter_kth_rank              (GwyLine *line,
                                                     gint klen,
                                                     gint pos,
                                                     gint len,
                                                     gint k);
gboolean gwy_field_area_filter_trimmed_mean         (GwyField *field,
                                                     GwyNield *kernel,
                                                     gint col,
                                                     gint row,
                                                     gint width,
                                                     gint height,
                                                     gint nlowest,
                                                     gint nhighest,
                                                     GwySetFractionFunc set_fraction);
void     gwy_field_filter_rms                       (GwyField *field,
                                                     GwyField *target,
                                                     gint size);
void     gwy_field_filter_canny                     (GwyField *field,
                                                     GwyField *target,
                                                     gdouble threshold);
void     gwy_field_shade                            (GwyField *field,
                                                     GwyField *target,
                                                     gdouble theta,
                                                     gdouble phi);
void     gwy_field_filter_harris                    (GwyField *x_gradient,
                                                     GwyField *y_gradient,
                                                     GwyField *result,
                                                     gint neighbourhood,
                                                     gdouble alpha);
void     gwy_field_deconvolve_regularized           (GwyField *field,
                                                     GwyField *operand,
                                                     GwyField *out,
                                                     gdouble sigma);
void     gwy_field_deconvolve_psf_leastsq           (GwyField *field,
                                                     GwyField *operand,
                                                     GwyField *out,
                                                     gdouble sigma,
                                                     gint border);
gdouble  gwy_field_find_regularization_sigma_for_psf(GwyField *field,
                                                     GwyField *ideal);
gdouble  gwy_field_find_regularization_sigma_leastsq(GwyField *field,
                                                     GwyField *ideal,
                                                     gint width,
                                                     gint height,
                                                     gint border);

G_END_DECLS

#endif

/* vim: set cin columns=120 tw=118 et ts=4 sw=4 cino=>1s,e0,n0,f0,{0,}0,^0,\:1s,=0,g1s,h0,t0,+1s,c3,(0,u0 : */
