function im_out = CERW_preprocess_image(im_in,options)

if isfield(options, 'z_scale')
    z_scale = options.z_scale;
else
    z_scale = 1;
end
do_rescale = z_scale ~= 1;

if isfield(options,'gamma')
    g_val = double(options.gamma);
    if isnan(g_val) || g_val > 3
        warning('invalid option: gamma correction, treating as 1');
        g_val = 1;
    end
else
    g_val = 1;
end
do_gamma = (g_val ~= 1);

if isfield(options, 'bp_sigma_small')
    bp_S = options.bp_sigma_small;
else
    bp_S = 0;
end
if isfield(options, 'bp_sigma_big')
    bp_B = options.bp_sigma_big;
else
    bp_B = 0;
end
do_bp = (bp_S > 0 && bp_B > 0);

if isfield(options, 'clahe_width')
    clahe_width = options.clahe_width;
else
    clahe_width = 1;
end
do_clahe = (clahe_width > 1);

if isfield(options, 'r_mean')
    r_mean = options.r_mean;
else
    r_mean = 0;
end
do_mean = (r_mean > 0);

if isfield(options, 'r_median')
    r_median = options.r_median;
else
    r_median = 0;
end
do_median = (r_median > 0);



sz = size(im_in);

if(do_rescale)
    sz = sz .* [1,1,z_scale];
    im_in = imresize3(im_in,sz);
end

sz = size(im_in);

im_in = im_in - min(im_in(:));
im_in = im_in / max(im_in(:));

if(do_gamma)
    im_in = im_in .^ g_val;
end

if(do_median)
    im_in = medfilt3(im_in,(2 * r_median+1)*[1,1,1]);
end
if(do_mean)
    for d = 1:3
        im_in = movmean(im_in,(2*r_mean+1),d);
    end
end

if(do_bp)
    im_in = imgaussfilt3(im_in,bp_S) - imgaussfilt3(im_in,bp_B);
    im_in = im_in - min(im_in(:));
    im_in = im_in / max(im_in(:));
end

if(do_clahe)
    for k = 1:sz(3)
        im_in(:,:,k) = adapthisteq(im_in(:,:,k),'NumTiles',round(sz(1:2)/clahe_width));
    end
end

im_out = im_in;
end