/*
Copyright (c) 2023 Dariusz Borkowski

This program is free software: you can redistribute it and/or modify it under
the terms of the GNU Affero General Public License as published by the Free Software Foundation,
either version 3 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 Affero General Public License for more details.

You should have received a copy of the GNU Affero General Public License along with this program.
If not, see <http://www.gnu.org/licenses/>.
*/

#include "libsegmentation.h"

int main(int argc,char **argv){

/*------------------Loading input data---------------------------------------*/
	size_t nx,ny,nc;
    	float *d_v = NULL;
	d_v = io_png_read_f32(argv[1], &nx, &ny, &nc);
	float mu=float(atof(argv[2]));

if(d_v && (int(nc)==3 || int(nc==1))){
    	dbRGB* D_V=new dbRGB[nx*ny];
	if(int(nc)==1){
    		for(int i=0;i<(int)(nx*ny);i++){
			D_V[i].R=d_v[i];
			D_V[i].G=d_v[i];
			D_V[i].B=d_v[i];
		}
	}
	if(int(nc)==3){
    		for(int i=0;i<(int)(nx*ny);i++){
			D_V[i].R=d_v[i];
			D_V[i].G=d_v[i+nx*ny];
			D_V[i].B=d_v[i+2*nx*ny];
		}
	}
    	dbImageRGB Input(D_V,nx,ny);
    	dbImageRGB Output(nx,ny);
    	dbImageRGB Otsu(nx,ny);
    	dbImage Out(nx,ny);
/*-----------Formula (2)--------------------------------------------------*/
	double Std=imStd(Input);
	if(mu<40 || mu>99)mu=fmax(50.0,fmin(99.0,Std));
	std::cout<<"The mu parameter has been set to: "<<mu<<"\n";
/*-----------Main algorithms for RGB images-------------------------------*/
/*-----------Segmentation-------------------------------------------------*/
	BSDE_Segmentation(Input,mu,Output);
/*-----------Binarization-------------------------------------------------*/
	BSDE_Binarization(Output,Otsu);
/*-----------Center region------------------------------------------------*/
	getRegion(nx/2,ny/2,Otsu,Out);
/*-----------Saving RGB images--------------------------------------------*/
	free(d_v);
	d_v=(float*)malloc(3*sizeof(float)*nx*ny);	
	nc=3;
	for(int i=0;i<(int)(nx*ny);i++){
		d_v[i]=Output.A[i].R;
		d_v[i+nx*ny]=Output.A[i].G;
		d_v[i+2*nx*ny]=Output.A[i].B;
	}
	if(io_png_write_f32(argv[3], d_v, nx, ny, nc) != 0)std::cout<<"... failed to save png image\n";
	for(int i=0;i<(int)(nx*ny);i++){
		d_v[i]=Otsu.A[i].R;
		d_v[i+nx*ny]=Otsu.A[i].G;
		d_v[i+2*nx*ny]=Otsu.A[i].B;
	}
	if(io_png_write_f32(argv[4], d_v, nx, ny, nc) != 0)std::cout<<"... failed to save png image\n";
	for(int i=0;i<(int)(nx*ny);i++){
		d_v[i]=Out.A[i];
		d_v[i+nx*ny]=Out.A[i];
		d_v[i+2*nx*ny]=Out.A[i];
	}
	if(io_png_write_f32(argv[5], d_v, nx, ny, nc) != 0)std::cout<<"... failed to save png image\n";

	return 0;
}

std::cout<<"error :: not found or not a correct png image\n";
return -1;
}
