// euler.c              Section: 11.6, Euler Number
//      Copyright 1994, Center for Computer Vision and Visualization,
//      University of Florida.  All rights reserved.


#include "euler.h"
#include "UcharDI.h"
#include "DDTempl.h"
#include "UcharConv.h"


//////////////////////////////////////////////////////////////////
// Create the template used for Euler calcuations.
//
IA_DDTemplate<IA_Image<IA_Point<int>, u_char> >
euler_template() {
    // Create template t

    IA_Image<IA_Point<int>,u_char>
	t_im( IA_boxy_pset( IA_Point<int>(0,0), IA_Point<int>(1,1) ),
	      u_char(3) ); // a common value

    t_im[ IA_Point<int>(1, 0) ] = 1;
    t_im[ IA_Point<int>(0, 1) ] = 1;

    // template t created.
    return
	IA_DDTemplate<IA_Image<IA_Point<int>, u_char> >( 2, t_im );
}


//////////////////////////////////////////////////////////////////
// 4-connected Euler Number
//
int
euler_number_e4( const IA_Image<IA_Point<int>,IA_Bit> & image ) {

    // Convert the input to a UDI
    IA_Image<IA_Point<int>,u_char>
	a = image,
	b = linear_product( a, euler_template() );

    return
	sum( IA_Image<IA_Point<int>,u_char>( chi_eq(b,1) )
	     + IA_Image<IA_Point<int>,u_char>( chi_eq(b,3) )
	     - IA_Image<IA_Point<int>,u_char>( chi_eq(b,5) )
	     - IA_Image<IA_Point<int>,u_char>( chi_eq(b,7) )
	     + 2* IA_Image<IA_Point<int>,u_char>( chi_eq(b,2) )
	     + 2* IA_Image<IA_Point<int>,u_char>( chi_eq(b,6) )
	     ) / 4;
}


//////////////////////////////////////////////////////////////////
// 8-connected Euler Number
//
int
euler_number_e8( const IA_Image<IA_Point<int>,IA_Bit> & image ) {

    // Convert the input to a UDI
    IA_Image<IA_Point<int>,u_char>
	a = image,
	b = linear_product( a, euler_template() );

    return
	sum( IA_Image<IA_Point<int>,u_char>( chi_eq(b,1) )
	     + IA_Image<IA_Point<int>,u_char>( chi_eq(b,3) )
	     - IA_Image<IA_Point<int>,u_char>( chi_eq(b,5) )
	     - IA_Image<IA_Point<int>,u_char>( chi_eq(b,7) )
	     - 2* IA_Image<IA_Point<int>,u_char>( chi_eq(b,2) )
	     - 2* IA_Image<IA_Point<int>,u_char>( chi_eq(b,6) )
	     ) / 4;
}
