imread

View: New views
7 Messages — Rating Filter:   Alert me  

imread

by thomas.l.scofield :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


I hope this is what is needed.  I'm sending two changesets (or whatever is produced by "export tip"), lamely giving them the extension .changeset.  (I'm not sure what the usual extension is.  I think I sometimes see .ksh files in the archives.)  There is more to do, I know.  I'm starting to learn the Magick++ API for the purpose of removing all system calls (assuming that is possible), so that imread() works without having either ImageMagick or GraphicsMagick installed on one's local machine.  That is why I see no point in changing the current system calls to "identify" and "convert" (ImageMagick routines) to "gm identify", etc.  So, as it stands, you'll need the GraphicsMagick libs to compile, and you'll need a working version of ImageMagick to keep imread() from reporting an error and actually return the image.

Thomas L. Scofield
--------------------------------------------------------
Associate Professor
Department of Mathematics and Statistics
Calvin College
--------------------------------------------------------






addImread.changeset (15K) Download Attachment
modImread1.changeset (29K) Download Attachment

imread

by John W. Eaton :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On 12-Jul-2008, Thomas L. Scofield wrote:

| I hope this is what is needed.  I'm sending two changesets (or  
| whatever is produced by "export tip"), lamely giving them the  
| extension .changeset.  (I'm not sure what the usual extension is.  I  
| think I sometimes see .ksh files in the archives.)

I don't care what you call the file, but it is slightly easier for me
if you send text/plain attachments instead of binary attachments.

I applied your patches and then made some additional changes.

I moved imread.m to scripts/image and also added it to the list of
files in scripts/image/Makefile.in.

Please take a look at the changeset below to see the additional
changes I made, including:

  check for graphics magick config script in Octave's configure script

  use graphics magick configure script to set

  note in octave_config_info

  add __magick_read__.cc to list of files in src/Makefile.in

  add rules in src/Makefile.in so proper flags are used to compile and
  link __magick_read__.cc

  eliminate "using namespace ..." directives

  include config.h, not octave/oct.h

  other style fixes

| There is more to  
| do, I know.  I'm starting to learn the Magick++ API for the purpose  
| of removing all system calls (assuming that is possible), so that  
| imread() works without having either ImageMagick or GraphicsMagick  
| installed on one's local machine.  That is why I see no point in  
| changing the current system calls to "identify" and  
| "convert" (ImageMagick routines) to "gm identify", etc.

I don't understand why any of that is present in imread.  Shouldn't it
just be a simple wrapper around __magick_read__?  And if that is all
it is, then I think we could just rename __magick_read__ to be imread,
and eliminate imread.m.

If you update your sources and run

  ./autogen.sh
  configure ...
  make ...

then __magick_read__ should be built now.  When I use it, it fails to
read jpg files correctly.  When I do

  x = __magick_read__ ("foo.jpg");
  imshow (x);

(for any jpg file) the displayed image appears washed out (too
bright).  If I change

  unsigned int
  scale_quantum_to_depth (const Magick::Quantum& quantum, unsigned int depth)
  {
    return (static_cast<unsigned int> (static_cast<double> (quantum)
                                       / MaxRGB * ((1 << depth) - 1)));
  }

to

  unsigned int
  scale_quantum_to_depth (const Magick::Quantum& quantum, unsigned int depth)
  {
    return (static_cast<unsigned int> (static_cast<double> (quantum)
                                       / 1024 * ((1 << depth) - 1)));
  }

my test image looks OK, but I don't think this is a proper fix.  What
is the purpose of this function?

Thanks,

jwe



# HG changeset patch
# User John W. Eaton <jwe@...>
# Date 1216065609 14400
# Node ID d74f996e005ddf71eb1f197ad281dd47945f0ded
# Parent  9316b59903c9b3b1e6e41dfd95f3284157ce4362
__magick_read__.cc: configuration and style fixes

diff --git a/ChangeLog b/ChangeLog
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2008-07-14  John W. Eaton  <jwe@...>
+
+ * Makeconf.in (MAGICK_CONFIG): Substitute here.
+ (MAGICK_INCFLAGS, MAGICK_LIBS): Define using GraphicsMagick++
+ config script.
+ (do-subst-config-vals): Include MAGICK_LIBS and MAGICK_INCFLAGS in
+ list of substitutions.
+ * configure.in: Check for GraphicsMagick++ config script.
+
 2008-07-10  John W. Eaton  <jwe@...>
 
  * octMakefile.in (DIRS_TO_MAKE): Delete $(localfcnfilepath) and
diff --git a/Makeconf.in b/Makeconf.in
--- a/Makeconf.in
+++ b/Makeconf.in
@@ -145,6 +145,10 @@
     -I$(top_srcdir)/libcruft/misc
 endif
 INCFLAGS = $(TMP_IF_1) $(TMP_IF_2)
+
+MAGICK_CONFIG = @MAGICK_CONFIG@
+MAGICK_INCFLAGS = $(shell $(MAGICK_CONFIG) --cppflags)
+MAGICK_LIBS = $(shell $(MAGICK_CONFIG) --ldflags --libs)
 
 LIBFLAGS = -L$(TOPDIR)
 
@@ -504,6 +508,8 @@
   -e "s|%OCTAVE_CONF_LIBREADLINE%|\"${LIBREADLINE}\"|" \
   -e "s|%OCTAVE_CONF_LIBS%|\"${LIBS}\"|" \
   -e "s|%OCTAVE_CONF_LN_S%|\"${LN_S}\"|" \
