diff libinterp/corefcn/__tiff__.cc @ 31177:c7c79973007f

Tiff: added octave_tiff_handle class to wrap the Tiff file pointer * __tiff__.cc (octave_tiff_handle): implemented a new class octave_tiff_handle as a child of octave_base_value to be a wrapper for the Tiff file handle to be passed to Octave instead of passing a pointer around. * __tiff__.cc (F__open_tiff__, F__tiff_close__): modified handling TIFF file pointer to use the new class (Other internal functions were modified as well). * Tiff.m: removed checking for closed file, it is now handled internally.
author magedrifaat <magedrifaat@gmail.com>
date Wed, 17 Aug 2022 18:51:16 +0200
parents c07461ca34d6
children 14edd6b09efe
line wrap: on
line diff
--- a/libinterp/corefcn/__tiff__.cc	Wed Aug 17 01:57:24 2022 +0200
+++ b/libinterp/corefcn/__tiff__.cc	Wed Aug 17 18:51:16 2022 +0200
@@ -23,6 +23,49 @@
 namespace octave
 {
 #if defined (HAVE_TIFF)
+  class OCTINTERP_API octave_tiff_handle : public octave_base_value
+  {
+  public:
+    octave_tiff_handle (TIFF *tif)
+      : tiff_file (tif), closed (false)
+    { }
+
+    TIFF *get_file(void) { return tiff_file; }
+
+    bool is_defined (void) const { return true; }
+    bool is_constant (void) const { return true; }
+
+    void close(void)
+    {
+      if (! closed)
+        {
+          closed = true;
+          TIFFClose (tiff_file);
+        }
+    }
+
+    bool is_closed (void) { return closed; }
+
+    ~octave_tiff_handle (void)
+    {
+      if (! closed)
+        close ();
+    }
+
+    static octave_tiff_handle *
+    get_tiff_handle (const octave_value& ov)
+    {
+      octave_base_value *rep = ov.internal_rep ();
+      octave_tiff_handle *handle = dynamic_cast<octave_tiff_handle *> (rep);
+      if (! handle)
+        error ("get_tiff_handle: dynamic_cast to octave_tiff_handle failed");
+      
+      return handle;
+    }
+  private:
+    TIFF *tiff_file;
+    bool closed;
+  };
 
   struct tiff_image_data
   {
@@ -65,13 +108,17 @@
   void
   check_readonly (TIFF *tif)
   {
-    // This can't use O_RDONLY directly because its header file "fcntl.h"
-    // isn't available on Windows. The wrapper, however, seems to return
-    // the right thing even on Windows.
     if (TIFFGetMode (tif) == octave_o_rdonly_wrapper ())
       error ("Can't write data to a file opened in read-only mode");
   }
 
+  void
+  check_closed (octave_tiff_handle *tiff_handle)
+  {
+    if (tiff_handle->is_closed ())
+      error ("The image file was closed");
+  }
+
   // Error if status is not 1 (success status for TIFFGetField)
   void
   validate_tiff_get_field (bool status, void *p_to_free=NULL)
@@ -2080,8 +2127,7 @@
     if (is_rplus && ! TIFFSetDirectory (tif, 0))
       error ("Failed to open Tiff file\n");
 
-    // TODO(maged): use inheritance of octave_base_value instead
-    octave_value tiff_ov = octave_value ((uint64_t)tif);
+    octave_value tiff_ov = octave_value (new octave_tiff_handle (tif));
     return octave_value_list (tiff_ov);
 #else
     octave_unused_parameter (args);
@@ -2099,8 +2145,10 @@
     if (nargin == 0)
       error ("No handle provided\n");
     
-    TIFF *tif = (TIFF *)(args(0).uint64_value ());
-    TIFFClose (tif);
+    octave_tiff_handle *tiff_handle
+      = octave_tiff_handle::get_tiff_handle (args(0));
+    
+    tiff_handle->close ();
 
     return octave_value_list ();
 #else
@@ -2110,7 +2158,7 @@
 
 
   DEFUN (__tiff_get_tag__, args, ,
-             "Get the value of a tag from a tiff image")
+         "Get the value of a tag from a tiff image")
   {
 #if defined (HAVE_TIFF)
     int nargin = args.length ();
@@ -2121,7 +2169,12 @@
     if (nargin < 2)
       error ("No tag name provided\n");
     
-    TIFF *tif = (TIFF *)(args(0).uint64_value ());
+    octave_tiff_handle *tiff_handle
+      = octave_tiff_handle::get_tiff_handle (args(0));
+    
+    check_closed (tiff_handle);
+
+    TIFF *tif = tiff_handle->get_file ();
 
     uint32_t tag_id;
     const TIFFField *fip;
@@ -2160,8 +2213,11 @@
     if (nargin < 2)
       error ("Too few arguments provided\n");
     
-    TIFF *tif = (TIFF *)(args(0).uint64_value ());
+    octave_tiff_handle *tiff_handle
+      = octave_tiff_handle::get_tiff_handle (args(0));
+    check_closed (tiff_handle);
 
+    TIFF *tif = tiff_handle->get_file ();
     check_readonly (tif);
     
     if (args(1).isstruct ())
@@ -2222,7 +2278,11 @@
     if (nargin == 0)
       error ("No handle provided\n");
     
-    TIFF *tif = (TIFF *)(args(0).uint64_value ());
+    octave_tiff_handle *tiff_handle
+      = octave_tiff_handle::get_tiff_handle (args(0));
+    check_closed (tiff_handle);
+    
+    TIFF *tif = tiff_handle->get_file ();
 
     // TODO(maged): nargout and ycbcr
     octave_unused_parameter (nargout);
@@ -2290,7 +2350,11 @@
     if (nargin != 2)
       error ("Wrong number of arguments");
     
-    TIFF *tif = (TIFF *)(args(0).uint64_value ());
+    octave_tiff_handle *tiff_handle
+      = octave_tiff_handle::get_tiff_handle (args(0));
+    check_closed (tiff_handle);
+
+    TIFF *tif = tiff_handle->get_file ();
 
     // TODO(maged): nargout and ycbcr
     octave_unused_parameter (nargout);
@@ -2325,7 +2389,11 @@
     if (nargin != 2)
       error ("Wrong number of arguments");
     
-    TIFF *tif = (TIFF *)(args(0).uint64_value ());
+    octave_tiff_handle *tiff_handle
+      = octave_tiff_handle::get_tiff_handle (args(0));
+    check_closed (tiff_handle);
+
+    TIFF *tif = tiff_handle->get_file ();
 
     // TODO(maged): nargout and ycbcr
     octave_unused_parameter (nargout);
@@ -2360,7 +2428,11 @@
     if (nargin != 1)
       error ("Wrong number of arguments");
     
-    TIFF *tif = (TIFF *)(args(0).uint64_value ());
+    octave_tiff_handle *tiff_handle
+      = octave_tiff_handle::get_tiff_handle (args(0));
+    check_closed (tiff_handle);
+
+    TIFF *tif = tiff_handle->get_file ();
 
     tiff_image_data image_data (tif);
 
@@ -2424,7 +2496,11 @@
     if (nargin != 2)
       error ("Wrong number of arguments");
     
-    TIFF *tif = (TIFF *)(args(0).uint64_value ());
+    octave_tiff_handle *tiff_handle
+      = octave_tiff_handle::get_tiff_handle (args(0));
+    check_closed (tiff_handle);
+
+    TIFF *tif = tiff_handle->get_file ();
 
     // Matlab (R2022a) requires row to be double
     if (! args(1).is_double_type ())
@@ -2522,7 +2598,11 @@
     if (nargin != 3)
       error ("Wrong number of arguments");
     
-    TIFF *tif = (TIFF *)(args(0).uint64_value ());
+    octave_tiff_handle *tiff_handle
+      = octave_tiff_handle::get_tiff_handle (args(0));
+    check_closed (tiff_handle);
+
+    TIFF *tif = tiff_handle->get_file ();
 
     if (! args(1).is_double_type ())
       error ("row should be of type double");
@@ -2628,7 +2708,11 @@
     if (nargin < 2)
       error ("Wrong number of arguments\n");
     
-    TIFF *tif = (TIFF *)(args(0).uint64_value ());
+    octave_tiff_handle *tiff_handle
+      = octave_tiff_handle::get_tiff_handle (args(0));
+    check_closed (tiff_handle);
+
+    TIFF *tif = tiff_handle->get_file ();
 
     check_readonly (tif);
 
@@ -2720,7 +2804,11 @@
     if (nargin < 3)
       error ("Too few arguments provided\n");
     
-    TIFF *tif = (TIFF *)(args(0).uint64_value ());
+    octave_tiff_handle *tiff_handle
+      = octave_tiff_handle::get_tiff_handle (args(0));
+    check_closed (tiff_handle);
+
+    TIFF *tif = tiff_handle->get_file ();
 
     check_readonly (tif);
 
@@ -2752,7 +2840,11 @@
     if (nargin < 3)
       error ("Too few arguments provided\n");
     
-    TIFF *tif = (TIFF *)(args(0).uint64_value ());
+    octave_tiff_handle *tiff_handle
+      = octave_tiff_handle::get_tiff_handle (args(0));
+    check_closed (tiff_handle);
+
+    TIFF *tif = tiff_handle->get_file ();
 
     check_readonly (tif);
 
@@ -2783,7 +2875,12 @@
     if (nargin == 0)
       error ("No handle provided\n");
     
-    TIFF *tif = (TIFF *)(args(0).uint64_value ());
+    octave_tiff_handle *tiff_handle
+      = octave_tiff_handle::get_tiff_handle (args(0));
+    check_closed (tiff_handle);
+
+    TIFF *tif = tiff_handle->get_file ();
+    
     bool is_tiled = static_cast<bool> (TIFFIsTiled (tif));
     return octave_value_list (octave_value (is_tiled));
 #else
@@ -2800,7 +2897,11 @@
     if (nargin == 0)
       error ("No handle provided\n");
     
-    TIFF *tif = (TIFF *)(args(0).uint64_value ());
+    octave_tiff_handle *tiff_handle
+      = octave_tiff_handle::get_tiff_handle (args(0));
+    check_closed (tiff_handle);
+
+    TIFF *tif = tiff_handle->get_file ();
     
     if (TIFFIsTiled (tif))
       error ("The image is tiled not stripped");
@@ -2821,7 +2922,11 @@
     if (nargin == 0)
       error ("No handle provided\n");
     
-    TIFF *tif = (TIFF *)(args(0).uint64_value ());
+    octave_tiff_handle *tiff_handle
+      = octave_tiff_handle::get_tiff_handle (args(0));
+    check_closed (tiff_handle);
+
+    TIFF *tif = tiff_handle->get_file ();
     
     if (! TIFFIsTiled (tif))
       error ("The image is stripped not tiled");
@@ -2842,7 +2947,11 @@
     if (nargin < 2 || nargin > 3)
       error ("Wrong number of arguments\n");
     
-    TIFF *tif = (TIFF *)(args(0).uint64_value ());
+    octave_tiff_handle *tiff_handle
+      = octave_tiff_handle::get_tiff_handle (args(0));
+    check_closed (tiff_handle);
+
+    TIFF *tif = tiff_handle->get_file ();
     
     if (TIFFIsTiled (tif))
       error ("The image is tiled not stripped");
@@ -2893,7 +3002,11 @@
     if (nargin < 2 || nargin > 3)
       error ("Wrong number of arguments\n");
     
-    TIFF *tif = (TIFF *)(args(0).uint64_value ());
+    octave_tiff_handle *tiff_handle
+      = octave_tiff_handle::get_tiff_handle (args(0));
+    check_closed (tiff_handle);
+
+    TIFF *tif = tiff_handle->get_file ();
     
     if (! TIFFIsTiled (tif))
       error ("The image is stripped not tiled");
@@ -2953,7 +3066,11 @@
     if (nargin != 1)
       error ("Wrong number of arguments\n");
     
-    TIFF *tif = (TIFF *)(args(0).uint64_value ());
+    octave_tiff_handle *tiff_handle
+      = octave_tiff_handle::get_tiff_handle (args(0));
+    check_closed (tiff_handle);
+
+    TIFF *tif = tiff_handle->get_file ();
 
     uint16_t dir = TIFFCurrentDirectory (tif);
     dir++;
@@ -2973,7 +3090,11 @@
     if (nargin != 1)
       error ("Wrong number of arguments\n");
     
-    TIFF *tif = (TIFF *)(args(0).uint64_value ());
+    octave_tiff_handle *tiff_handle
+      = octave_tiff_handle::get_tiff_handle (args(0));
+    check_closed (tiff_handle);
+
+    TIFF *tif = tiff_handle->get_file ();
 
     bool is_last = TIFFLastDirectory (tif);
     
@@ -2992,7 +3113,11 @@
     if (nargin != 1)
       error ("Wrong number of arguments\n");
     
-    TIFF *tif = (TIFF *)(args(0).uint64_value ());
+    octave_tiff_handle *tiff_handle
+      = octave_tiff_handle::get_tiff_handle (args(0));
+    check_closed (tiff_handle);
+
+    TIFF *tif = tiff_handle->get_file ();
 
     bool is_last = TIFFLastDirectory (tif);
     if (is_last)
@@ -3016,7 +3141,11 @@
     if (nargin != 2)
       error ("Wrong number of arguments\n");
     
-    TIFF *tif = (TIFF *)(args(0).uint64_value ());
+    octave_tiff_handle *tiff_handle
+      = octave_tiff_handle::get_tiff_handle (args(0));
+    check_closed (tiff_handle);
+
+    TIFF *tif = tiff_handle->get_file ();
 
     uint16_t dir = args(1).uint16_scalar_value ();
     if (dir < 1 || dir > TIFFNumberOfDirectories (tif))
@@ -3042,7 +3171,11 @@
     if (nargin != 1)
       error ("Wrong number of arguments\n");
     
-    TIFF *tif = (TIFF *)(args(0).uint64_value ());
+    octave_tiff_handle *tiff_handle
+      = octave_tiff_handle::get_tiff_handle (args(0));
+    check_closed (tiff_handle);
+
+    TIFF *tif = tiff_handle->get_file ();
     
     if (! TIFFWriteDirectory(tif))
       error ("Failed to write directory");
@@ -3062,7 +3195,11 @@
     if (nargin != 1)
       error ("Wrong number of arguments\n");
     
-    TIFF *tif = (TIFF *)(args(0).uint64_value ());
+    octave_tiff_handle *tiff_handle
+      = octave_tiff_handle::get_tiff_handle (args(0));
+    check_closed (tiff_handle);
+
+    TIFF *tif = tiff_handle->get_file ();
 
     if (! TIFFRewriteDirectory(tif))
       error ("Failed to rewrite directory");
@@ -3082,7 +3219,11 @@
     if (nargin != 2)
       error ("Wrong number of arguments\n");
     
-    TIFF *tif = (TIFF *)(args(0).uint64_value ());
+    octave_tiff_handle *tiff_handle
+      = octave_tiff_handle::get_tiff_handle (args(0));
+    check_closed (tiff_handle);
+    
+    TIFF *tif = tiff_handle->get_file ();
     
     if (! args(1).is_double_type () && ! args(1).is_uint32_type ()
         && ! args(1).is_uint64_type ())