function sampdemo(action,varargin)
%SAMPDEMO Image Sampling demo :
%   It shows the relationship between improper sampling and its aliasing
%   results.
%

%Author: J.Yang 2/24/99
%Copyright: Professor Jan. Allebach at Purdue ECE
%$ Revision: 1.01 $   $ Date : 3/12/99 $
%---- << subfunctions: ( invisible to exterior ) >> ---
% 1. init
% 2. Radio
% 3. Popup
% 4. close
% 5-1. disp_orig
% 5-2. disp_Moire
% 5-3. disp_origdft
% 5-4. disp_Moireidft
% 5-5. disp_sampimg
% 5-6. disp_sampdft
% 5-7. disp_reco
% 6.
%---------------------------------------------------------
%{
if nargin < 1
   action = 'init' ;
end ;

feval(action,varargin{:}) ;
return ;
%}


function init()
%{{
%   Parameter sharing by global cell array
%   'Gparm' = [ ... ] ;
%   To fit 6 image axes into 800x600 screen, allocate 256x256 images
%   to each axes.
%
%     |                  |                  |
%     | orig             | sampled          | reconstruct
%     +------            +---------         +-------
%    (8,326)
%     |                  |                  |
%     | orig DFT         | sampled DFT      | reconstruct DFT
%     +------            +---------         +-------
%    (8,50)           (8+256+8,50)        (8+8+256+8+256,50)    
%   +-------------------------------------------------+
%   |   button box                                    |
%   |   +-------+       +--------+        +--------+  |
%   |   | Moire |20     | Image  |        | Close  |  |
%   |   +-------+       +--------+        +--------+  |
%   |  (30,10)  <- 200--X-- 100 -> 
%   +-------------------------------------------------+
% (5,5)
% If demo is already running, bring it to the foreground.
h = findobj(allchild(0), 'tag', '2D Sampling');

if ~isempty(h)
   figure(h(1))
   return
end

global GParm ;

%------------------------------------------
% Set up for screen frame and attributes
% FIGURE
GParm.figure = figure('Color',[0.7 0.7 0.7], ...
	'MenuBar','none', ...
   'Colormap',gray(256), ...
	'Name','2D Sampling Demo', ...
   'Visible','on', 'Resize','off', ... % initially not drawn
	'NumberTitle','off', ...
   'ShareColor','off', ...
   'RendererMode','manual','Renderer','painters', ...
   'Units','pixels', ...
	'Position',[5 5 790 595], ...
  'Pointer','watch', ... 
  'Tag','2D Sampling');
%%   'Nextplot','add', ...
%-----------------
% button layout
% BUTTON
posbox = [5 1 786 30] ;
h = uicontrol('Style','frame', ...
   'Parent',GParm.figure, ...
   'Background',[.45 .45 .45], ...
   'Units','pixels', ...
   'Position',posbox) ;
%% Moire radio button
posbox = [47 7 100 20] ;
GParm.radio = uicontrol( ...
   'Parent',GParm.figure, ...
   'Style','Radiobutton', ...
   'Units','pixel', ...
   'BusyAction','queue','Interruptible','off', ...
   'Position',posbox, ...
   'String','Moire', ...
   'value',0, ...  % means pressed or released
   'Callback','sampdemo(''Radio'');'... 
) ;
%% Image list button
posbox = [347 7 100 20] ;
GParm.popup = uicontrol( ...
   'Parent',GParm.figure, ...
   'Style','popupmenu', ...
   'Units','pixel', ...
   'BusyAction','queue','Interruptible','off', ...
   'Position',posbox, ...
   'value',2, ...
   'String','Racing|Checker|Grid|Rectangle|Circle|Cross' , ...
   'Callback','sampdemo(''Popup'');' ...
) ;
%% Close button
posbox = [647 7 100 20] ;
GParm.close = uicontrol( ...
   'Parent',GParm.figure, ...
   'Style','Pushbutton', ...
   'BusyAction','queue','Interruptible','off', ...
   'Units','pixel', ...
   'String','Close', ...
   'Position',posbox, ...
   'Callback','sampdemo(''Close'');' ...
) ;
%-------------------------
% axes, image, surface
% AXES
% --- left axes and images ---
xdim = 256 ; ydim = 256; 
xs = 5 ; ys = 317 ; yb = 33 ;
GParm.origimgAxe = axes( ...
   'Parent',GParm.figure, ...
   'Units','pixels', ...
   'BusyAction','Queue','Interruptible','off',...
   'ydir', 'reverse', ...
   'Layer', 'top', ...
   'Nextplot','add', ...
   'Drawmode','fast', ...
   'XLim', [-1 xdim+2], ...
   'YLim', [-1 ydim+2],...
   'CLim', [0 1], ...
   'Position',[xs ys  xdim ydim], ...
   'Box','on', ...   
	 'XTick',[],'YTick',[], ...
   'Tag','origimgaxes' ...
   ) ;
GParm.origimg = image( ... % sampling grid interactive
   'Parent',GParm.origimgAxe, ...
   'Visible', 'off', ...
   'CData', [], ...
   'BusyAction','Queue','Interruptible','off',...
   'CDataMapping', 'direct', ...
   'XData', [1:xdim],...
   'YData', [1:ydim],...
   'EraseMode', 'normal' ...
   );
title('Original image') ;
GParm.gridmode = 0 ;
GParm.gridsz = [ 25 25 0 0 0] ; % initial sampling grid size, 3rd is counter
%GParm.origsampGrid = - 100 ;
      cmd1 = 'set(gcf,''WindowButtonMotionFcn'',''sampdemo(''''Samp_grid'''',0)'');' ;
      cmd2 = 'set(gcf,''WindowButtonUpFcn'',''sampdemo(''''Samp_grid'''',1)'');' ; ...
      xi = floor(xdim/GParm.gridsz(1))+1 ; yi = floor(ydim/GParm.gridsz(2))+1 ;
      xd(1:xi+yi) = 129 ; yd(1:xi+yi) = 129 ;
      xd(1:xi) = [1:GParm.gridsz(1):256]; 
      yd(xi+1:xi+yi)=[1:GParm.gridsz(2):256] ;
      %'EraseMode','xor', do not set 'xor' at init time. it can block proper visibility
      GParm.origsampGrid = line( ...  % sampling grid manipulation
      'Parent', GParm.origimgAxe, ...
      'Visible','on', ...
      'Color','red', ...
      'LineStyle','none', ...
      'Marker','x', ...
      'MarkerFaceColor','red', ...
      'ButtonDownFcn', strcat(cmd1,cmd2), ...
      'tag','sample grid', ...
      'XData',xd,'YData',yd ...
   );
   GParm.gridtps = [140 80] ;
   GParm.gridtext = text( ...
      'Parent',GParm.origimgAxe, ...
      'Visible','on', ...
      'color','r', ...
      'position',GParm.gridtps, ...
      'units', 'pixels', ...
      'string',{'sample step', '(x,y) = (25,25)'} , ...
      'verticalalignment','top', ...
      'horizontalalignment','left' ...
      ) ;
GParm.origdftAxe = axes( ...
   'Parent',GParm.figure, ...
   'Units','pixels', ...
   'BusyAction','Queue','Interruptible','off',...
   'ydir', 'reverse', ...
   'XLim', [-1 xdim+2], ...
   'YLim', [-1 ydim+2],...
   'CLim', [0 1], ...
   'Position',[xs yb  xdim ydim], ...
   'Drawmode','fast', ...
   'Box','on', ...   
   'Layer','top', ...   % show grid line above image   
   'XGrid','on','YGrid','on', ...
   'XTick',[129],'YTick',[129], ...
   'Tag','origdftaxes' ...
);
GParm.origdft = image(...
   'Parent',GParm.origdftAxe, ...
   'Visible', 'off', ...
   'CData', [], ...
   'BusyAction','Queue','Interruptible','off',...
   'CDataMapping', 'scaled', ...
   'XData', [1:xdim],...
   'YData', [1:ydim],...
   'EraseMode', 'normal' ...
) ;
title('DFT of original image') ;

cmd1 = 'set(gcf,''WindowButtonMotionFcn'',''sampdemo(''''Moire_freq'''',0)'');' ;
cmd2 = 'set(gcf,''WindowButtonUpFcn'',''sampdemo(''''Moire_freq'''',1)'');' ; ...
GParm.Moireline=[10 5] ;   
GParm.origMoire = line( ...
   'Parent',GParm.origdftAxe, ...
   'Visible','off', ...
   'Color','blue', ...
   'Marker','diamond', ...
   'MarkerFaceColor','red', ...
   'EraseMode','xor', ...
   'ButtonDownFcn',strcat(cmd1,cmd2), ...
   'XData',[129-10 129+10],'YData',[129-5 129+5] ...
   );
GParm.Moiretext = text( ...
   'parent',GParm.origdftAxe, ...
   'Visible', 'off', ...
   'Color','blue', ...
   'EraseMode','xor', ...
   'position',[10 80], ...
   'units', 'pixels', ...
   'string','(10\pi/128, 5\pi/128)' ...
   ) ;
%-- -- -- -- -- -- -- --
% --- middle axes and images ---
xs = xs + xdim + 8 ;
GParm.sampimgAxe = axes(...
   'Parent',GParm.figure, ...
   'Units','pixels', ...
   'BusyAction','Queue','Interruptible','off',...
   'ydir', 'reverse', ...
   'XLim', [-1 xdim+2], ...
   'YLim', [-1 ydim+2],...
   'CLim', [0 1], ...
   'Position',[xs ys  xdim ydim], ...
   'Drawmode','fast', ...
   'Box','on', ...   
	 'XTick',[],'YTick',[], ...
   'Tag','sampimgaxes' ...
);
GParm.sampimg = image(...
   'Parent',GParm.sampimgAxe, ...
   'Visible', 'off', ...
   'CData', [], ...
   'BusyAction','Queue','Interruptible','off',...
   'CDataMapping', 'direct', ...
   'XData', [1:xdim],...
   'YData', [1:ydim],...
   'EraseMode', 'normal' ...
) ;
title('Sampled image') ;

GParm.sampdftAxe = axes(...
   'Parent',GParm.figure, ...
   'Units','pixels', ...
   'BusyAction','Queue','Interruptible','off',...
   'ydir', 'reverse', ...
   'Layer', 'top', ...
   'Drawmode','fast', ...
   'Nextplot','add', ...
   'XLim', [-1 xdim+2], ...
   'YLim', [-1 ydim+2],...
   'CLim', [0 1], ...
   'Position',[xs yb  xdim ydim], ...
   'Box','on','Xgrid','on','Ygrid','on', ...   
	 'XTick',[],'YTick',[], ...
   'Tag','sampdftaxes' ...
);
GParm.sampdft = image(... % ideal LPF grid interactive
   'Parent',GParm.sampdftAxe, ...
   'Visible', 'off', ...
   'CData', [], ...
   'BusyAction','Queue','Interruptible','off',...
   'CDataMapping', 'direct', ...
   'XData', [1:xdim],...
   'YData', [1:ydim],...
   'EraseMode', 'normal' ...
) ;
title('DFT of sampled image') ;
   cmd1 = 'set(gcf,''WindowButtonMotionFcn'',''sampdemo(''''LPF_freq'''',0)'');' ;
   cmd2 = 'set(gcf,''WindowButtonUpFcn'',''sampdemo(''''LPF_freq'''',1)'');' ; ...
   GParm.sampLPF = line( ...
   'Parent',GParm.sampdftAxe, ...
   'Visible','on', ...
   'Color','blue', ...
   'Linestyle', '-', ...
   'Marker','s', ...
   'MarkerFaceColor','red', ...
   'ButtonDownFcn',strcat(cmd1,cmd2), ...
   'XData',[129-20 129+20 129+20 129-20 129-20], ...
   'YData',[129-20 129-20 129+20 129+20 129-20] ...
   );
GParm.LPFtext = text( ...
   'parent',GParm.sampdftAxe, ...
   'Visible', 'on', ...
   'Color','blue', ...
   'EraseMode','normal', ...
   'position',[10 40], ...
   'units', 'pixels', ...
   'string',{'LPF cutoff','(20\pi/128, 20\pi/128)'} ...
   ) ;
%-- -- -- -- -- -- -- --
% --- right axes and images ---
xs = xs + xdim + 8 ;
GParm.recoimgAxe = axes(...
   'Parent',GParm.figure, ...
   'Units','pixels', ...
   'BusyAction','Queue','Interruptible','off',...
   'ydir', 'reverse', ...
   'XLim', [-1 xdim+2], ...
   'YLim', [-1 ydim+2],...
   'CLim', [0 1], ...
   'Position',[xs ys  xdim ydim], ...
   'Box','on', ...   
   'Drawmode','fast', ...
	 'XTick',[],'YTick',[], ...
   'Tag','recoimgaxes' ...
);
GParm.recoimg = image(...
   'Parent',GParm.recoimgAxe, ...
   'Visible', 'off', ...
   'CData', [], ...
   'BusyAction','Queue','Interruptible','off',...
   'CDataMapping', 'direct', ...
   'XData', [1:xdim],...
   'YData', [1:ydim],...
   'EraseMode', 'normal' ...
) ;
title('Reconstructed image') ;

GParm.recodftAxe = axes(...
   'Parent',GParm.figure, ...
   'Units','pixels', ...
   'BusyAction','Queue','Interruptible','off',...
   'ydir', 'reverse', ...
   'XLim', [-1 xdim+2], ...
   'YLim', [-1 ydim+2],...
   'CLim', [0 1], ...
   'Position',[xs yb  xdim ydim], ...
   'Drawmode','fast', ...
   'Box','on', ...   
	 'XTick',[],'YTick',[], ...
   'Tag','recodftaxes' ...
);
GParm.recodft = image(...
   'Parent',GParm.recodftAxe, ...
   'Visible', 'off', ...
   'CData', [], ...
   'BusyAction','Queue','Interruptible','off',...
   'CDataMapping', 'direct', ...
   'XData', [1:xdim],...
   'YData', [1:ydim],...
   'EraseMode', 'normal' ...
) ;
title('DFT of reconstructed image') ;
GParm.colorAxe = axes( ...
   'Parent',GParm.figure, ...
   'Units','pixels', ...
   'BusyAction','Queue','Interruptible','off',...
   'XLim', [-1 32], ...
   'YLim', [-1 ydim+2],...
   'CLim', [0 1], ...
   'Position',[xs yb  30 ydim], ...
   'Drawmode','fast', ...
   'xtick',[],'ytick',[1 65 129 193 256], ...
   'Box','on' ...   
   );
cd = jet(256) ;
cd1 = repmat(cd(:,1),1,30) ;
cd2 = repmat(cd(:,2),1,30) ;
cd3 = repmat(cd(:,3),1,30) ;
cmd1 = 'set(gcf,''WindowButtonMotionFcn'',''sampdemo(''''CB_move'''',0)'');' ;
cmd2 = 'set(gcf,''WindowButtonUpFcn'',''sampdemo(''''CB_move'''',1)'');' ; ...
GParm.colorbarimg = image( ...
   'Parent',GParm.colorAxe, ...
   'visible','on', ...
   'CData',cat(3,cd1,cd2,cd3) , ...
   'CDatamapping','direct', ...
   'Buttondownfcn',strcat('sampdemo(''CB_move'',-1);',strcat(cmd1,cmd2) ), ...
   'XData',[1:30], 'YData',[1:ydim], ...
   'Erasemode','normal' ...
) ;
t = gray(256) ;
GParm.graymap = t(:,1) ;
%-- -- -- -- -- -- -- --
GParm.imgdata = [] ;      % origin gray img data
GParm.Moireimgdata = [] ; % one sinusoidal freq gray pattern origin
GParm.dftdata = [] ;      % dft of original img data
%-- -- --
GParm.sampimgdata = [] ;  % sampled gray img data
GParm.sampMoireimgdata =[] ; % sampled img of original sinousoids
GParm.sampdftdata = [] ;
GParm.sampMoiredftdata = [] ;
%-- -- --
GParm.recoimgdata = [] ;
GParm.recodftdata = [] ;
%-- -- --
GParm.cbpos = [-1 -1] ;
GParm.prex=0 ;
GParm.prey=0 ;
GParm.LPFxy = [20 20] ;
GParm.DFTmmx = [2 2] ;

Popup ; % to draw initial orig image
set(GParm.figure,'Pointer','arrow') ;
drawnow 
return ;
%}}

