function filtdemo(action,varargin)
%FILTDEMO - shows the effects of 2d filter spatial coefficients on
%           its frequency  response.
%

% Author: J. Yang, 5/99
% Copyright: Professor Jan. Allebach. 
% Revision: 1.02
%--------- << Sub function lists: >> ---------
% 1. init                                    ;
% 2. ImageSet                                ;
% 3. FilterType                              ;
% 4. Close                                   ;
% 5. CV_edit, (cancel)                       ;
% 6. CV_apply                                ;
% 7. Spatial_mask  -- not implemented        ;
% 8. CV_field                                ;
%---------------------------------------------
% dispatch appropriate actions
%{
if nargin < 1
   action='init' ;
end ;
feval(action,varargin{:}) ;
return ;
%}


%---------------- Screen layout -------------------------
% 
%                                             
%    |                        |  3x3        |
%    |    f[m,n]              |  h[k,l]     |    g[m,n]
%    |                        | mask        |
%    |                        +----------   |
%    +----------              +---------+   +---------
%   (5,317)                   | 9 edit  |
%                   color bar |  boxes  | color bar
%    |                 +-+    | =can=app| +-+|
%    |                 | |    +---------+ | ||    G(u,v)
%    |   log|F(u,v)|   | |    |  |H(u,v)| | ||
%    |                 | |    | mesh plot | ||
%    +----------       +-+    +---------- +-++--------- (780,) 
%  (5,33)          (266,)+10 (296,)            (375,) (380)
%    +---------------------------------------------------+
%    |    buttons                                        |
%    +---------------------------------------------------+
%------------------( 800 -20) x (600 -30 ) ---------------
function init()
%{
h = findobj(allchild(0), 'tag', 'Spatial Filter Demo');

if ~isempty(h)
   figure(h)
   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','Spatial Filtering Demo', ...
   'Visible','on', 'Resize','off', ... % initially not drawn
	'NumberTitle','off', ...
   'Units','pixels', ...
	'Position',[5 5 790 595], ...
   'Pointer','watch', ... 
   'Tag','Spatial Filter Demo');
%   'ShareColor','off', ...
%   'RendererMode','manual','Renderer','painters', ...
%-----------------
% button layout
% BUTTON
posbox = [5 1 786 30] ;
h = uicontrol('Style','frame', ...
   'Parent',GParm.figure, ...
   'Background',[.45 .45 .45], ...
   'Units','pixels', ...
   'Position',posbox) ;
%% Image list button
labelpos = [12 9 55 16] ;
h = uicontrol('Parent',GParm.figure, ...
   'Style','text', 'Units','pixel', ...
   'position',labelpos, ...
   'String','Image', ...
   'Horiz','left') ;
%   'Verti','center', ...

posbox = [67 7 100 20] ;
GParm.imglist = uicontrol( ...
   'Parent',GParm.figure, ...
   'Style','popupmenu', ...
   'Units','pixel', ...
   'BusyAction','queue','Interruptible','off', ...
   'Position',posbox, ...
   'value',1, ...
   'String','Racing|Checker|Grid|Rectangle|Circle|Cross' , ...
   'Callback','filtdemo(''ImageSet'');' ...
) ;
%% Filter type list button
labelpos = [312 9 55 16] ;
h = uicontrol('Parent',GParm.figure, ...
   'Style','text', 'Units','pixel', ...
   'position',labelpos, ...
   'String','Filter :', ...
   'Horiz','left') ;

posbox = [367 7 100 20] ;
GParm.typelist = uicontrol( ...
   'Parent',GParm.figure, ...
   'Style','popupmenu', ...
   'Units','pixel', ...
   'BusyAction','queue','Interruptible','off', ...
   'Position',posbox, ...
   'String','LPF|HPF|EDGE|Edit', ...
   'value',1 , ...  % means pressed or released
   'Callback','filtdemo(''FilterType'');'... 
) ;
%% 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','filtdemo(''Close'');' ...
) ;
%-------------------------
% axes, image, surface
% AXES
% --- left axes and images ---
xdim = 256 ; ydim = 256; 
xs = 5 ; ys = 317 ; yb = 33 ;
GParm.fmnAxe = 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','f[m,n]' ...
   ) ;
