help-octave
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

win32 imread and imwrite


From: Rahman Mohamud Faisal MOORABY
Subject: win32 imread and imwrite
Date: Thu, 22 Apr 2004 17:32:30 -0500

Hi listers

I managed to make the imread and imwrite M files work on win32 platforms. They should still work on unix platforms as well. Would be great to get your feedback.

You will need to set isunix to false in isunix.m

The problems where :

octave uses the unix file tree while the path to image magick must be in win32 format.


------------------------------------------------------------------------------------------------------------------------------

#IMREAD: read images into octave from various file formats
#
# Note: this requires the ImageMagick "convert" utility
#       get this from www.imagemagick.org if required
#       additional documentation of options is available from the
#       convert man page
#
# BASIC USAGE:
# img    = imread( fname )
#                 - img is a greyscale (0-255) of image in fname
# [im,map]=imread( fname )
#                 - map is a matrix of [r,g,b], 0-1 triples
#                 - img is a matrix on indeces into map
# [r,g,b]= imread( fname )
#                 - r,g,b are red,green,blue (0-255) compondents
#
# Formats for image fname
#   1. simple guess from extention ie "fig.jpg", "blah.gif"
#   2. specify explicitly             "jpg:fig.jpg", "gif:blah.gif"
#   3. specify subimage for multi-image format "tiff:file.tif[3]"
#   4. raw images (row major format) specify geometry
#                                      "raw:img[256x180]"
#
# IMREAD OPTIONS:
# imread will support most of the options for convert.1
#
# img    = imread( fname , options)
# [r,g,b]= imread( fname , options)
#
# where options is a string matrix (or list) of options
#
# example:   options= ["-rotate 25";
#                      "-crop 200x200+150+150";
#                      "-sample 200%" ];
#   will rotate, crop, and then expand the image.
#   note that the order of operations is important
#
# The following options are supported
#  -antialias           remove pixel-aliasing
#  -blur geometry       blur the image
#  -border geometry     surround image with a border of color
#  -bordercolor color   border color
#  -colors value        maximum number of colors in the image
#  -colorspace type     alternate image colorspace
#  -contrast            enhance or reduce the image contrast
#  -crop geometry       preferred size and location of the cropped image
#  -despeckle           reduce the speckles within an image
#  -dither              apply Floyd/Steinberg error diffusion to image
#  -draw string         annotate the image with a graphic primitive
#  -edge radius         apply a filter to detect edges in the image
#  -emboss radius       emboss an image
#  -enhance             apply a digital filter to enhance a noisy image
#  -equalize            perform histogram equalization to an image
#  -filter type         use this filter when resizing an image
#  -flip                flip image in the vertical direction
#  -flop                flop image in the horizontal direction
#  -font name           font for rendering text
#  -frame geometry      surround image with an ornamental border
#  -fuzz distance       colors within this distance are considered equal
#  -gamma value         level of gamma correction
#  -geometry geometry   perferred size or location of the image
#  -gaussian geometry   gaussian blur an image
#  -gravity type        vertical and horizontal text placement
#  -implode amount      implode image pixels about the center
#  -intent type         Absolute, Perceptual, Relative, or Saturation
#  -interlace type      None, Line, Plane, or Partition
#  -level value         adjust the level of image contrast
#  -map filename        transform image colors to match this set of colors
#  -median radius       apply a median filter to the image
#  -modulate value      vary the brightness, saturation, and hue
#  -monochrome          transform image to black and white
#  -mosaic              create an mosaic from an image sequence
#  -negate              replace every pixel with its complementary color
#  -noise radius        add or reduce noise in an image
#  -normalize           transform image to span the full range of colors
#  -paint radius        simulate an oil painting
#  -raise value         lighten/darken image edges to create a 3-D effect
#  -region geometry     apply options to a portion of the image
#  -roll geometry       roll an image vertically or horizontally
#  -rotate degrees      apply Paeth rotation to the image
#  -sample geometry     scale image with pixel sampling
#  -scale geometry      resize image
#  -scene value         image scene number
#  -segment values      segment an image
#  -seed value          pseudo-random number generator seed value
#  -shade degrees       shade the image using a distant light source
#  -sharpen geometry    sharpen the image
#  -shave geometry      shave pixels from the image edges
#  -shear geometry      slide one edge of the image along the X or Y axis
#  -size geometry       width and height of image
#  -solarize threshold  negate all pixels above the threshold level
#  -spread amount       displace image pixels by a random amount
#  -swirl degrees       swirl image pixels about the center
#  -texture filename    name of texture to tile onto the image background
#  -threshold value     threshold the image
#  -transparent color   make this color transparent within the image
#  -treedepth value     depth of the color tree
#  -type type           image type
#  -unsharp geometry    sharpen the image
#  -wave geometry       alter an image along a sine wave