%%--------------------------------
%% button functions
%%--------------------------------
function Radio()
%{{
global GParm ;

  h = GParm.radio ; % get handle for radio button showing 'Moire'
  val = get(h,'value') ;
  set(GParm.figure,'pointer','watch') ;
  switch get(h,'value') ;
  case 0;
     set(GParm.popup,'enable','on') ; % Moire deactivated, list active
     disp_orig ;   
  case 1;  
     set(GParm.popup,'enable','off') ; % Moire active, list deactive
     disp_Moire ;   
  otherwise; 
     set(GParm.popup,'enable','on') ;
     set(GParm.origimg,'visible','off') ;
     set(GParm.origMoire,'visible','on') ;
  end ;
  set(GParm.figure,'pointer','arrow') ;
  drawnow  
return ;
%}}

function Popup()
%{{
global GParm ;

  h = GParm.popup ; % get handle for popup list button
  v = get(h,{'value','String'}) ;
  name = deblank(v{2}(v{1},:)) ;
  set(GParm.figure,'pointer','watch') ;
  switch name
  case 'Racing'
     load demo1 Racing ;    GParm.imgdata = Racing ;    Racing = [] ;
  case 'Checker'
     load demo1 Checker ;   GParm.imgdata = Checker ;   Checker = [] ;
  case 'Grid'
     load demo1 Grid ;      GParm.imgdata = Grid ;      Grid = [] ;
  case 'Rectangle'
     load demo1 Rectangle ; GParm.imgdata = Rectangle ; Rectangle = [] ;
  case 'Circle'
     load demo1 Circle ;    GParm.imgdata = Circle ;    Circle = [] ;
  case 'Cross' 
     load demo1 Cross ;     GParm.imgdata = Cross ;     Cross = [] ;
  end ;
  
  disp_orig ;
  set(GParm.figure,'pointer','arrow') ;
return ;
%}}