GParm.fmnimg = image( ... % sampling grid interactive
   'Parent',GParm.fmnAxe, ...
   'Visible', 'on', ...
   'CData', [], ...
   'BusyAction','Queue','Interruptible','off',...
   'CDataMapping', 'direct', ...
   'XData', [1:xdim],...
   'YData', [1:ydim],...
   'EraseMode', 'normal' ...
   );
title('Original image : f[m,n]') ;
% --- left bottom and DFT plot ---
GParm.logFuvAxe = 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','Log|F(u,v)|' ...
);
GParm.Fuvdft = image(...
   'Parent',GParm.logFuvAxe, ...
   'Visible', 'on', ...
   'CData', [], ...
   'BusyAction','Queue','Interruptible','off',...
   'CDataMapping', 'scaled', ...
   'XData', [1:xdim],...
   'YData', [1:ydim],...
   'EraseMode', 'normal' ...
) ;
title('DFT of original image : Log|F[u,v]|') ;
% -- color bar axes needed ----
GParm.colorAxe1 = axes( ...
   'Parent',GParm.figure, ...
   'Units','pixels', ...
   'BusyAction','Queue','Interruptible','off',...
   'XLim', [-1 16], ...
   'YLim', [-1 ydim+2],...
   'CLim', [0 1], ...
   'Position',[xs+xdim+2 yb  15 ydim], ...
   'YaxisLocation','right', ...
   'Drawmode','fast', ...
   'xtick',[],'ytick',[], ...
   'Box','on' ...   
   );
cd = jet(256) ;
GParm.cd = cd ;
cd1 = repmat(cd(:,1),1,15) ;
cd2 = repmat(cd(:,2),1,15) ;
cd3 = repmat(cd(:,3),1,15) ;
GParm.colorbarimg = image( ...
   'Parent',GParm.colorAxe1, ...
   'visible','on', ...
   'CData',cat(3,cd1,cd2,cd3) , ...
   'CDatamapping','direct', ...
   'XData',[1:15], 'YData',[1:ydim], ...
   'Erasemode','normal' ...
) ;

%-- -- -- -- -- -- -- -- -- -- -- -- --
% --- middle axes and Filter coeffs ---
xs = 296 ; ym = ys - 80 ;
posbox = [ xs-3 ys-3  246  ydim+6] ;
%h = uicontrol('Style','frame','Parent',GParm.figure, ...
%    'Units','pixels','Position',posbox) ;
GParm.hklAxe = axes(...
   'Parent',GParm.figure, ...
   'Units','pixels', ...
   'BusyAction','Queue','Interruptible','off',...
   'Xlim', [.9 3.1], ...
   'YLim', [.9 3.1], ...
   'Zlim', [-1.2 1.2], ...
   'CLim', [0 1], ...
   'Position',[xs+10 ym+135  180 180], ...
   'Nextplot','add', ...
   'Visible','on', ...
   'view',[-37.5, 30], ...
   'Box','off', ...
   'Xgrid','on','Ygrid','on','Zgrid','on', ...
	'XTick',[1 2 3],'YTick',[1 2 3], ...
   'Tag','h[k,l]' ...
   );
title('Spatial Filter Coefficient h(m,n)') ;
GParm.zerolevel = patch(...
   'Parent',GParm.hklAxe, ...
   'Xdata',[1 1 3 3],    ...
   'Ydata',[1 3 3 1],    ...
   'Zdata',[0 0 0 0], ...
   'FaceColor',[.8 .1 .1], ...
   'FaceLighting','flat', ...
   'Erasemode','xor' ...
);
cmd1 = 'set(gcf,''WindowButtonMotionFcn'',''filtdemo(''''Spatial_mask'''',0)'');' ;
cmd2 = 'set(gcf,''WindowButtonUpFcn'',''filtdemo(''''Spatial_mask'''',1)'');' ; 
GParm.LPF_coeff = [ 1/16 1/8 1/16 ; 1/8 1/4 1/8; 1/16 1/8 1/16] ;
GParm.HPF_coeff = [ -1 -1 -1;-1 17 -1; -1 -1 -1]/9 ;
GParm.EDGE_coeff = [-10 -10 -10;-10 80 -10; -10 -10 -10]/9 ;
GParm.filt = GParm.LPF_coeff ;
GParm.savefilt = [];

