#pragma once
/*
 *  $Id: correct.h 29862 2026-04-21 15:29:47Z 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_CORRECT_H__
#define __GWY_CORRECT_H__

#include <libgwyddion/math.h>
#include <libgwyddion/field.h>

G_BEGIN_DECLS

typedef enum {
    GWY_SYMMETRY_AUTO,
    GWY_SYMMETRY_PARALLEL,
    GWY_SYMMETRY_TRIANGULAR,
    GWY_SYMMETRY_SQUARE,
    GWY_SYMMETRY_RHOMBIC,
    GWY_SYMMETRY_HEXAGONAL,
    GWY_SYMMETRY_LAST
} GwyPlaneSymmetry;

typedef enum {
    GWY_AFFINE_SCALING_AS_GIVEN      = 0,
    GWY_AFFINE_SCALING_PRESERVE_AREA = 1,
    GWY_AFFINE_SCALING_PRESERVE_X    = 2,
} GwyAffineScalingType;

typedef enum {
    GWY_LAPLACE_UNMASKED   = 0,
    GWY_LAPLACE_MASKED     = -1,
    GWY_LAPLACE_ALL_GRAINS = -2,
} GwyLaplaceAll;

typedef void (*GwyCoordTransform2DFunc)(gdouble x,
                                        gdouble y,
                                        gdouble *px,
                                        gdouble *py,
                                        gpointer user_data);

const GwyEnum*   gwy_plane_symmetry_get_enum           (void)                             G_GNUC_CONST;
void             gwy_field_laplace_solve               (GwyField *field,
                                                        GwyNield *mask,
                                                        gint grain_id,
                                                        gdouble qprec);
void             gwy_field_correct_average             (GwyField *field,
                                                        GwyNield *mask);
void             gwy_field_mark_outliers               (GwyField *field,
                                                        GwyNield *mask,
                                                        gdouble thresh);
void             gwy_field_mark_outliers2              (GwyField *field,
                                                        GwyNield *mask,
                                                        gdouble thresh_low,
                                                        gdouble thresh_high);
void             gwy_field_mark_outliers_iqr           (GwyField *field,
                                                        GwyNield *mask,
                                                        gdouble thresh_low,
                                                        gdouble thresh_high);
void             gwy_field_distort                     (GwyField *source,
                                                        GwyField *dest,
                                                        GwyCoordTransform2DFunc invtrans,
                                                        gpointer user_data,
                                                        GwyInterpolationType interp,
                                                        GwyExteriorType exterior,
                                                        gdouble fill_value);
void             gwy_field_sample_distorted            (GwyField *source,
                                                        GwyField *dest,
                                                        const GwyXY *coords,
                                                        GwyInterpolationType interp,
                                                        GwyExteriorType exterior,
                                                        gdouble fill_value);
void             gwy_field_affine                      (GwyField *source,
                                                        GwyField *dest,
                                                        const gdouble *invtrans,
                                                        GwyInterpolationType interp,
                                                        GwyExteriorType exterior,
                                                        gdouble fill_value);
void             gwy_field_affine_prepare              (GwyField *source,
                                                        GwyField *dest,
                                                        const gdouble *a1a2,
                                                        gdouble *a1a2_corr,
                                                        gdouble *invtrans,
                                                        GwyAffineScalingType scaling,
                                                        gboolean prevent_rotation,
                                                        gdouble oversampling);
gboolean         gwy_field_measure_lattice_acf         (GwyField *acf2d,
                                                        gdouble *a1a2);
gboolean         gwy_field_measure_lattice_psdf        (GwyField *psdf2d,
                                                        gdouble *a1a2);
gboolean         gwy_line_laplace_solve                (GwyLine *line,
                                                        GwyLine *mask_line);
void             gwy_field_mark_scars                  (GwyField *field,
                                                        GwyNield *result,
                                                        gdouble threshold_high,
                                                        gdouble threshold_low,
                                                        gdouble min_scar_len,
                                                        gdouble max_scar_width,
                                                        GwySignFlags sign);
void             gwy_field_subtract_row_shifts         (GwyField *field,
                                                        GwyLine *shifts);
GwyLine*         gwy_field_find_row_shifts_trimmed_mean(GwyField *field,
                                                        GwyNield *mask,
                                                        GwyMaskingType masking,
                                                        gdouble trimfrac,
                                                        gint mincount);
GwyLine*         gwy_field_find_row_shifts_trimmed_diff(GwyField *field,
                                                        GwyNield *mask,
                                                        GwyMaskingType masking,
                                                        gdouble trimfrac,
                                                        gint mincount);
void             gwy_field_row_level_poly              (GwyField *field,
                                                        GwyNield *mask,
                                                        GwyMaskingType masking,
                                                        gint degree,
                                                        GwyLine *shifts);
GwyPlaneSymmetry gwy_field_unrotate_find_corrections   (GwyLine *derdist,
                                                        gdouble *correction);
void             gwy_field_distance_blend              (GwyField *field,
                                                        GwyField *operand,
                                                        GwyField *distances,
                                                        gint col,
                                                        gint row);

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 : */
