function x=readiq(fid,Info,FrameNo,format)

%READIQ     Read IQ data frame
%
%   x=READIQ(fid,Info,FrameNo,format)
%
%   Inputs: fid     - file identifier, see OPENCLP
%           Info    - Info vector returned by READINFO
%           FrameNo - Frame number
%                    (default=0 ->next frame after current filepos)
%           format  - Set format='3d' to get 3D matrix output
%                     for packetsize>1.
%
%   Output: x       - One frame of complex IQ data
%
%   See also: OPENCLP, READINFO, READECHO

% (c) GE Vingmed Ultrasound 1997-99. All rights reserved
% Written by: HT, 14.07.96
% Last update: 05.02.99, JK

startpos=0;
iqpos=[];

if nargin<4, format='normal';end;
if nargin<3, FrameNo=0;end;
if nargin<2, error('Too few input parameters');end;

if isempty(fid)|(prod(size(fid))>1)|isstr(fid)|~isreal(fid),
    error('Invalid file identifier');
end;
if (~(round(fid)==fid))|fid<3|~any(fopen(fid)),
    error('Invalid file identifier');
end;

if ~getparam('isinfo',Info,0),
    error('Invalid infovector');
end;
infofid=getparam('fid',Info,0);
if ~any(find([0,infofid]==fid)),
    error('fid and infovector does not match');
end;

if isempty(FrameNo)|isstr(FrameNo)|abs(round(FrameNo))~=FrameNo|prod(size(FrameNo))>1,
    error('FrameNo must be a integer >=0');
end;
if FrameNo==0,
    startpos=ftell(fid);
    FrameNo=1;
end;
frames=getparam('framesiq',Info,0);
if ~any(frames),
    error('No IQ frames in the file');
elseif FrameNo>frames,
    error('The requested FrameNo is too large');
end;

%% Extract parameters:
rpb=getparam('rpb',Info,0);
bpf=getparam('bpf',Info,0);
spr=getparam('spr',Info,0);
blockpos=getparam('blockpos',Info,0);
blocktype=getparam('blocktype',Info,0);
recsize=getparam('recsize',Info,0);
numberrecs=getparam('numberrecs',Info,0);

%% Constants:
DataFlowLinC    = 22;
DataFlowC       = 17;

if getparam('LinIQ',Info,0),
    iqblocks=find(blocktype==DataFlowLinC);
    for n=1:prod(size(iqblocks)),
        iqpos=[iqpos;(blockpos(iqblocks(n))+16)+[0:numberrecs(iqblocks(n))-1].*[recsize(iqblocks(n))] ];
    end;
elseif getparam('sectIQ',Info,0),
    iqblocks=find(blocktype==DataFlowC);
    for n=1:prod(size(iqblocks)),
        iqpos=[iqpos;(blockpos(iqblocks(n))+16)+[0:numberrecs(iqblocks(n))-1].*[recsize(iqblocks(n))] ];
    end;
else
    error('No IQ frames in the file');
end;

recordSize=recsize(iqblocks(1));
if mean(recsize(iqblocks))~=recordSize,
    error('Different IQ frames have different size');
end;

iqpos=iqpos(find(iqpos>=startpos));
if length(iqpos)<FrameNo,
    error('No IQ frames left in the file. Try frewind(fid)');
end;

fseek(fid,iqpos(FrameNo),-1);

if recordSize==(2*2*spr*bpf*rpb)+12,
    fseek(fid,12,0);
else
    error('Size of frame and parameters in info does not match');
end;

v=version;v=str2num(v(1));

if v<5,
    raw=zeros(1,4*rpb*bpf*spr); 
    raw=fread(fid,4*spr*rpb*bpf,'uint8');
    raw=reshape(raw,2,2*spr*rpb*bpf);
    raw(1,:)=256*raw(1,:); 
    raw=sum(raw); 
    neg=find(raw>=2^15);
    raw(neg)=raw(neg)-2^16;
    clear neg;
    raw=reshape(raw,2*spr*rpb,bpf);
else
    raw=fread(fid,[2*spr*rpb bpf],'bit16');
end;

if ~any(findstr(lower(format),'3d'))|(spr==1)|(v<5),
    x=i*ones(rpb,spr*bpf);
    for k=1:spr,
        x(:,k:spr:spr*bpf )= i*raw(2*k-1:2*spr:2*spr*rpb,:) + raw(2*k:2*spr:2*spr*rpb,:);
    end; 
else
    x=i*ones(rpb,bpf,spr);
    for k=1:spr,
        x(:,:,k)=i*raw(2*k-1:2*spr:2*spr*rpb,:) + raw(2*k:2*spr:2*spr*rpb,:);
    end;
end;