changeset 31097:75ab26f147a5

getTag: Implemented single array tags, only multi-array and special tags are unimplemented
author magedrifaat <magedrifaat@gmail.com>
date Sun, 26 Jun 2022 02:58:49 +0200
parents c581ec211b45
children 3cbd0d82167c
files libinterp/dldfcn/__tiff__.cc
diffstat 1 files changed, 205 insertions(+), 113 deletions(-) [+]
line wrap: on
line diff
--- a/libinterp/dldfcn/__tiff__.cc	Fri Jun 24 17:45:00 2022 +0200
+++ b/libinterp/dldfcn/__tiff__.cc	Sun Jun 26 02:58:49 2022 +0200
@@ -10,101 +10,220 @@
 
 // TODO(maged): Tidy up the formatting to be consistant with octave
 
-octave_value interpret_data(void *data, uint32_t count, TIFFDataType tag_datatype)
+octave_value_list interpret_data(void *data, uint32_t count, TIFFDataType tag_datatype)
 {
-    // TODO(maged): Find the correct way fo returning multivalues
-    octave_value_list ov_data;
-    switch (tag_datatype)
+    // TODO(maged): Find the correct way fo returning multivalues (Matrix for numericals?)
+    octave_value_list ovl_data;
+    // TODO(maged): check if this should be row matrix or column matrix
+    dim_vector arr_dims(1, count);
+    if (tag_datatype == TIFF_BYTE || tag_datatype == TIFF_UNDEFINED)
+    {
+        uint8NDArray arr(arr_dims);
+        for (uint32_t i = 0; i < count; i++)
+        {
+            arr(i) = ((uint8_t *)data)[i];
+        }
+        ovl_data(0) = arr;
+    }
+    else if(tag_datatype == TIFF_ASCII)
+    {
+        ovl_data(0) = *(char **)data;
+    }
+    else if (tag_datatype == TIFF_SHORT)
+    {
+        uint16NDArray arr(arr_dims);
+        for (uint32_t i = 0; i < count; i++)
+        {
+            arr(i) = ((uint16_t *)data)[i];
+        }
+        ovl_data(0) = arr;
+    }
+    else if (tag_datatype == TIFF_LONG)
+    {
+        uint32NDArray arr(arr_dims);
+        for (uint32_t i = 0; i < count; i++)
+        {
+            arr(i) = ((uint32_t *)data)[i];
+        }
+        ovl_data(0) = arr;
+    }
+    else if (tag_datatype == TIFF_LONG8)
+    {
+        uint64NDArray arr(arr_dims);
+        for (uint32_t i = 0; i < count; i++)
+        {
+            arr(i) = ((uint64_t *)data)[i];
+        }
+        ovl_data(0) = arr;
+    }
+    else if (tag_datatype == TIFF_RATIONAL)
+    {
+        NDArray arr(arr_dims);
+        for (uint32_t i = 0; i < count; i+=2)
+        {
+            arr(i / 2) = (float)((uint32_t *)data)[i] / (float)((uint32_t *)data)[i+1];
+        }
+        ovl_data(0) = arr;
+    }
+    else if (tag_datatype == TIFF_SBYTE)
     {
-        case TIFF_BYTE:
-        case TIFF_UNDEFINED:
-            for (uint32_t i = 0; i < count; i++)
-            {
-                ov_data(i) = octave_value(((uint8_t *)data)[i]);
-            }
-            break;
-
-        case TIFF_ASCII:
-            ov_data(0) = octave_value(*(char **)data);
-            break;
-
-        case TIFF_SHORT:
-            for (uint32_t i = 0; i < count; i++)
-            {
-                ov_data(i) = octave_value(((uint16_t *)data)[i]);
-            }
-            break;
-        
-        // TODO(maged): why is the data type 64-bit for non-bigtiff images?
-        case TIFF_LONG:
-        case TIFF_LONG8:
-            for (uint32_t i = 0; i < count; i++)
-            {
-                ov_data(i) = octave_value(((uint32_t *)data)[i]);
-            }
-            break;
-
-        case TIFF_RATIONAL:
-            for (uint32_t i = 0; i < count; i+=2)
-            {
-                ov_data(i / 2) = octave_value((float)((uint32_t *)data)[i] / (float)((uint32_t *)data)[i+1]);
-            }
-            break;
+        int8NDArray arr(arr_dims);
+        for (uint32_t i = 0; i < count; i++)
+        {
+            arr(i) = ((int8_t *)data)[i];
+        }
+        ovl_data(0) = arr;
+    }
+    else if (tag_datatype == TIFF_SSHORT)
+    {
+        int16NDArray arr(arr_dims);
+        for (uint32_t i = 0; i < count; i++)
+        {
+            arr(i) = ((int16_t *)data)[i];
+        }
+        ovl_data(0) = arr;
+    }
+    else if (tag_datatype == TIFF_SLONG)
+    {
+        int32NDArray arr(arr_dims);
+        for (uint32_t i = 0; i < count; i++)
+        {
+            arr(i) = ((int32_t *)data)[i];
+        }
+        ovl_data(0) = arr;
+    }
+    else if (tag_datatype == TIFF_SLONG8)
+    {
+        int64NDArray arr(arr_dims);
+        for (uint32_t i = 0; i < count; i++)
+        {
+            arr(i) = ((int64_t *)data)[i];
+        }
+        ovl_data(0) = arr;
+    }
+    else if (tag_datatype == TIFF_FLOAT)
+    {
+        NDArray arr(arr_dims);
+        for (uint32_t i = 0; i < count; i++)
+        {
+            arr(i) = ((float *)data)[i];
+        }
+        ovl_data(0) = arr;
+    }
+    else if (tag_datatype == TIFF_DOUBLE)
+    {
+        NDArray arr(arr_dims);
+        for (uint32_t i = 0; i < count; i++)
+        {
+            arr(i) = ((double *)data)[i];
+        }
+        ovl_data(0) = arr;
+    }
+    else if (tag_datatype == TIFF_SRATIONAL)
+    {
+        NDArray arr(arr_dims);
+        for (uint32_t i = 0; i < count; i+=2)
+        {
+            arr(i / 2) = (float)((int32_t *)data)[i] / (float)((int32_t *)data)[i+1];
+        }
+        ovl_data(0) = arr;
+    }
+    else if (tag_datatype == TIFF_IFD || tag_datatype == TIFF_IFD8)
+    {
+        // TODO(maged): implement IFD datatype
+        error("Unimplemented IFFD data type");
+    }
+    else
+    {
+        // TODO(maged): find the correct response in this case
+        error("Unsupported tag data type");
+    }
 
-        case TIFF_SBYTE:
-            for (uint32_t i = 0; i < count; i++)
-            {
-                ov_data(i) = octave_value(((int8_t *)data)[i]);
-            }
-            break;
+    return ovl_data;
+}
+
+octave_value_list 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 (e.g. Compression)
+    // But TIFFFieldPassCount seems consistent
+    if (!TIFFFieldPassCount(fip))
+    {
+        // TODO(maged): test this function vs actual data type size
+        int type_size = TIFFDataWidth(TIFFFieldDataType(fip));
+        void *data = _TIFFmalloc(type_size);
+        if (TIFFGetField(tif, tag_ID, data))
+        {
+            tag_data_ovl = interpret_data(data, 1, TIFFFieldDataType(fip));
+            _TIFFfree(data);
+        }
+        else
+        {
+            _TIFFfree(data);
+
+            // TODO(maged): Give a better error message?
+            error("Failed to read tag");
+        }
         
-        case TIFF_SSHORT:
-            for (uint32_t i = 0; i < count; i++)
-            {
-                ov_data(i) = octave_value(((int16_t *)data)[i]);
-            }
-            break;
+    }
+    else
+    {
+        // TODO(maged): Implement support for variable read argument tags
+        error("Variable argument tags not implemented");
+    }
 