function Close()
%{{
global GParm ;
%% close(gcf) ;
  close(GParm.figure) ;
  clear global GParm ;
  
return ;
%}}
%%%%%%%level 3 functions %%%%%%%%%

function disp_orig()
%{{{
global GParm ;

   set(GParm.origMoire,'visible','off') ;
   set(GParm.origMoire,'visible','off') ;
   set(GParm.origdft,'visible','on') ;
   d = double(GParm.imgdata) ;
   f = GParm.graymap(d(:,:)+1) ;
   set(GParm.origimg,'CData',cat(3,f,f,f),'visible','on') ;
   %%set(GParm.origimg,'CData',f,'visible','on','CDatamapping','scaled') ;
   disp_origdft ;
   disp_sampimg(0) ;
return ;
%}}}

function disp_Moire()
%{{{
global GParm ;

   set(GParm.origdft,'visible','off') ;
   set(GParm.origMoire,'visible','on') ;
   set(GParm.Moiretext,'visible','on') ;
   disp_Moireidft ;
   d = double(GParm.Moireimgdata);
   f = GParm.graymap(d(:,:)+1) ;
   set(GParm.origimg,'CData',cat(3,f,f,f),'visible','on') ;
   %%set(GParm.origimg,'CData',f,'visible','on','CDatamapping','scaled') ;
   disp_sampimg(1) ;
   
return ;
%}}}

