function img_ary = read_image(obj, src_ary, tidx)
	% read images from source file
	%
	% Input:
	%	src_ary		cell array containing (file names of) images to load
	%	tidx		index of timestep to load
	%
	% Output:
	%	img_ary		1 x n_cameras cell array containing (double) array of 
	%	n_i x n_j sized images
	%
	% src_ary is one of
	%		n_t x n_cameras cell array of n_i x n_j images for particle tracking
	%		n_t x n_cameras cell array of filenames, which can be loaded with imread
	%		1   x n_cameras cell array of filenames of
	%		multipage TIFF files which could be loaded with imread

	%% initialise
	img_ary = cell(1, obj.n_cameras);

	%% read file for each camera
	for c = 1 : obj.n_cameras
		%% read file
		if size(src_ary, 1) == 1
			% read multi-page TIFF file
			im = imread(src_ary{1,c}, obj.frame_range(tidx)).';
		elseif size(src_ary, 1) == obj.n_t
			if ischar(src_ary{tidx,c})
				% read single page TIFF 
				im = imread(src_ary{tidx,c}).';
			else
				% load data directly from array
				im = src_ary{tidx,c};
			end
		else
			error('invalid size for src_ary');
		end

		%% image preprocessing
		im			= double(im);
		img_ary{c}	= image_preprocess(im, obj.opts.preprocessing(:,c));
	end
end