+  -e "s|%OCTAVE_CONF_MAGICK_INCFLAGS%|\"${MAGICK_INCFLAGS}\"|" \
+  -e "s|%OCTAVE_CONF_MAGICK_LIBS%|\"${MAGICK_LIBS}\"|" \
   -e 's|%OCTAVE_CONF_MKOCTFILE_DL_LDFLAGS%|\"@MKOCTFILE_DL_LDFLAGS@\"|' \
   -e "s|%OCTAVE_CONF_OCTINCLUDEDIR%|\"${octincludedir}\"|" \
   -e "s|%OCTAVE_CONF_OCTLIBDIR%|\"${octlibdir}\"|" \
diff --git a/configure.in b/configure.in
--- a/configure.in
+++ b/configure.in
@@ -635,6 +635,13 @@
   warn_curl="cURL library not found.  The urlread and urlwrite functions will be disabled."
 fi
 
+# GraphicsMagick++
+
+warn_magick=
+AC_CHECK_PROGS(MAGICK_CONFIG, [GraphicsMagick++-config GraphicsMagick-config])
+if test -z "$MAGICK_CONFIG"; then
+  warn_magick="GraphicsMagick++ config script not found.  Assuming GraphicsMagic++ library and header files are missing, so imread will not be fully functional"
+fi
 
 # ---------------------------------------------------------------------
 
@@ -2016,6 +2023,7 @@
   gnuplot:              $GNUPLOT
   OPENGL libraries:     $OPENGL_LIBS
   fltk backend libs:    $GRAPHICS_LIBS
+  Magick config:        $MAGICK_CONFIG
 
   Do internal array bounds checking:  $BOUNDS_CHECKING
   Build static libraries:             $STATIC_LIBS
@@ -2132,6 +2140,11 @@
   warn_msg_printed=true
 fi
 
+if test -n "$warn_magick"; then
+  AC_MSG_WARN($warn_magick)
+  warn_msg_printed=true
+fi
+
 if test -n "$warn_hdf5"; then
   AC_MSG_WARN($warn_hdf5)
   warn_msg_printed=true
diff --git a/scripts/ChangeLog b/scripts/ChangeLog
--- a/scripts/ChangeLog
+++ b/scripts/ChangeLog
@@ -1,3 +1,7 @@
+2008-07-14  John W. Eaton  <jwe@...>
+
+ * image/Makefile.in (SOURCES): Add imread.m to the list.
+
 2008-07-14  Thomas L. Scofield  <scofield@...>
 
  * image/imread.m: New file from Octave Forge.
diff --git a/scripts/image/Makefile.in b/scripts/image/Makefile.in
--- a/scripts/image/Makefile.in
+++ b/scripts/image/Makefile.in
@@ -35,9 +35,9 @@
 
 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 imshow.m ind2gray.m ind2rgb.m \
-  jet.m loadimage.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 imread.m imshow.m ind2gray.m \
+  ind2rgb.m jet.m loadimage.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
 
diff --git a/src/ChangeLog b/src/ChangeLog
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,18 @@
+2008-07-14  John W. Eaton  <jwe@...>
+
+ * DLD-FUNCTIONS/__magick_read__.cc: Delete "using namespace std"
+ and "using namespace Magick" directives.  Style fixes.
+
+ * oct-conf.h.in (OCTAVE_CONF_MAGICK_INCFLAGS,
+ OCTAVE_CONF_MAGICK_LIBS): Substitute here.
+ * toplev.cc (octave_config_info): Include MAGICK_INCFLAGS and
+ MAGICK_LIBS in the struct.
+ * Makefile.in (DLD_XSRC): Add __magick_read__.cc to the list.
+ (OCTAVE_LIBS): Add $(MAGICK_LIBS) to the list for static linking case.
+ (__magick_read__.d, __magick_read__.o, pic/__magick_read__.o):
+ Append MAGICK_INCFLAGS to CPPFLAGS.
+ (__magick_read__.oct): Append MAGICK_LIBS to LDFLAGS.
+
 2008-07-14  Thomas L. Scofield  <scofield@...>
 
  * DLD-FUNCTIONS/__magick_read__.cc: New file from Octave Forge.
diff --git a/src/DLD-FUNCTIONS/__magick_read__.cc b/src/DLD-FUNCTIONS/__magick_read__.cc
--- a/src/DLD-FUNCTIONS/__magick_read__.cc
+++ b/src/DLD-FUNCTIONS/__magick_read__.cc
@@ -21,40 +21,45 @@
 
 */
 
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
 
-#include <octave/oct.h>
+#include "defun-dld.h"
+#include "error.h"
+
 #include <GraphicsMagick/Magick++.h>
-#include <iostream>
-using namespace std;
-using namespace Magick;
 
 unsigned int
-scaleQuantumToDepth (const Quantum &_quantum, unsigned int depth)
+scale_quantum_to_depth (const Magick::Quantum& quantum, unsigned int depth)
 {
-  return (static_cast<unsigned int> (static_cast<double>(_quantum) /
-                                     MaxRGB * ((1 << depth) - 1)));
+  return (static_cast<unsigned int> (static_cast<double> (quantum)
+     / MaxRGB * ((1 << depth) - 1)));
 }
 
 octave_value_list