function disp_origdft()
%{{{
global GParm ;

   F = fftshift(fft2(GParm.imgdata)) ;
   GParm.origdftdata = F ;
   f = log(abs(F) + 1) ;
   GParm.DFTmmx = [ min(f(:)) max(f(:)) ] ;
   set(GParm.origdft,'CData',map_color(f),'visible','on') ;
   
return ;
%}}}

function disp_Moireidft()
%{{{
global GParm ;

     xoff = GParm.Moireline(1) ; yoff = GParm.Moireline(2) ;
     d = zeros(256,256) ;
     d( 129 - yoff, 129 - xoff ) =  32768 ; % to make (129,129) = 65536
     d( 129 + yoff, 129 + xoff ) =  32768 ; 
     GParm.DFTmmx = [0 32768] ;
     d = real(ifft2(ifftshift(d))) ;
     if (yoff~=0 | xoff~=0), d = d+1; 
     else, d = d + d ;
     end ;
     GParm.Moireimgdata = uint8(d*127.5) ;
     
return ;
%}}}

function disp_sampimg(mode)
%{{{
global GParm ;

   xs = GParm.gridsz(1) ; ys = GParm.gridsz(2) ;
   switch mode
   case 0, cd = double(GParm.imgdata) ;
   case 1, cd = double(GParm.Moireimgdata) ;
   end ;
   % get samples
   tx = 1:xs:256 ; ty = 1:ys:256 ;   
   data = zeros(256,256) ;
   data(ty,tx) = cd(ty,tx) ;
   cd = conv2(data,[1 1 1;1 1 1;1 1 1],'same') ;
   
   f = GParm.graymap( min(255, floor(cd(:,:))) + 1 ) ;
   set(GParm.sampimg,'CData',cat(3,f,f,f),'visible','on','xdata',[1:256],'ydata',[1:256]) ;
   switch( mode )
   case 0
      GParm.sampimgdata = [] ;  % sampled gray img data
      GParm.sampimgdata = uint8(data) ; % 0 < img data = uint8 < 256
   case 1
      GParm.sampMoireimgdata =[] ; % sampled img of original sinousoids
      GParm.sampMoireimgdata = uint8(data) ;
   end ;
   disp_sampdft(mode)
   
return ;
%}}}

