changeset 10333:0c42b6b7da24

imfinfo: support image files with multiple frames
author Søren Hauberg <soren@hauberg.org>
date Thu, 18 Feb 2010 01:36:04 -0500
parents 5f6298220ced
children db540cb0e959
files scripts/ChangeLog scripts/image/imfinfo.m src/ChangeLog src/DLD-FUNCTIONS/__magick_read__.cc src/oct-map.h
diffstat 5 files changed, 116 insertions(+), 46 deletions(-) [+]
line wrap: on
line diff
--- a/scripts/ChangeLog	Wed Feb 17 14:24:22 2010 -0500
+++ b/scripts/ChangeLog	Thu Feb 18 01:36:04 2010 -0500
@@ -1,3 +1,7 @@
+2010-02-18  John W. Eaton  <jwe@octave.org>
+
+	* image/imfinfo.m: Don't handle file time stamp here.
+
 2010-02-17  Jaroslav Hajek  <highegg@gmail.com>
 
 	* statistics/base/center.m: Convert integer inputs to doubles.
--- a/scripts/image/imfinfo.m	Wed Feb 17 14:24:22 2010 -0500
+++ b/scripts/image/imfinfo.m	Thu Feb 18 01:36:04 2010 -0500
@@ -119,15 +119,7 @@
 
     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__ (fn);
-    info.FileModDate = time_stamp;
 
   unwind_protect_cleanup
 
--- a/src/ChangeLog	Wed Feb 17 14:24:22 2010 -0500
+++ b/src/ChangeLog	Thu Feb 18 01:36:04 2010 -0500
@@ -1,3 +1,13 @@
+2010-02-18  Søren Hauberg  <hauberg@gmail.com>
+
+	* DLD-FUNCTIONS/__magick_read__.cc (__magick_finfo__):
+	Handle multiple frames in a single image file.
+
+2010-02-18  John W. Eaton  <jwe@octave.org>
+
+	* oct-map.h (Octave_map::Octave_map): Allow dimension to also be
+	specified in string_vector constructor.
+
 2010-02-17  John W. Eaton  <jwe@octave.org>
 
 	* Makefile.am (OCTAVE_LIBS, OCTINTERP_LINK_DEPS):
--- a/src/DLD-FUNCTIONS/__magick_read__.cc	Wed Feb 17 14:24:22 2010 -0500
+++ b/src/DLD-FUNCTIONS/__magick_read__.cc	Thu Feb 18 01:36:04 2010 -0500
@@ -28,6 +28,9 @@
 
 #include <cmath>
 
+#include "file-stat.h"
+#include "oct-time.h"
+
 #include "defun-dld.h"
 #include "error.h"
 #include "ov-struct.h"
@@ -900,7 +903,7 @@
 #define GET_PARAM(NAME, OUTNAME) \
   try \
     { \
-      st.assign (OUTNAME, magick_to_octave_value (im.NAME ())); \
+      info.contents (OUTNAME)(frame,0) = magick_to_octave_value (im.NAME ()); \
     } \
   catch (Magick::Warning& w) \
     { \
@@ -916,14 +919,14 @@
 @seealso{imfinfo, imread}\n\
 @end deftypefn")
 {
-  octave_value_list output;
+  octave_value retval;
 
 #ifdef HAVE_MAGICK
 
   if (args.length () < 1 || ! args (0).is_string ())
     {
       print_usage ();
-      return output;
+      return retval;
     }
 
   const std::string filename = args (0).string_value ();
@@ -931,37 +934,97 @@
   try
     {
       // Read the file.
-      Magick::Image im;
-      im.read (filename);
-      
-      // Read properties.
-      Octave_map st;
-      st.assign ("Filename", filename);
+      std::vector<Magick::Image> imvec;
+      Magick::readImages (&imvec, args(0).string_value ());
+      int nframes = imvec.size (); 
       
-      // 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;
+      // Create the right size for the output.
+
+      static const char *fields[] =
+        {
+          "Filename",
+          "FileModDate",
+          "FileSize",
+          "Height",
+          "Width",
+          "BitDepth",
+          "Format",
+          "LongFormat",
+          "XResolution",
+          "YResolution",
+          "TotalColors",
+          "TileName",
+          "AnimationDelay",
+          "AnimationIterations",
+          "ByteOrder",
+          "Gamma",
+          "Matte",
+          "ModulusDepth",
+          "Quality",
+          "QuantizeColors",
+          "ResolutionUnits",
+          "ColorType",
+          "View",
+          0
+        };
+
+      Octave_map info (string_vector (fields), dim_vector (nframes, 1));
+
+      file_stat fs (filename);
+
+      std::string filetime;
+
+      if (fs)
+        {
+          octave_localtime mtime = fs.mtime ();
+
+          filetime = mtime.strftime ("%e-%b-%Y %H:%M:%S");
+        }
+      else
+        {
+          std::string msg = fs.error ();
+
+          error ("imfinfo: error reading `%s': %s",
+                 filename.c_str (), msg.c_str ());
+
+          return retval;
+        }
+
+      // For each frame in the image (some images contain multiple
+      // layers, each to be treated like a separate image).
+      for (int frame = 0; frame < nframes; frame++)
+        {
+          Magick::Image im = imvec[frame];
+      
+          // Add file name and timestamp.
+          info.contents ("Filename")(frame,0) = filename;
+          info.contents ("FileModDate")(frame,0) = filetime;
+          
+          // 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")
+        }
+
+      retval = octave_value (info);
     }
   catch (Magick::Warning& w)
     {
@@ -974,7 +1037,7 @@
   catch (Magick::Exception& e)
     {
       error ("Magick++ exception: %s", e.what ());
-      return output;
+      return retval;
     }
 
 #else
@@ -983,7 +1046,7 @@
 
 #endif
 
-  return output;
+  return retval;
 }
 
 #undef GET_PARAM
--- a/src/oct-map.h	Wed Feb 17 14:24:22 2010 -0500
+++ b/src/oct-map.h	Thu Feb 18 01:36:04 2010 -0500
@@ -56,13 +56,14 @@
     key_list.push_back (k);
   }
 
-  Octave_map (const string_vector& sv)
-    : map (), key_list (), dimensions (0, 0)
+  Octave_map (const string_vector& sv,
+              const dim_vector& dv = dim_vector (0, 0))
+    : map (), key_list (), dimensions (dv)
   {
     for (octave_idx_type i = 0; i < sv.length (); i++)
       {
         std::string k = sv[i];
-        map[k] = Cell ();
+        map[k] = Cell (dv);
         key_list.push_back (k);
       }
   }