-read_indexed_images( vector<Image> imvec, Array<int> frameidx, bool wantalpha )
+read_indexed_images (std::vector<Magick::Image>& imvec,
+     const Array<int>& frameidx, bool wantalpha)
 {
   octave_value_list output;
+
   int rows = imvec[0].baseRows ();
   int columns = imvec[0].baseColumns ();
   int nframes = frameidx.length ();
-  ImageType type = imvec[0].type ();
-    
+
+  Magick::ImageType type = imvec[0].type ();
+
   unsigned int mapsize = imvec[0].colorMapSize ();
   int i = mapsize;
   unsigned int depth = 0;
-  while (i >>= 1) depth++;
+  while (i >>= 1)
+    depth++;
   i = 0;
   depth--;
-  while (depth >>= 1) i++;
+  while (depth >>= 1)
+    i++;
   depth = 1 << i;
 
-  int x, y, frame;
-  const IndexPacket *pix;
   switch (depth)
     {
     case 1:
@@ -62,303 +67,339 @@
     case 4:
     case 8:
       {
-      uint8NDArray im = uint8NDArray(dim_vector ( rows, columns, nframes ));
-      for (frame=0; frame < nframes; frame++)
-        {
-        imvec[frameidx(frame)].getConstPixels ( 0, 0, columns, rows );
-        pix = imvec[frameidx(frame)].getConstIndexes ();
-        i = 0;      
-        for ( y=0; y < rows; y++ )
-          for ( x=0; x < columns; x++ )
-            im(y, x, frame) = static_cast<octave_uint8>(pix[i++]);
-        }
+ uint8NDArray im = uint8NDArray (dim_vector (rows, columns, nframes));
+
+ for (int frame = 0; frame < nframes; frame++)
+  {
+    imvec[frameidx(frame)].getConstPixels (0, 0, columns, rows);
+    const Magick::IndexPacket *pix
+      = imvec[frameidx(frame)].getConstIndexes ();
+    i = 0;
+    for (int y = 0; y < rows; y++)
+      for (int x = 0; x < columns; x++)
+ im(y,x,frame) = static_cast<octave_uint8> (pix[i++]);
+  }
       im.chop_trailing_singletons ();
       output(0) = octave_value (im);
       }
       break;
+
     case 16:
       {
-      uint16NDArray im = uint16NDArray(dim_vector( rows, columns, nframes ));
-      for (frame=0; frame < nframes; frame++)
-        {
-        imvec[frameidx(frame)].getConstPixels ( 0, 0, columns, rows );
-        pix = imvec[frameidx(frame)].getConstIndexes ();        
-        i = 0;      
-        for ( y=0; y < rows; y++ )
-          for ( x=0; x < columns; x++ )
-            im(y, x, frame) = static_cast<octave_uint16>(pix[i++]);
-        }
+ uint16NDArray im = uint16NDArray (dim_vector(rows, columns, nframes));
+ for (int frame = 0; frame < nframes; frame++)
+  {
+    imvec[frameidx(frame)].getConstPixels (0, 0, columns, rows);
+    const Magick::IndexPacket *pix
+      = imvec[frameidx(frame)].getConstIndexes ();
+    i = 0;
+    for (int y = 0; y < rows; y++)
+      for (int x = 0; x < columns; x++)
+ im(y,x,frame) = static_cast<octave_uint16> (pix[i++]);
+  }
         im.chop_trailing_singletons ();
         output(0) = octave_value (im);
       }
       break;
+
     default:
-      error ("Index depths bigger than 16-bit not supported");
+      error ("__magic_read__: index depths bigger than 16-bit not supported");
       return octave_value_list ();
     }
 
-  ColorRGB c;
-  Matrix map = Matrix ( mapsize, 3 );
+  Matrix map = Matrix (mapsize, 3);
   Matrix alpha;
+
   switch (type)
     {
-    case PaletteMatteType:
-/*    warning ("palettematte");
-      map = Matrix ( mapsize, 3 );
-      alpha = Matrix ( mapsize, 1 );
-      for ( i = 0; i < mapsize; i++ )
+    case Magick::PaletteMatteType:
+#if 0
+      warning ("palettematte");
+      Matrix map (mapsize, 3);
+      Matrix alpha (mapsize, 1);
+      for (i = 0; i < mapsize; i++)
         {
-        warning ( "%d", i );
-        c = imvec[0].colorMap (i);
-        map(i, 0) = c.red ();
-        map(i, 1) = c.green ();
-        map(i, 2) = c.blue ();
-        alpha(i, 1) = c.alpha ();                
+  warning ("%d", i);
+  Magick::ColorRGB c = imvec[0].colorMap (i);
+  map(i,0) = c.red ();
+  map(i,1) = c.green ();
+  map(i,2) = c.blue ();
+  alpha(i,1) = c.alpha ();
         }
-      break;        */
-    case PaletteType:
-      alpha = Matrix ( 0, 0 );
-      for ( i = 0; i < mapsize; i++ )
+      break;
+#endif
+
+    case Magick::PaletteType:
+      alpha = Matrix (0, 0);
+      for (i = 0; i < mapsize; i++)
         {
-        c = imvec[0].colorMap (i);
-        map(i, 0) = c.red ();
-        map(i, 1) = c.green ();
-        map(i, 2) = c.blue ();        
+  Magick::ColorRGB c = imvec[0].colorMap (i);
+  map(i,0) = c.red ();
+  map(i,1) = c.green ();
+  map(i,2) = c.blue ();
         }
-      break;        
+      break;
+
     default:
-      error ("Unsupported indexed image type");
+      error ("__magick_read__: unsupported indexed image type");
       return octave_value_list ();
     }
 
-  output(1) = octave_value (map);
   if (wantalpha)
-    output(2) = octave_value (alpha);
+    output(2) = alpha;
+
+  output(1) = map;
+
   return output;
 }
 
 template <class T>