function disp_sampdft(mode)
%{{{
global GParm ;

   switch mode
   case 0,  x = GParm.sampimgdata    ; % 0<val<1
   case 1,  x = GParm.sampMoireimgdata ;
   end
   y = fftshift(fft2(x)) ;
   f = log( abs(y)+1 ) ;
   set(GParm.sampdft,'CData',map_color(f),'visible','on') ;
   switch mode
   case 0,  GParm.sampdftdata = y ;
   case 1,  GParm.sampMoiredftdata = y ;
   end
   disp_reco(mode) ; 
return ;
%}}}


function disp_reco(mode)
%{{{
global GParm ;
% display both img and dft together since no user interaction
% don't need to hold the following data
%   GParm.recoimgdata = [] ;   GParm.recodftdata = [] ;
     
   xd = GParm.LPFxy(1); yd = GParm.LPFxy(2) ; % temporary ycutoff, xcutoff
   xs = GParm.gridsz(1); ys = GParm.gridsz(2) ; % sampling factor
   xd = min(max(xd,1),127) ; yd = min(max(yd,1),127) ;
   normfac = xs*ys ;
   ys = 129 - yd ; yd = 129 + yd ; % reuse xs, ys as starting point
   xs = 129 - xd ; xd = 129 + xd ; 
   d = zeros(256,256) ;
   if( mode == 0 )
      d(ys:yd,xs:xd) = GParm.sampdftdata(ys:yd, xs:xd) ;
   else
      d(ys:yd,xs:xd) = GParm.sampMoiredftdata(ys:yd, xs:xd) ;
   end ;
   k = real(ifft2(ifftshift(d))) * (normfac) ;
   l = GParm.graymap( max(min(floor(k(:,:)),255),1) ) ;
   set(GParm.recoimg,'CData',cat(3,l,l,l),'visible','on') ;
   d = map_color( log(abs(d)+1) ) ;
   set(GParm.recodft,'CData',d,'visible','on') ;   
   
return ;
%}}}

