changeset 8144:01fac748b680

Add the 'imfinfo' function for reading image file information.
author sh@sh-laptop
date Wed, 24 Sep 2008 15:40:27 -0400
parents 3a4694d67dbb
children 7ef5b1b4e029
files doc/ChangeLog doc/interpreter/image.txi scripts/ChangeLog scripts/image/Makefile.in scripts/image/imfinfo.m src/ChangeLog src/DLD-FUNCTIONS/__magick_read__.cc
diffstat 7 files changed, 302 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/doc/ChangeLog	Wed Sep 24 14:42:04 2008 -0400
+++ b/doc/ChangeLog	Wed Sep 24 15:40:27 2008 -0400
@@ -1,3 +1,7 @@
+2008-09-24  Soren Hauberg  <hauberg@gmail.com>
+
+	* interpreter/image.txi: Document imfinfo.
+
 2008-09-23  Francesco Potorti`  <Potorti@isti.cnr.it>.
 
 	* interpreter/container.txi: Fix cross reference in struct docs.
--- a/doc/interpreter/image.txi	Wed Sep 24 14:42:04 2008 -0400
+++ b/doc/interpreter/image.txi	Wed Sep 24 15:40:27 2008 -0400
@@ -64,6 +64,13 @@
 
 @DOCSTRING(IMAGE_PATH)
 
+It is possible to get information about an image file on disk, without actually
+reading in into Octave. This is done using the @code{imfinfo} function which
+provides read access to many of the parameters stored in the header of the image
+file.
+
+@DOCSTRING(imfinfo)
+
 @node Displaying Images
 @section Displaying Images
 
--- a/scripts/ChangeLog	Wed Sep 24 14:42:04 2008 -0400
+++ b/scripts/ChangeLog	Wed Sep 24 15:40:27 2008 -0400
@@ -1,3 +1,8 @@
+2008-09-24  Soren Hauberg  <hauberg@gmail.com>
+
+	* image/imfinfo.m: New function.
+	* image/Makefile.in (SOURCES): Add it to the list.
+
 2008-09-24  Ben Abbott  <bpabbott@mac.com>
 
 	* strings/strcat.m: Improve Matlab compatibility for non-character
--- a/scripts/image/Makefile.in	Wed Sep 24 14:42:04 2008 -0400
+++ b/scripts/image/Makefile.in	Wed Sep 24 15:40:27 2008 -0400
@@ -35,9 +35,10 @@
 
 SOURCES = __img__.m __img_via_file__.m autumn.m bone.m brighten.m colormap.m \
   contrast.m cool.m copper.m flag.m gmap40.m gray.m gray2ind.m hot.m hsv.m \
-  hsv2rgb.m image.m image_viewer.m imagesc.m imread.m imshow.m imwrite.m \
-  ind2gray.m ind2rgb.m jet.m ntsc2rgb.m ocean.m pink.m prism.m rainbow.m \
-  rgb2hsv.m rgb2ind.m rgb2ntsc.m saveimage.m spring.m summer.m white.m winter.m
+  hsv2rgb.m image.m image_viewer.m imagesc.m imfinfo.m imread.m imshow.m \
+  imwrite.m ind2gray.m ind2rgb.m jet.m ntsc2rgb.m ocean.m pink.m prism.m \
+  rainbow.m rgb2hsv.m rgb2ind.m rgb2ntsc.m saveimage.m spring.m summer.m \
+  white.m winter.m
 
 IMAGES = default.img
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/scripts/image/imfinfo.m	Wed Sep 24 15:40:27 2008 -0400
@@ -0,0 +1,120 @@
+## Copyright (C) 2008 Soren Hauberg <hauberg@gmail.com>
+##
+## 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 3 of the License, 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, see
+## <http://www.gnu.org/licenses/>.
+
+## -*- texinfo -*-
+## @deftypefn {Function File} {@var{info} =} imfinfo (@var{filename})
+## @deftypefnx{Function File} {@var{info} =} imfinfo (@var{url})
+## Read image information from a file.
+##
+## @code{imfinfo} returns a structure containing information about the image
+## stored in the file @var{filename}. The output structure contains the
+## following fields.
+##
+## @table @samp
+## @item Filename
+## The full name of the image file.
+## @item FileSize
+## Number of bytes of the image on disk
+## @item FileModDate
+## Date of last modification to the file.
+## @item Height
+## Image height in pixels.
+## @item Width
+## Image Width in pixels.
+## @item BitDepth
+## Number of bits per channel per pixel.
+## @item Format
+## Image format (e.g. @code{"jpeg"}).
+## @item LongFormat
+## Long form image format description.
+## @item XResolution
+## X resolution of the image.
+## @item YResolution
+## Y resolution of the image.
+## @item TotalColors
+## Number of unique colors in the image.
+## @item TileName
+## Tile name.
+## @item AnimationDelay
+## Time in 1/100ths of a second (0 to 65535) which must expire before displaying
+## the next image in an animated sequence.
+## @item AnimationIterations
+## Number of iterations to loop an animation (e.g. Netscape loop extension) for.
+## @item ByteOrder
+## Endian option for formats that support it. Is either @code{"little-endian"},
+## @code{"big-endian"}, or @code{"undefined"}.
+## @item Gamma
+## Gamma level of the image. The same color image displayed on two different
+## workstations  may  look  different due to differences in the display monitor.
+## @item Matte
+## @code{true} if the image has transparency.
+## @item ModulusDepth
+## Image modulus depth (minimum number of bits required to support red/green/blue
+## components without loss of accuracy).
+## @item Quality
+## JPEG/MIFF/PNG compression level.
+## @item QuantizeColors
+## Preferred number of colors in the image.
+## @item ResolutionUnits
+## Units of image resolution. Is either @code{"pixels per inch"},
+## @code{"pixels per centimeter"}, or @code{"undefined"}.
+## @item ColorType
+## Image type. Is either @code{"grayscale"}, @code{"indexed"}, @code{"truecolor"},
+## or @code{"undefined"}.
+## @item View
+## FlashPix viewing parameters.
+## @end table
+##
+## @seealso{imread, imwrite}
+## @end deftypefn
+
+function info = imfinfo (filename)
+
+  if (nargin < 1)
+    print_usage ();
+  endif
+
+  if (!ischar (filename))
+    error ("imfinfo: filename must be a string")
+  endif
+
+  filename = tilde_expand (filename);
+
+  fn = file_in_path (IMAGE_PATH, filename);
+  if (isempty (fn))
+    ## Couldn't find file. See if it's an URL.
+    tmp = tmpnam ();
+
+    [fn, status, msg] = urlwrite (filename, tmp);
+
+    if (! status)
+      error ("imfinfo: cannot find %s", filename);
+    endif
+  endif
+
+  [statinfo, err, msg] = stat (fn);
+  if (err != 0)
+    error ("imfinfo: error reading '%s': %s", fn, msg);
+  endif
+
+  time_stamp = strftime ("%e-%b-%Y %H:%M:%S", localtime (statinfo.mtime));
+  
+  info = __magick_finfo__ (filename);
+  info.FileModDate = time_stamp;
+
+endfunction
--- a/src/ChangeLog	Wed Sep 24 14:42:04 2008 -0400
+++ b/src/ChangeLog	Wed Sep 24 15:40:27 2008 -0400
@@ -1,3 +1,10 @@
+2008-09-24  Soren Hauberg  <hauberg@gmail.com>
+
+	* DLD-FUNCTIONS/__magick_read__.cc (magick_to_octave_value): New
+	template function with specializations for various
+	GraphicsMagick++ types.
+	(F__magick_finfo__): New function.
+
 2008-09-24  John W. Eaton  <jwe@octave.org>
 
 	* ov-usr-fcn.cc (octave_user_function::do_multi_index_op):
--- a/src/DLD-FUNCTIONS/__magick_read__.cc	Wed Sep 24 14:42:04 2008 -0400
+++ b/src/DLD-FUNCTIONS/__magick_read__.cc	Wed Sep 24 15:40:27 2008 -0400
@@ -799,6 +799,161 @@
 return retval;
 }
 
+template<class T>
+static octave_value
+magick_to_octave_value (const T magick)
+{
+  return octave_value (magick);
+}
+
+static octave_value
+magick_to_octave_value (const Magick::EndianType magick)
+{
+  switch (magick)
+    {
+      case Magick::LSBEndian:
+        return octave_value ("little-endian");
+
+      case Magick::MSBEndian:
+        return octave_value ("big-endian");
+
+      default:
+        return octave_value ("undefined");
+    }
+}
+
+static octave_value
+magick_to_octave_value (const Magick::ResolutionType magick)
+{
+  switch (magick)
+    {
+      case Magick::PixelsPerInchResolution:
+        return octave_value ("pixels per inch");
+
+      case Magick::PixelsPerCentimeterResolution:
+        return octave_value ("pixels per centimeter");
+
+      default:
+        return octave_value ("undefined");
+    }
+}
+
+static octave_value
+magick_to_octave_value (const Magick::ImageType magick)
+{
+  switch (magick)
+    {
+      case Magick::BilevelType:
+      case Magick::GrayscaleType:
+      case Magick::GrayscaleMatteType:
+        return octave_value ("grayscale");
+
+      case Magick::PaletteType:
+      case Magick::PaletteMatteType:
+        return octave_value ("indexed");
+
+      case Magick::TrueColorType:
+      case Magick::TrueColorMatteType:
+      case Magick::ColorSeparationType:
+        return octave_value ("truecolor");
+
+      default:
+        return octave_value ("undefined");
+    }
+}
+
+// We put this in a try-block because GraphicsMagick will throw
+// exceptions if a parameter isn't present in the current image.
+#define GET_PARAM(NAME, OUTNAME) \
+  try \
+    { \
+      st.assign (OUTNAME, magick_to_octave_value (im.NAME ())); \
+    } \
+  catch (Magick::Warning& w) \
+    { \
+    }
+
+DEFUN_DLD (__magick_finfo__, args, ,
+  "-*- texinfo -*-\n\
+@deftypefn {Loadable File} {} __magick_finfo__(@var{fname})\n\
+Read image information with GraphicsMagick++. In general you should\n\
+not be using this function.  Instead you should use @code{imfinfo}.\n\
+@seealso{imfinfo, imread}\n\
+@end deftypefn")
+{
+  octave_value_list output;
+
+#ifdef HAVE_MAGICK
+
+  if (args.length () < 1 || ! args (0).is_string ())
+    {
+      print_usage ();
+      return output;
+    }
+
+  const std::string filename = args (0).string_value ();
+
+  try
+    {
+      // Read the file.
+      Magick::Image im;
+      im.read (filename);
+      
+      // Read properties.
+      Octave_map st;
+      st.assign ("Filename", filename);
+      
+      // Annoying CamelCase naming is for Matlab compatibility.
+      GET_PARAM (fileSize, "FileSize")
+      GET_PARAM (rows, "Height")
+      GET_PARAM (columns, "Width")
+      GET_PARAM (depth, "BitDepth")
+      GET_PARAM (magick, "Format")
+      GET_PARAM (format, "LongFormat")
+      GET_PARAM (xResolution, "XResolution")
+      GET_PARAM (yResolution, "YResolution")
+      GET_PARAM (totalColors, "TotalColors")
+      GET_PARAM (tileName, "TileName")
+      GET_PARAM (animationDelay, "AnimationDelay")
+      GET_PARAM (animationIterations, "AnimationIterations")
+      GET_PARAM (endian, "ByteOrder")
+      GET_PARAM (gamma, "Gamma")
+      GET_PARAM (matte, "Matte")
+      GET_PARAM (modulusDepth, "ModulusDepth")
+      GET_PARAM (quality, "Quality")
+      GET_PARAM (quantizeColors, "QuantizeColors")
+      GET_PARAM (resolutionUnits, "ResolutionUnits")
+      GET_PARAM (type, "ColorType")
+      GET_PARAM (view, "View")
+        
+      output (0) = st;
+    }
+  catch (Magick::Warning& w)
+    {
+      warning ("Magick++ warning: %s", w.what ());
+    }
+  catch (Magick::ErrorCoder& e)
+    {
+      warning ("Magick++ coder error: %s", e.what ());
+    }
+  catch (Magick::Exception& e)
+    {
+      error ("Magick++ exception: %s", e.what ());
+      return output;
+    }
+
+#else
+
+  error ("imfinfo: not available in this version of Octave");
+
+#endif
+
+  return output;
+}
+
+#undef GET_PARAM
+      
+
 /*
 ;;; Local Variables: ***
 ;;; mode: C++ ***