changeset 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
files libinterp/corefcn/__tiff__.cc scripts/io/Tiff.m
diffstat 2 files changed, 174 insertions(+), 106 deletions(-) [+]
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 ())
--- a/scripts/io/Tiff.m	Wed Aug 17 01:57:24 2022 +0200
+++ b/scripts/io/Tiff.m	Wed Aug 17 18:51:16 2022 +0200
@@ -1,6 +1,6 @@
 ## PKG_ADD: __tiff_set_errors_enabled__ (false);
 
-classdef Tiff < handle
+classdef Tiff
   properties (Constant = true)
     TagID = struct (
       "SubFileType", 254,
@@ -198,7 +198,6 @@
 
   properties (Access = private)
     tiff_handle;
-    closed=false;
   endproperties
 
   methods
@@ -212,170 +211,98 @@
     endfunction
 
     function close (t)
-      if (! t.closed)
-        __close_tiff__ (t.tiff_handle);
-        t.closed = true;
-      endif
+      __close_tiff__ (t.tiff_handle);
     endfunction
 
     function tag = getTag (t, tag_name)
-      if (t.closed)
-        error ("Image file was closed");
-      endif
       tag = __tiff_get_tag__ (t.tiff_handle, tag_name);
     endfunction
 
     function setTag (t, varargin)
-      if (t.closed)
-        error ("Image file was closed");
-      endif
       __tiff_set_tag__ (t.tiff_handle, varargin{:});
     endfunction
 
     function argout = read (t)
-      if (t.closed)
-        error ("Image file was closed");
-      endif
       argout = __tiff_read__ (t.tiff_handle);
     endfunction
 
     function stripData = readEncodedStrip (t, stripNumber)
-      if (t.closed)
-        error ("Image file was closed");
-      endif
       stripData = __tiff_read_encoded_strip__ (t.tiff_handle, stripNumber);
     endfunction
 
     function tileData = readEncodedTile (t, tileNumber)
-      if (t.closed)
-        error ("Image file was closed");
-      endif
       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 [RGB, alpha] = readRGBAStrip (t, row)
-      if (t.closed)
-        error ("Image file was closed");
-      endif
       [RGB, alpha] = __tiff_read_rgba_strip__ (t.tiff_handle, row);
     endfunction
 
     function [RGB, alpha] = readRGBATile (t, row, col)
-      if (t.closed)
-        error ("Image file was closed");
-      endif
       [RGB, alpha] = __tiff_read_rgba_tile__ (t.tiff_handle, row, col);
     endfunction
 
     function write (t, imageData)
-      if (t.closed)
-        error ("Image file was closed");
-      endif
       __tiff_write__ (t.tiff_handle, imageData);
     endfunction
 
     function writeEncodedStrip (t, stripNumber, imageData)
-      if (t.closed)
-        error ("Image file was closed");
-      endif
       __tiff_write_encoded_strip__ (t.tiff_handle, stripNumber, imageData);
     endfunction
 
     function writeEncodedTile (t, tileNumber, imageData)
-      if (t.closed)
-        error ("Image file was closed");
-      endif
       __tiff_write_encoded_tile__ (t.tiff_handle, tileNumber, imageData);
     endfunction
 
     function tf = isTiled (t)
-      if (t.closed)
-        error ("Image file was closed");
-      endif
       tf = __tiff_is_tiled__ (t.tiff_handle);
     endfunction
 
     function numStrips = numberOfStrips (t)
-      if (t.closed)
-        error ("Image file was closed");
-      endif
       numStrips = __tiff_number_of_strips__ (t.tiff_handle);
     endfunction
 
     function numTiles = numberOfTiles (t)
-      if (t.closed)
-        error ("Image file was closed");
-      endif
       numTiles = __tiff_number_of_tiles__ (t.tiff_handle);
     endfunction
 
     function stripNumber = computeStrip (t, varargin)
-      if (t.closed)
-        error ("Image file was closed");
-      endif
       stripNumber = __tiff_compute_strip__ (t.tiff_handle, varargin{:});
     endfunction
 
     function tileNumber = computeTile (t, varargin)
-      if (t.closed)
-        error ("Image file was closed");
-      endif
       tileNumber = __tiff_compute_tile__ (t.tiff_handle, varargin{:});
     endfunction
 
     function dirNum = currentDirectory (t)
-      if (t.closed)
-        error ("Image file was closed");
-      endif
       dirNum = __tiff_current_directory__ (t.tiff_handle);
     endfunction
 
     function isLast = lastDirectory (t)
-      if (t.closed)
-        error ("Image file was closed");
-      endif
       isLast = __tiff_last_directory__ (t.tiff_handle);
     endfunction
 
     function nextDirectory (t)
-      if (t.closed)
-        error ("Image file was closed");
-      endif
       __tiff_next_directory__ (t.tiff_handle);
     endfunction
 
     function setDirectory (t, dirNum)
-      if (t.closed)
-        error ("Image file was closed");
-      endif
       __tiff_set_directory__ (t.tiff_handle, dirNum);
     endfunction
 
     function writeDirectory (t)
-      if (t.closed)
-        error ("Image file was closed");
-      endif
       __tiff_write_directory__ (t.tiff_handle);
     endfunction
 
     function rewriteDirectory (t)
-      if (t.closed)
-        error ("Image file was closed");
-      endif
       __tiff_rewrite_directory__ (t.tiff_handle);
     endfunction
 
     function setSubDirectory (t, offset)
-      if (t.closed)
-        error ("Image file was closed");
-      endif
       __tiff_set_sub_directory__ (t.tiff_handle, offset);
     endfunction