changeset 31114:9dead1249449

Tiff getTag: fixed matrix shape for ColorMap and TransferFunction * __tiff__.cc (get_field_data): fixed return matrix for colormap and transferfunction to be consistent with matlab.
author magedrifaat <magedrifaat@gmail.com>
date Sat, 16 Jul 2022 17:29:14 +0200
parents a74059523d74
children 5b3465a9c340
files libinterp/dldfcn/__tiff__.cc
diffstat 1 files changed, 89 insertions(+), 55 deletions(-) [+]
line wrap: on
line diff
--- a/libinterp/dldfcn/__tiff__.cc	Sat Jul 16 01:26:40 2022 +0200
+++ b/libinterp/dldfcn/__tiff__.cc	Sat Jul 16 17:29:14 2022 +0200
@@ -83,6 +83,10 @@
                         // TODO(maged): copy entire strip at once?
                         for (uint16_t sample = 0;
                              sample < image_data->samples_per_pixel; sample++)
+                          // The memory organization of fvec is inverted from
+                          // what would be expected for a normal C-like array.
+                          // It is treated as samples * columns * rows as
+                          // opposed to rows * columns * samples.
                           img_fvec[sample * image_data->width * image_data->height
                                    + column * image_data->height
                                    + row_index + row_subindex]
@@ -148,7 +152,7 @@
   }
 
   // Convert tag value to double
-  octave_value_list
+  octave_value
   interpret_scalar_tag_data (void *data, TIFFDataType tag_datatype)
   {
     double retval;
@@ -224,20 +228,20 @@
         error ("Unsupported tag data type");
       }
 
-    return octave_value_list (octave_value (retval));
+    return octave_value (retval);
   }
 
-  // Convert memory buffer into suitable octave values
+  // Convert memory buffer into a suitable octave value
   // depending on tag_datatype
-  octave_value_list
+  octave_value
   interpret_tag_data (void *data, uint32_t count, TIFFDataType tag_datatype)
   {
-    octave_value_list ovl_data;
+    octave_value retval;
     // Apparently matlab converts scalar numerical values into double
     // but doesn't do the same for arrays
     if (count == 1 && tag_datatype != TIFF_ASCII)
       {
-        ovl_data = interpret_scalar_tag_data (data, tag_datatype);
+        retval = interpret_scalar_tag_data (data, tag_datatype);
       }
     else
       {
@@ -253,12 +257,12 @@
                 {
                   arr(i) = ((uint8_t *)data)[i];
                 }
-              ovl_data(0) = arr;
+              retval = octave_value (arr);
               break;
             }
           case TIFF_ASCII:
             {
-              ovl_data(0) = octave_value (*(char **)data);
+              retval = octave_value (*(char **)data);
               break;
             }
           case TIFF_SHORT:
@@ -268,7 +272,7 @@
                 {
                   arr(i) = ((uint16_t *)data)[i];
                 }
-              ovl_data(0) = arr;
+              retval = octave_value (arr);
               break;
             }
           case TIFF_LONG:
@@ -278,7 +282,7 @@
                 {
                   arr(i) = ((uint32_t *)data)[i];
                 }
-              ovl_data(0) = arr;
+              retval = octave_value (arr);
               break;
             }
           case TIFF_LONG8:
@@ -288,7 +292,7 @@
                 {
                   arr(i) = ((uint64_t *)data)[i];
                 }
-              ovl_data(0) = arr;
+              retval = octave_value (arr);
               break;
             }
           case TIFF_RATIONAL:
@@ -299,7 +303,7 @@
                   arr(i / 2) = (float)((uint32_t *)data)[i] 
                                 / (float)((uint32_t *)data)[i+1];
                 }
-              ovl_data(0) = arr;
+              retval = octave_value (arr);
               break;
             }
           case TIFF_SBYTE:
@@ -309,7 +313,7 @@
                 {
                   arr(i) = ((int8_t *)data)[i];
                 }
-              ovl_data(0) = arr;
+              retval = octave_value (arr);
               break;
             }
           case TIFF_SSHORT:
@@ -319,7 +323,7 @@
                 {
                   arr(i) = ((int16_t *)data)[i];
                 }
-              ovl_data(0) = arr;
+              retval = octave_value (arr);
               break;
             }
           case TIFF_SLONG:
@@ -329,7 +333,7 @@
                 {
                   arr(i) = ((int32_t *)data)[i];
                 }
