function histdemo(action, varargin)

%HISTDEMO - It demonstrates histogram mapping experiments

%

%

%


% Author: J.Yang 4/99
% Copyright: Professor Jan Allebach at Purdue ECE
% $ Revision: 1.01  $  $ Date : 5/10/99


%-------<< Sub functions >>---------
% 1. init
% 2. Open
% 3. Popup
% 3-1. Active load image
% 4. close
% 5. MapBtn
% 5-1. stretch
% 5-2. equalize
% 5-3. reset_hist
% 6. EditBtn
% 6-1. histmap_add
% 6-2. histmap_drop
% 6-3. histmap_move
% 7. disp_new, disp_orig
% 8. disp_hist
% 9. show_value
%-----------------------------------

%{

if nargin < 1
   action = 'init' ;
end ;

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

%}



function init()
%{{
%   Parameter sharing by global cell array
%   'Gparm' = [ ... ] ;
% If demo is already running, bring it to the foreground.
h = findobj(allchild(0), 'tag', 'Hist convert');

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','Histogram convert 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','Hist convert');
xdim = 256 ; ydim = 256; 
xs1 = 8 ; xs2 = 261 + xs1 ; xs3 = xs2 + 261 ; 
yb = 20 ; yu = yb + ydim + 39 ;
%-----------------
% button layout
% BUTTON
posbox = [xs1 yb 200 100] ;
h = uicontrol('Style','frame', ...
   'Parent',GParm.figure, ...
   'Background',[.45 .45 .45], ...
   'Units','pixels', ...
   'Position',posbox) ;
%% File radio button
posbox = [xs1+50 yb+70 100 20] ;
GParm.open = uicontrol( ...
   'Parent',GParm.figure, ...
   'Style','Pushbutton', ...
   'Units','pixel', ...
   'BusyAction','queue','Interruptible','off', ...
   'Position',posbox, ...
   'String','Open File', ...
   'Callback','histdemo(''Open'');'... 
) ;
%% Image list button
posbox = [xs1+50 yb+40 100 20] ;
GParm.popup = uicontrol( ...
   'Parent',GParm.figure, ...
   'Style','popupmenu', ...
   'Units','pixel', ...
   'BusyAction','queue','Interruptible','off', ...
   'Position',posbox, ...
   'value',2, ...
   'String','Blur|Dark|House|Narrow|Race|Yacht' , ...
   'Callback','histdemo(''Popup'');' ...
) ;
%% Close button
posbox = [xs1+50 yb+10 100 20] ;
GParm.close = uicontrol( ...
   'Parent',GParm.figure, ...
   'Style','Pushbutton', ...
   'BusyAction','queue','Interruptible','off', ...
   'Units','pixel', ...
   'String','Close', ...
   'Position',posbox, ...
   'Callback','histdemo(''Close'');' ...
) ;
%% histogram manuipulation button
GParm.histMapText = uicontrol(...
   'Parent',GParm.figure, ...
   'Style','text', ...
   'Units','pixels', ...
   'Position',[xs3+4 yu-29 40 20], ...
   'Clipping','off', ...
   'String','MAP ' ...
) ;
posbox = [xs3+42 yu-25 83 20] ;
GParm.histMapBtn = uicontrol(...
   'Parent',GParm.figure, ...
   'Style','popupmenu', ...
   'BusyAction','queue','Interruptible','off', ...
   'Units','pixel', ...
   'String','Invert|Normal|Equalize|Stretch|Reset', ...
   'value',5, ...
   'Position',posbox, ...
   'Callback','histdemo(''MapBtn'');' ...
   );
GParm.histMapText = uicontrol(...
   'Parent',GParm.figure, ...
   'Style','text', ...
   'Units','pixels', ...
   'Position',[xs3+132 yu-29 40 20], ...
   'String','EDIT' ...
) ;
posbox(1) = posbox(1) + 128 ;
GParm.histEditBtn = uicontrol(...
   'Parent',GParm.figure, ...
   'Style','popupmenu', ...
   'BusyAction','queue','Interruptible','off', ...
   'Units','pixel', ...
   'String','Add|Drop|Move|Done', ...
   'value',4, ...
   'Position',posbox,...
   'Callback','histdemo(''EditBtn'');' ...
   ) ;
%% Show value box --- shared by histogram and image value display
GParm.padBox = uicontrol( ...
   'Parent',GParm.figure, ...
   'Style','frame', ...   
   'Background','k', ...
   'Visible','off', ...
   'Position',[0 0 100 20]...
   ) ;
GParm.padText = uicontrol( ...
   'Parent',GParm.figure, ...
   'Units','pixel', ...
   'Style','text', ...
   'Visible','off', ...
   'HitTest','off', ...
   'BackgroundColor','w', ...
   'Position',[0 0 98 18], ...
   'String','', ...
   'tag','Pad' ...
   ) ;
%------------------< screen layout >---------------------------------
%   To fit 6 image axes into 800x600 screen, allocate 256x256 images
%   to each axes.
%       
%     |              new  |        |
%     | orig         hist |        | reconstruct 256
%     +------          ---+        +-------
%    (8,336)                    (430,336)  
%     +------------------+         | orig hist  64
%     | button box       |         +--------
%     |                  |      (430,266) 
%     |                  |         | orig img  256
%     +------------------+         +-------
%    (8,5)           (400,5)    (430,5)    
%--------------------------------------------------------------------
% axes, image, surface
% AXES
% --- orig axes and images ---
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',[xs2 yb  xdim ydim], ...
   'Box','on', ...   
	 'XTick',[],'YTick',[], ...
   'Tag','origimgaxes' ...
   ) ;
GParm.origimg = image( ... % sampling grid interactive
   'Parent',GParm.origimgAxe, ...
   'Visible', 'off', ...
   'CData', [], ...
   'BusyAction','Queue','Interruptible','off',...
   'XData', [1:xdim],...
   'YData', [1:ydim],...
   'ButtonDownFcn','histdemo(''show_value'',20);', ...
   'EraseMode', 'normal' ...
   );
title('Original image') ;

% orig histogram axes and plot
GParm.orighistAxe = axes( ...
   'Parent',GParm.figure, ...
   'Units','pixels', ...
   'BusyAction','Queue','Interruptible','off',...
   'XLim', [-1 xdim+2], ...
   'YLim', [-1 ydim+2],...
   'CLim', [0 1], ...
   'Position',[xs3 yb  xdim ydim], ...
   'Drawmode','fast', ...
   'Box','on', ...   
   'Layer','top', ...   % show grid line above image   
   'XGrid','on','YGrid','on', ...
   'XTick',[128],'YTick',[10000], ...
   'Tag','orighistaxes' ...
);
title('Given Histogram','units','pixels','position',[110 257])   ;

GParm.origHist = line( ...
   'Parent',GParm.orighistAxe, ...
   'Visible','off', ...
   'Color','blue', ...
   'Linewidth',2, ...
   'EraseMode','xor', ...
   'ButtonDownFcn','histdemo(''show_value'',0);' , ...
   'XData',[],'YData',[] ...
   );

% histogram conversion plot & axes
GParm.histmapAxe = axes( ...
   'Parent',GParm.figure, ...
   'Units','pixels', ...
   'BusyAction','Queue','Interruptible','off',...
   'XLim', [-.5 xdim-.5], ...
   'YLim', [-.5 ydim-.5],...
   'CLim', [0 1], ...
   'Position',[xs3 yu  xdim ydim], ...
   'Drawmode','fast', ...
   'Box','on', ...   
   'Layer','top', ...   % show grid line above image   
   'XGrid','on','YGrid','on', ...
   'XTick',[128],'YTick',[128], ...
   'XTickLabel','','YTickLabel','', ...
   'Tag','orighistaxes' ...
   );
GParm.vertex = [[0;0],[255;255]] ;   
GParm.histMap = line( ...
   'Parent',GParm.histmapAxe, ...
   'Visible','on', ...
   'Color','blue', ...
   'Marker','diamond', ...
   'MarkerFaceColor','red', ...
   'EraseMode','normal', ...
   'XData',[0,255],'YData',[0,255] ...
   );
%%   'ButtonDownFcn','histdemo(''map_start'');',... 
title('Mapping Curve') ;
% new mapped histogram axes and plot
GParm.newhistAxe = axes( ...
   'Parent',GParm.figure, ...
   'Units','pixels', ...
   'BusyAction','Queue','Interruptible','off',...
   'xdir', 'reverse', ...
   'XLim', [-1 xdim+2], ...
   'YLim', [-1 ydim+2],...
   'CLim', [0 1], ...
   'Position',[xs2 yu  xdim ydim], ...
   'Drawmode','fast', ...
   'Box','on', ...   
   'Layer','top', ...   % show grid line above image   
   'XGrid','on','YGrid','on', ...
   'XTick',[10000],'YTick',[128], ...
   'Tag','orighistaxes' ...
   );
GParm.newHist = line( ...
   'Parent',GParm.newhistAxe, ...
   'Visible','off', ...
   'Color','blue', ...
   'Linewidth',2, ...
   'EraseMode','xor', ...
   'ButtonDownFcn','histdemo(''show_value'',10);', ...
   'XData',[],'YData',[] ...
   );
title('New Histogram') ;
% new image with histogram transformed
GParm.newimgAxe = 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',[xs1 yu  xdim ydim], ...
   'Box','on', ...   
	 'XTick',[],'YTick',[], ...
   'Tag','origimgaxes' ...
   ) ;