GParm.editAxe = axes( ...
   'Parent',GParm.figure, ...
   'Units','pixels', ...
   'layer','top', ...
   'box','on', 'Gridlinestyle','-', ...
   'Position',[xs-6 ym+50  72*3 20*3], ...
   'Xlim', [1 216],'Ylim',[1 60], ...
   'XTick',[72 144],'YTick',[20 40], ...
   'Xgrid','on','Ygrid','on','Tickdir','in', ...   
   'XTickLabel',{' ',' '},'YTickLabel',{' ',' '}, ... % don't draw the tick labels
   'Tag','edittableaxes' ...
);
GParm.editbox = uicontrol(...
   'Parent',GParm.figure, ...
   'style','edit', ...
   'callback','filtdemo(''CV_edit'',1'');', ...
   'visible','off' ...
) ;

for i=1:3 ; 
   for j=1:3 ;
	GParm.hklline(i,j) = line(...
   		'Parent',GParm.hklAxe,'Visible','on','Color','blue','Linestyle', '-', ...
   		'XData',[i i],'YData',[j j],'ZData',[0 GParm.filt(i,j)], ...
   		'Erasemode','xor'   ...
	) ;
	GParm.hklmark(i,j) = line(...
   		'Parent',GParm.hklAxe,'Visible','on','Color','blue','Linestyle', '-', ...
   		'Marker','o','MarkerFacecolor','b', ...
   		'XData',[i], 'YData',[j], 'Zdata',[GParm.filt(i,j)], ...
   		'ButtonDownFcn',strcat(cmd1,cmd2), ...
   		'Erasemode','xor' ...
   ) ;
   posbox = [ 72*i-35, 20*j - 10] ;
   %% cmd = sprintf('%s,%d,%d%s','filtdemo(''CV_edit''',i,j,');' ) ;
   GParm.edittext(i,j) = text(...
      'Parent',GParm.editAxe, ...
      'HorizontalAlign','center', ... % 'VerticalAlign',middle is default
      'Clipping','on','visible','on', ...
      'units','pixels', 'Position',posbox, ...   
      'Erasemode','xor', ...
      'String',num2str(GParm.filt(i,j),'%0.4g'), ...
      'ButtondownFcn','filtdemo(''CV_edit'',0'');'...
   ) ;
   end ;
end ;
posbox=[xs+20 ym+20 70 25] ;
GParm.cancelpush = uicontrol(... % shared with cancel, displayed on top of coeff axe
   'Parent',GParm.figure, ...
   'Style','Pushbutton', ...
   'BusyAction','queue','Interruptible','off', ...
   'Units','pixel', ...
   'Enable','off', ...
   'String','Cancel', ...
   'Position',posbox, ...
   'value',0 , ... % pressed or released -> cancel or edit toggle
   'Callback','filtdemo(''CV_cancel'');' ... 
   ) ;
posbox=[xs+120 ym+20 70 25] ;
GParm.applypush = uicontrol(...
   'Parent',GParm.figure, ...
   'Style','Pushbutton', ...
   'BusyAction','queue','Interruptible','off', ...
   'Units','pixel', 'Enable','off', ...
   'String','Apply', ...
   'Position',posbox, ...
   'value',0, ... % pressed or released
   'Callback','filtdemo(''CV_apply'');' ...
   );