-              ovl_data(0) = arr;
+              retval = octave_value (arr);
               break;
             }
           case TIFF_SLONG8:
@@ -339,7 +343,7 @@
                 {
                   arr(i) = ((int64_t *)data)[i];
                 }
-              ovl_data(0) = arr;
+              retval = octave_value (arr);
               break;
             }
           case TIFF_FLOAT:
@@ -349,7 +353,7 @@
                 {
                   arr(i) = ((float *)data)[i];
                 }
-              ovl_data(0) = arr;
+              retval = octave_value (arr);
               break;
             }
           case TIFF_DOUBLE:
@@ -359,7 +363,7 @@
               {
                   arr(i) = ((double *)data)[i];
               }
-              ovl_data(0) = arr;
+              retval = octave_value (arr);
               break;
             }
           case TIFF_SRATIONAL:
@@ -370,7 +374,7 @@
                   arr(i / 2) = (float)((int32_t *)data)[i] 
                                 / (float)((int32_t *)data)[i+1];
                 }
-              ovl_data(0) = arr;
+              retval = octave_value (arr);
               break;
             }
           case TIFF_IFD:
@@ -383,13 +387,12 @@
           }
       }
 
-    return ovl_data;
+    return retval;
   }
 
-  octave_value_list
+  octave_value
   get_scalar_field_data (TIFF *tif, const TIFFField *fip)
   {
-    octave_value_list tag_data_ovl;
     uint32_t tag_id = TIFFFieldTag (fip);
 
     // TIFFFieldReadCount returns VARIABLE for some scalar tags
@@ -403,13 +406,14 @@
     int type_size = TIFFDataWidth (TIFFFieldDataType (fip));
     void *data = _TIFFmalloc (type_size);
     validate_tiff_get_field (TIFFGetField (tif, tag_id, data), data);
-    tag_data_ovl = interpret_tag_data (data, 1, TIFFFieldDataType (fip));
+    octave_value tag_data_ov = interpret_tag_data (data, 1,
+                                                   TIFFFieldDataType (fip));
     _TIFFfree (data);
 
-    return tag_data_ovl;
+    return tag_data_ov;
   }
 
-  octave_value_list
+  octave_value
   get_array_field_data (TIFF *tif, const TIFFField *fip, uint32_t array_size)
   {
     void *data;
@@ -421,7 +425,7 @@
   octave_value_list
   get_field_data (TIFF *tif, const TIFFField *fip)
   {
-    octave_value_list tag_data_ovl;
+    octave_value_list tag_data_ovl (1);
     uint32_t tag_id = TIFFFieldTag (fip);
 
     // TODO(maged): find/create images to test the special tags
@@ -453,6 +457,8 @@
         }
       case TIFFTAG_COLORMAP:
         {
+          // TODO(maged): Fix output formatting to be consistent with matlab
+          // Matlab returns a float colormap?
           uint16_t bits_per_sample;
           if (! TIFFGetField (tif, TIFFTAG_BITSPERSAMPLE, &bits_per_sample))
             error ("Failed to obtain the bit depth");
@@ -463,17 +469,31 @@
           uint32_t count = 1 << bits_per_sample;
           uint16_t *red, *green, *blue;
           validate_tiff_get_field (TIFFGetField (tif, TIFFTAG_COLORMAP,
-                                                &red, &green, &blue));
-          tag_data_ovl(0) 
-            = octave_value (interpret_tag_data (red, count,
-                                            TIFFFieldDataType (fip)));
-          tag_data_ovl(1) 
-            = octave_value (interpret_tag_data (green, count,
-                                            TIFFFieldDataType (fip)));
-          tag_data_ovl(2) 
-            = octave_value (interpret_tag_data (blue, count,
-                                            TIFFFieldDataType (fip)));
+                                                 &red, &green, &blue));
           
+          uint16NDArray mat_out (dim_vector (count, 3));
+
+          uint16NDArray red_array
+            = interpret_tag_data (red,
+                                  count,
+                                  TIFFFieldDataType (fip)).uint16_array_value ();
+          uint16NDArray green_array
+            = interpret_tag_data (green,
+                                  count,
+                                  TIFFFieldDataType (fip)).uint16_array_value ();
+          uint16NDArray blue_array
+            = interpret_tag_data (blue,
+                                  count,
+                                  TIFFFieldDataType (fip)).uint16_array_value ();
+          
+          octave_uint16 *out_ptr = mat_out.fortran_vec ();
+          memcpy (out_ptr, red_array.fortran_vec (), sizeof(uint16_t) * count);
+          out_ptr += count;
+          memcpy (out_ptr, green_array.fortran_vec (), sizeof(uint16_t) * count);
+          out_ptr += count;
+          memcpy (out_ptr, blue_array.fortran_vec (), sizeof(uint16_t) * count);
+
+          tag_data_ovl(0) = octave_value (mat_out);
           break;
         }
       case TIFFTAG_TRANSFERFUNCTION:
@@ -492,22 +512,36 @@
             {
               validate_tiff_get_field (TIFFGetField (tif, TIFFTAG_COLORMAP, &ch1));
               tag_data_ovl(0) 
-                = octave_value (interpret_tag_data (ch1, count,
-                                                TIFFFieldDataType (fip)));
+                = interpret_tag_data (ch1, count, TIFFFieldDataType (fip));
             }
           else
             {
               validate_tiff_get_field (TIFFGetField (tif, TIFFTAG_COLORMAP,
-                                                    &ch1, &ch2, &ch3));
-              tag_data_ovl(0)
-                = octave_value (interpret_tag_data (ch1, count,
-                                                TIFFFieldDataType (fip)));
-              tag_data_ovl(1)
-                = octave_value (interpret_tag_data (ch2, count,
-                                                TIFFFieldDataType (fip)));
-              tag_data_ovl(2)
-                = octave_value (interpret_tag_data (ch3, count,
-                                                TIFFFieldDataType (fip)));
+                                                     &ch1, &ch2, &ch3));
+              
+              uint16NDArray mat_out (dim_vector (count, 3));
+
+              uint16NDArray ch1_array
+                = interpret_tag_data (ch1,
+                                      count,
+                                      TIFFFieldDataType (fip)).uint16_array_value ();
+              uint16NDArray ch2_array
+                = interpret_tag_data (ch2,
+                                      count,
+                                      TIFFFieldDataType (fip)).uint16_array_value ();
+              uint16NDArray ch3_array
+                = interpret_tag_data (ch3,
+                                      count,
+                                      TIFFFieldDataType (fip)).uint16_array_value ();
+              
+              octave_uint16 *out_ptr = mat_out.fortran_vec ();
+              memcpy (out_ptr, ch1_array.fortran_vec (), sizeof(uint16_t) * count);
+              out_ptr += count;
+              memcpy (out_ptr, ch2_array.fortran_vec (), sizeof(uint16_t) * count);
+              out_ptr += count;
+              memcpy (out_ptr, ch3_array.fortran_vec (), sizeof(uint16_t) * count);
+
+              tag_data_ovl(0) = octave_value (mat_out);
             }
           break;
         }
@@ -518,13 +552,11 @@
         {
           uint16_t tag_part1, tag_part2;
           validate_tiff_get_field (TIFFGetField (tif, tag_id,
-                                                &tag_part1, &tag_part2));
+                                                 &tag_part1, &tag_part2));
           tag_data_ovl(0)
-            = octave_value (interpret_tag_data (&tag_part1, 1,
-                                            TIFFFieldDataType (fip)));
+            = interpret_tag_data (&tag_part1, 1, TIFFFieldDataType (fip));
           tag_data_ovl(1)
-            = octave_value (interpret_tag_data (&tag_part2, 1,
-                                            TIFFFieldDataType (fip)));
+            = interpret_tag_data (&tag_part2, 1, TIFFFieldDataType (fip));
           break;
         }
       case TIFFTAG_SUBIFD:
@@ -532,7 +564,8 @@
           uint16_t count;
           uint64_t *offsets;
           validate_tiff_get_field (TIFFGetField (tif, tag_id, &count, &offsets));
-          tag_data_ovl = interpret_tag_data (offsets, count, TIFFFieldDataType (fip));
+          tag_data_ovl(0) = interpret_tag_data (offsets, count,
+                                                TIFFFieldDataType (fip));
           break;
         }
       case TIFFTAG_EXTRASAMPLES:
@@ -540,7 +573,8 @@
           uint16_t count;
           uint16_t *types;
           validate_tiff_get_field (TIFFGetField (tif, tag_id, &count, &types));
-          tag_data_ovl = interpret_tag_data (types, count, TIFFFieldDataType (fip));
+          tag_data_ovl(0) = interpret_tag_data (types, count,
+                                                TIFFFieldDataType (fip));
           break;
         }
       // TODO(maged): These tags are more complex to implement