-octave_value_list read_images( vector<Image> imvec, Array<int> frameidx,
-                               unsigned int depth )
+octave_value_list
+read_images (const std::vector<Magick::Image>& imvec,
+     const Array<int>& frameidx, unsigned int depth)
 {
-  int i;
-  T im;  
+  octave_value_list retval (3, Matrix ());
+
+  T im;
+
   int rows = imvec[0].baseRows ();
   int columns = imvec[0].baseColumns ();
   int nframes = frameidx.length ();
-  ImageType type = imvec[0].type ();
-  int x, y, frame;
-  const PixelPacket *pix;
+
   dim_vector idim = dim_vector ();
   idim.resize (4);
   idim(0) = rows;
   idim(1) = columns;
   idim(2) = 1;
   idim(3) = nframes;
+
   Array<int> idx (dim_vector (4));
+
+  Magick::ImageType type = imvec[0].type ();
+
   switch (type)
     {
-    case BilevelType:
-    //    break;
-    case GrayscaleType:
-      im = T(dim_vector ( rows, columns, nframes ));
-      for ( frame=0; frame < nframes; frame++ )
+    case Magick::BilevelType:
+    case Magick::GrayscaleType:
+      im = T(dim_vector (rows, columns, nframes));
+      for (int frame = 0; frame < nframes; frame++)
         {
-        pix = imvec[frameidx(frame)].getConstPixels ( 0, 0, columns, rows );
-        i = 0;      
-        for ( y=0; y < rows; y++ )
-          for ( x=0; x < columns; x++ )
-            im(y, x, frame) = scaleQuantumToDepth ( pix[i++].red, depth );
+  const Magick::PixelPacket *pix
+    = imvec[frameidx(frame)].getConstPixels (0, 0, columns, rows);
+
+  int i = 0;
+
+  for (int y = 0; y < rows; y++)
+    for (int x = 0; x < columns; x++)
+      im(y, x, frame) = scale_quantum_to_depth (pix[i++].red, depth);
         }
       break;
-    case GrayscaleMatteType:
+
+    case Magick::GrayscaleMatteType:
       idim(2) = 2;
-      im = T(idim);
-      for ( frame=0; frame < nframes; frame++ )
+      im = T (idim);
+      for (int frame = 0; frame < nframes; frame++)
         {
-        idx(3) = frame;
-        i = 0;
-        pix = imvec[frameidx(frame)].getConstPixels ( 0, 0, columns, rows );
-        for ( y=0; y < rows; y++ )
-          {
-          idx(0) = y;
-          for ( x=0; x < columns; x++ )
-            {
-            idx(1) = x;
-            idx(2) = 0;
-            im(idx) = scaleQuantumToDepth ( pix[i].red, depth );
-            idx(2) = 1;
-            im(idx) = scaleQuantumToDepth ( pix[i].opacity, depth );
-            i++;
-            }
-          }
-        }    
+  const Magick::PixelPacket *pix
+    = imvec[frameidx(frame)].getConstPixels (0, 0, columns, rows);
+
+  int i = 0;
+  idx(3) = frame;
+
+  for (int y = 0; y < rows; y++)
+    {
+      idx(0) = y;
+      for (int x = 0; x < columns; x++)
+ {
+  idx(1) = x;
+  idx(2) = 0;
+  im(idx) = scale_quantum_to_depth (pix[i].red, depth);
+  idx(2) = 1;
+  im(idx) = scale_quantum_to_depth (pix[i].opacity, depth);
+  i++;
+ }
+    }
+        }
       break;
-    case PaletteType:
-    case TrueColorType:
+
+    case Magick::PaletteType:
+    case Magick::TrueColorType:
       idim(2) = 3;
-      im = T(idim);      
-      for ( frame=0; frame < nframes; frame++ )
+      im = T (idim);
+      for (int frame=0; frame < nframes; frame++)
         {
-        idx(3) = frame;
-        i = 0;
-        pix = imvec[frameidx(frame)].getConstPixels ( 0, 0, columns, rows );
-        for ( y=0; y < rows; y++ )
-          {
-          idx(0) = y;
-          for ( x=0; x < columns; x++ )
-            {
-            idx(1) = x;
-            idx(2) = 0;
-            im(idx) = scaleQuantumToDepth ( pix[i].red, depth );
-            idx(2) = 1;
-            im(idx) = scaleQuantumToDepth ( pix[i].green, depth );
-            idx(2) = 2;
-            im(idx) = scaleQuantumToDepth ( pix[i].blue, depth );
-            i++;
-            }
-          }
-        }      
+  const Magick::PixelPacket *pix
+    = imvec[frameidx(frame)].getConstPixels (0, 0, columns, rows);
+
+  int i = 0;
+  idx(3) = frame;
+
+  for (int y = 0; y < rows; y++)
+    {
+      idx(0) = y;
+      for (int x = 0; x < columns; x++)
+ {
+  idx(1) = x;
+  idx(2) = 0;
+  im(idx) = scale_quantum_to_depth (pix[i].red, depth);
+  idx(2) = 1;
+  im(idx) = scale_quantum_to_depth (pix[i].green, depth);
+  idx(2) = 2;
+  im(idx) = scale_quantum_to_depth (pix[i].blue, depth);
+  i++;
+ }
+    }
+        }
       break;