GParm.newimg = image( ... % sampling grid interactive
   'Parent',GParm.newimgAxe, ...
   'Visible', 'off', ...
   'CData', [], ...
   'BusyAction','Queue','Interruptible','off',...
   'XData', [1:xdim],...
   'YData', [1:ydim],...
   'ButtonDownFcn', 'histdemo(''show_value'',30);', ...
   'EraseMode', 'normal' ...
   );
title('Transformed image') ;

%------------------------------
%GParm.mapstart = 1 ;
GParm.veridx = 1 ;
GParm.imgData = [] ;
GParm.newimgData = [] ;
GParm.orighistData = [] ;
GParm.newhistData = [] ;
GParm.menuval = 1 ;
%------------------------------

Popup ;
drawnow ;

return ;

%}}

%--- Menu button function ----
function Open()
%{{
global GParm ;

   pos = get(GParm.open,'position') ;
   x = pos(1) + pos(3) + 10 ;
   y = pos(2) + pos(4) + 10 ;
   [fname,path] = uigetfile('*.tif','Open an image file :',x,y) ;

	if fname ~= 0
   		fname = strcat(path, fname) ;
	   Action_loadimage(fname) ;
   		disp_orig ;
	   draw_hist(1) ;
   		set(GParm.figure,'pointer','arrow') ;
   end ;
      
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 'Blur'
     load demo2 Blur ;   GParm.imgData = Blur ;    Blur = [] ;
  case 'Dark'
     load demo2 Dark ;   GParm.imgData = Dark ;    Dark = [] ;
  case 'House'
     load demo2 House ;  GParm.imgData = House ;   House = [] ;
  case 'Narrow'
     load demo2 Narrow ; GParm.imgData = Narrow ;  Narrow = [] ;
  case 'Race'
     load demo2 Race ;   GParm.imgData = Race ;    Race = [] ;
  case 'Yacht' 
     load demo2 Yacht ;  GParm.imgData = Yacht ;   Yacht = [] ;
  end ;
  
  disp_orig ;
  draw_hist(1) ;
  set(GParm.figure,'pointer','arrow') ;
return ;
%}}

