function [A, varargout] = teximage(imno, imrange, verbose)
% teximage         Return a (scaled) texture image for training or testing
%
% Now the (original) *.pgm images are used, (The same as the ones used by 
% T.Randen many years ago, "Filtering for Texture Classification: A Comparative 
% Study" IEEE Trans. Pat. Anal. 1999, from the Brodatz album, the MIT Vision
% texture database and MeasTex Image Texture Database), when they are in
% catalogs given in my_matlab_path.m (see that m-file), name 'test' or 'textures'.
% Alternatively, a filename may be given, or an internet URL (imread is used here) 
% For Outex database see: http://www.outex.oulu.fi/index.php?page=outex_home
% 
% ex:   A = teximage(imno, imrange, verbose);   % first argument a number
%       A = teximage(imfile, imrange, verbose); % first argument a char (string)
%       A = teximage(imfile); 
%       A = teximage(A, imrange, verbose);
%       [A, imfile, imtext] = teximage(imfile, imrange, verbose);
%       outex_url = 'http://www.outex.oulu.fi/db/color/scaled/';
%       [A,imfile] = teximage([outex_url,'wallpaper015-inca-100dpi-00.bmp'],[-1,1]);
%----------------------------------------------------------------------
%  imno     1-85     some predefined training images (*.pgm)
%           101-113  the corresponding test images
%           201-213  and the corresponding reference images
%  imfile   char array (string) with name of file
%  A        as input an image (matrix) that will be scaled to be within
%           imrange and grayscale (i.e. a RGB image --> a grayscale image)
%           as output: the image
%  imrange  range of image, default [] (keep range), or [-1,1] or [0,1] 
%  verbose  default 0 for displaying only errors and warnings.
%----------------------------------------------------------------------
% ex: [A, imfile, imtext] = teximage(1, [-1,1]);

%----------------------------------------------------------------------
% Copyright (c) 2012.  Karl Skretting.  All rights reserved.
% University of Stavanger, Signal Processing Group
% Mail:  karl.skretting@uis.no   Homepage:  http://www.ux.uis.no/~karlsk/
% 
% HISTORY:  dd.mm.yyyy
% Ver. 1.0  18.01.2012  Made function  
% Ver. 1.1  18.02.2013  Minor modifications  
%----------------------------------------------------------------------

mfile = 'TexImage';
train_f = {'Nat-5c_1', 'Nat-5c_2', 'Nat-5c_3', 'Nat-5c_4', 'Nat-5c_5', ...
           'Nat-5v_1', 'Nat-5v_2', 'Nat-5v_3', 'Nat-5v_4', 'Nat-5v_5', ...
           'Nat-5v2_1', 'Nat-5v2_2', 'Nat-5v2_3', 'Nat-5v2_4', 'Nat-5v2_5', ...
           'Nat-5v3_1', 'Nat-5v3_2', 'Nat-5v3_3', 'Nat-5v3_4', 'Nat-5v3_5', ...
           'Nat-5m_1', 'Nat-5m_2', 'Nat-5m_3', 'Nat-5m_4', 'Nat-5m_5', ...
           'Nat-16c_1', 'Nat-16c_2', 'Nat-16c_3', 'Nat-16c_4', 'Nat-16c_5', 'Nat-16c_6', 'Nat-16c_7', 'Nat-16c_8', ...
           'Nat-16c_9', 'Nat-16c_10', 'Nat-16c_11', 'Nat-16c_12', 'Nat-16c_13', 'Nat-16c_14', 'Nat-16c_15', 'Nat-16c_16', ...
           'Nat-16v_1', 'Nat-16v_2', 'Nat-16v_3', 'Nat-16v_4', 'Nat-16v_5', 'Nat-16v_6', 'Nat-16v_7', 'Nat-16v_8', ...
           'Nat-16v_9', 'Nat-16v_10', 'Nat-16v_11', 'Nat-16v_12', 'Nat-16v_13', 'Nat-16v_14', 'Nat-16v_15', 'Nat-16v_16', ...
           'Nat-10_1', 'Nat-10_2', 'Nat-10_3', 'Nat-10_4', 'Nat-10_5', 'Nat-10_6', 'Nat-10_7', 'Nat-10_8', 'Nat-10_9', 'Nat-10_10', ...
           'Nat-10v_1', 'Nat-10v_2', 'Nat-10v_3', 'Nat-10v_4', 'Nat-10v_5', 'Nat-10v_6', 'Nat-10v_7', 'Nat-10v_8', 'Nat-10v_9', 'Nat-10v_10', ...
           'D5D92_1', 'D5D92_2', 'D4D84_1', 'D4D84_2', 'D8D84_1', 'D8D84_2', 'D12D17_1', 'D12D17_2'};