-    case PaletteMatteType:
-    case TrueColorMatteType:
-    case ColorSeparationType:
+
+    case Magick::PaletteMatteType:
+    case Magick::TrueColorMatteType:
+    case Magick::ColorSeparationType:
       idim(2) = 4;
-      im = T(idim);            
-      for ( frame=0; frame < nframes; frame++ )
+      im = T (idim);
+      for (int frame=0; frame < nframes; frame++)
         {
-        idx(3) = frame;
-        i = 0;
-        pix = imvec[frameidx(frame)].getConstPixels ( 0, 0, columns, rows );
-        for ( y=0; y < rows; y++ )
-          {
-          idx(0) = y;
-          for ( x=0; x < columns; x++ )
-            {
-            idx(1) = x;
-            idx(2) = 0;
-            im(idx) = scaleQuantumToDepth ( pix[i].red, depth );
-            idx(2) = 1;
-            im(idx) = scaleQuantumToDepth ( pix[i].green, depth );
-            idx(2) = 2;
-            im(idx) = scaleQuantumToDepth ( pix[i].blue, depth );
-            idx(2) = 3;
-            im(idx) = scaleQuantumToDepth ( pix[i].opacity, depth );
-            i++;
-            }
-          }
-        }      
+  const Magick::PixelPacket *pix
+    = imvec[frameidx(frame)].getConstPixels (0, 0, columns, rows);
+
+  int i = 0;
+  idx(3) = frame;
+
+  for (int y = 0; y < rows; y++)
+    {
+      idx(0) = y;
+      for (int x = 0; x < columns; x++)
+ {
+  idx(1) = x;
+  idx(2) = 0;
+  im(idx) = scale_quantum_to_depth (pix[i].red, depth);
+  idx(2) = 1;
+  im(idx) = scale_quantum_to_depth (pix[i].green, depth);
+  idx(2) = 2;
+  im(idx) = scale_quantum_to_depth (pix[i].blue, depth);
+  idx(2) = 3;
+  im(idx) = scale_quantum_to_depth (pix[i].opacity, depth);
+  i++;
+ }
+    }
+        }
       break;
+
     default:
-      error ("Undefined Imagemagick image type");
-      return octave_value_list ();
+      error ("__magick_read__: undefined ImageMagick image type");
+      return retval;
     }
 
   im.chop_trailing_singletons ();
-  return octave_value_list (octave_value (im));
+
+  retval(0) = im;
+
+  return retval;
 }
 
-// instantiate templates
-template octave_value_list
-read_images<boolNDArray> ( vector<Image>, Array<int>, unsigned int depth );
-template octave_value_list
-read_images<uint8NDArray> ( vector<Image>, Array<int>, unsigned int depth );
-template octave_value_list
-read_images<uint16NDArray> ( vector<Image>, Array<int>, unsigned int depth );
-
-DEFUN_DLD ( __magick_read__, args, nargout, "\
--*- texinfo -*-\n\
-@deftypefn {Function File} {@var{m} =} __imagemagick_read__(@var{fname}, @var{index})\n\
-@deftypefnx{Function File} {[@var{m}, @var{colormap}] =} __imagemagick_read__(@var{fname}, @var{index})\n\
-@deftypefnx{Function File} {[@var{m}, @var{colormap}, @var{alpha}] =} __imagemagick_read__(@var{fname}, @var{index})\n\
+DEFUN_DLD (__magick_read__, args, nargout,
+  "-*- texinfo -*-\n\
+@deftypefn {Function File} {@var{m} =} __magick_read__(@var{fname}, @var{index})\n\
+@deftypefnx{Function File} {[@var{m}, @var{colormap}] =} __magick_read__(@var{fname}, @var{index})\n\
+@deftypefnx{Function File} {[@var{m}, @var{colormap}, @var{alpha}] =} __magick_read__(@var{fname}, @var{index})\n\
 Read images with ImageMagick++. In general you should not be using this function.\n\
 Instead you should use @code{imread}.\n\
 @seealso{imread}\n\
-@end deftypefn\n\
-" )
+@end deftypefn")
 {
   octave_value_list output;
-  int i;    
-  if( args.length() > 2 || args.length() < 1 || !args(0).is_string() \
-            || nargout > 3 )
+
+  if (args.length() > 2 || args.length() < 1 || ! args(0).is_string ()
+      || nargout > 3)
     {
       print_usage ();
-      return octave_value_list ();
+      return output;
     }
+
   Array<int> frameidx;
-  if ( args.length() == 2 && args(1).is_real_type() )
+
+  if (args.length() == 2 && args(1).is_real_type())
     frameidx = args(1).int_vector_value();
   else
     {
-    frameidx = Array<int> (1);
-    frameidx(0) = 1;
+      frameidx = Array<int> (1);
+      frameidx(0) = 1;
     }
 
-  vector<Image> imvec;
+  std::vector<Magick::Image> imvec;
+
   try
     {
-    // Read a file into vector of image objects
-    readImages(&imvec, args(0).string_value ());
+      // Read a file into vector of image objects
+      Magick::readImages (&imvec, args(0).string_value ());
     }
-  catch (Warning &warning_)
-    { warning ( "Magick++ warning: %s", warning_.what () ); }
-  catch (ErrorCoder &error_)
-    { warning ( "Magick++ coder error: %s", error_.what () ); }
-  catch (Exception &error_)
+  catch (Magick::Warning& w)
     {
-    error ( "Magick++ exception: %s", error_.what () );
-    imvec.clear ();
-    return octave_value_list ();
+      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;
     }
 
-  int nframes = imvec.size ();
-  for ( i = 0; i < frameidx.length(); i++ )
+  for (int i = 0; i < frameidx.length(); i++)
     {
-    frameidx(i) = frameidx(i) - 1;
-    if ( frameidx(i) >= nframes || frameidx(i) < 0 )
-      {
-      error ("Invalid index vector");
-      imvec.clear ();
-      return output;
-      }
+      frameidx(i) = frameidx(i) - 1;
+
+      int nframes = imvec.size ();
+
+      if (frameidx(i) >= nframes || frameidx(i) < 0)
+ {
+  error ("__magick_read__: invalid index vector");
+  return output;
+ }
     }
-    
-  ClassType klass = imvec[0].classType ();
-  if ( klass == PseudoClass && nargout > 1 )
-    output = read_indexed_images( imvec, frameidx, (nargout == 3) );
+
+  Magick::ClassType klass = imvec[0].classType ();
+
+  if (klass == Magick::PseudoClass && nargout > 1)
+    output = read_indexed_images (imvec, frameidx, (nargout == 3));
   else
     {
-    unsigned int depth = imvec[0].modulusDepth ();
-    i = 0;
-    while (depth >>= 1) i++;
-    depth = 1 << i;
-    
-    switch (depth)
-      {
-      case 1:
-        output = read_images<boolNDArray> ( imvec, frameidx, depth );
-        break;
-      case 2:
-      case 4:
-      case 8:
-        output = read_images<uint8NDArray> ( imvec, frameidx, depth) ;
-        break;
-      case 16:
-        output = read_images<uint16NDArray> ( imvec, frameidx, depth );
-        break;
-      case 32:
-      case 64:
+      unsigned int depth = imvec[0].modulusDepth ();
+      int i = 0;
+      while (depth >>= 1)
+ i++;
+      depth = 1 << i;
+
+      switch (depth)
+ {
+ case 1:
+  output = read_images<boolNDArray> (imvec, frameidx, depth);
+  break;
+
+ case 2:
+ case 4:
+ case 8:
+  output = read_images<uint8NDArray> (imvec, frameidx, depth) ;
+  break;
+
+ case 16:
+  output = read_images<uint16NDArray> (imvec, frameidx, depth);
+  break;
+
+ case 32:
+ case 64:
         default:
-        error ("Image depths bigger than 16-bit not supported");
-      }
-    if (nargout > 1)
-      {
-      output(1) = Matrix ( 0, 0 );
-      if (nargout > 2)
-        output(2) = Matrix ( 0, 0 );
-      }
+  error ("__magick_read__: image depths bigger than 16-bit not supported");
+ }
     }
-  imvec.clear ();
 
   return output;
 }