function znorm = map_color(x) 
%{{{
global GParm ;
% need to unify max and min value through all dft's to yield same color range

   cmap = jet(256);%bone %jet(256) ;
   zmin = min(x(:)) ; zmax = max(x(:)) ;
   %zmin = GParm.DFTmmx(1);  zmax = GParm.DFTmmx(2) ;
   
   alpha = 254/(zmax - zmin) ;
   zidx = floor((x-zmin)*alpha + 1.5) ;
   
 
   for i=1:256,;
      znorm(i,:,:) = cmap(zidx(i,:),:)  ;
   end ;
   
return ;
%}}}




%%%----
%%  Button down user interaction
%%%----

function Moire_freq(mode)
%{{{
global GParm ;

   pt = get(GParm.origdftAxe,'currentpoint') ;
   x = pt(1,1) ; y = pt(1,2) ;
   x = min(256,max(x,1)) ; y = min(256,max(y,1)) ;
   xoff = floor(129 - x) ; yoff = floor(129 - y) ;
   set(GParm.origMoire,'XData',[129-xoff 129+xoff], ...
      'YData',[129-yoff 129+yoff]) ;
   pos = [139 200] ; % 1st quadrant, -xoff>0 & yoff>0
   if( -xoff <= 0), pos(1) = 10 ; end ;
   if(  yoff <= 0), pos(2) = 40 ; end ;
   set(GParm.Moiretext,'string',sprintf('(%d\\pi/128,%d\\pi/128)',-xoff,yoff), ...
      'position',pos) ;
    
   if mode == 1
     set(GParm.figure,'WindowButtonMotionFcn','','WindowButtonUpFcn','','pointer','watch') ;
     GParm.Moireline=[xoff yoff] ;
     % draw the moire pattern
     disp_Moire ;  
      set(GParm.figure,'pointer','arrow') ;
   end ;
   drawnow 
return ;
%}}}