test_f = {'Nat-5c', 'Nat-5v', 'Nat-5v2', 'Nat-5v3', 'Nat-5m', ...
          'Nat-16c', 'Nat-16v', 'Nat-10', 'Nat-10v', ....
          'D005D092', 'D004D084', 'D008D084', 'D012D017' };

if (nargin < 3); verbose = 0; end;
if (nargin < 2); imrange = []; end;


cat_test = my_matlab_path('test');
cat_train = my_matlab_path('textures');
if isunix
    cat_sep = '/';
else
    cat_sep = '\';
end

if isnumeric(imno)
    if numel(imno) == 1
        if (imno <= 0)
            error([mfile,': texture image number ',int2str(imno),' is not valid.']);    
        elseif (imno <= numel(train_f))
            imfile = [cat_train,cat_sep,train_f{imno}];  
        elseif (imno <= 100)
            error([mfile,': texture image number ',int2str(imno),' is not valid.']);    
        elseif (imno <= (100+numel(test_f)))
            imfile = [cat_test,cat_sep,test_f{imno-100}];  
        elseif (imno <= 200)
            error([mfile,': texture image number ',int2str(imno),' is not valid.']);    
        elseif (imno <= (200+numel(test_f)))            % reference image
            text = ['Reference image for test image number ',int2str(imno-100)];
            if (imno <= 205)
                imfile = [cat_test,cat_sep,'Nat-5b-ref.bmp'];
                A = double(imread(imfile,'bmp'))+1;   % range: 1-5
            elseif (imno == 206) || (imno == 207) 
                imfile = [cat_test,cat_sep,'Nat-16b-ref.bmp'];
                A = double(imread(imfile,'bmp'))+1;   % range: 1-16
            elseif (imno == 208) 
                a = ones(128);
                A = [2*a,5*a,8*a,1*a,4*a; 7*a,9*a,3*a,6*a,10*a];
                imfile = '[ 2 5 8 1 4; 7 9 3 6 10]';
            elseif (imno == 209) 
                a = ones(128);
                A = [1*a,2*a,3*a,4*a,5*a; 6*a,7*a,8*a,9*a,10*a];
                imfile = '[ 1 2 3 4 5; 6 7 8 9 10]';
            elseif (imno == 210) || (imno == 211)  || (imno == 212)  || (imno == 213) 
                A = [ones(256), 2*ones(256)];   % reference imagefile
                imfile = '[ones(256), 2*ones(256)]';
            else
                A = []; 
                imfile = ''; 
                text = 'Not valid numer for reference image.';
            end
            if nargout >= 1
                varargout{1} = imfile;
            end
            if nargout >= 2
                varargout{2} = text;
            end
            return;
        else
            error([mfile,': texture image number ',int2str(imno),' is not valid.']);    
        end
        if exist([imfile,'.pgm'],'file')
            imfile = [imfile,'.pgm'];
        elseif exist([imfile,'.bmp'],'file')
            imfile = [imfile,'.bmp'];
        elseif exist([imfile,'.gif'],'file')
            imfile = [imfile,'.gif'];
        else
            error([mfile,': can not find .pgm, .bmp or .gif for texture ',int2str(imno)]);    
        end
        A = double(imread(imfile));
    else
        A = double(imno);
        imno = 0;
        imfile = '';
    end