+
+/*
+;;; Local Variables: ***
+;;; mode: C++ ***
+;;; End: ***
+*/
diff --git a/src/Makefile.in b/src/Makefile.in
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -77,7 +77,7 @@
  spparms.cc sqrtm.cc svd.cc syl.cc symrcm.cc symbfact.cc \
  time.cc tsearch.cc typecast.cc \
  urlwrite.cc __contourc__.cc __delaunayn__.cc __dsearchn__.cc \
- __glpk__.cc __lin_interpn__.cc __pchip_deriv__.cc \
+ __glpk__.cc __lin_interpn__.cc __magick_read__.cc __pchip_deriv__.cc \
  __qp__.cc __voronoi__.cc __convn__.cc
 
 DLD_SRC := $(addprefix DLD-FUNCTIONS/, $(DLD_XSRC))
@@ -273,7 +273,7 @@
     $(LIBPLPLOT) $(LIBGLOB)
 else
   OCTAVE_LIBS = $(LIBOCTINTERP) $(LIBOCTAVE) $(QHULL_LIBS) \
-    $(GLPK_LIBS) $(REGEX_LIBS) $(SPECIAL_MATH_LIB) $(LIBCRUFT) \
+    $(GLPK_LIBS) $(MAGICK_LIBS) $(REGEX_LIBS) $(SPECIAL_MATH_LIB) $(LIBCRUFT) \
     $(LIBPLPLOT) $(LIBGLOB)
 endif
 
@@ -625,6 +625,10 @@
   || (rm -f $@-t; exit 1)
  @mv $@-t $@
 
+__magick_read__.d: CPPFLAGS += $(MAGICK_INCFLAGS)
+__magick_read__.o pic/__magick_read__.o: CPPFLAGS += $(MAGICK_INCFLAGS)
+__magick_read__.oct: DL_LDFLAGS += $(MAGICK_LIBS)
+
 # How to make a .oct file from a .o file:
 
 ifeq ($(ENABLE_DYNAMIC_LINKING), true)
diff --git a/src/oct-conf.h.in b/src/oct-conf.h.in
--- a/src/oct-conf.h.in
+++ b/src/oct-conf.h.in
@@ -229,6 +229,14 @@
 #define OCTAVE_CONF_LN_S %OCTAVE_CONF_LN_S%
 #endif
 