function Close()
%{{
global GParm ;
%% close(gcf) ;
  close(GParm.figure) ;
  clear global GParm ;
return ;
%}}
%-------------------- sub functions -----------%
function disp_orig()
%{{{
global GParm ;

   im = GParm.imgData ;
   set(GParm.origimg,'CData',double(im),'visible','on') ;
   draw_hist(0) ;
   
return ;
%}}}

function disp_new()
%{{{
global GParm ;

   im = GParm.newimgData ;
   set(GParm.newimg,'CData',double(im),'visible','on' );
   drawnow ;
   
return ;
%}}}   

function nd = draw_hist(mode)
%{{ draw normalized histogram of orig and mapped image
global GParm ;

   switch mode
   case 0
      x = GParm.imgData ; 
      GParm.newimgData = GParm.imgData ; % just allocate mem
      for k=0:255 ;
         d(k+1) = sum(sum( x==uint8(k) )) ;
      end ;
      GParm.orighistData = d ;   % for show_val
      max_hist = max(255,max(d(:))) ;
      set(GParm.orighistAxe,'Ylim',[-0.01 max_hist+10]);  %,'yscale','log');
      set(GParm.origHist,'Xdata',[0:255], 'YData',d,'color','b','visible','on') ;
   case 1
      ax = GParm.newhistAxe ;
      h = GParm.newHist;  
      x = [GParm.vertex(1,:)] ;
      y = [GParm.vertex(2,:)] ;
      len = length(x) ;
      d = zeros(1,256) ;
      ng = zeros(1,256) ;
      for m = 1:len-1 ;
         dx = x(m+1) - x(m) ;
         dy = y(m+1) - y(m) ;
         sy = y(m) * dx + 0.5;
         if( x(m) ~= x(m+1) )
         for k=x(m)+(m>1)+1:x(m+1)+1 ; % to prevent divide zero [0,255] -> [ 1,256]
            cnt = sum(sum(GParm.imgData == uint8(k-1) ) );
            sy = sy + dy ;
            ng(k) = min(255,max( floor(sy / dx),0)) ;  % new gray value
            d(ng(k)+1) = d(ng(k)+1) + cnt ;
         end ;
         end ;
      end ;
      GParm.newimgData = uint8(ng(double(GParm.imgData(:,:))+1)) ;
      GParm.newhistData = d ;   % for show_val
      max_hist = max(255,max(d(:))) ;
      set(GParm.newhistAxe,'xlim',[-0.01 max_hist+10]) ; % ,'xscale','log');
      set(GParm.newHist,'ydata',[0:255], 'xData',d,'color','b','visible','on') ;
      disp_new ;
   end ;