# Author: Andy Adler

function [out1,out2,out3]= imread(filename, options );

try save_empty_list_elements_ok= empty_list_elements_ok;
catch save_empty_list_elements_ok= 0;
end
try save_warn_empty_list_elements= warn_empty_list_elements;
catch save_warn_empty_list_elements= 0;
end
unwind_protect
empty_list_elements_ok= 1;
warn_empty_list_elements= 0;

if (nargin == 0)
 usage (["img    =  imread (filename,options)\n", ...
         "[r,g,b]=  imread (filename,options)\n", ...
         "[img,map]=imread (filename,options)" ]);
elseif (! isstr (filename))
 error ("imread: expecting filename as a string");
endif

if any(filename==':') || any(filename=='[')
  # we've using special imagemagick characters, so we don't
  # do any octave path processing
  fname= filename;
else
  fname= file_in_path(IMAGEPATH,filename);
  if isempty(fname)
     error(['imread: file ' filename ' not found']);
  end
end

# Put together the options string
# TODO: add some error checking here
if nargin==1
  option_str="";
else
  option_str="";
  if     ( is_list( options ) )
     for i= 1:length(options)
        option_str=[option_str," ", nth(options,i) ];
     end
  elseif ( isstr( options ) )
     for i= 1:size(options,1)
        option_str=[option_str," ", options(i,:) ];
     end
  else
    error ("imread: expecting options as a string");
  end
end
#
# decode the nargout to output what the user wants
#
if     nargout==3;
   wantgreyscale= 0;
   wantmap= 0;
   outputtype="ppm";
elseif nargout==2;
   wantgreyscale= 0; wantmap= 1;
   outputtype="ppm";
else
   wantgreyscale= 1; wantmap= 0;
   outputtype="pgm";
end

#  pname= sprintf("convert %s '%s' %s:- 2>/dev/null",
#  pname= sprintf("convert %s '%s' %s:- ",
#                 option_str, fname, outputtype);
#  fid= popen(pname ,'r');
#  disp(pname); disp(fid);

  # create temporary file name
  tnam= tmpnam();

  if (isunix);
       printf("You are running the UN*X version of ImRead\n");
        cmd= sprintf("convert %s '%s' %s:%s 2>/dev/null ",
                 option_str, fname, outputtype, tnam);

  else
        printf("You are running the WiNdOWz version of ImRead\n");

        # convert input file path into windowz format
        fname=sprintf("cygpath -w %s", fname);
        fname=system(fname);

# change the '\' strokes to '/' in the path name to prevent string conflicts
        for i=1:length(fname)
                        if fname(i)=='\\';
                                fname(i)='/';
                        end
        end

# this routine because a newline character is added into fname (maybe bug in the "file_in_path" function <see line 123>. This has to be removed.
        if double(fname(length(fname))) >122 || double(fname(length(fname))) 
<65;
                fname=fname(1:length(fname)-1);
        end

        # create the command string
cmd= sprintf("convert %s ""%s"" %s:""%s""",option_str,fname,outputtype,tnam);

       # command string convert the input file name path back to UN*X form
       fname=sprintf("cygpath -u ""%s""", fname);

        # Again convert the '\' strokes to '/' to prevent conflicts
        for i=1:length(tnam)
                if tnam(i)=='\\';
                        tnam(i)='/';
                end
        end

        # do same for the temp file name created
        for i=1:length(tnam)
                        if tnam(i)=='\\';
                                tnam(i)='/';
                        end
        end

        # execute command string to change filename to UN*X format
        fname=system(fname);

        # create command string to convert temporary file name path to unix 
format
        if tnam(2)==':';
                tnam(2)=tnam(1);
                tnam(1)='/';
                tnam=sprintf("/cygdrive%s",tnam);
        end

  end

  system(cmd);
  fid= fopen(tnam,"rb");