%-- -- -- -- -- -- -- -- -- -- 
GParm.HuvAxe = axes(...
   'Parent',GParm.figure, ...
   'Units','pixels', ...
   'View', [-37.5 30], ...
   'Position',[xs+15 yb+15  180 180], ...
	'XTick',[-1 0 1],'YTick',[-1 0 1], ...
   'Zgrid','on','Xgrid','on','Ygrid','on', ...   
   'Tag','filtdftaxes' ...
);
title('Frequency Response H(u,v)') ;
%-- -- -- -- -- -- -- --
% --- right axes and images ---
xs = xs + xdim - 20 ;
GParm.gmnAxe = axes(...
   'Parent',GParm.figure, ...
   'Units','pixels', ...
   'XLim', [-1 xdim+2], ...
   'YLim', [-1 ydim+2],...
   'CLim', [0 1], ...
   'Position',[xs ys  xdim+1 ydim+1], ...
   'ydir','reverse', ...
   'layer','top', ...
   'Box','on', ...   
   'Drawmode','fast', ...
   'XTick',[],'YTick',[], ...
   'Tag','outimgaxes' ...
);
GParm.gmnimg = image(...
   'Parent',GParm.gmnAxe, ...
   'Visible', 'on', ...
   'CData', [], ...
   'CDataMapping', 'direct', ...
   'XData', [1:xdim],...
   'YData', [1:ydim],...
   'EraseMode', 'normal' ...
) ;
title('f[m,n] ** h[m,n] result image') ;

GParm.GuvAxe = 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+1 ydim+1], ...
   'Drawmode','fast', ...
   'Box','on', ...   
   'Layer','top', ...   % show grid line above image   
   'XGrid','on','YGrid','on', ...
   'XTick',[129],'YTick',[129], ...
   'XTicklabel','','YTicklabel','',...
   'Tag','recodftaxes' ...
);
GParm.Guvdft = image(...
   'Parent',GParm.GuvAxe, ...
   'Visible', 'on', ...
   'CData', [], ...
   'BusyAction','Queue','Interruptible','off',...
   'CDataMapping', 'direct', ...
   'XData', [1:xdim],...
   'YData', [1:ydim],...
   'EraseMode', 'normal' ...
) ;
title('DFT of result image: Log|G[u,v]|') ;
GParm.colorAxe = axes( ...
   'Parent',GParm.figure, ...
   'Units','pixels', ...
   'BusyAction','Queue','Interruptible','off',...
   'XLim', [-1 32], ...
   'YLim', [-1 ydim+2],...
   'CLim', [0 1], ...
   'Position',[xs-17 yb  15 ydim], ...
   'Drawmode','fast', ...
   'xtick',[],'ytick',[], ...
   'Box','on' ...   
   );
cd = GParm.cd ;
cd1 = repmat(cd(:,1),1,15) ;
cd2 = repmat(cd(:,2),1,15) ;
cd3 = repmat(cd(:,3),1,15) ;
GParm.colorbarimg = image( ...
   'Parent',GParm.colorAxe, ...
   'visible','on', ...
   'CData',cat(3,cd1,cd2,cd3) , ...
   'CDatamapping','direct', ...
   'XData',[1:30], 'YData',[1:ydim], ...
   'Erasemode','normal' ...
) ;
t = gray(256) ;
GParm.graymap = t(:,1) ;
%-- -- -- -- -- -- -- --
GParm.fmndata = [] ;      % origin gray img data
%-- -- --
GParm.Huvdata = [] ;
%-- -- --
GParm.gmndata = [] ;
%-- -- --
ImageSet ; % to draw initial orig image
disp_hkl_Huv ;
set(GParm.figure,'Pointer','arrow') ;
drawnow 
return ;
%}

function disp_fmn_Fuv()
%{
global GParm ;

   f = GParm.fmndata ;
   F = fftshift(fft2(f)) ;
   G = log(abs(F) + 1) ;
   uf = GParm.graymap(floor(f + 1.5)) ;
   set(GParm.fmnimg,'CData',cat(3,uf,uf,uf),'visible','on','CDatamapping','direct') ;
   set(GParm.Fuvdft,'CData',map_color(G),'visible','on','CDatamapping','direct') ;

return ;
%}