return ;
%}}
%------- histogram map button functions  ----------------
function MapBtn()
%{{
global GParm ;

   % get name and value for popup list button
   v = get(GParm.histMapBtn,{'value','String'}) ;
   name = deblank(v{2}(v{1},:)) ;
   switch ( v{1} )
   case 5, % Reset
      reset_hist ;   
   case {1, 2} %Invert,Normal
      if( v{1} ~= GParm.menuval ) return ; end ;
      GParm.menuval = 3 - v{1} ;
      GParm.vertex(2,:) = 255 - GParm.vertex(2,:)  ;
      set(GParm.histMap,'Xdata',[GParm.vertex(1,:)],'YData',[GParm.vertex(2,:)]) ;
      draw_hist(1) ;
   case 3, %Equalize
      equalize ;
   case 4, %Stretch
      stretch ;
   end ;
   
return ;
%}}

function stretch()
%{{ ignore below 2% occurrence
global GParm ;

   d = GParm.orighistData ;   % for show_val
   max_hist = max(255,max(d(:))) ;
   k = GParm.menuval ;  % holds Invert/Normal status
   yb = [0 255] ;
   big = find( d > max_hist * 0.02 ) ; % over than 2 percent
   GParm.vertex = [ 0 big(1) big(length(big)) 255 ; ...
                   yb(k) yb(k) yb(3-k) yb(3-k)] ; 
   set(GParm.histMap,'XData',[GParm.vertex(1,:)],'YData',[GParm.vertex(2,:)]) ;
   draw_hist(1) ;
   drawnow ;
   
return ;
%}}

function equalize()
%{{ use 'histeq' matlab function
global GParm ;

   set(GParm.figure,'Pointer','watch') ;
   [GParm.newimgData ng] = histeq(GParm.imgData,64) ;
   GParm.vertex(1,1:256) = 0:255  ;
   GParm.vertex(2,1:256) = floor(ng(:)*255+.5) ;
   set(GParm.histMap,'XData',[GParm.vertex(1,:)],'YData',[GParm.vertex(2,:)],...
      'Erasemode','xor') ;
   drawnow ;
   d = zeros(1,256) ;
   for k=1:256 ;
      cnt = sum(sum(GParm.newimgData == uint8(k-1) ) );
      d(k) = cnt ;
   end ;
   GParm.newimgData = uint8(GParm.newimgData) ;
   GParm.newhistData = d ;   % for show_val
   max_hist = max(255,max(d(:))) ;
   set(GParm.newhistAxe,'xlim',[-0.01 max_hist+10]) ; % ,'xscale','log');
   set(GParm.newHist,'ydata',[0:255], 'xData',d,'color','b','visible','on') ;
   
   set(GParm.figure,'Pointer','arrow') ;
   disp_new ;
return ;
%}}

function reset_hist()
%{{ back to normal mapping
global GParm ;

   GParm.menuval = 1 ;
   set(GParm.histMap,'XData',[0,255],'YData',[0,255]) ;
   GParm.vertex = [[0;0],[255;255]] ;   
   draw_hist(1) ;
   drawnow ;
return ;
%}}
%------- histogram Edit button functions  ----------------

