changeset 31203:fa50e2c17568

Tiff: fixed bug RGBA incorrect orientation handling for rotated orientations * libinterp/corefcn/__tiff__.cc (F__tiff_read_rgba_image__, F__tiff_read_rgba_strip__, F__tiff_read_rgba_tile__): fixed bug where orientations that require rotation and flipping were incorrectly handled.
author magedrifaat <magedrifaat@gmail.com>
date Fri, 02 Sep 2022 23:27:47 +0200
parents be6ccdcd5775
children 86d7c1be75dd
files libinterp/corefcn/__tiff__.cc
diffstat 1 files changed, 72 insertions(+), 13 deletions(-) [+]
line wrap: on
line diff
--- a/libinterp/corefcn/__tiff__.cc	Fri Sep 02 21:20:56 2022 +0200
+++ b/libinterp/corefcn/__tiff__.cc	Fri Sep 02 23:27:47 2022 +0200
@@ -2752,9 +2752,18 @@
     if (! TIFFRGBAImageOK (tif, emsg)
         || ! TIFFRGBAImageBegin (&img_config, tif, 0, emsg))
       error ("Failed to read image");
+
+    if (orientation == ORIENTATION_RIGHTTOP
+        || orientation == ORIENTATION_LEFTBOT)
+      // LibTIFF can only do flips and doesn't do rotations, so if we need
+      // an orientation that requires a rotation before flipping
+      // (i.e. LeftBottom, RightTop) then the only thing we can do is start
+      // with an orientation that doesn't require a rotation, then permute at
+      // the end.
+      img_config.orientation = ORIENTATION_RIGHTBOT;
+    else
+      img_config.orientation = ORIENTATION_TOPLEFT;
     
-    // FIXME: rotated orientation don't work correctly (e.g. LeftTop)
-    img_config.orientation = ORIENTATION_TOPLEFT;
     img_config.req_orientation = orientation;
 
     bool success = TIFFRGBAImageGet (&img_config, img_ptr, img_config.width,
@@ -2766,9 +2775,19 @@
     
     // Permute to the correct Octave dimension order
     Array<octave_idx_type> perm (dim_vector (3, 1));
-    perm(0) = 2;
-    perm(1) = 1;
-    perm(2) = 0;
+    if (orientation >= ORIENTATION_LEFTTOP)
+      {
+        // Transpose for rotated orientations
+        perm(0) = 1;
+        perm(1) = 2;
+        perm(2) = 0;
+      }
+    else
+      {
+        perm(0) = 2;
+        perm(1) = 1;
+        perm(2) = 0;
+      }
     img = img.permute (perm);
 
     // Slice the data into RGB and alpha
@@ -2844,7 +2863,17 @@
         || ! TIFFRGBAImageBegin (&img_config, tif, 0, emsg))
       error ("Failed to read strip");
     
-    img_config.orientation = ORIENTATION_TOPLEFT;
+    if (orientation == ORIENTATION_RIGHTTOP
+        || orientation == ORIENTATION_LEFTBOT)
+      // LibTIFF can only do flips and doesn't do rotations, so if we need
+      // an orientation that requires a rotation before flipping
+      // (i.e. LeftBottom, RightTop) then the only thing we can do is start
+      // with an orientation that doesn't require a rotation, then permute at
+      // the end.
+      img_config.orientation = ORIENTATION_RIGHTBOT;
+    else
+      img_config.orientation = ORIENTATION_TOPLEFT;
+
     img_config.req_orientation = orientation;
     img_config.row_offset = row;
     img_config.col_offset = 0;
@@ -2858,9 +2887,19 @@
     
     // Permute to the correct order of dimensions for Octave
     Array<octave_idx_type> perm (dim_vector (3, 1));
-    perm(0) = 2;
-    perm(1) = 1;
-    perm(2) = 0;
+    if (orientation >= ORIENTATION_LEFTTOP)
+      {
+        // Transpose for rotated orientations
+        perm(0) = 1;
+        perm(1) = 2;
+        perm(2) = 0;
+      }
+    else
+      {
+        perm(0) = 2;
+        perm(1) = 1;
+        perm(2) = 0;
+      }
     strip_data = strip_data.permute (perm);
 
     // Slice the data into RGB and alpha
@@ -2945,7 +2984,17 @@
         || ! TIFFRGBAImageBegin (&img_config, tif, 0, emsg))
       error ("Failed to read tile");
     
-    img_config.orientation = ORIENTATION_TOPLEFT;
+    if (orientation == ORIENTATION_RIGHTTOP
+        || orientation == ORIENTATION_LEFTBOT)
+      // LibTIFF can only do flips and doesn't do rotations, so if we need
+      // an orientation that requires a rotation before flipping
+      // (i.e. LeftBottom, RightTop) then the only thing we can do is start
+      // with an orientation that doesn't require a rotation, then permute at
+      // the end.
+      img_config.orientation = ORIENTATION_RIGHTBOT;
+    else
+      img_config.orientation = ORIENTATION_TOPLEFT;
+      
     img_config.req_orientation = orientation;
     img_config.row_offset = row;
     img_config.col_offset = col;
@@ -2959,9 +3008,19 @@
     
     // Permute to the correct order of dimensions for Octave
     Array<octave_idx_type> perm (dim_vector (3, 1));
-    perm(0) = 2;
-    perm(1) = 1;
-    perm(2) = 0;
+    if (orientation >= ORIENTATION_LEFTTOP)
+      {
+        // Transpose for rotated orientations
+        perm(0) = 1;
+        perm(1) = 2;
+        perm(2) = 0;
+      }
+    else
+      {
+        perm(0) = 2;
+        perm(1) = 1;
+        perm(2) = 0;
+      }
     tile_data = tile_data.permute (perm);
     
     // Slice the data into RGB and alpha