octave-maintainers
[Top][All Lists]
Advanced

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

imwrite


From: Thomas L. Scofield
Subject: imwrite
Date: Sun, 17 Aug 2008 07:57:42 -0400


Here is a large changeset, mostly addressing functionality in imwrite.  I've made a change to imread (really __magick_read__ and/or the functions it calls) so that frame data is always returned in the 4th coordinate.  Imwrite now should handle frames and color maps.  I have a start at handling options---right now only  'Quality' setting is handled when writing a .jpg file.

Please give this a test run and supply feedback.  I will be out of touch for the next week.

Thanks.

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


# HG changeset patch
# User address@hidden
# Date 1218973934 14400
# Node ID 37450f1d144e285f08b2ae5df32aee413c67d5ab
# Parent  2fd4a5ef6b593a531f248d25341e7e25d4d979e3
Add functionality to imwrite

diff -r 2fd4a5ef6b59 -r 37450f1d144e scripts/image/imwrite.m
--- a/scripts/image/imwrite.m Tue Aug 12 16:26:53 2008 -0400
+++ b/scripts/image/imwrite.m Sun Aug 17 07:52:14 2008 -0400
@@ -30,7 +30,7 @@ function imwrite (varargin)
 function imwrite (varargin)
 
   persistent accepted_formats = { "bmp", "gif", "jpg", "jpeg", ...
-    "pbm", "pgm", "png", "ppm", "svg", "tiff" };
+    "ras", "pbm", "pgm", "png", "ppm", "svg", "tif", "tiff" };
 
   img = [];
   map = [];
@@ -42,7 +42,7 @@ function imwrite (varargin)
     if (isnumeric (varargin{2}))
       map = varargin{2};
       if (isempty (map))
- error ("imwrite: colormap must not be empty");
+        error ("imwrite: colormap must not be empty");
       endif
       offset = 3;
     endif
@@ -50,14 +50,19 @@ function imwrite (varargin)
       filename = varargin{offset};
       offset++;
       if (rem (nargin - offset, 2) == 0 && ischar (varargin{offset}))
- fmt = varargin{offset};
- offset++;
+        fmt = varargin{offset};
+        offset++;
       endif
     else
       print_usage ();
     endif
     if (offset < nargin)
-      warning ("imwrite: parameter-value options not implemented");
+      isParamList = 1;
+      for ii=offset:2:(nargin - 1)
+        options.(varargin{ii}) = varargin{ii + 1};
+      end
+    else
+      isParamList = 0;
     endif
   else
     print_usage ();
@@ -86,46 +91,51 @@ function imwrite (varargin)
 
   img_class = class (img);
   map_class = class (map);
+  nd = ndims (img);
 
   if (isempty (map))
     if (any (strcmp (img_class, {"logical", "uint8", "uint16", "double"})))
-      nd = ndims (img);
       if ((nd == 2 || nd == 3) && strcmp (img_class, "double"))
- img = uint8 (img * 255);
+        img = uint8 (img * 255);
       endif
-      if (nd == 3 && size (img, 3) != 3)
- error ("imwrite: invalid dimensions for truecolor image");
-      endif
-      if (nd == 4 && size (img, 3) != 1)
- error ("imwrite: invalid size for multiframe image");
+      if (nd == 3 && size (img, 3) < 3)   # modify to accept color images w/ alpha ch.
+        error ("imwrite: invalid dimensions for truecolor image");
       endif
       if (nd > 5)
- error ("imwrite: invalid %d-dimensional image data", nd);
+        error ("imwrite: invalid %d-dimensional image data", nd);
       endif
     else
       error ("imwrite: %s: invalid class for truecolor image", img_class);
     endif
-    __magick_write__ (filename, fmt, img);
+    if (isParamList)
+      __magick_write__ (filename, fmt, img, options);
+    else
+      __magick_write__ (filename, fmt, img);
+    endif
   else
     if (any (strcmp (img_class, {"uint8", "uint16", "double"})))
       if (strcmp (img_class, "double"))
- img = uint8 (img - 1);
+        img = uint8 (img - 1);
       endif
-      if (ndims (img) != 2)
- error ("imwrite: invalid size for indexed image");
+      if (nd != 2 && nd != 4)
+        error ("imwrite: invalid size for indexed image");
       endif
     else
       error ("imwrite: %s: invalid class for indexed image data", img_class);
     endif
     if (isa (map, "double"))
       if (ndims (map) != 2 || size (map, 2) != 3)
