changeset 6164:d90b16110095

[project @ 2006-11-14 21:08:00 by jwe]
author jwe
date Tue, 14 Nov 2006 21:08:01 +0000
parents 8614649c454c
children ea26b8fda4d7
files scripts/ChangeLog scripts/image/__img__.m scripts/image/__img_gnuplot__.m scripts/image/__img_via_file__.m scripts/image/image.m scripts/image/image_viewer.m
diffstat 6 files changed, 320 insertions(+), 145 deletions(-) [+]
line wrap: on
line diff
--- a/scripts/ChangeLog	Tue Nov 14 18:52:39 2006 +0000
+++ b/scripts/ChangeLog	Tue Nov 14 21:08:01 2006 +0000
@@ -1,3 +1,19 @@
+2006-11-14  John W. Eaton  <jwe@octave.org>
+
+	* image/image_viewer.m: Set default values here.
+	* image/image.m: Not here.
+
+	* image/image_viewer.m: Always return old values.  Check arguments.
+	* image/__img_gnuplot__.m: Rename from __img__m.
+
+2006-11-14  Søren Hauberg  <soren@hauberg.org>
+
+	* image/image_viewer.m: New function.
+	* image/__img_via_file__.m: New function.
+	* image/image.m: Use image_viewer to determine which program to
+	use for image viewing.
+	* scripts/image/__img__.m: Silently accept more than 3 args.
+
 2006-11-14  John W. Eaton  <jwe@octave.org>
 
 	* plot/__do_legend__.m, plot/__errplot__.m,
