-- M module extracted from ITU-T J.340 (06/2010)
function [y,cb,cr] = read_bigyuv(file_name, varargin);
% READ_BIGYUV
% Read images from bigyuv-file.
%
% SYNTAX
% [y] = read_bigyuv(file_name);
% [y,cb,cr] = read_bigyuv(...);
% [...] = read_bigyuv(...,'PropertyName',PropertyValue,...);
%
% DESCRIPTION
% Read in images from bigyuv file named 'file_name'.
%
% The luminance plane is returned in 'Y'; the color planes are
% returned in 'cb' and 'cr' if requested. The Cb and Cr color planes
% will be up-sampled by 2 horizontally.
%
% The following optional properties may be requested:
%
% 'sroi',top,left,bottom,right,
% Spatial region of interest to be returned. By
% default, the entirety of each image is returned.
% Inclusive coordinates (top,left),(bottom,right)
% start numbering with row/line number 1.
% 'size',row,col, Size of images (row,col). By default, row=486,
% col=720.
% 'frames',start,stop, Specify the first and last frames, inclusive,
% to be read ('start' and 'stop'). By default,
% the first frame is read.
% '128' Subtract 128 from all Cb and Cr values. By default, Cb and
% Cr values are left in the [0..255] range.
% 'interp' Interpolate Cb and Cr values. By default, color planes
% are pixel replicated. Note: Interpolation is slow.
%
% read values from clip_struct that can be over written by variable argument
% list.
is_whole_image = 1;
is_sub128 = 0;
is_interp = 0;
num_rows = 486;
num_cols = 720;
start = 1;
stop = 1;
% parse varargin list (property values)
cnt = 1;
while cnt <= nargin - 1,
if ~isstr(varargin{cnt}),
error('Property value passed into read_bigyuv not recognized');
end
if strcmp(lower(varargin(cnt)),'sroi') == 1,
sroi.top = varargin{cnt+1};
sroi.left = varargin{cnt+2};
sroi.bottom = varargin{cnt+3};
sroi.right = varargin{cnt+4};
is_whole_image = 0;
cnt = cnt + 5;
elseif strcmp(lower(varargin(cnt)),'size') == 1,
num_rows = varargin{cnt+1};
num_cols = varargin{cnt+2};
cnt = cnt + 3;
elseif strcmp(lower(varargin(cnt)),'frames') == 1,
start = varargin{cnt+1};
stop = varargin{cnt+2};
cnt = cnt + 3;
elseif strcmp(lower(varargin(cnt)),'128') == 1,
is_sub128 = 1;
cnt = cnt + 1;
elseif strcmp(lower(varargin(cnt)),'interp') == 1,
is_interp = 1;
cnt = cnt + 1;
else
error('Property value passed into read_bigyuv not recognized');
end
end
if mod(num_cols,2) ~= 0,
fprintf('Error: number of columns must be even.\nFile format stores 4 bytes for 2 pixels\n');
error('Invalid specification for argument "num_cols" in read_bigyuv');
end
% Open image file
% [test_struct.path{1} clip_struct.file_name{1}]
[fid, message] = fopen(file_name, 'r');
if fid == -1
fprintf(message);
error('read_bigyuv cannot open this clip''s bigyuv file, %s', file_name);
end
% Find last frame.
fseek(fid,0, 'eof');
total = ftell(fid) / (2 * num_rows * num_cols);
if stop > total,
error('Requested a frame past the end of the file. Only %d frames available', total);
end
if stop < 0,
error('Range of frames invalid');
end
if start > stop | stop < 1,
error('Range of frames invalid, or no images exist in this bigyuv file');
end
% find range of frames requested.
prev_tslice_frames = start - 1;
tslice_frames = stop - start + 1;
number = start;
% go to requested location
if isnan(start),
error('first frame of this clip is undefined (NaN).');
end
offset = prev_tslice_frames * num_rows * num_cols * 2; %pixels each image
status = fseek(fid, offset, 'bof');
if status == -1,
fclose(fid);
error('read_bigyuv cannot seek requested image location');
end
% initialize memory to hold return images.
y = zeros(num_rows,num_cols,tslice_frames, 'single');
if (nargout == 3),
cb = y;
cr = y;
end
% loop through & read in the time-slice of images
this_try = 1;
for cnt = 1:tslice_frames,
where = ftell(fid);
[hold_fread,count] = fread(fid, [2*num_cols,num_rows], 'uint8=>uint8');
if count ~= 2*num_cols*num_rows,
% try one more time.
fprintf('Warning: read_bigyuv could not read requested time-slice; re-trying\n');
%pause(5);
if where == -1,
fprintf('Could not determine current location. Re-try failed.\n');
error('read_bigyuv could not read entirety of requested image time-slice');
fclose(fid);
end
fseek(fid, where, 'bof');
[hold_fread,count] = fread(fid, [2*num_cols,num_rows], 'uint8=>uint8');
if count ~= 2*num_cols*num_rows,
fclose(fid);
hold = sprintf('read_bigyuv failed for %s\nCould not read time-slice', file_name);
error(hold);
end
end
% pick off the Y plane (luminance)
temp = reshape(hold_fread', num_rows, 2, num_cols);
uncalib = squeeze(temp(:,2,:));
y(:,:,cnt) = single(uncalib);
% If color image planes are requested, pick those off and perform
% pixel replication to upsample horizontally by 2.
if nargout == 3,
temp = reshape(hold_fread,4,num_rows*num_cols/2);
color = reshape(temp(1,:),num_cols/2,num_rows)';
color2 = [color ; color];
uncalib = reshape(color2,num_rows,num_cols);
cb(:,:,cnt) = single(uncalib);
if is_sub128,
cb(:,:,cnt) = cb(:,:,cnt) - 128;
end
color = reshape(temp(3,:),num_cols/2,num_rows)';
color2 = [color ; color];
uncalib = reshape(color2,num_rows,num_cols);
cr(:,:,cnt) = single(uncalib);
if is_sub128,
cr(:,:,cnt) = cr(:,:,cnt) - 128;
end
% Interpolate, if requested
if is_interp == 1,
for i=2:2:num_cols-2,
cb(:,i,cnt) = (cb(:,i-1,cnt) + cb(:,i+1,cnt))/2;
cr(:,i,cnt) = (cr(:,i-1,cnt) + cr(:,i+1,cnt))/2;
end
end
end
end
fclose(fid);
if ~is_whole_image,
y = y(sroi.top:sroi.bottom, sroi.left:sroi.right, :);
if nargout == 3,
cb = cb(sroi.top:sroi.bottom, sroi.left:sroi.right, :);
cr = cr(sroi.top:sroi.bottom, sroi.left:sroi.right, :);
end
end