#
# can we open the pipe?
# if not 1) The file format is wrong and the conver program has bailed out
#        2) The apropriate converter program hasn't been installed
#
  if fid<0;
     unlink(tnam);
     error(['could not read file: ' tnam]);
  end

# get file type
  line= fgetl( fid );
  if     strcmp(line, 'P1');   bpp=1; spp=1; bindata=0;
  elseif strcmp(line, 'P4');   bpp=1; spp=1; bindata=1;
  elseif strcmp(line, 'P2');   bpp=8; spp=1; bindata=0;
  elseif strcmp(line, 'P5');   bpp=8; spp=1; bindata=1;
  elseif strcmp(line, 'P3');   bpp=8; spp=3; bindata=0;
  elseif strcmp(line, 'P6');   bpp=8; spp=3; bindata=1;
  else
#     pclose(fid);
     fclose(fid); unlink(tnam);
     error(['Image format error for ',fname,':line=', setstr(line)]);
  end

# ignore comments
  line= fgetl( fid );
  while length(line)==0 || line(1)=='#'
     line= fgetl( fid );
  end

# get width, height
  [wid, hig]= sscanf( line, '%d %d', 'C' );

# get max component value
  if bpp==8
    max_component= sscanf( fgetl(fid), '%d' );
    if (max_component > 255)
      # The PGM standard supports only values below 65536
      bpp = 16;
    endif
  end

  if bindata
     if(bpp == 16)
        # PGM format has MSB first, i.e. big endian
        data = fread(fid, "uint16", 0, "ieee-be");
     else
        data = fread(fid);
     endif
     numdata= size(data,1);

     if bpp==1
        data= rem( floor( (data*ones(1,8)) ./ ...
                (ones(length(data),1)*[128 64 32 16 8 4 2 1]) ), 2)';
     end
  else
     numdata= wid*hig*spp;
     data= zeros( numdata,1 );
     dptr= 1;

        line= fgetl( fid );
     while !feof( fid)
        rdata= sscanf( line ,' %d');
        nptr= dptr + size(rdata,1);
        data( dptr:nptr-1 ) = rdata;
        dptr= nptr;
        line= fgetl( fid );
     end # feof
  end #if bindata

#  pclose(fid);
  fclose(fid); unlink(tnam);

  if spp==1
     greyimg= reshape( data(:), wid, hig )';
  elseif spp==3
     redimg= reshape( data(1:spp:numdata), wid, hig )';
     grnimg= reshape( data(2:spp:numdata), wid, hig )';
     bluimg= reshape( data(3:spp:numdata), wid, hig )';
  else
error(sprintf("imread: don't know how to handle pnm with spp=%d",spp));
  end


#   This section outputs the image in the desired output format
# if the user requested the colour map, the we regenerate it from
# the image.
#
#   Of course, 1) This may result in huge colourmaps
#              2) The colourmap will not be in the same order as
#                   in the original file

