changeset 17361:80bf005cdf8e

New function __magick_ping__ to speed reading of images. * __magick_read__.cc (__magick_ping__): New function that only pings one of the images in a file to obtain height, width and format information. This becomes an alternative to imfinfo for internal Octave functions. Because imfinfo requires reading of the whole file and all images, this has a large speed increase, specially for multipage images. * imformats.m: use __magick_ping__() to check image format. * private/__imread__.m: use __magick_ping__() to get rows and columns of an image which is used to set the reading defaults.
author Carnë Draug <carandraug@octave.org>
date Fri, 30 Aug 2013 07:19:13 +0100
parents ba79ba4e83ab
children 0e14b25c5f0f 4a348443de9b
files libinterp/dldfcn/__magick_read__.cc scripts/image/imformats.m scripts/image/private/__imread__.m
diffstat 3 files changed, 51 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/libinterp/dldfcn/__magick_read__.cc
+++ b/libinterp/dldfcn/__magick_read__.cc
@@ -1411,6 +1411,52 @@
 %!assert (1)
 */
 
+// Gets the minimum information from images such as its size and format. Much
+// faster than using imfinfo, which slows down a lot since. Note than without
+// this, we need to read the image once for imfinfo to set defaults (which is
+// done in Octave language), and then again for the actual reading.
+DEFUN_DLD (__magick_ping__, args, ,
+  "-*- texinfo -*-\n\
+@deftypefn {Loadable Function} {} __magick_ping__ (@var{fname}, @var{idx})\n\
+Ping image information with GraphicsMagick or ImageMagick.\n\
+\n\
+This is a private internal function not intended for direct use.\n\
+\n\
+@seealso{imfinfo}\n\
+@end deftypefn")
+{
+  octave_value retval;
+#ifndef HAVE_MAGICK
+  gripe_disabled_feature ("imfinfo", "Image IO");
+#else
+  maybe_initialize_magick ();
+
+  if (args.length () < 1 || ! args(0).is_string ())
+    {
+      print_usage ();
+      return retval;
+    }
+  const std::string filename = args(0).string_value ();
+  int idx;
+  if (args.length () > 1)
+    idx = args(1).int_value () -1;
+  else
+    idx = 0;
+
+  Magick::Image img;
+  img.subImage (idx);
+  img.subRange (1);
+  img.ping (filename);
+  static const char *fields[] = {"rows", "columns", "format", 0};
+  octave_scalar_map ping = octave_scalar_map (string_vector (fields));
+  ping.setfield ("rows",    octave_value (img.rows ()));
+  ping.setfield ("columns", octave_value (img.columns ()));
+  ping.setfield ("format",  octave_value (img.magick ()));
+  retval = octave_value (ping);
+#endif
+  return retval;
+}
+
 #ifdef HAVE_MAGICK
 static octave_value
 magick_to_octave_value (const Magick::CompressionType& magick)
--- a/scripts/image/imformats.m
+++ b/scripts/image/imformats.m
@@ -277,7 +277,7 @@
 function bool = isa_magick (coder, filename)
   bool = false;
   try
-    info = __imfinfo__ (filename);
+    info = __magick_ping__ (filename, 1);
     bool = strcmp (coder, info.Format);
   end_try_catch
 endfunction
--- a/scripts/image/private/__imread__.m
+++ b/scripts/image/private/__imread__.m
@@ -92,10 +92,10 @@
 
   try
     ## Use information from the first image to be read to set defaults.
-    info = imfinfo (fn)(options.index(1));
+    info = __magick_ping__ (fn, options.index(1));
 
     ## Set default for options.
-    options.region = {1:1:info.Height 1:1:info.Width};
+    options.region = {1:1:info.rows 1:1:info.columns};
 
     for idx = offset:2:(numel (varargin) - offset + 1)
       switch (tolower (varargin{idx}))
@@ -120,9 +120,9 @@
                                       floor (options.region{reg_idx}(2)): ...
                                       floor (options.region{reg_idx}(3));
           endfor
-          if (options.region{1}(end) > info.Height)
+          if (options.region{1}(end) > info.rows)
             error ("imread: end ROWS for PixelRegions option is larger than image height");
-          elseif (options.region{2}(end) > info.Width)
+          elseif (options.region{2}(end) > info.columns)
             error ("imread: end COLS for PixelRegions option is larger than image width");
           endif