function Samp_grid(mode)
%{{{ sampling grid manipulation
global GParm ;

   pt = get(GParm.origimgAxe,'currentpoint') ;
   x = floor(pt(1,1)) ; y = floor(pt(1,2)) ;
   x = min(256,max(x,1)); y = min(256,max(y,1)) ;
   xs = GParm.gridsz(1) ; ys = GParm.gridsz(2) ;
   if( GParm.gridsz(3) == 0 )
      if( GParm.gridmode == 5 )
         if( abs(GParm.prex -x) > abs(GParm.prey-y) ) % xdir
            GParm.gridmode = 10 ;
            GParm.gridsz(4:5) = [floor(x/xs+.5) , ceil(256/ys)] ;
         else % ydir
            GParm.gridmode = 20 ;
            GParm.gridsz(4:5) = [ceil(256/xs), floor(y/ys+.5) ] ;
         end;
         GParm.gridsz(3) = 10 ;
      end ;
      
      if( x~=1 & y <= 132 & y >= 126)
         if( x>=126 & x<=132 )  % suspect y dir
            GParm.prex = x ; GParm.prey = y ;
            GParm.gridmode = 5 ;
         else
            GParm.gridsz(3) = 10 ;
            GParm.gridmode = 10 ;
            % index of grabbed point for x dir
            GParm.gridsz(4:5) = [floor(x/xs+.5) , ceil(256/ys)] ;
         end ;
      else if(x>=126 & x <= 132 & y~=1)
            GParm.gridmode = 20 ;
            GParm.gridsz(4:5) = [ceil(256/xs), floor(y/ys+.5) ] ;
         else
            GParm.gridmode = 0 ;
         end ;
         GParm.gridsz(3) = 10 ;
      end;
      if( GParm.gridmode > 0 )
         set(GParm.origimg,'visible','off') ;
         set(GParm.origsampGrid,'Erasemode','xor','visible','on','color',[.1 .1 .1]) ;
         set(GParm.gridtext,'Erasemode','xor') ;
      end ;
   end ;
   
   switch GParm.gridmode
   case 10 % x dir sample grid
      xi = GParm.gridsz(4) ;
      yi = GParm.gridsz(5) ;
      xs = floor((x-1)/xi+.5) ;
      xs = min(128, max(xs,2)) ;
      xdd = [ 1:xs:256 ] ;
      xi =  size(xdd,2);
      xd(1:xi+yi) = 129 ; yd(1:xi+yi) = 129 ;
      xd(1:xi) = xdd; 
      yd(xi+1:xi+yi)=[1:ys:256] ;
      set(GParm.origsampGrid,'XData',xd,'YData',yd) ;
      GParm.gridsz(1) = xs ;
      set(GParm.gridtext,'string', ...
         {'sample step',sprintf('(x,y)=(%d,%d)',xs,GParm.gridsz(2))} ) ;
   case 20 % ydir sample grid
      xi = GParm.gridsz(4) ;
      yi = GParm.gridsz(5) ;
      ys = floor((y-1)/yi+.5) ;
      ys = min(128,max(ys,2)) ;
      ydd = [1:ys:256] ;
      yi = size(ydd,2) ;
      xd(1:xi+yi) = 129 ; yd(1:xi+yi) = 129 ;
      xd(1:xi) = [1:xs:256]; 
      yd(xi+1:xi+yi)=ydd ;
      set(GParm.origsampGrid,'XData',xd,'YData',yd) ;
      GParm.gridsz(2) = ys ;
      set(GParm.gridtext,'string', ...
         {'sample step',sprintf('(x,y)=(%d,%d)',GParm.gridsz(1),ys )} ) ;
   end ;
   if mode == 1 % button released
      set(GParm.figure,'WindowButtonMotionFcn','','WindowButtonUpFcn','','pointer','watch') ;
      set(GParm.origsampGrid,'EraseMode','normal','color','r') ;
      set(GParm.gridtext,'EraseMode','normal','color','r', ...
         'string',{'sample step',sprintf('(x,y)=(%d,%d)',GParm.gridsz(1),GParm.gridsz(2))} ) ;
      set(GParm.origimg,'visible','on') ;
      GParm.gridmode = 0 ;
      GParm.gridsz(3) = 0 ;
      % disp_sampdft will be called inside following
      disp_sampimg( get(GParm.radio,'value') ) ;
      set(GParm.figure,'pointer','arrow') ;
   end ;
   drawnow
return ;
%}}}