function EditBtn()
%{{
global GParm ;

   % get name and value for popup list button
   v = get(GParm.histEditBtn,{'value','String'}) ;
   name = deblank(v{2}(v{1},:)) ;
   GParm.editmode = v{1} ;
   set(GParm.histmapAxe,'ButtonDownFcn','') ;
   switch ( v{1} )
   case 1, % Add
      set([GParm.histmapAxe GParm.histMap],'ButtonDownFcn','histdemo(''histmap_add'')' ) ;   
   case 2, % Drop
      set(GParm.histMap,'ButtonDownFcn','histdemo(''histmap_drop'')' ) ;   
   case 3, % Move
      set(GParm.histMap,'ButtonDownFcn','histdemo(''histmap_move'',0)' ) ;   
   case 4, % Done
      set(GParm.histMap,'ButtonDownFcn','' ) ;   
      set(GParm.figure,'pointer','watch') ;
      drawnow ;
      draw_hist(1) ;
      disp_new ;
      set(GParm.figure,'pointer','arrow') ;
      drawnow ;
   end ;
   
return ;
%}}

function histmap_add()
%{{{
global GParm ;

   pt = get(GParm.histmapAxe,'currentpoint') ;
   pos = floor(pt(1,1:2) + [.5 .5]) ;
   % insert point and sort by column -- x increasing order
   a = sort([256 1] * [GParm.vertex,[pos(1,1);pos(1,2)]]) ;
   GParm.vertex = [floor(a/256) ; mod(a,256)] ;
   % GParm.vertex = [x1 x2 x3 .. xe ; 
   %                 y1 y2 y3 .. ye ] ;
   set(GParm.histMap,'Erasemode','xor', ...
      'Xdata',[GParm.vertex(1,:)],'YData',[GParm.vertex(2,:)]) ;
   
return ;
%}}}

function histmap_drop()
%{{{
global GParm ;

   pt = get(GParm.histmapAxe,'currentpoint') ;
   % distance from cursor to vetice.
   dist = round([GParm.vertex(1,:)-pt(1,1); GParm.vertex(2,:)-pt(1,2)] ) ;
   dist = sum(dist.^2,1) ; 
   [v idx] = min (dist) ;
   len = size(GParm.vertex,2) ;
   % preserve start, end point
   if( idx == 1 | idx == len ) return ; end ;
   a = GParm.vertex   ;
   % delete picked vetex
   GParm.vertex = [ a(:,1:idx-1), a(:,idx+1:len) ];
   set(GParm.histMap,'Erasemode','xor', ...
      'Xdata',[GParm.vertex(1,:)],'YData',[GParm.vertex(2,:)]) ;
   
return ;
%}}}

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

   pt = get(GParm.histmapAxe,'currentpoint') ;
   x = floor( pt(1,1)+.5) ; y = (pt(1,2)+.5) ;
   x = min(255,max(x,0)) ; y = min(255,max(y,0)) ;
   len = size(GParm.vertex,2) ; % column length
   % check if new vertex added
   % GParm.vertex = [x1 x2 x3 .. xe ; 
   %                 y1 y2 y3 .. ye ] ;
   switch( mode )
   case 0, % initial pick
      % distance from cursor to vetice.
      dist = round([GParm.vertex(1,:)-x; GParm.vertex(2,:)-y] ) ;
      dist = sum(dist.^2,1) ; 
      [v idx] = min (dist) ;
      % preserve start, end point
      if( idx == 1 | idx == len ) return ; end ;
      GParm.veridx = idx ;
      set(GParm.figure,'WindowButtonMotionFcn','histdemo(''histmap_move'',1)' );
      set(GParm.figure,'WindowButtonUpFcn','histdemo(''histmap_move'',2)' );
      set(GParm.histMap,'Erasemode','xor','XData',[GParm.vertex(1,:)],'YData',[GParm.vertex(2,:)]) ;
      set(GParm.figure,'pointer','cross') ;
      drawnow ;
   case {1,2} % button and motion
      % bounding x segment
      bsx = max(1,GParm.veridx-1) ; bex = min(len,GParm.veridx+1) ;
      bsx = GParm.vertex(1,bsx) ; bex = GParm.vertex(1,bex) ;
      GParm.vertex(1,GParm.veridx) = max( bsx, min(x, bex) ) ; 
      GParm.vertex(2,GParm.veridx) = max( 0,min(y,255) ) ;
      if mode == 2 , % button release
   	      a = GParm.vertex ;
   		   % eliminate duplicated pts
   		   b = [] ; % start from null
   		   for i=1:len-1 ;
           	if( abs(a(1,i)-a(1,i+1))>2 | abs(a(2,i)-a(2,i+1))>2 ) b = [b, [a(:,i);]] ; end ;   
   		   end ;
         GParm.vertex = [b, [a(:,len);]] ; % append last
         set(GParm.figure,'WindowButtonMotionFcn','','WindowButtonUpFcn','','pointer','watch') ;
         set(GParm.histMap,'Erasemode','normal','visible','on') ;
         set(GParm.figure,'pointer','arrow') ;
      end ;
      set(GParm.histMap,'XData',[GParm.vertex(1,:)],'YData',[GParm.vertex(2,:)]) ;
      drawnow ;
   end ;
   
