changeset 17228:2f1729cae08f

Initial support for writing of floating point and uint32 images. * __magick_read__.cc (img_float2uint): new function to convert floating point values in the range [0 1] to uint. (encode_indexed_images): add new case for images with uint32 values; avoid overflowing of div_factor for big bitdepth. (__magick_write__): add new case for uint32 and floating point images.
author Carnë Draug <carandraug@octave.org>
date Tue, 13 Aug 2013 05:50:33 +0100
parents 35abfa2e5a27
children 2736bc7bf8d9
files libinterp/dldfcn/__magick_read__.cc
diffstat 1 files changed, 47 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/libinterp/dldfcn/__magick_read__.cc	Tue Aug 13 03:50:51 2013 +0100
+++ b/libinterp/dldfcn/__magick_read__.cc	Tue Aug 13 05:50:33 2013 +0100
@@ -747,6 +747,25 @@
 #ifdef HAVE_MAGICK
 
 template <class T>
+static uint32NDArray
+img_float2uint (const T& img)
+{
+  typedef typename T::element_type P;
+  uint32NDArray out (img.dims ());
+
+  octave_uint32* out_fvec = out.fortran_vec ();
+  const P*       img_fvec = img.fortran_vec ();
+
+  const octave_uint32 max = octave_uint32::max ();
+  const octave_idx_type numel = img.numel ();
+  for (octave_idx_type idx = 0; idx < numel; idx++)
+    {
+      out_fvec[idx] = img_fvec[idx] * max;
+    }
+  return out;
+}
+
+template <class T>
 static void
 encode_indexed_images (std::vector<Magick::Image>& imvec,
                        const T& img,
@@ -892,6 +911,11 @@
       bitdepth = 16;
       m = img.uint16_array_value ();
     }
+  else if (img.is_uint32_type ())
+    {
+      bitdepth = 32;
+      m = img.uint32_array_value ();
+    }
   else
     error ("__magick_write__: invalid image class");
 
@@ -907,7 +931,7 @@
   octave_idx_type rows = m.rows ();
   octave_idx_type columns = m.columns ();
 
-  unsigned int div_factor = (1 << bitdepth) - 1;
+  double div_factor = (uint64_t(1) << bitdepth) - 1;
 
   for (unsigned int ii = 0; ii < nframes; ii++)
     {
@@ -1085,6 +1109,28 @@
         {
           encode_uint_image<uint16NDArray> (imvec, img);
         }
+      else if (img.is_uint32_type ())
+        {
+          encode_uint_image<uint32NDArray> (imvec, img);
+        }
+      else if (img.is_float_type ())
+        {
+          // For image formats that support floating point values, we write
+          // the actual values. For those who don't, we only use the values
+          // on the range [0 1] and save integer values.
+          // But here, even for formats that would support floating point
+          // values, GM seems unable to do that so we at least make them uint32.
+          uint32NDArray clip_img;
+          if (img.is_single_type ())
+            {
+              clip_img = img_float2uint<FloatNDArray> (img.float_array_value ());
+            }
+          else
+            {
+              clip_img = img_float2uint<NDArray> (img.array_value ());
+            }
+          encode_uint_image<uint32NDArray> (imvec, octave_value (clip_img));
+        }
       else
         {
           error ("__magick_write__: image type not supported");