function LPF_freq(mode)
%{{{ 2D Lpf cutoff region adjust
global GParm ;

   pt = get(GParm.sampdftAxe,'currentpoint') ;
   x = pt(1,1) ; y = pt(1,2) ;
   x = min(256,max(x,1)) ; y = min(256,max(y,1)) ;
   xoff = floor(129 - x) ; yoff = floor(129 - y) ;
   pos = [10 40] ;
   if( abs(xoff) > 64 & abs(yoff)>64 ), pos =[70 120] ; end ;
   set(GParm.LPFtext,'position',pos,'Erasemode','xor','color','r', ...
      'string',{'LPF cutoff',sprintf('(%d\\pi/128,%d\\pi/128)',abs(xoff),abs(yoff))} ) ;
   xs = 129-xoff; xd = 129 + xoff ;
   ys = 129-yoff; yd = 129 + yoff ;
   set(GParm.sampLPF,'Erasemode','xor', ...
      'XData',[xs xd xd xs xs], ...
      'YData',[ys ys yd yd ys]) ;
   if mode == 1
      set(GParm.figure,'WindowButtonMotionFcn','','WindowButtonUpFcn','','pointer','watch') ;
      set(GParm.sampLPF,'Erasemode','normal','visible','on') ;
      set(GParm.LPFtext,'Erasemode','normal','color','b') ;
      GParm.LPFxy = [ abs(xoff)  abs(yoff)] ;
      % draw the reconstructed img & dft together
      disp_reco( get(GParm.radio,'value') ) ;  
      set(GParm.figure,'pointer','arrow') ;
   end ;
   drawnow 
return ;
%}}}



function CB_move(mode)
%{{{ colorbar move
global GParm ;

   pt = get(GParm.figure,'currentpoint') ;
   bound = get(GParm.figure,'position') ;
   x = min(bound(3), max(bound(1),pt(1,1)) ) ;
   y = min(bound(4), max(bound(2),pt(1,2)) ) ;
   if mode == -1
      GParm.cbpos = [ x y ] ;   
      set([GParm.origimg GParm.origdft GParm.sampimg GParm.sampdft],'visible','off') ;
      set([GParm.recoimg GParm.recodft],'visible','off') ;
   else   
     xoff = x - GParm.cbpos(1) ; yoff = y - GParm.cbpos(2) ;
     GParm.cbpos = [ x y ] ;
     bound = get(GParm.colorAxe,'position') ;  
     bound(1) = bound(1) + xoff ; bound(2) = bound(2) + yoff ;
     set(GParm.colorAxe,'position',bound) ;
   end ;
   
   if mode == 1
      set(GParm.figure, 'WindowButtonMotionFcn','','WindowButtonUpFcn','') ;
      set([GParm.origimg GParm.origdft GParm.sampimg GParm.sampdft],'visible','on') ;
      set([GParm.recoimg GParm.recodft],'visible','on') ;
   end ;
   drawnow ;
   
return ;
%}}}

