elseif ischar(imno)
    imfile = imno;
    imno = 0;
    if strcmp(imfile(1:min(7,numel(imfile))),'http://')
        % a file on www, does not check if it exist, just try to read it
    elseif strcmp(imfile(end-3),'.') || strcmp(imfile(end-4),'.')
        if exist(imfile,'file')
            % imfile = imfile;
        elseif exist([cat_train,cat_sep,imfile],'file')
            imfile = [cat_train,cat_sep,imfile];
        elseif exist([cat_test,cat_sep,imfile],'file')
            imfile = [cat_test,cat_sep,imfile];
        else
            error([mfile,': can not find texture ',imfile]);
        end
    else
        if exist([imfile,'.pgm'],'file')
            imfile = [imfile,'.pgm'];
        elseif exist([imfile,'.bmp'],'file')
            imfile = [imfile,'.bmp'];
        elseif exist([imfile,'.gif'],'file')
            imfile = [imfile,'.gif'];
        elseif exist([cat_train,cat_sep,imfile,'.pgm'],'file')
            imfile = [cat_train,cat_sep,imfile,'.pgm'];
        elseif exist([cat_train,cat_sep,imfile,'.bmp'],'file')
            imfile = [cat_train,cat_sep,imfile,'.bmp'];
        elseif exist([cat_train,cat_sep,imfile,'.gif'],'file')
            imfile = [cat_train,cat_sep,imfile,'.gif'];
        elseif exist([cat_test,cat_sep,imfile,'.pgm'],'file')
            imfile = [cat_test,cat_sep,imfile,'.pgm'];
        elseif exist([cat_test,cat_sep,imfile,'.bmp'],'file')
            imfile = [cat_test,cat_sep,imfile,'.bmp'];
        elseif exist([cat_test,cat_sep,imfile,'.gif'],'file')
            imfile = [cat_test,cat_sep,imfile,'.gif'];
        else
            error([mfile,': can not find texture ',imfile]);
        end
    end
    % imfile is probably ok!
    try
        A = double(imread(imfile));
    catch ME
        error([mfile,': an error occured while reading ',imfile]);
    end
else
    error([mfile,': texture image not given (number or name).']);    
end

% check if RGB then make it a grayscale image
immax = max(A(:));
immin = min(A(:));
[I,J,Layers] = size(A);   % RGB: Layers==3
if Layers == 3
    T = [   0.299,    0.587,    0.114; ...
           -0.16875, -0.33126,  0.5; ...
            0.5,     -0.41869, -0.08131  ];
    A(:,:,1:3) = permute(reshape(T*reshape(permute(A(:,:,1:3),...
                    [3,1,2]),3,I*J),3,I,J),[2,3,1]);
    A = A(:,:,1);  % first (luminance) layer only                
end    

text = char([mfile,': started ',datestr(now)], ...
    ['  Input image is ',int2str(imno),' ''',imfile,'''.'], ['  Size of input image is ',...
     '(A: ',int2str(size(A,1)),'x',int2str(size(A,2)),'x',int2str(size(A,3)),').'], ...
    ['  Input range is [',num2str(immin),', ',num2str(immax),']'], ...
    ['  Size of output image is (A: ',int2str(I),'x',int2str(J),').']   );
if numel(imrange) > 0
    imr0 = min(imrange);
    imr1 = max(imrange);
    text = char(text, ['  Output range should be [',num2str(imr0),...
                       ', ',num2str(imr1),']'] );
end
if (numel(imrange) > 0) && (imr1 > imr0)
    % assume imrange to be [-1,1], [0,1], [-128,127], [0,255]
    if (immin < 0) || (immin > 127) || (immax < 128) || (immax > 255)
        disp([mfile,' warning: image range not in [0-255], may be ok.']);
        A = (A-immin)*( (imr1-imr0)/(immax-immin) ) + imr0;
    else   % image range as expected, i.e. in [0-255]
        if (imr0 == -1) && (imr1 == 1)
            A = A/128 - 1;
        elseif (imr0 == 0) && (imr1 == 1)
            A = A/256;
        elseif (imr0 == -128) && (imr1 == 127)
            A = A - 128;
        elseif (imr0 ~= 0) || (imr1 ~= 255)
            A = (A-immin)*( (imr1-imr0)/(immax-immin) ) + imr0;
        end
    end
    text = char(text, ['  Output range is [',num2str(min(A(:))),...
                       ', ',num2str(max(A(:))),']'] );
end
if verbose > 0
    disp(text);
end

if nargout >= 1
    varargout{1} = imfile;
end
if nargout >= 2
    varargout{2} = text;
end

return;