- error ("imwrite: invalid size for colormap");
+        error ("imwrite: invalid size for colormap");
       endif
     else
       error ("imwrite: %s invalid class for indexed image colormap",
-     class (map));
+             class (map));
     endif
-    __magick_write__ (filename, fmt, img, map);
+    if (isParamList)
+      __magick_write__ (filename, fmt, img, map, options);
+    else
+      __magick_write__ (filename, fmt, img, map);
+    endif
   endif
 
 endfunction
diff -r 2fd4a5ef6b59 -r 37450f1d144e src/DLD-FUNCTIONS/__magick_read__.cc
--- a/src/DLD-FUNCTIONS/__magick_read__.cc Tue Aug 12 16:26:53 2008 -0400
+++ b/src/DLD-FUNCTIONS/__magick_read__.cc Sun Aug 17 07:52:14 2008 -0400
@@ -25,7 +25,9 @@ along with Octave; see the file COPYING.
 #include <config.h>
 #endif
 
+#include <math.h>
 #include "defun-dld.h"
+#include <ov-struct.h>
 #include "error.h"
 
 #ifdef HAVE_MAGICK
@@ -36,18 +38,27 @@ scale_quantum_to_depth (const Magick::Qu
 scale_quantum_to_depth (const Magick::Quantum& quantum, unsigned int depth)
 {
   return (static_cast<unsigned int> (static_cast<double> (quantum)
-     / MaxRGB * ((1 << depth) - 1)));
+                                     / MaxRGB * ((1 << depth) - 1)));
 }
 
 octave_value_list
 read_indexed_images (std::vector<Magick::Image>& imvec,
-     const Array<int>& frameidx, bool wantalpha)
+                     const Array<int>& frameidx, bool wantalpha)
 {
   octave_value_list output;
 
   int rows = imvec[0].baseRows ();
   int columns = imvec[0].baseColumns ();
   int nframes = frameidx.length ();
+
+  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 ();
 
@@ -69,43 +80,59 @@ read_indexed_images (std::vector<Magick:
     case 4:
     case 8:
       {
- uint8NDArray im = uint8NDArray (dim_vector (rows, columns, nframes));
+        uint8NDArray im = uint8NDArray (idim);
 
- for (int frame = 0; frame < nframes; frame++)
-  {
-    imvec[frameidx(frame)].getConstPixels (0, 0, columns, rows);
+        idx(2) = 0;
+        for (int frame = 0; frame < nframes; frame++)
+          {
+            imvec[frameidx(frame)].getConstPixels (0, 0, columns, rows);
 
-    const Magick::IndexPacket *pix
-      = imvec[frameidx(frame)].getConstIndexes ();
+            const Magick::IndexPacket *pix
+              = imvec[frameidx(frame)].getConstIndexes ();
 
-    i = 0;
+            i = 0;
+            idx(3) = frame;
 
-    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);
+            for (int y = 0; y < rows; y++)
+              {
+                idx(0) = y;
+                for (int x = 0; x < columns; x++)
+                  {
+                    idx(1) = x;
+                    im(idx) = 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));
+        uint16NDArray im = uint16NDArray (idim);
 
- for (int frame = 0; frame < nframes; frame++)
-  {
-    imvec[frameidx(frame)].getConstPixels (0, 0, columns, rows);
+        idx(2) = 0;
+        for (int frame = 0; frame < nframes; frame++)
+          {
+            imvec[frameidx(frame)].getConstPixels (0, 0, columns, rows);
 
-    const Magick::IndexPacket *pix
-      = imvec[frameidx(frame)].getConstIndexes ();
+            const Magick::IndexPacket *pix
+              = imvec[frameidx(frame)].getConstIndexes ();
 
-    i = 0;
+            i = 0;
+            idx(3) = frame;
 
-    for (int y = 0; y < rows; y++)
-      for (int x = 0; x < columns; x++)
- im(y,x,frame) = static_cast<octave_uint16> (pix[i++]);
-  }
+            for (int y = 0; y < rows; y++)
+              {
+                idx(0) = y;
+                for (int x = 0; x < columns; x++)
+                  {
+                    idx(1) = x;
+                    im(idx) = static_cast<octave_uint16> (pix[i++]);
+                  }
+              }
+          }
         im.chop_trailing_singletons ();
         output(0) = octave_value (im);
       }
@@ -128,12 +155,12 @@ read_indexed_images (std::vector<Magick:
       Matrix alpha (mapsize, 1);
       for (i = 0; i < mapsize; i++)
         {
-  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 ();
+          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;
 #endif
@@ -142,10 +169,10 @@ read_indexed_images (std::vector<Magick:
       alpha = Matrix (0, 0);
       for (i = 0; i < mapsize; i++)
         {
-  Magick::ColorRGB 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;
 
@@ -165,7 +192,7 @@ template <class T>
 template <class T>
 octave_value_list
 read_images (const std::vector<Magick::Image>& imvec,
-     const Array<int>& frameidx, unsigned int depth)
+             const Array<int>& frameidx, unsigned int depth)
 {
   octave_value_list retval (3, Matrix ());
 
@@ -190,17 +217,25 @@ read_images (const std::vector<Magick::I
     {
     case Magick::BilevelType:
     case Magick::GrayscaleType:
-      im = T (dim_vector (rows, columns, nframes));
+      im = T (idim);
       for (int frame = 0; frame < nframes; frame++)
         {
-  const Magick::PixelPacket *pix
-    = imvec[frameidx(frame)].getConstPixels (0, 0, columns, rows);
+          const Magick::PixelPacket *pix
+            = imvec[frameidx(frame)].getConstPixels (0, 0, columns, rows);
 
-  int i = 0;
+          int i = 0;
+          idx(2) = 0;
+          idx(3) = frame;
 
-  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);
+          for (int y = 0; y < rows; y++)
+            {
+              idx(0) = y;
+              for (int x = 0; x < columns; x++)
+                {
+                  idx(1) = x;
+                  im(idx) = scale_quantum_to_depth (pix[i++].red, depth);
+                }
+            }
         }
       break;
 
@@ -209,25 +244,25 @@ read_images (const std::vector<Magick::I
       im = T (idim);
       for (int frame = 0; frame < nframes; frame++)
         {
-  const Magick::PixelPacket *pix
-    = imvec[frameidx(frame)].getConstPixels (0, 0, columns, rows);
+          const Magick::PixelPacket *pix
+            = imvec[frameidx(frame)].getConstPixels (0, 0, columns, rows);
 
-  int i = 0;
-  idx(3) = frame;
+          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++;
- }
-    }
+          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;
 
@@ -237,27 +272,27 @@ read_images (const std::vector<Magick::I
       im = T (idim);
       for (int frame = 0; frame < nframes; frame++)
         {
-  const Magick::PixelPacket *pix
-    = imvec[frameidx(frame)].getConstPixels (0, 0, columns, rows);
+          const Magick::PixelPacket *pix
+            = imvec[frameidx(frame)].getConstPixels (0, 0, columns, rows);
 
-  int i = 0;
-  idx(3) = frame;
+          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++;
- }
-    }
+          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;
 
@@ -268,29 +303,29 @@ read_images (const std::vector<Magick::I
       im = T (idim);
       for (int frame = 0; frame < nframes; frame++)
         {
-  const Magick::PixelPacket *pix
-    = imvec[frameidx(frame)].getConstPixels (0, 0, columns, rows);
+          const Magick::PixelPacket *pix
+            = imvec[frameidx(frame)].getConstPixels (0, 0, columns, rows);
 
-  int i = 0;
-  idx(3) = frame;
+          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++;
- }
-    }
+          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;
 
@@ -367,10 +402,10 @@ Instead you should use @code{imread}.\n\
       int nframes = imvec.size ();
 
       if (frameidx(i) >= nframes || frameidx(i) < 0)
- {
-  error ("__magick_read__: invalid index vector");
-  return output;
- }
+        {
+          error ("__magick_read__: invalid index vector");
+          return output;
+        }
     }
 
   Magick::ClassType klass = imvec[0].classType ();
@@ -382,30 +417,30 @@ Instead you should use @code{imread}.\n\
       unsigned int depth = imvec[0].modulusDepth ();
       int i = 0;
       while (depth >>= 1)
- i++;
+        i++;
       depth = 1 << i;
 
       switch (depth)
- {
- case 1:
-  output = read_images<boolNDArray> (imvec, frameidx, depth);
-  break;
+        {
+        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 2:
+        case 4:
+        case 8:
+          output = read_images<uint8NDArray> (imvec, frameidx, depth) ;
+          break;
 
- case 16:
-  output = read_images<uint16NDArray> (imvec, frameidx, depth);
-  break;
+        case 16:
+          output = read_images<uint16NDArray> (imvec, frameidx, depth);
+          break;
 
- case 32:
- case 64:
+        case 32:
+        case 64:
         default:
-  error ("__magick_read__: image depths bigger than 16-bit not supported");
- }
+          error ("__magick_read__: image depths bigger than 16-bit not supported");
+        }
     }
 #else
 
@@ -418,21 +453,278 @@ Instead you should use @code{imread}.\n\
 
 #ifdef HAVE_MAGICK
 
-static void 
-write_image (Magick::Image& im, const std::string& filename,
-     const std::string& fmt)
+static void
+jpg_settings (std::vector<Magick::Image>& imvec,
+              const Octave_map& options,
+              const bool& has_map)
 {
-  im.syncPixels ();
+  int nframes = static_cast<int>(imvec.size ());
+  bool something_set = 0;
 
-  // FIXME -- setting fmt to "jpg" and writing to "foo.png" results in
-  // a PNG file, not a JPEG file (for example).  How can the file type
-  // be forced regardless of the name?
+  // Quality setting
+  octave_value result;
+  Octave_map::const_iterator p;
+  bool found_it = 0;
+  for (p = options.begin (); p != options.end (); p++)
+    if (options.key (p) == "Quality")
+      {
+        found_it = 1;
+        result = options.contents (p).elem (0);
+        break;
+      }
+  if (found_it && (! result.is_empty ()))
+    {
+      something_set = 1;
+      if (result.is_real_type ())
+        {
+          int qlev = static_cast<int>(result.int_value ());
+          if (qlev < 0 || qlev > 100)
+            warning ("warning: Quality setting invalid--use default of 75");
+          else
+            for (int fnum = 0; fnum < nframes; fnum++)
+              imvec[fnum].quality (static_cast<unsigned int>(qlev));
+        }
+      else
+        warning ("warning: Quality setting invalid--use default of 75");
+    }
 
-  im.magick (fmt);
+  // Other settings go here
+
+  if (! something_set)
+    warning ("__magick_write__ warning: All write parameters ignored.");
+}
+
+static void
+encode_boolIm (std::vector<Magick::Image>& imvec, const octave_value& img)
+{
+  unsigned int bitdepth = 1;
+  unsigned int nframes = 1;
+  boolNDArray m = img.bool_array_value ();
+
+  dim_vector dsizes = m.dims ();
+  if (dsizes.length () == 4)
+    nframes = dsizes(3);
+
+  Array<octave_idx_type> idx (dsizes.length ());
+
+  octave_idx_type rows = m.rows ();
+  octave_idx_type columns = m.columns ();
+
+  for (int ii = 0; ii < nframes; ii++)
+    {
+      Magick::Image im(Magick::Geometry (columns, rows), "black");
+      im.classType (Magick::DirectClass);
+      im.depth (1);
+
+      for (int y=0; y < columns; y++)
+        {
+          idx(1) = y;
+          for (int x=0; x < rows; x++)
+            {
+              if (nframes > 1)
+                {
+                  idx(2) = 0;
+                  idx(3) = ii;
+                }
+              idx(0) = x;
+              if (m(idx))
+                im.pixelColor (y, x, "white");
+            }
+        }
+      imvec.push_back (im);
+    }
+}
+
+template <class T>
+static void
+encode_uintIm (std::vector<Magick::Image>& imvec,
+               const octave_value& img,
+               bool has_map)
+{
+  unsigned int bitdepth;
+  T m;
+
+  if (img.is_uint8_type ())
+    {
+      bitdepth = 8;
+      m = img.uint8_array_value ();
+    }
+  else if (img.is_uint16_type ())
+    {
+      bitdepth = 16;
+      m = img.uint16_array_value ();
+    }
+  else
+    error ("__magick_write__: invalid image class");
+
+  dim_vector dsizes = m.dims ();
+  unsigned int nframes = 1;
+  if (dsizes.length () == 4)
+    nframes = dsizes(3);
+  bool is_color = ((dsizes.length () > 2) && (dsizes(2) > 2));
+  bool has_alpha = (dsizes.length () > 2 && (dsizes(2) == 2 || dsizes(2) == 4));
+
+  Array<octave_idx_type> idx (dsizes.length ());
+  octave_idx_type rows = m.rows ();
+  octave_idx_type columns = m.columns ();
+  unsigned int div_factor = pow (2, bitdepth) - 1;
+
+  for (int ii = 0; ii < nframes; ii++)
+    {
+      Magick::Image im(Magick::Geometry (columns, rows), "black");
+      im.depth (bitdepth);
+      if (has_map)
+        im.classType (Magick::PseudoClass);
+      else
+        im.classType (Magick::DirectClass);
+
+      if (is_color)
+        {
+          if (has_alpha)
+            im.type (Magick::TrueColorMatteType);
+          else
+            im.type (Magick::TrueColorType);
+
+          Magick::ColorRGB c;
+          for (int y=0; y < columns; y++)
+            {
+              idx(1) = y;
+              for (int x=0; x < rows; x++)
+                {
+                  idx(0) = x;
+                  if (nframes > 1)
+                    idx(3) = ii;
+
+                  idx(2) = 0;
+                  c.red (static_cast<double>(m(idx)) / div_factor);
+                  idx(2) = 1;
+                  c.green (static_cast<double>(m(idx)) / div_factor);
+                  idx(2) = 2;
+                  c.blue (static_cast<double>(m(idx)) / div_factor);
+
+                  if (has_alpha)
+                    {
+                      idx(2) = 3;
+                      c.alpha (static_cast<double>(m(idx)) / div_factor);
+                    }
+                  im.pixelColor (y, x, c);
+                }
+            }
+        }
+      else
+        {
+          if (has_alpha)
+            im.type (Magick::GrayscaleMatteType);
+          else
+            im.type (Magick::GrayscaleType);
+
+          Magick::ColorGray c;
+
+          for (int y=0; y < columns; y++)
+            {
+              idx(1) = y;
+              for (int x=0; x < rows; x++)
+                {
+                  idx(0) = x;
+                  if (nframes > 1)
+                    {
+                      idx(2) = 0;
+                      idx(3) = ii;
+                    }
+                  if (has_alpha)
+                    {
+                      idx(2) = 1;
+                      c.alpha (static_cast<double>(m(idx)) / div_factor);
+                      idx(2) = 0;
+                    }
+
+                  c.shade (static_cast<double>(m(idx)) / div_factor);
+                  im.pixelColor (y, x, c);
+                }
+            }
+        }
+      imvec.push_back (im);
+    }
+}
+
+static void
+encode_map (std::vector<Magick::Image>& imvec, const NDArray& cmap)
+{
+  unsigned int mapsize = cmap.dim1 ();
+  Magick::ColorRGB c;
+  int nframes = static_cast<int>(imvec.size ());
+
+  for (int fnum = 0; fnum < nframes; fnum++)
+    {
+      imvec[fnum].colorMapSize (mapsize);
+      imvec[fnum].type (Magick::PaletteType);
+    }
+  for (unsigned int ii = 0; ii < mapsize; ii++)
+    {
+      c.red (cmap(ii,0));
+      c.green (cmap(ii,1));
+      c.blue (cmap(ii,2));
+      if (cmap.dim2 () == 4)  // left this in, but I think this case ruled out
+        c.alpha (cmap(ii,3));
+      try
+        {
+          for_each (imvec.begin (), imvec.end (),
+                    Magick::colorMapImage (ii, c));
+        }
+      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 ());
+        }
+    }
+}
+
+static void
+write_image (const std::string& filename, const std::string& fmt,
+     const octave_value& img,
+     const octave_value& map = octave_value (),
+     const octave_value& params = octave_value ())
+{
+  std::vector<Magick::Image> imvec;
+
+  if (img.is_bool_type ())
+    encode_boolIm (imvec, img);
+  else if (img.is_uint8_type ())
+    encode_uintIm<uint8NDArray> (imvec, img, map.is_defined ());
+  else if (img.is_uint16_type ())
+    encode_uintIm<uint16NDArray> (imvec, img, map.is_defined ());
+  else
+    error ("__magick_write__: image type not supported");
+
+  if (! error_state && map.is_defined ())
+    {
+      NDArray cmap = map.array_value ();
+
+      if (! error_state)
+        encode_map (imvec, cmap);
+    }
+
+  if (! error_state && params.is_defined ())
+    {
+      Octave_map options = params.map_value ();
+
+      // Insert calls here to handle parameters for various image formats
+      if (fmt == "jpg" || fmt == "jpeg")
+        jpg_settings (imvec, options, map.is_defined ());
+      else
+        warning ("warning: your parameter(s) currently not supported");
+    }
 
   try
     {
-      im.write (filename);
+      Magick::writeImages (imvec.begin (), imvec.end (), filename);
     }
   catch (Magick::Warning& w)
     {
@@ -445,82 +737,6 @@ write_image (Magick::Image& im, const st
   catch (Magick::Exception& e)
     {
       error ("Magick++ exception: %s", e.what ());
-    }
-}
-
-static void
-write_image (const std::string& filename, const std::string& fmt,
-     const octave_value& img,
-     const octave_value& map = octave_value ())
-{
-  if (img.is_bool_type ())
-    {
-      boolNDArray m = img.bool_array_value ();
-
-      if (! error_state)
- {
-  error ("__magick_write__: not implemented");
- }
-      else
- error ("__magick_write__: internal error");
-    }
-  else if (img.is_uint8_type ())
-    {
-      uint8NDArray m = img.uint8_array_value ();
-
-      if (! error_state)
- {
-  octave_idx_type rows = m.rows ();
-  octave_idx_type columns = m.columns ();
-
-  Magick::Image im (Magick::Geometry (columns, rows), "white");
-
-  im.type (Magick::TrueColorType);
-
-  im.modifyImage ();
-  
-  Magick::PixelPacket *pix = im.getPixels (0, 0, columns, rows);
-
-  int i = 0;
-
-  for (int y = 0; y < rows; y++)
-    {
-      for (int x = 0; x < columns; x++)
- {
-  pix[i].red = m(y,x,0);
-  pix[i].green = m(y,x,1);
-  pix[i].blue = m(y,x,2);
-  i++;
- }
-    }
-
-  write_image (im, filename, fmt);
- }
-      else
- error ("__magick_write__: internal error");
-    }
-  else if (img.is_uint16_type ())
-    {
-      uint16NDArray m = img.uint16_array_value ();
-
-      if (! error_state)
- {
-  error ("__magick_write__: not implemented");
- }
-      else
- error ("__magick_write__: internal error");
-    }
-  else
-    error ("__magick_write__: internal error");
-
-  if (! error_state && map.is_defined ())
-    {
-      NDArray cmap = map.array_value ();
-
-      if (! error_state)
- {
-  error ("__magick_write__: not implemented");
- }
     }
 }
 
@@ -545,21 +761,26 @@ Instead you should use @code{imwrite}.\n
       std::string filename = args(0).string_value ();
 
       if (! error_state)
- {
-  std::string fmt = args(1).string_value ();
+        {
+          std::string fmt = args(1).string_value ();
 
-  if (! error_state)
-    {
-      if (nargin > 3)
- write_image (filename, fmt, args(2), args(3));
-      else
- write_image (filename, fmt, args(2));
-    }
-  else
-    error ("__magick_write__: expecting format as second argument");
- }
+          if (! error_state)
+            {
+              if (nargin > 4)
+                write_image (filename, fmt, args(2), args(3), args(4));
+              else if (nargin > 3)
+                if (args(3).is_real_type ())
+                  write_image (filename, fmt, args(2), args(3));
+                else
+                  write_image (filename, fmt, args(2), octave_value(), args(3));
+              else
+                write_image (filename, fmt, args(2));
+            }
+          else
+            error ("__magick_write__: expecting format as second argument");
+        }
       else
- error ("__magick_write__: expecting filename as first argument");
+        error ("__magick_write__: expecting filename as first argument");
     }
   else
     print_usage ();
@@ -569,7 +790,7 @@ Instead you should use @code{imwrite}.\n
 
 #endif
 
-  return retval;
+return retval;
 }
 
 /*
@@ -577,3 +798,4 @@ Instead you should use @code{imwrite}.\n
 ;;; mode: C++ ***
 ;;; End: ***
 */
+


reply via email to

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