function disp_hkl_Huv()
%{
global GParm ;

   h = GParm.filt ;
   [r,f1,f2] = freqz2(h,16,16) ;
   r = real(r) ; 
   rmin = min(r(:)) ; rmax = max(r(:)) ;
   delete( findobj(get(GParm.HuvAxe,'children'),'type','surface') );
   GParm.Huvdft = surface(f1,f2,r,'Parent',GParm.HuvAxe, ...
      'edgecolor','b','CData',r,'edgelighting','flat','facelighting','gouraud') ; %
   set(GParm.HuvAxe,'zlim',[rmin-(.05*abs(rmin)) rmax*1.05]) ;
   
return; 
%}

function disp_gmn_Guv()
%{
global GParm ;

   g = filter2(GParm.filt,GParm.fmndata,'same') ; % sample domain convolution
   gg = floor( min(255,max(g(1:256,1:256),0) ) + 1.5 ) ;   
   ug = GParm.graymap( gg ) ;
   G = fftshift(fft2(g)) ;
   H = log(abs(G) + 1) ;
   set(GParm.gmnimg,'CData',cat(3,ug,ug,ug),'visible','on','CDatamapping','direct') ;
   set(GParm.Guvdft,'CData',map_color(H),'visible','on','CDatamapping','direct') ;
   
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) ;
   zmax = max(max(x)) ;
   alpha = 255/zmax ;
   zidx = floor( x * alpha + 1.5) ;
   
   for i=1:256,;
      znorm(i,:,:) = cmap(zidx(i,:),:)  ;
   end ;
   
return ;
%}}}


%-----------------
%   Menu control
%-----------------
function ImageSet()
%%{
global GParm ;

  h = GParm.imglist ; % handle for image 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.fmndata = double(Racing) ;    Racing = [] ;
  case 'Checker'
     load demo1 Checker ;   GParm.fmndata = double(Checker) ;   Checker = [] ;
  case 'Grid'
     load demo1 Grid ;      GParm.fmndata = double(Grid) ;      Grid = [] ;
  case 'Rectangle'
     load demo1 Rectangle ; GParm.fmndata = double(Rectangle) ; Rectangle = [] ;
  case 'Circle'
     load demo1 Circle ;    GParm.fmndata = double(Circle );    Circle = [] ;
  case 'Cross' 
     load demo1 Cross ;     GParm.fmndata = double(Cross) ;     Cross = [] ;
  end ;
  
  disp_fmn_Fuv ;
  disp_gmn_Guv ;
  set(GParm.figure,'pointer','arrow') ;
  
return ;
%%}

function FilterType()
%%{
global GParm ;

  h = GParm.typelist ; % handle for filter type list
  v = get(h,'value') ;
  set(GParm.figure,'pointer','watch') ;
  switch v
  case 1 %'LPF'
     GParm.filt = GParm.LPF_coeff ;
  case 2 %'HPF'
     GParm.filt = GParm.HPF_coeff ;
  case 3 %'EDGE'
     GParm.filt = GParm.EDGE_coeff ;
  case 4 %'Edit' -- This uses input dialog for bulk coeff input
     prompt = 'Enter 9 values (comma delimted):' ;
     title = '3x3 Filter coefficient input' ;
     ans = inputdlg(prompt,title,1) ;
     if( ~isempty(ans) )
        r = ans{1} ; delim = ' \t\n,;:"' ;
        i = 1 ; j = 1 ;
        while ( size(r,2) ~= 0 )
           [t,r] = strtok(r,delim) ;
           if( i < 4 ), GParm.filt(j,i) = str2num(t) ; end ; % bypass more than 9 input
           j = j+1 ; if( j > 3 ), j = 1 ; i = i + 1 ; end ;
        end ;
     end ;
  end ;
  
  disp_mask ;
  draw_mask ;
  disp_hkl_Huv ;
  disp_gmn_Guv ;
  set(GParm.figure,'pointer','arrow') ;
return ;
%%}