+#ifndef OCTAVE_CONF_MAGICK_INCFLAGS
+#define OCTAVE_CONF_MAGICK_INCFLAGS %OCTAVE_CONF_MAGICK_INCFLAGS%
+#endif
+
+#ifndef OCTAVE_CONF_MAGICK_LIBS
+#define OCTAVE_CONF_MAGICK_LIBS %OCTAVE_CONF_MAGICK_LIBS%
+#endif
+
 #ifndef OCTAVE_CONF_MKOCTFILE_DL_LDFLAGS
 #define OCTAVE_CONF_MKOCTFILE_DL_LDFLAGS %OCTAVE_CONF_MKOCTFILE_DL_LDFLAGS%
 #endif
diff --git a/src/toplev.cc b/src/toplev.cc
--- a/src/toplev.cc
+++ b/src/toplev.cc
@@ -1149,6 +1149,8 @@
       { false, "LIBREADLINE", OCTAVE_CONF_LIBREADLINE },
       { false, "LIBS", OCTAVE_CONF_LIBS },
       { false, "LN_S", OCTAVE_CONF_LN_S },
+      { false, "MAGICK_INCFLAGS", OCTAVE_CONF_MAGICK_INCFLAGS },
+      { false, "MAGICK_LIBS", OCTAVE_CONF_MAGICK_LIBS },
       { false, "MKOCTFILE_DL_LDFLAGS", OCTAVE_CONF_MKOCTFILE_DL_LDFLAGS },
       { false, "RANLIB", OCTAVE_CONF_RANLIB },
       { false, "RDYNAMIC_FLAG", OCTAVE_CONF_RDYNAMIC_FLAG },

imread

by John W. Eaton :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On 14-Jul-2008, John W. Eaton wrote:

| If you update your sources and run
|
|   ./autogen.sh
|   configure ...
|   make ...
|
| then __magick_read__ should be built now.  When I use it, it fails to
| read jpg files correctly.  When I do
|
|   x = __magick_read__ ("foo.jpg");
|   imshow (x);
|
| (for any jpg file) the displayed image appears washed out (too
| bright).

It seems the problem is not with imread, but with imshow.

jwe

Re: imread

by thomas.l.scofield :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


On Jul 14, 2008, at 4:14 PM, John W. Eaton wrote:

On 12-Jul-2008, Thomas L. Scofield wrote:

| I hope this is what is needed.  I'm sending two changesets (or  
| whatever is produced by "export tip"), lamely giving them the  
| extension .changeset.  (I'm not sure what the usual extension is.  I  
| think I sometimes see .ksh files in the archives.)

I don't care what you call the file, but it is slightly easier for me
if you send text/plain attachments instead of binary attachments.


I'm not exactly sure what to do differently.  The files on my machine are text files.  I included them as attachments (email program is the Mac Mail program).  At what stage would they have become binary files?

I applied your patches and then made some additional changes.

I moved imread.m to scripts/image and also added it to the list of
files in scripts/image/Makefile.in.

Please take a look at the changeset below to see the additional
changes I made, including:

  check for graphics magick config script in Octave's configure script

  use graphics magick configure script to set 

  note in octave_config_info

  add __magick_read__.cc to list of files in src/Makefile.in

  add rules in src/Makefile.in so proper flags are used to compile and
  link __magick_read__.cc

  eliminate "using namespace ..." directives

  include config.h, not octave/oct.h

What's the reason behind these last two?  Am I correct, in the case of the last one, that inclusion of oct.h pulls in config.h as well?  If so, is the need for only a smaller set of declarations something that, as the principle architect of the package, you (and perhaps only a handful of others) would be able to determine efficiently, or is there some process a novice like me could use?  The only documentation I've seen (Appendix A of the manual) suggests that you generally just go ahead and include oct.h when you write dynamically linked functions.

  other style fixes

| There is more to  
| do, I know.  I'm starting to learn the Magick++ API for the purpose  
| of removing all system calls (assuming that is possible), so that  
| imread() works without having either ImageMagick or GraphicsMagick  
| installed on one's local machine.  That is why I see no point in  
| changing the current system calls to "identify" and  
| "convert" (ImageMagick routines) to "gm identify", etc.

I don't understand why any of that is present in imread.  Shouldn't it
just be a simple wrapper around __magick_read__?  And if that is all
it is, then I think we could just rename __magick_read__ to be imread,
and eliminate imread.m.


I think the same thing, but I wasn't the code's original author.  To date, I've changed only about a line or so of the code.  I would like to write a modified __magick_read__.cc routine for all of the handling and information-gathering of the image files themselves.  I'm sure the more mundane things can be wrapped there as well, but given where I am in the knowledge of C++ these days, I'd rather not have to deal with the appropriateness of arguments to imread there.  There's already a bit of argument checking in the existing imread routine, and my recollection of C++ file handling in general is that it is harder to check if files exist, etc. than the commands provided in Octave (not to mention that the commands provided in Octave are, I presume, platform independent).

If you update your sources and run

  ./autogen.sh
  configure ...
  make ...

then __magick_read__ should be built now.  When I use it, it fails to
read jpg files correctly.  When I do

  x = __magick_read__ ("foo.jpg");
  imshow (x);

(for any jpg file) the displayed image appears washed out (too
bright).  If I change 

  unsigned int
  scale_quantum_to_depth (const Magick::Quantum& quantum, unsigned int depth)
  {
    return (static_cast<unsigned int> (static_cast<double> (quantum)
      / MaxRGB * ((1 << depth) - 1)));
  }

to

  unsigned int
  scale_quantum_to_depth (const Magick::Quantum& quantum, unsigned int depth)
  {
    return (static_cast<unsigned int> (static_cast<double> (quantum)
      / 1024 * ((1 << depth) - 1)));
  }

