changeset 31170:72a159bc5a4c

Tiff: added readRGBAImage method to read image using the RGBA interface * __tiff__.cc(F__tiff_reag_rgba_image__): implemented logic for reading images using LibTIFF's RGBA interface. * Tiff.m: added method readRGBAImage and added unit tests for the new method.
author magedrifaat <magedrifaat@gmail.com>
date Sat, 13 Aug 2022 17:36:12 +0200
parents ae41e14bf5c7
children 8bf3fa6b6977
files libinterp/corefcn/__tiff__.cc scripts/io/Tiff.m
diffstat 2 files changed, 90 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/libinterp/corefcn/__tiff__.cc	Sat Aug 13 02:45:51 2022 +0200
+++ b/libinterp/corefcn/__tiff__.cc	Sat Aug 13 17:36:12 2022 +0200
@@ -2272,7 +2272,7 @@
     int nargin = args.length ();
 
     if (nargin != 2)
-      error ("rong number of arguments");
+      error ("Wrong number of arguments");
     
     TIFF *tif = (TIFF *)(args(0).uint64_value ());
 
@@ -2307,7 +2307,7 @@
     int nargin = args.length ();
 
     if (nargin != 2)
-      error ("rong number of arguments");
+      error ("Wrong number of arguments");
     
     TIFF *tif = (TIFF *)(args(0).uint64_value ());
 
@@ -2335,6 +2335,50 @@
 #endif
   }
 
+  DEFUN (__tiff_read_rgba_image__, args, ,
+             "Read the image data in rgba mode")
+  {
+#if defined (HAVE_TIFF)
+    int nargin = args.length ();
+
+    if (nargin != 1)
+      error ("Wrong number of arguments");
+    
+    TIFF *tif = (TIFF *)(args(0).uint64_value ());
+
+    tiff_image_data image_data (tif);
+
+    dim_vector img_dims (4, image_data.width, image_data.height);
+    uint8NDArray img (img_dims);
+    uint32_t *img_ptr = reinterpret_cast <uint32_t *> (img.fortran_vec ());
+    // Matlab (R2022a) uses a top-left orientation ignoring the tag if present
+    if (! TIFFReadRGBAImageOriented (tif, image_data.width, image_data.height,
+                                     img_ptr, 1))
+      error ("Failed to read image");
+    
+    Array<octave_idx_type> perm (dim_vector (3, 1));
+    perm(0) = 2;
+    perm(1) = 1;
+    perm(2) = 0;
+    img = img.permute (perm);
+
+    Array<idx_vector> idx (dim_vector (3, 1));
+    idx(0) = idx_vector (':');
+    idx(1) = idx_vector (':');
+    idx(2) = idx_vector (0, 3);
+    uint8NDArray rgb = uint8NDArray (img.index (idx));
+    idx(2) = idx_vector (3);
+    uint8NDArray alpha = uint8NDArray (img.index (idx));
+    
+    octave_value_list retval (2);
+    retval(0) = octave_value (rgb);
+    retval(1) = octave_value (alpha);
+    return retval;
+#else
+    err_disabled_feature ("readEncodedTile", "Tiff");
+#endif
+  }
+
   DEFUN (__tiff_write__, args, ,
              "Write the image data to the current IFD")
   {
--- a/scripts/io/Tiff.m	Sat Aug 13 02:45:51 2022 +0200
+++ b/scripts/io/Tiff.m	Sat Aug 13 17:36:12 2022 +0200
@@ -253,6 +253,13 @@
       tileData = __tiff_read_encoded_tile__ (t.tiff_handle, tileNumber);
     endfunction
 
+    function [RGB, alpha] = readRGBAImage (t)
+      if (t.closed)
+        error ("Image file was closed");
+      endif
+      [RGB, alpha] = __tiff_read_rgba_image__ (t.tiff_handle);
+    endfunction
+
     function write (t, imageData)
       if (t.closed)
         error ("Image file was closed");
@@ -1450,3 +1457,40 @@
 %!    img.close();
 %!  endfunction
 %!  file_wrapper (@test_fn);
+
+## test readRGBAImage
+%!testif HAVE_TIFF
+%!  function test_fn (filename)
+%!    img = Tiff (filename, "w");
+%!    setTag(img, struct (
+%!      "ImageLength", 10, "ImageWidth", 10,
+%!      "BitsPerSample", 8, "SamplesPerPixel", 3,
+%!      "PhotometricInterpretation", 2,
+%!      "PlanarConfiguration", 1
+%!    ));
+%!    data = uint8 (reshape (1:300, [10, 10, 3]));
+%!    write (img, data);
+%!    [rgb, alpha] = readRGBAImage (img);
+%!    assert (rgb, data);
+%!    assert (alpha, uint8 (repmat ([255], [10, 10])));
+%!  endfunction
+%!  file_wrapper (@test_fn);
+
+## test readRGBAImage with alpha
+%!testif HAVE_TIFF
+%!  function test_fn (filename)
+%!    img = Tiff (filename, "w");
+%!    setTag(img, struct (
+%!      "ImageLength", 10, "ImageWidth", 10,
+%!      "BitsPerSample", 8, "SamplesPerPixel", 4,
+%!      "PhotometricInterpretation", 2,
+%!      "PlanarConfiguration", 1,
+%!      "ExtraSamples", 1
+%!    ));
+%!    data = uint8 (randi ([0,255], [10, 10, 4]));
+%!    write (img, data);
+%!    [rgb, alpha] = readRGBAImage (img);
+%!    assert (rgb, data(:,:,1:3));
+%!    assert (alpha, data(:,:,4));
+%!  endfunction
+%!  file_wrapper (@test_fn);