-        case TIFF_SLONG:
-        case TIFF_SLONG8:
-            for (uint32_t i = 0; i < count; i++)
-            {
-                ov_data(i) = octave_value(((int32_t *)data)[i]);
-            }
-            break;
+    return tag_data_ovl;
+}
 
-        case TIFF_FLOAT:
-            for (uint32_t i = 0; i < count; i++)
-            {
-                ov_data(i) = octave_value(((float *)data)[i]);
-            }
-            break;
-        
-        case TIFF_DOUBLE:
-            for (uint32_t i = 0; i < count; i++)
-            {
-                ov_data(i) = octave_value(((double *)data)[i]);
-            }
+octave_value_list get_array_field_data(TIFF *tif, const TIFFField *fip, uint32_t array_size)
+{
+    octave_value_list tag_data_ovl;
+
+    uint32_t tag_ID = TIFFFieldTag(fip);
+    TIFFDataType tag_datatype = TIFFFieldDataType(fip);
+    int type_size = TIFFDataWidth(tag_datatype);
+    void *data;
+    if (TIFFGetField(tif, tag_ID, &data))
+    {
+        tag_data_ovl = interpret_data(data, array_size, tag_datatype);
+    }
+    else
+    {
+        // TODO(maged): Give a better error message?
+        error("Failed to read tag");
+    }
+
+    return tag_data_ovl;
+}
+
+octave_value_list get_field_data(TIFF *tif, const TIFFField *fip)
+{
+    octave_value_list tag_data_ovl;
+    uint32_t tag_ID = TIFFFieldTag(fip);
+
+    switch(tag_ID)
+    {
+        case TIFFTAG_STRIPBYTECOUNTS:
+        case TIFFTAG_STRIPOFFSETS:
+            tag_data_ovl = get_array_field_data(tif, fip, TIFFNumberOfStrips(tif));
             break;
-
-        case TIFF_SRATIONAL:
-            for (uint32_t i = 0; i < count; i+=2)
-            {
-                ov_data(i / 2) = octave_value((float)((int32_t *)data)[i] / (float)((int32_t *)data)[i+1]);
-            }
+        case TIFFTAG_TILEBYTECOUNTS:
+        case TIFFTAG_TILEOFFSETS:
+            tag_data_ovl = get_array_field_data(tif, fip, TIFFNumberOfTiles(tif));
             break;
-
-        case TIFF_IFD:
-        case TIFF_IFD8:
-            // TODO(maged): implement IFD datatype
-            error("Unimplemented IFFD data type");
+        case TIFFTAG_YCBCRCOEFFICIENTS:
+            tag_data_ovl = get_array_field_data(tif, fip, 3);
+            break;
+        case TIFFTAG_REFERENCEBLACKWHITE:
+            tag_data_ovl = get_array_field_data(tif, fip, 6);
             break;
         default:
-            // TODO(maged): find the correct response in this case
-            error("Unsupported tag data type");
+            tag_data_ovl = get_scalar_field_data(tif, fip);
     }
-
-    return octave_value(ov_data);
+    
+    return tag_data_ovl;
 }
 
 DEFUN_DLD (__open_tiff__, args, nargout,
@@ -192,34 +311,7 @@
     }
 
 
-    octave_value tag_data_ov;
-    // TIFFFieldReadCount returns VARIABLE for some scalar tags (e.g. Compression)
-    // But TIFFFieldPassCount seems consistent
-    if (!TIFFFieldPassCount(fip))
-    {
-        // TODO(maged): test this function vs actual data type size
-        int type_size = TIFFDataWidth(TIFFFieldDataType(fip));
-        void *data = _TIFFmalloc(type_size);
-        // TODO(maged): This won't always work, e.g. string exepcts char **
-        if (TIFFGetField(tif, tag_ID, data))
-        {
-            tag_data_ov = interpret_data(data, 1, TIFFFieldDataType(fip));
-            _TIFFfree(data);
-        }
-        else
-        {
-            _TIFFfree(data);
+    octave_value_list tag_data_ovl = get_field_data(tif, fip);
 
-            // TODO(maged): Give a better error message?
-            error("Failed to read tag");
-        }
-        
-    }
-    else
-    {
-        // TODO(maged): Implement support for variable read argument tags
-        error("Variable argument tags not implemented");
-    }
-
-    return octave_value_list (octave_value(tag_data_ov));
+    return tag_data_ovl;
 }