function Close()
%%{
global GParm ;
%% close(gcf) ;
  close(GParm.figure) ;
  clear global GParm ;
  
return ;
%%}
%-------------------- User interaction Call backs --------------
function disp_mask()
%{{
global GParm ;

  %%norm = sum(sum(GParm.filt)) ;
  %%GParm.filt = GParm.filt/norm ;
  for i = 1:3 ;   
     for j = 1:3 ;
     set(GParm.edittext(i,j),'String',num2str(GParm.filt(i,j),'%.3f') ) ;
     end ;  
   end ;
  
return ;
%}}

function draw_mask()
%{{
global GParm ;

   zmax = max(GParm.filt(:)) ;
   set(GParm.hklAxe,'zlim',[-1.05*abs(zmax) 1.05*abs(zmax)]) ;
   for i = 1:3 ; for j= 1:3 ;
      hl = GParm.hklline(i,j) ; 
   	   set(hl,'XData',[i i],'YData',[j j],'ZData',[0 GParm.filt(i,j)]);
      hm = GParm.hklmark(i,j);
      set(hm,'XData',[i], 'YData',[j], 'Zdata',[GParm.filt(i,j)]);
   end ; end ;

return ;
%}}

function Spatial_mask(mode)
%{{
return ;
%}}

function CV_cancel()
%{{
global GParm ;

   set(GParm.figure,'pointer','watch') ;
   GParm.filt = GParm.savefilt ;
   set([GParm.cancelpush GParm.applypush],'enable','off') ;
   disp_mask ;
   set(GParm.figure,'pointer','arrow') ;
   drawnow ;
   
return ;
%}}

function CV_apply()
%{{
global GParm ;

   set(GParm.figure,'pointer','watch') ;
   set([GParm.applypush GParm.cancelpush],'enable','off') ;
   get_maskvalue ;
   draw_mask ;
   disp_hkl_Huv ;
   disp_gmn_Guv ;
   set(GParm.figure,'pointer','arrow') ;
   drawnow ;
   
return ;
%}}

function CV_edit(mode)
%{{
global GParm ;

   % mouse initiated field move --> just show editbox
   if ( ~mode )
      h = get(GParm.figure,'currentobj') ;
      [r,c] = find(GParm.edittext==h) ;   
      str = get(h,'string') ;
      pos = get(GParm.editAxe,'position') ;
      x = pos(1); y = pos(2) ;
      pos = get(h,'position') ;
      x = x+pos(1)-36; y = y+pos(2)-10 ;
      set(GParm.editbox,'position',[x y 70 20],'visible','on','string',str, ...
         'userdata',[r,c]) ;
      drawnow ;
      return ; 
   % editbox is activated by mouse hit   
   else
      set(GParm.editbox,'visible','off') ;
      str = get(GParm.editbox,'string') ;
      s = str2num(str) ;
      id = get(GParm.editbox,'userdata') ;
      r = id(1); c = id(2) ;
      % check number string
      if( isempty(s) )
         msgbox('Non-number entries ignored!') ;
         return ;
      end ;
      % check precision bound ( -x.xxxx 4 digit below fraction point )
      s = round(s*10000) / 10000 ;
      if( length(str)>8 | abs(s)>9999 ),
         msgbox('Too many digits -> rounded') ;
      end ;
      s = max(-9999, min(s, 9999) ) ;
      GParm.filt(r,c) = s ;
      set(GParm.edittext(r,c),'string',num2str(s,'%0.4g') ) ;
   end ;
   % first time before apply
   if strcmp(get(GParm.applypush,'enable'),'off' ),
      GParm.savefilt = GParm.filt ;
   end ;
   set([GParm.applypush GParm.cancelpush], 'enable', 'on') ;
   
return ;
%}}

function get_maskvalue()
%{{
global GParm ;

   s = GParm.edittext ;
   v = GParm.filt ;
   
   for i=1:3 ; for j=1:3 ;
      v(i,j) = str2num(get(s(i,j),'String')) ;
   end; end ;
   disp_mask ;

return ;
%}}

