function varargout = ImBruit(varargin)
% Génération de bruit corrélé dans une image
% Pour image non binaire
% 
% INPUT:
% - image PxQ, Q>1
% - cell array des paramètres :
%   + opération : 'GaussAdd' | 'GaussMul' | 'UniformeAdd' | 'UniformeMul'
%   + écart type du bruit marginal
%   + écart type du bruit commun
%   + matrice (1,P) ou (1,1) : coefficients de corrélation (0 <= ci <= 1)
%   + reset du générateur aléatoire : true | false
%
% OUTPUT:
% - image PxQ
%
% INFOS:
% - saturation des valeurs < 0 et > ValMax
% - coefficient de corrélation (1,1) dupliqué (1,P) si P > 1
% - reset du générateur aléatoire => résultats identiques à chaque appel
%
% D'après P. Lambert Université de Savoie 2002
%
% Plugin for OpenIsaac
% version 1
% © 2002-2018 Alain Clément - Université d'Angers

%---------------------------------------------------------------------------------------------------

% Copyright 2007 - 2018 Université d'Angers - Author: Alain Clément
%
% 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 3 of the
% License, or 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.

%---------------------------------------------------------------------------------------------------

% PLUGIN PARAMETERS
if (nargin == 1) && strcmp(varargin{1},'-f')
    % input
	varargout{1} = {'IMG','image', ...
					'DATA','cell array des paramètres'};
    % output
	varargout{2} = {'IMG','image résultat'};
	return
end	

% INPUT
ObjIMG = varargin{1};
DataVal = IsaacDATA_get(varargin{2},'Val');
oper = DataVal{1};
sigma_m = DataVal{2};
sigma_c = DataVal{3};
corr = DataVal{4};
doreset = DataVal{5};

%---------------------------------------------------------------------------------------------------

if (IsaacIMG_get(ObjIMG,'BitClass') == 1)
	error('image incompatible')
end
% nombre de plans
dimz = IsaacIMG_get(ObjIMG,'DimZ');
nbv = numel(corr);
if (nbv ~= dimz)
	if (nbv == 1)
		corr = repmat(corr,1,dimz);
	else	
		error('image et paramètres incompatibles')
	end	
end
img = IsaacIMG_img2mat(ObjIMG,'double');
dimx = IsaacIMG_get(ObjIMG,'DimX');
dimy = IsaacIMG_get(ObjIMG,'DimY');
if doreset
	% Reset du générateur aléatoire
	reset(RandStream.getDefaultStream)
end	
switch oper
case 'GaussAdd'
	% bruit gaussien commun d'écart-type sigma_c et de moyenne 0
	BC = sigma_c * randn(dimy,dimx);
	for k = 1:dimz
		% bruit gaussien marginal d'écart-type sigma_m et de moyenne 0
		BM = sigma_m * randn(dimy,dimx);
		% image avec bruit additif
		img(:,:,k) = img(:,:,k) + corr(k) * BC + (1-corr(k)) * BM;
	end
case 'GaussMul'
	% bruit gaussien commun d'écart-type sigma_c et de moyenne 1
	BC = 1 + sigma_c * randn(dimy,dimx);
	for k = 1:dimz
		% bruit gaussien marginal d'écart-type sigma_m et de moyenne 1
		BM = 1 + sigma_m * randn(dimy,dimx);
		% image avec bruit multiplicatif
		img(:,:,k) = img(:,:,k) .* (corr(k) * BC + (1-corr(k)) * BM);
	end
case 'UniformeAdd'
	% bruit uniforme commun d'écart-type sigma_c et de moyenne 0
	BC = sigma_c * sqrt(12) * (rand(dimy,dimx) - 0.5);
	for k = 1:dimz
		% bruit uniforme marginal d'écart-type sigma_m et de moyenne 0
		BM = sigma_m * sqrt(12) * (rand(dimy,dimx) - 0.5);
		% image avec bruit additif
		img(:,:,k) = img(:,:,k) + corr(k) * BC + (1-corr(k)) * BM;
	end
case 'UniformeMul'
	% bruit uniforme commun d'écart-type sigma_c et de moyenne 1
	BC = 1 + sigma_c * sqrt(12) * (rand(dimy,dimx) - 0.5);
	for k = 1:dimz
		% bruit uniforme marginal d'écart-type sigma_m et de moyenne 1
		BM = 1 + sigma_m * sqrt(12) * (rand(dimy,dimx) - 0.5);
		% image avec bruit multiplicatif
		img(:,:,k) = img(:,:,k) .* (corr(k) * BC + (1-corr(k)) * BM);
	end
otherwise
	error('opération invalide')
end
% gestion de la saturation
img(img < 0) = 0;
img(img > 1) = 1;
ObjIMG = IsaacIMG_mat2img(ObjIMG,img);

%---------------------------------------------------------------------------------------------------

% OUTPUT
varargout{1} = ObjIMG;