/* $Id: hawki_mask.c,v 1.4 2013-03-25 11:35:09 cgarcia Exp $
 *
 * This file is part of the HAWKI Pipeline
 * Copyright (C) 2002,2003 European Southern Observatory
 *
 * 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
 */

/*
 * $Author: cgarcia $
 * $Date: 2013-03-25 11:35:09 $
 * $Revision: 1.4 $
 * $Name: not supported by cvs2svn $
 */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

/*-----------------------------------------------------------------------------
   								Includes
 -----------------------------------------------------------------------------*/

#include <math.h>
#include <string.h>
#include <cpl.h>
#include <cpl_mask.h>
#include <cpl_matrix.h>

#include "hawki_mask.h"

/*----------------------------------------------------------------------------*/
/**
 * @defgroup hawki_mask     Mask manipulation
 *
 */
/*----------------------------------------------------------------------------*/

/**@{*/

/** 
 *  FIXME: documentation
 */
cpl_error_code hawki_mask_convolve(
        cpl_mask            *   in,
        const cpl_matrix    *   ker)
{
    cpl_mask        *   out;
    const double    *   ker_arr;
    int                 nc, nr;
    int                 hsx, hsy;
    int                 curr_pos, im_pos, filt_pos;
    int                 i, j, k, l;
    double              sum;
    int                 nx;
    int                 ny;
    cpl_binary      *   in_data;
    cpl_binary      *   out_data;

    /* Test entries */
    cpl_ensure_code(in && ker, CPL_ERROR_NULL_INPUT);

    /* Get kernel informations */
    nr = cpl_matrix_get_nrow(ker);
    nc = cpl_matrix_get_ncol(ker);
    ker_arr = cpl_matrix_get_data_const(ker);

    /* Test the kernel validity */
    cpl_ensure_code(nc%2 && nr%2, CPL_ERROR_ILLEGAL_INPUT);
    cpl_ensure_code(nc<=31 && nr<=31, CPL_ERROR_ILLEGAL_INPUT);

    /* Initialise */
    hsx = (nc-1) / 2;
    hsy = (nr-1) / 2;

    /* Create a tmp binary image */
    nx = cpl_mask_get_size_x(in);
    ny = cpl_mask_get_size_y(in);
    out = cpl_mask_new(nx, ny);
    in_data = cpl_mask_get_data(in);
    out_data = cpl_mask_get_data(out);

    /* Main filter loop */
    for (j=0; j<ny; j++) {
        for (i=0; i<nx; i++) {
            /* Curent pixel position */
            curr_pos = i + j*nx;
            /* Edges are not computed   */
            if ((i<hsx) || (i>=nx-hsx) || (j<hsy) || (j>=ny-hsy)) {
                (out_data)[curr_pos] = CPL_BINARY_0;
            } else {
                /* Initialise */
                (out_data)[curr_pos] = CPL_BINARY_0;
                /* Go into upper left corner of current pixel   */
                im_pos = curr_pos - hsx + hsy*nx;
                filt_pos = 0;
                sum      = 0;
                for (k=0; k<nr; k++) {
                    for (l=0; l<nc; l++) {
                        if (((in_data)[im_pos] == CPL_BINARY_1) &&
                                (fabs(ker_arr[filt_pos]) > FLT_MIN))
                            sum+=fabs(ker_arr[filt_pos]);
                        /* Next col */
                        filt_pos++;
                        im_pos++;
                    }
                    /* Next row */
                    im_pos -= nx + nc;
                }
                if(sum>0.5)
                    (out_data)[curr_pos] = CPL_BINARY_1;
            }
        }
    }
    memcpy(in_data, out_data, nx * ny * sizeof(cpl_binary));
    cpl_mask_delete(out);
    return CPL_ERROR_NONE;
}

/**@}*/