--- a/scripts/image/__img__.m	Tue Nov 14 18:52:39 2006 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,107 +0,0 @@
-## Copyright (C) 2006 Daniel Sebald
-##
-## Octave is free software; you can redistribute it and/or modify it
-## under the terms of the GNU General Public License as published by
-## the Free Software Foundation; either version 2, or (at your option)
-## any later version.
-##
-## Octave is distributed in the hope that it will be useful, but
-## WITHOUT ANY WARRANTY; without even the implied warranty of
-## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-## General Public License for more details.
-##
-## You should have received a copy of the GNU General Public License
-## along with Octave; see the file COPYING.  If not, write to the Free
-## Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-## 02111-1307, USA.
-
-## -*- texinfo -*-
-## @deftypefn {Function File} {} __img__ (@var{x}, @var{y}, @var{A})
-## Display an image using @code{gnuplot}, where vectors @var{x} and
-## @var{y} define the axes and the matrix @var{A} contains the image
-## data.
-## @end deftypefn
-
-function __img__ (x, y, A)
-
-  if (nargin != 3)
-    print_usage ();
-  endif
-
-  if (isempty (A))
-    error ("image matrix is empty");
-  endif
-
-  __gnuplot_raw__ ("set nokey\n");
-  __gnuplot_raw__ ("set size ratio -1;\n");
-  __current_color_map__ = colormap ();
-  palette_size = size (__current_color_map__, 1);
-  __gnuplot_raw__ (sprintf ("set palette positive color model RGB maxcolors %i\n", palette_size));
-  if (palette_size <= 128)
-    ## Break up command to avoid buffer overflow.
-    __gnuplot_raw__ ("set palette file \"-\"\n");
-    for i = 1:palette_size
-      __gnuplot_raw__ (sprintf ("%g %g %g %g\n", 1e-3 * round (1e3 * [(i-1)/(palette_size-1), __current_color_map__(i,:)])));
-    end
-    __gnuplot_raw__("e\n");
-  else
-    ## Let the file be deleted when Octave exits or `purge_tmp_files' is called.
-    [fid, binary_file_name, msg] = mkstemp ([P_tmpdir,"/gpimageXXXXXX"], 1);
-    fwrite (fid, __current_color_map__', "float32", 0, "ieee-le");
-    fclose (fid);
-    __gnuplot_raw__ (sprintf ("set palette file \"%s\" binary record=%d using 1:2:3\n", binary_file_name, palette_size));
-  endif
-
-  ## Use the newly added mode of "plot" called "with image".
-  if (isempty (x))
-    x = [1, size(A,2)];
-    y = [1, size(A,1)];
-  endif
-
-  ## Force rectangular grid by using only end points of
-  ## first row (column) if x (y) is a matrix or vector.
-  if ((size (x, 2)) > 1)
-    x = x(1,:)';
-  endif
-  if (abs (x(end) - x(1)) < (10*eps))
-    error ("end points in x dimension must not be equal");
-  else
-    x_dim = size (A, 2);
-    if (x_dim > 1)
-      dx = (x(end)-x(1))/(x_dim-1);
-    else
-      dx = 1;
-    endif
-  endif
-  if ((size (y, 1)) > 1)
-    y = y(:,1)';
-  endif
-  if (abs(y(end) - y(1)) < 10*eps)
-    error ("end points in y dimension must not be equal");
-  else
-    y_dim = size (A, 1);
-    if (y_dim > 1)
-      dy = (y(end)-y(1))/(y_dim-1);
-    else
-      dy = 1;
-    endif
-  endif
-
-  __gnuplot_raw__ (sprintf ("set xrange [%g:%g]\n", x(1)-dx/2, x(end)+dx/2));
-  __gnuplot_raw__ (sprintf ("set yrange [%g:%g]\n", y(1)-dy/2, y(end)+dy/2));
-  __gnuplot_raw__ ("set autoscale fix\n"); # "fix" is helpful for "a" hotkey
-  __gnuplot_raw__ ("set tics out\n");
-
-  A = reshape(A,size(A,1)*size(A,2),1);
-  ## Let the file be deleted when Octave exits or `purge_tmp_files' is called.
-  [fid, binary_file_name, msg] = mkstemp ([P_tmpdir, "/gpimageXXXXXX"], 1);
-  ## Gnuplot reads binary files very quickly.  However, the 'fwrite' below
-  ## is much slower than using the current '__gnuplot_plot__' command.
-  fwrite (fid, A', "float", 0, "ieee-le");
-  fclose (fid);
-  __gnuplot_raw__ (sprintf ("plot \"%s\" binary array=%dx%d scan=yx flipy origin=(%g,%g) dx=%g dy=%g endian=little using 1 with image\n", binary_file_name, x_dim, y_dim, min (x(1), x(end)), min(y(1), y(end)), abs (dx), abs (dy)));
-  ## Put back in default data mode.
-  __gnuplot_raw__ ("set xrange [*:*];\n");
-  __gnuplot_raw__ ("set yrange [*:*];\n");
-
-endfunction
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/image/__img_gnuplot__.m	Tue Nov 14 21:08:01 2006 +0000
@@ -0,0 +1,109 @@
+## Copyright (C) 2006 Daniel Sebald
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 2, or (at your option)
+## any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, write to the Free
+## Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+## 02111-1307, USA.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} __img_gnuplot__ (@var{x}, @var{y}, @var{A})
+## Display an image using @code{gnuplot}, where vectors @var{x} and
+## @var{y} define the axes and the matrix @var{A} contains the image
+## data.
+## @end deftypefn
+
+function __img_gnuplot__ (x, y, A, zoom)
+
+  ## ZOOM is ignored.
+
+  if (nargin < 3)
+    print_usage ();
+  endif
+
+  if (isempty (A))
+    error ("image matrix is empty");
+  endif
+
+  __gnuplot_raw__ ("set nokey\n");
+  __gnuplot_raw__ ("set size ratio -1;\n");
+  __current_color_map__ = colormap ();
+  palette_size = size (__current_color_map__, 1);
+  __gnuplot_raw__ (sprintf ("set palette positive color model RGB maxcolors %i\n", palette_size));
+  if (palette_size <= 128)
+    ## Break up command to avoid buffer overflow.
+    __gnuplot_raw__ ("set palette file \"-\"\n");
+    for i = 1:palette_size
+      __gnuplot_raw__ (sprintf ("%g %g %g %g\n", 1e-3 * round (1e3 * [(i-1)/(palette_size-1), __current_color_map__(i,:)])));
+    end
+    __gnuplot_raw__("e\n");
+  else
+    ## Let the file be deleted when Octave exits or `purge_tmp_files' is called.
+    [fid, binary_file_name, msg] = mkstemp ([P_tmpdir,"/gpimageXXXXXX"], 1);
+    fwrite (fid, __current_color_map__', "float32", 0, "ieee-le");
+    fclose (fid);
+    __gnuplot_raw__ (sprintf ("set palette file \"%s\" binary record=%d using 1:2:3\n", binary_file_name, palette_size));
+  endif
+
+  ## Use the newly added mode of "plot" called "with image".
+  if (isempty (x))
+    x = [1, size(A,2)];
+    y = [1, size(A,1)];
+  endif
+
+  ## Force rectangular grid by using only end points of
+  ## first row (column) if x (y) is a matrix or vector.
+  if ((size (x, 2)) > 1)
+    x = x(1,:)';
+  endif
+  if (abs (x(end) - x(1)) < (10*eps))
+    error ("end points in x dimension must not be equal");
+  else
+    x_dim = size (A, 2);
+    if (x_dim > 1)
+      dx = (x(end)-x(1))/(x_dim-1);
+    else
+      dx = 1;
+    endif
+  endif
+  if ((size (y, 1)) > 1)
+    y = y(:,1)';
+  endif
+  if (abs(y(end) - y(1)) < 10*eps)
+    error ("end points in y dimension must not be equal");
+  else
+    y_dim = size (A, 1);
+    if (y_dim > 1)
+      dy = (y(end)-y(1))/(y_dim-1);
+    else
+      dy = 1;
+    endif
+  endif
+
+  __gnuplot_raw__ (sprintf ("set xrange [%g:%g]\n", x(1)-dx/2, x(end)+dx/2));
+  __gnuplot_raw__ (sprintf ("set yrange [%g:%g]\n", y(1)-dy/2, y(end)+dy/2));
+  __gnuplot_raw__ ("set autoscale fix\n"); # "fix" is helpful for "a" hotkey
+  __gnuplot_raw__ ("set tics out\n");
+
+  A = reshape(A,size(A,1)*size(A,2),1);
+  ## Let the file be deleted when Octave exits or `purge_tmp_files' is called.
+  [fid, binary_file_name, msg] = mkstemp ([P_tmpdir, "/gpimageXXXXXX"], 1);
+  ## Gnuplot reads binary files very quickly.  However, the 'fwrite' below
+  ## is much slower than using the current '__gnuplot_plot__' command.
+  fwrite (fid, A', "float", 0, "ieee-le");
+  fclose (fid);
+  __gnuplot_raw__ (sprintf ("plot \"%s\" binary array=%dx%d scan=yx flipy origin=(%g,%g) dx=%g dy=%g endian=little using 1 with image\n", binary_file_name, x_dim, y_dim, min (x(1), x(end)), min(y(1), y(end)), abs (dx), abs (dy)));
+  ## Put back in default data mode.
+  __gnuplot_raw__ ("set xrange [*:*];\n");
+  __gnuplot_raw__ ("set yrange [*:*];\n");
+
+endfunction
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/image/__img_via_file__.m	Tue Nov 14 21:08:01 2006 +0000
@@ -0,0 +1,64 @@
+## Copyright (C) 2006 Søren Hauberg
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 2, or (at your option)
+## any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, write to the Free
+## Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+## 02110-1301, USA.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {} __img_via_file__(@var{x}, @var{y}, @var{im}, @var{zoom}, @var{command})
+## Display an image by saving it to a file in PPM format and launching
+## @var{command}.
+##
+## The @var{command} must be a format string containing @code{%s} and
+## possibly @code{%f}.  The @code{%s} will be replaced by the filename
+## of the image, and the @code{%f} will be replaced by @var{zoom}. The
+## @var{x} and @var{y} arguments are ignored.
+## @seealso{image, imshow, __img__, __img_via_file__, image_viewer}
+## @end deftypefn
+
+function __img_via_file__ (x, y, im, zoom, command)
+
+  ppm_name = tmpnam ();
+  saveimage (ppm_name, im, "ppm");
+
+  rm = sprintf ("rm -f \"%s\"", ppm_name);
+
+  if (isempty (command))
+    ## Different image viewer commands.
+    xv = sprintf ("xv -raw -expand %f \"%s\"", zoom, ppm_name);
+    xloadimage = sprintf ("xloadimage -zoom %f \"%s\"", zoom*100, ppm_name);
+    im_display = sprintf ("display -geometry %f%% \"%s\"", zoom*100, ppm_name);
+  
+    ## Need to let the shell clean up the tmp file because we are putting
+    ## the viewer in the background.
+    status = system (sprintf ("( %s || %s || %s && %s ) > /dev/null 2>&1 &",
+                              im_display, xv, xloadimage, rm));
+  else
+    ## Does the command support zooming?
+    if (findstr (command, "%f"))
+      command = sprintf (command, zoom, ppm_name);
+    else
+      command = sprintf (command, ppm_name);
+    endif
+    status = system (sprintf ("( %s && %s) > /dev/null 2>&1 &", command, rm));
+  endif
+  
+  ## Did the system call fail?
+  if (status != 0)
+    error ("the image viewing command failed");
+  endif
+
+endfunction
--- a/scripts/image/image.m	Tue Nov 14 18:52:39 2006 +0000
+++ b/scripts/image/image.m	Tue Nov 14 21:08:01 2006 +0000
@@ -25,12 +25,15 @@
 ## length of the colormap.  If @var{zoom} is omitted, the image will be
 ## scaled to fit within 600x350 (to a max of 4).
 ##
-## It first tries to use @code{display} from @code{ImageMagick} then
-## @code{xv} and then @code{xloadimage}.
+## It first tries to use @code{gnuplot}, then @code{display} from 
+## @code{ImageMagick}, then @code{xv}, and then @code{xloadimage}.
+## The actual program used can be changed using the @code{image_viewer}
+## function.
 ##
 ## The axis values corresponding to the matrix elements are specified in
-## @var{x} and @var{y}. At present they are ignored.
-## @seealso{imshow, imagesc, colormap}
+## @var{x} and @var{y}. If you're not using gnuplot 4.2 or later, these
+## variables are ignored.
+## @seealso{imshow, imagesc, colormap, image_viewer}
 ## @end deftypefn
 
 ## Author: Tony Richardson <arichard@stark.cc.oh.us>
@@ -55,43 +58,24 @@
   elseif (nargin == 3)
     zoom = [];
   elseif (nargin > 4)
-    print_usage ();
+    usage ("image (matrix, zoom) or image (x, y, matrix, zoom)");
   endif
 
-  if (compare_versions (__gnuplot_version__ (), "4.0", ">"))
-    __img__ (x, y, A);
-  else
-
-    if (isempty (zoom))
-      ## Find an integer scale factor which sets the image to
-      ## approximately the size of the screen.
-      zoom = min ([350/rows(A), 600/columns(A), 4]);
-      if (zoom >= 1)
-	zoom = floor (zoom);
-      else
-	zoom = 1 / ceil (1/zoom);
-      endif
+  if (isempty (zoom))
+    ## Find an integer scale factor which sets the image to
+    ## approximately the size of the screen.
+    zoom = min ([350/rows(A), 600/columns(A), 4]);
+    if (zoom >= 1)
+      zoom = floor (zoom);
+    else
+      zoom = 1 / ceil (1/zoom);
     endif
-    ppm_name = tmpnam ();
-
-    saveimage (ppm_name, A, "ppm");
-
-    ## Start the viewer.  Try display, xv, then xloadimage.
-
-    xv = sprintf ("xv -raw -expand %f \"%s\"", zoom, ppm_name);
-
-    xloadimage = sprintf ("xloadimage -zoom %f \"%s\"", zoom*100, ppm_name);
-
-    ## ImageMagick:
-    im_display = sprintf ("display -geometry %f%% \"%s\"", zoom*100, ppm_name);
-  
-    rm = sprintf ("rm -f \"%s\"", ppm_name);
-
-    ## Need to let the shell clean up the tmp file because we are putting
-    ## the viewer in the background.
-
-    system (sprintf ("( %s || %s || %s && %s ) > /dev/null 2>&1 &",
-                     im_display, xv, xloadimage, rm));
   endif
 
+  ## Get the image viewer.
+  [view_cmd, view_fcn, view_zoom] = image_viewer ();
+
+  ## Show the image.
+  view_fcn (x, y, A, zoom*view_zoom, view_cmd);
+
 endfunction
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/image/image_viewer.m	Tue Nov 14 21:08:01 2006 +0000
@@ -0,0 +1,109 @@
+## Copyright (C) 2006 Søren Hauberg
+##
+## This file is part of Octave.
+##
+## Octave is free software; you can redistribute it and/or modify it
+## under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 2, or (at your option)
+## any later version.
+##
+## Octave is distributed in the hope that it will be useful, but
+## WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+## General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with Octave; see the file COPYING.  If not, write to the Free
+## Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+## 02110-1301, USA.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {[@var{fcn}, @var{default_zoom}] =} image_viewer (@var{fcn}, @var{default_zoom})
+## Change the program or function used for viewing images and return the
+## previous values.
+##
+## When the @code{image} or @code{imshow} function is called it will
+## launch an external program to display the image.  The default behaviour
+## is to use gnuplot if the installed version supports image viewing,
+## and otherwise try the programs @code{display}, @code{xv}, and
+## @code{xloadimage}.  Using this function it is possible to change that
+## behaviour.
+##
+## When called with one input argument images will be displayed by saving
+## the image to a file and the system command @var{command} will called
+## to view the image.  The @var{command} must be a string containing
+## @code{%s} and possibly @code{%f}. The @code{%s} will be replaced by
+## the filename of the image, and the @code{%f} will (if present) be
+## replaced by the zoom factor given to the @code{image} function.
+## For example,
+## @example
+## image_viewer ("eog %s");
+## @end example
+## changes the image viewer to the @code{eog} program.
+##
+## With two input arguments, images will be displayed by calling
+## the function @var{function_handle}.  For example,
+## @example
+## image_viewer (data, @@my_image_viewer);
+## @end example
+## sets the image viewer function to @code{my_image_viewer}.  The image
+## viewer function is called with
+## @example
+## my_image_viewer (@var{x}, @var{y}, @var{im}, @var{zoom}, @var{data})
+## @end example
+## where @var{x} and @var{y} are the axis of the image, @var{im} is the image
+## variable, and @var{data} is extra user-supplied data to be passed to
+## the viewer function.
+##
+## With three input arguments it is possible to change the zooming.
+## Some programs (like @code{xloadimage}) require the zoom factor to be
+## between 0 and 100, and not 0 and 1 like Octave assumes. This is
+## solved by setting the third argument to 100.
+##
+## @seealso{image, imshow, __img_gnuplot__, __img_via_file__}
+## @end deftypefn
+
+function [ocmd, ofcn, ozoom] = image_viewer (cmd, fcn, zoom)
+
+  persistent view_cmd;
+  persistent view_fcn;
+  persistent view_zoom = 1;
+
+  if (isempty (view_fcn))
+    if (isempty (view_cmd)
+	&& compare_versions (__gnuplot_version__ (), "4.0", ">"))
+      view_fcn = @__img_gnuplot__;
+    else
+      view_fcn = @__img_via_file__;
+    endif
+  endif
+
+  if (nargin > 3)
+    print_usage ();
+  endif
+
+  ocmd = view_cmd;
+  ofcn = view_fcn;
+  ozoom = view_zoom;
+
+  if (nargin > 0)
+    view_cmd = cmd;
+  endif
+
+  if (nargin > 1)
+    if (isa (fcn, "function_handle"))
+      view_fcn = fcn;
+    else
+      error ("image_viewer: expecting second argument to be a function handle");
+    endif
+  endif
+
+  if (nargin > 2)
+    if (isnumeric (zoom) && isscalar (zoom) && isreal (zoom))
+      view_zoom = zoom;
+    else
+      error ("image_viewer: expecting third argument to be a real scalar");
+    endif
+  endif
+
+endfunction