my test image looks OK, but I don't think this is a proper fix.  What
is the purpose of this function?


I'll dig into it to see if I can determine what its purpose is.  Is the issue you mention the same one discussed between Soren Hauberg and me soon after I submitted the files for review (a couple of weeks ago)?  I get washed-out pictures not only with jpegs (that type of file, in the one instance I've tried, has not been particularly egregious), but also with png files (some really bad examples).  But the problem only exists when I am doing things on my linux machine. Assuming nothing I've done has changed the behavior of imread drastically, I find the pictures appear like they ought when displayed using imread on my mac (there I am using the original imread from octave-forge).  To understand that comment fully, I guess you need to know that the problem does not arise on either machine when I display these images with either "display" (ImageMagick command) or "gm display" (GraphicsMagick).

---

Just got your message about it being imshow.  Can it be the source of the problem I describe here, too?

Thomas L. Scofield
--------------------------------------------------------
Associate Professor
Department of Mathematics and Statistics
Calvin College
--------------------------------------------------------


Re: imread

by John W. Eaton :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On 15-Jul-2008, Thomas L. Scofield wrote:

|
| On Jul 14, 2008, at 4:14 PM, John W. Eaton wrote:
|
| > On 12-Jul-2008, Thomas L. Scofield wrote:
| >
| > | I hope this is what is needed.  I'm sending two changesets (or
| > | whatever is produced by "export tip"), lamely giving them the
| > | extension .changeset.  (I'm not sure what the usual extension is.  I
| > | think I sometimes see .ksh files in the archives.)
| >
| > I don't care what you call the file, but it is slightly easier for me
| > if you send text/plain attachments instead of binary attachments.
| >
|
| I'm not exactly sure what to do differently.  The files on my machine  
| are text files.  I included them as attachments (email program is the  
| Mac Mail program).  At what stage would they have become binary files?

The attachments arrived with

  Content-Type: application/octet-stream; x-unix-mode=0644;
          name=addImread.changeset

instead of "Content-Type: text/plain".  I'd guess that happens because
your mailer doesn't know what kind of file corresponds to
".changeset", but that's just a guess.

| >   eliminate "using namespace ..." directives
| >
| >   include config.h, not octave/oct.h
|
| What's the reason behind these last two?

The convention in Octave is to use explicit namespace tags.

Using "#include <octave/oct.h>" won't work inside the Octave source
tree, and I think it is better to avoid including so many unneeded
declarations in every source file.  If you want to know what is
declared where, then use grep.

| I think the same thing, but I wasn't the code's original author.  To  
| date, I've changed only about a line or so of the code.  I would like  
| to write a modified __magick_read__.cc routine for all of the  
| handling and information-gathering of the image files themselves.  
| I'm sure the more mundane things can be wrapped there as well, but  
| given where I am in the knowledge of C++ these days, I'd rather not  
| have to deal with the appropriateness of arguments to imread there.  
| There's already a bit of argument checking in the existing imread  
| routine, and my recollection of C++ file handling in general is that  
| it is harder to check if files exist, etc. than the commands provided  
| in Octave (not to mention that the commands provided in Octave are, I  
| presume, platform independent).

Why would you need to check the existence of the file before trying to
read it?  Isn't it sufficient to just try to read the file, and if
that fails, report the failure?  In any case, if it is necessary to
check first, there are functions in Octave's C++ classes to do that.

jwe

Re: imread

by John W. Eaton :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On 15-Jul-2008, Thomas L. Scofield wrote:

| Just got your message about it being imshow.  Can it be the source of  
| the problem I describe here, too?

Yes, I think the problem is that uint8 images of size MxNx3 are not
displayed properly by imshow.  For example, try this:

  imshow (uint8 (repmat (kron ((0:255)', ones (1, 200)), [1, 1, 3])))

It should show a smooth black to white gradient from top to bottom,
but I see the attached image instead.

jwe



Screenshot-Figure 1.png (11K) Download Attachment

Re: imread

by Ben Abbott :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

 
On Tuesday, July 15, 2008, at 02:42PM, "Thomas L. Scofield" <scofield@...> wrote:

>
>On Jul 14, 2008, at 4:14 PM, John W. Eaton wrote:
>
>> On 12-Jul-2008, Thomas L. Scofield wrote:
>>
>> | I hope this is what is needed.  I'm sending two changesets (or
>> | whatever is produced by "export tip"), lamely giving them the
>> | extension .changeset.  (I'm not sure what the usual extension is.  I
>> | think I sometimes see .ksh files in the archives.)
>>
>> I don't care what you call the file, but it is slightly easier for me
>> if you send text/plain attachments instead of binary attachments.
>>
>
>I'm not exactly sure what to do differently.  The files on my machine  
>are text files.  I included them as attachments (email program is the  
>Mac Mail program).  At what stage would they have become binary files?
>
>

I'm also a Mac user, and encountered the same (at least very similar) problem in the past.

In my case, there were two causes.

(1) The files were RTF files (which was the default in my Mail Preferences). You can force TextEdit or Mail to convert to plain text, and can change the preferences for Mail so that it sends plain text.

(2) In addition, the EOL character was occasionally wrong. For than I used a mac2unix command line utility.

To avoid each of these problems, I eventually used unix style redirection to save the chageset directly to a file (from the Terminal) and then attached the saved changeset to the email. For example,

hg export tip > ~/Desktop/myChangeSet.diff

Ben

LightInTheBox - Buy quality products at wholesale price