if wantgreyscale

  if exist('greyimg')
     out1= greyimg;
  elseif exist('idximg')
     greymap= mean(map')';
     out1= reshape( greymap( idximg ) , size(idximg,1), size(idximg,2) );
  else
     out1= ( redimg+grnimg+bluimg ) / 3 ;
  end

elseif wantmap

  if exist('idximg')
     out1= idximg;
     out2= map;
  elseif exist('greyimg')
     [simg, sidx] = sort( greyimg(:) );
     [jnkval, sidx] = sort( sidx );

     dimg= [1; diff(simg)>0 ];
     cimg= cumsum( dimg );
     out1= reshape( cimg( sidx ) , hig, wid);
     out2= ( simg(find( dimg ))*[1,1,1] - 1)/256;
  else
#
# Generate a colourmap for RGB images by packing RGB into
# an integer and assigning the unique values to a colormap.
#
     c_range= 256; # use 65536 for 48 bit color
     [simg, sidx] = sort( round(redimg(:)) + ...
                 c_range *round(grnimg(:)) + ...
               c_range^2 *round(bluimg(:)) );
     [jnkval, sidx] = sort( sidx );

     dimg= [1; diff(simg)>0 ];
     cimg= cumsum( dimg );
     out1= reshape( cimg( sidx ) , hig, wid );
     tmpv= simg(find( dimg ));
     out2= [ rem(tmpv,c_range), ...
             rem(floor(tmpv/c_range), c_range), ...
             floor(tmpv/c_range^2) ]/c_range;
  end


else

  if exist('greyimg')
     out1= greyimg;
     out2= greyimg;
     out3= greyimg;
  else
     out1= redimg;
     out2= grnimg;
     out3= bluimg;
  end

end

unwind_protect_cleanup
empty_list_elements_ok= save_empty_list_elements_ok;
warn_empty_list_elements= save_warn_empty_list_elements;
end_unwind_protect

#
# $Log: imread.m,v $
# Revision 1.10  2004/04/15 11:24:10  Faisal Mooraby
# Support for Win32 platforms
#
# $Log: imread.m,v $
# Revision 1.9  2004/02/18 14:54:10  pkienzle
# Colour values from ppm are 0-255 not 1-256
#
# Revision 1.8  2003/11/14 16:55:10  tpikonen
# Fix endianess bug in 16-bit reads.
#
# Revision 1.6  2003/09/12 14:22:42  adb014
# Changes to allow use with latest CVS of octave (do_fortran_indexing, etc)
#
# Revision 1.5  2003/07/25 19:11:41  pkienzle
# Make sure all files names referenced in system calls are wrapped in quotes
# to protect against spaces in the path.
#
# Revision 1.4  2002/11/27 08:40:11  pkienzle
# author/license updates
#
# Revision 1.3  2002/03/19 18:14:13  aadler
# unfortunately using popen seems to create problems, mostly
# on win32, but also on linux, so we need to move to a tmpfile approach
#
# Revision 1.2  2002/03/17 05:26:14  aadler
# now accept filenames with spaces
#
# Revision 1.1  2002/03/11 01:56:47  aadler
# general image read/write functionality using imagemagick utilities
#
#

-------------------------------------------------------------------------------------------------------------------------------------------

#IMWRITE: write image from octave to various file formats
#
# Note: this requires the ImageMagick "convert" utility.
#       get this from www.imagemagick.org if required
#       additional documentation of options is available from the
#       convert man page
#
# BASIC USAGE:
# imwrite( fname, img )
#                 - img is a greyscale (0-255) of image in fname
# imwrite( fname, img, map )
#                 - map is a matrix of [r,g,b], 0-1 triples
#                 - img is a matrix on indeces into map
# imwrite( fname, r,g,b );
#                 - r,g,b are red,green,blue (0-255) compondents
#
# Formats for image fname
#   1. simple guess from extention ie "fig.jpg", "blah.gif"
#   2. specify explicitly             "jpg:fig.jpg", "gif:blah.gif"
#   3. specify subimage for multi-image format "tiff:file.tif[3]"
#   4. raw images (row major format) specify geometry
#                                      "raw:img[256x180]"
#
# IMREAD OPTIONS:
# imread will support most of the options for convert.1
#
# imwrite( fname, img, options )
# imwrite( fname, img, map, options )
# imwrite( fname, r,g,b, options );
#
# where options is a string matrix (or list) of options
#
# example:   options= ["-rotate 25";
#                      "-crop 200x200+150+150";
#                      "-sample 200%" ];
#   will rotate, crop, and then expand the image.
#   note that the order of operations is important
#
# The following options are supported
#  -antialias           remove pixel-aliasing
#  -background color    background color
#  -blur geometry       blur the image
#  -border geometry     surround image with a border of color
#  -bordercolor color   border color
#  -box color           color for annotation bounding box
#  -charcoal radius     simulate a charcoal drawing
#  -colorize value      colorize the image with the fill color
#  -colors value        preferred number of colors in the image
#  -colorspace type     alternate image colorspace
#  -comment string      annotate image with comment
#  -compress type       type of image compression
#  -contrast            enhance or reduce the image contrast
#  -crop geometry       preferred size and location of the cropped image
#  -density geometry    vertical and horizontal density of the image
#  -depth value         depth of the image
#  -despeckle           reduce the speckles within an image
#  -dispose method      GIF disposal method
#  -dither              apply Floyd/Steinberg error diffusion to image
#  -draw string         annotate the image with a graphic primitive
#  -edge radius         apply a filter to detect edges in the image
#  -emboss radius       emboss an image
#  -enhance             apply a digital filter to enhance a noisy image
#  -equalize            perform histogram equalization to an image
#  -fill color          color to use when filling a graphic primitive
#  -filter type         use this filter when resizing an image
#  -flip                flip image in the vertical direction
#  -flop                flop image in the horizontal direction
#  -font name           font for rendering text
#  -frame geometry      surround image with an ornamental border
#  -fuzz distance       colors within this distance are considered equal
#  -gamma value         level of gamma correction
#  -geometry geometry   perferred size or location of the image
#  -gaussian geometry   gaussian blur an image
#  -gravity type        vertical and horizontal text placement
#  -implode amount      implode image pixels about the center
#  -intent type         Absolute, Perceptual, Relative, or Saturation
#  -interlace type      None, Line, Plane, or Partition
#  -label name          assign a label to an image
#  -level value         adjust the level of image contrast
#  -list type           Color, Delegate, Format, Magic, Module, or Type
#  -map filename        transform image colors to match this set of colors
#  -matte               store matte channel if the image has one
#  -median radius       apply a median filter to the image
#  -modulate value      vary the brightness, saturation, and hue
#  -monochrome          transform image to black and white
#  -morph value         morph an image sequence
#  -negate              replace every pixel with its complementary color
#  -noise radius        add or reduce noise in an image
#  -normalize           transform image to span the full range of colors
#  -opaque color        change this color to the fill color
#  -page geometry       size and location of an image canvas
#  -paint radius        simulate an oil painting
#  -profile filename    add ICM or IPTC information profile to image
#  -quality value       JPEG/MIFF/PNG compression level
#  -raise value         lighten/darken image edges to create a 3-D effect
#  -region geometry     apply options to a portion of the image
#  -roll geometry       roll an image vertically or horizontally
#  -rotate degrees      apply Paeth rotation to the image
#  -sample geometry     scale image with pixel sampling
#  -scale geometry      resize image
#  -segment values      segment an image
#  -seed value          pseudo-random number generator seed value
#  -shade degrees       shade the image using a distant light source
#  -sharpen geometry    sharpen the image
#  -shave geometry      shave pixels from the image edges
#  -shear geometry      slide one edge of the image along the X or Y axis
#  -size geometry       width and height of image
#  -solarize threshold  negate all pixels above the threshold level
#  -spread amount       displace image pixels by a random amount
#  -stroke color        color to use when stoking a graphic primitive
#  -strokewidth value   width of stroke
#  -swirl degrees       swirl image pixels about the center
#  -texture filename    name of texture to tile onto the image background
#  -threshold value     threshold the image
#  -tile filename       tile image when filling a graphic primitive
#  -transparent color   make this color transparent within the image
#  -treedepth value     depth of the color tree
#  -type type           image type
#  -units type          PixelsPerInch, PixelsPerCentimeter, or Undefined
#  -unsharp geometry    sharpen the image

# Author: Andy Adler

function imwrite(fname, p2, p3 ,p4 ,p5 );

try save_empty_list_elements_ok= empty_list_elements_ok;
catch save_empty_list_elements_ok= 0;
end
try save_warn_empty_list_elements= warn_empty_list_elements;
catch save_warn_empty_list_elements= 0;
end
unwind_protect
empty_list_elements_ok= 1;
warn_empty_list_elements= 0;

if  ( nargin <= 1 )     || ...
   ( ! isstr (fname))  || ...
   ( nargin == 2 && isstr(p2) )
   usage([ ...
   "imwrite( fname, img )\n", ...
   "imwrite( fname, img, map )\n", ...
   "imwrite( fname, r,g,b );\n", ...
   "imwrite( fname, img, options )\n", ...
   "imwrite( fname, img, map, options )\n", ...
   "imwrite( fname, r,g,b, options );\n"]);
endif

# Put together the options string
# TODO: add some error checking to options
option_str="";
n_mat= nargin-1;

options= eval(sprintf("p%d",nargin));
# process options strings if given
if    isstr(options)
  n_mat--;
  for i= 1:size(options,1)
     option_str=[option_str," ", options(i,:) ];
  end
elseif is_list( options )
  n_mat--;
  for i= 1:length(options)
     option_str=[option_str," ", nth(options,i) ];
  end
end

[hig,wid] = size(p2);
if n_mat==1
  data= p2';
  outputtype="pgm";
  pnm_sig="P5";
elseif n_mat==2
  img= p2';
  data= [ 255*reshape(p3(img,1),1, hig*wid);
          255*reshape(p3(img,2),1, hig*wid);
          255*reshape(p3(img,3),1, hig*wid) ];
  outputtype="ppm";
  pnm_sig="P6";
elseif n_mat==3
  data= [ reshape(p2',1, hig*wid);
          reshape(p3',1, hig*wid);
          reshape(p4',1, hig*wid) ];
  outputtype="ppm";
  pnm_sig="P6";
else
  error("imwrite: too many data matrices specified");
end

#  pname= sprintf("convert %s %s:- '%s' 2>/dev/null",
#                 option_str, outputtype, fname);
#  fid= popen(pname ,'w');

  tnam= tmpnam();


     # create temporary file name
     tnam= tmpnam();

     if (isunix);
          printf("You are running the UN*X version of ImWrite\n");
        cmd= sprintf("convert %s '%s:%s' '%s' 2>/dev/null",
                option_str, outputtype, tnam, fname);

     else
        printf("You are running the WiNdOWz version of ImWrite\n");

        # convert input file path into windowz format
        fname=sprintf("cygpath -w %s", fname);
        fname=system(fname);

# change the '\' strokes to '/' in the path name to prevent string conflicts
        for i=1:length(fname)
                        if fname(i)=='\\';
                                fname(i)='/';
                        end
        end

# this routine because a newline character is added into fname (maybe bug in the "file_in_path" function <see line 123>. This has to be removed. if double(fname(length(fname))) >122 || double(fname(length(fname))) <65;
                fname=fname(1:length(fname)-1);
        end

        # create the command string
cmd= sprintf("convert %s ""%s:%s"" ""%s""",option_str,outputtype,tnam, fname);

# command string convert the input file name path back to UN*X form
          fname=sprintf("cygpath -u ""%s""", fname);

        # Again convert the '\' strokes to '/' to prevent conflicts
        for i=1:length(tnam)
                if tnam(i)=='\\';
                        tnam(i)='/';
                end
        end

        # do same for the temp file name created
        for i=1:length(tnam)
                        if tnam(i)=='\\';
                                tnam(i)='/';
                        end
        end

        # execute command string to change filename to UN*X format
        fname=system(fname);

# create command string to convert temporary file name path to unix format
        if tnam(2)==':';
                tnam(2)=tnam(1);
                tnam(1)='/';
                tnam=sprintf("/cygdrive%s",tnam);
        end

  end

  fid= fopen(tnam, "wb");

#  disp(pname); disp(fid);
  if fid<0;
     error(['could not create file: ',tnam]);
  end

  fprintf(fid,"%s\n%d %d\n255\n",pnm_sig,wid,hig);
  write_count= fwrite(fid,data(:));
  if write_count != prod(size(data))
     fclose(fid); unlink(tnam);
     error(['Unable to write image: ', fname ]);
  end

  fclose(fid);
  [jnk,retcode] = system(cmd);
  if retcode !=0
     error('could not call imagemagick convert');
  end
  unlink( tnam );

unwind_protect_cleanup
empty_list_elements_ok= save_empty_list_elements_ok;
warn_empty_list_elements= save_warn_empty_list_elements;
end_unwind_protect

#
# $Log: imwrite.m,v $
# Revision 1.6  2003/09/12 14:22:42  adb014
# Changes to allow use with latest CVS of octave (do_fortran_indexing, etc)
#
# Revision 1.5  2003/07/25 19:11:41  pkienzle
# Make sure all files names referenced in system calls are wrapped in quotes
# to protect against spaces in the path.
#
# Revision 1.4  2002/11/27 08:40:11  pkienzle
# author/license updates
#
# Revision 1.3  2002/03/19 18:14:13  aadler
# unfortunately using popen seems to create problems, mostly
# on win32, but also on linux, so we need to move to a tmpfile approach
#
# Revision 1.2  2002/03/17 05:26:14  aadler
# now accept filenames with spaces
#
# Revision 1.1  2002/03/11 01:56:47  aadler
# general image read/write functionality using imagemagick utilities
#
#
-------------------------------------------------------------------------------------------------------------------------------------------
Faisal ...

_________________________________________________________________
Sign-up for a FREE BT Broadband connection today! http://www.msn.co.uk/specials/btbroadband



-------------------------------------------------------------
Octave is freely available under the terms of the GNU GPL.

Octave's home on the web:  http://www.octave.org
How to fund new projects:  http://www.octave.org/funding.html
Subscription information:  http://www.octave.org/archive.html
-------------------------------------------------------------



reply via email to

[Prev in Thread] Current Thread [Next in Thread]