return ;
%}}}



%----------- auxiliary functions ---------------------------
function show_value(mode)
%{{{
global GParm ;

   if rem(mode,10) ,
      set([GParm.padBox GParm.padText],'visible','off') ;
      set(GParm.figure,'WindowButtonUpFcn','') ;
      drawnow ;
      return ;
   end ;
   
   pt = get(GParm.figure,'currentpoint') ;
   if( pt(1,1) > 690 ) pt(1,1) = pt(1,1) - 100 ; end ;
   if( pt(1,2) > 540 ) pt(1,2) = pt(1,2) - 40 ; end ;
   pos = [pt(1,1)+2 pt(1,2)+4 98 36] ;
   pos1 = [pt(1,1)+1 pt(1,2)+3 100 38] ;
   
   hax = get(GParm.figure,'currentAxes') ;
   pt = get(hax,'currentpoint') ;
   idx = min(255, max(floor( pt(1,1) + .5 ),1) ); 
   idy = min(255, max(floor( pt(1,2) + .5 ),1) );
   switch (mode/10) ,
   case 0, % orighist
      s = sprintf(' gray : %d\n count : %ld ',idx-1, GParm.orighistData(idx)) ;
   case 1, % newhist
      s = sprintf(' gray : %d\n count : %ld ',idy-1, GParm.newhistData(idy)) ;
   case 2,  % origimg 
disp([idx,256-idy]) ;      
      s = sprintf('pixel: (%d,%d)\ngray : %d',idx,256-idy,...
         double( GParm.imgData(idy,idx)) );
   case 3, % newimg
      s = sprintf('pixel: (%d,%d)\ngray : %d',idx,256-idy,...
         double( GParm.newimgData(idy,idx)) );
   end ;
   set(GParm.padBox,'Visible','on','position',pos1) ;
   set(GParm.padText,'visible','on','position',pos,'String',s) ;
   set(GParm.figure,'WindowButtonUpFcn','histdemo(''show_value'',1);' ) ;
   drawnow ;
         
return ;
%}}}


function Action_loadimage(fname)
% {{{{
global GParm ;

   set(GParm.figure,'Pointer','watch') ;
   drawnow
   
   try
   if exist(fname)   % fname ~= [] or ''
      x = imread(fname) ;
   else 
      set(GParm.figure,'Pointer','arrow') ;
      errordlg(LASTERR,'No such File','modal') ;
      return ; 
   end  
   catch
   errordlg(LASTERR,'MATLAB Error Message','modal') ;
   set(GParm.figure,'Pointer','arrow') ;
   drawnow 
   return  ;
   end
   
   % crop center area
   [xs ys] = size(x) ;
   if( xs>256 & ys>=256) | (ys>256 & xs>=256)
      xs = ceil( (xs-255)/2 ) ;
      ys = ceil( (ys-255)/2 ) ;
      y = x(xs:xs+255,ys:ys+255) ;
      x = y ;   
   else if( xs<256 | ys<256 )
      errmsg = ['The "' fname '" file has smaller image size than 256 x 256.' ...
            '\n Image Load operation aborted.'] ;
      errordlg(errmsg,'Image size error','modal') ;
      set(GParm.figure,'Pointer','arrow') ;
      drawnow
      return ;
      end ;   
   end ;
   
   GParm.imgData = x ;
   drawnow
 
   return ;
% }}}} end of Action_loadimage
