Mercurial > octave-libtiff
changeset 31150:6bede2d6f273
Tiff: added computeStrip and computeTile methods
* Tiff.m: added computeStrip and computeTile methods to the tiff class
and added tests for the twwo methods.
* __tiff__.cc: added the internal function that implements the two methods.
author | magedrifaat <magedrifaat@gmail.com> |
---|---|
date | Mon, 01 Aug 2022 00:34:34 +0200 |
parents | d4dbc69f301e |
children | 6fb54834aa93 |
files | libinterp/dldfcn/__tiff__.cc scripts/io/Tiff.m |
diffstat | 2 files changed, 202 insertions(+), 28 deletions(-) [+] |
line wrap: on
line diff
--- a/libinterp/dldfcn/__tiff__.cc Sun Jul 31 22:32:02 2022 +0200 +++ b/libinterp/dldfcn/__tiff__.cc Mon Aug 01 00:34:34 2022 +0200 @@ -1226,11 +1226,11 @@ error ("No filename supplied\n"); } - std::string filename = args (0).string_value (); + std::string filename = args(0).string_value (); std::string mode = "r"; if (nargin == 2) - mode = args (1).string_value (); + mode = args(1).string_value (); const std::vector<std::string> supported_modes {"r", "w", "w8", "a"}; @@ -1267,7 +1267,7 @@ if (nargin == 0) error ("No handle provided\n"); - TIFF *tif = (TIFF *)(args (0).uint64_value ()); + TIFF *tif = (TIFF *)(args(0).uint64_value ()); TIFFClose (tif); return octave_value_list (); @@ -1289,14 +1289,14 @@ if (nargin < 2) error ("No tag name provided\n"); - TIFF *tif = (TIFF *)(args (0).uint64_value ()); + TIFF *tif = (TIFF *)(args(0).uint64_value ()); uint32_t tag_id; const TIFFField *fip; - if (args (1).is_string ()) + if (args(1).is_string ()) { - std::string tagName = args (1).string_value (); + std::string tagName = args(1).string_value (); fip = TIFFFieldWithName (tif, tagName.c_str ()); if (! fip) error ("Tiff tag not found"); @@ -1305,7 +1305,7 @@ } else { - tag_id = args (1).int_value (); + tag_id = args(1).int_value (); fip = TIFFFieldWithTag (tif, tag_id); if (! fip) @@ -1328,11 +1328,11 @@ if (nargin < 2) error ("Too few arguments provided\n"); - TIFF *tif = (TIFF *)(args (0).uint64_value ()); + TIFF *tif = (TIFF *)(args(0).uint64_value ()); - if (args (1).isstruct ()) + if (args(1).isstruct ()) { - octave_scalar_map tags = args (1).scalar_map_value (); + octave_scalar_map tags = args(1).scalar_map_value (); string_vector keys = tags.fieldnames (); // Using iterators instead of this loop method seems to process // the elements of the struct in a different order than they were @@ -1354,22 +1354,22 @@ const TIFFField *fip; // TODO(maged): matlab actually checks for its own strings not LibTIFF's - if (args (1).is_string ()) + if (args(1).is_string ()) { - std::string tagName = args (1).string_value (); + std::string tagName = args(1).string_value (); fip = TIFFFieldWithName (tif, tagName.c_str ()); if (! fip) error ("Tiff tag not found"); } else { - uint32_t tag_id = args (1).int_value (); + uint32_t tag_id = args(1).int_value (); fip = TIFFFieldWithTag (tif, tag_id); if (! fip) error ("Tiff tag not found"); } - set_field_data (tif, fip, args (2)); + set_field_data (tif, fip, args(2)); } return octave_value_list (); @@ -1387,7 +1387,7 @@ if (nargin == 0) error ("No handle provided\n"); - TIFF *tif = (TIFF *)(args (0).uint64_value ()); + TIFF *tif = (TIFF *)(args(0).uint64_value ()); // TODO(maged): nargout and ycbcr octave_unused_parameter (nargout); @@ -1456,7 +1456,7 @@ if (nargin < 3) error ("Too few arguments provided\n"); - TIFF *tif = (TIFF *)(args (0).uint64_value ()); + TIFF *tif = (TIFF *)(args(0).uint64_value ()); // TODO(maged): check on windows if (TIFFGetMode (tif) == O_RDONLY) @@ -1468,7 +1468,7 @@ if (image_data.is_tiled) error ("Can't write strips to a tiled image"); - uint32_t strip_no = args (1).uint32_scalar_value (); + uint32_t strip_no = args(1).uint32_scalar_value (); if (strip_no < 1 || strip_no > TIFFNumberOfStrips (tif)) error ("Strip number out of range"); @@ -1490,7 +1490,7 @@ if (nargin < 3) error ("Too few arguments provided\n"); - TIFF *tif = (TIFF *)(args (0).uint64_value ()); + TIFF *tif = (TIFF *)(args(0).uint64_value ()); // TODO(maged): check on windows if (TIFFGetMode (tif) == O_RDONLY) @@ -1502,7 +1502,7 @@ if (! image_data.is_tiled) error ("Can't write tiles to a stripped image"); - uint32_t tile_no = args (1).uint32_scalar_value (); + uint32_t tile_no = args(1).uint32_scalar_value (); if (tile_no < 1 || tile_no > TIFFNumberOfTiles (tif)) error ("Tile number out of range"); @@ -1514,7 +1514,7 @@ #endif } - DEFUN_DLD (__is_tiled__, args, , + DEFUN_DLD (__tiff_is_tiled__, args, , "Get whether the image is tiled") { #if defined (HAVE_TIFF) @@ -1523,15 +1523,15 @@ if (nargin == 0) error ("No handle provided\n"); - TIFF *tif = (TIFF *)(args (0).uint64_value ()); + TIFF *tif = (TIFF *)(args(0).uint64_value ()); bool is_tiled = static_cast<bool> (TIFFIsTiled (tif)); return octave_value_list (octave_value (is_tiled)); #else - err_disabled_feature ("close", "Tiff"); + err_disabled_feature ("isTiled", "Tiff"); #endif } - DEFUN_DLD (__number_of_strips__, args, , + DEFUN_DLD (__tiff_number_of_strips__, args, , "Get the number of strips in the image") { #if defined (HAVE_TIFF) @@ -1540,14 +1540,122 @@ if (nargin == 0) error ("No handle provided\n"); - TIFF *tif = (TIFF *)(args (0).uint64_value ()); + TIFF *tif = (TIFF *)(args(0).uint64_value ()); + // What is the behavior in matlab? if (TIFFIsTiled (tif)) error ("The image is tiled not stripped"); double strip_count = static_cast<double> (TIFFNumberOfStrips (tif)); return octave_value_list (octave_value (strip_count)); #else - err_disabled_feature ("close", "Tiff"); + err_disabled_feature ("numberOfStrips", "Tiff"); +#endif + } + + DEFUN_DLD (__tiff_compute_strip__, args, , + "Get the strip index containing the given row") + { +#if defined (HAVE_TIFF) + int nargin = args.length (); + + if (nargin < 2 || nargin > 3) + error ("Wrong number of arguments\n"); + + TIFF *tif = (TIFF *)(args(0).uint64_value ()); + // What is the behavior in matlab? + if (TIFFIsTiled (tif)) + error ("The image is tiled not stripped"); + + tiff_image_data image_data (tif); + + uint32_t row = args(1).uint32_scalar_value (); + if (row > image_data.height) + row = image_data.height; + + // Convert from 1-based to zero-based indexing but avoid underflow + if (row > 0) + row--; + + uint16_t plane; + if (nargin > 2) + { + plane = args(2).uint16_scalar_value (); + if (plane > image_data.samples_per_pixel) + plane = image_data.samples_per_pixel; + if (plane > 0) + plane--; + } + else + { + plane = 0; + } + + // TODO(maged): What is the behavior in matlab for using/not using plane? + // TODO(maged): what is the behavior for out of bounds? + double strip_number = TIFFComputeStrip (tif, row, plane) + 1; + if (strip_number > TIFFNumberOfStrips (tif)) + strip_number = TIFFNumberOfStrips (tif); + return octave_value_list (octave_value (strip_number)); +#else + err_disabled_feature ("computeStrip", "Tiff"); +#endif + } + + DEFUN_DLD (__tiff_compute_tile__, args, , + "Get the tile index containing the given row and column") + { +#if defined (HAVE_TIFF) + int nargin = args.length (); + + if (nargin < 2 || nargin > 3) + error ("Wrong number of arguments\n"); + + TIFF *tif = (TIFF *)(args(0).uint64_value ()); + // What is the behavior in matlab? + if (! TIFFIsTiled (tif)) + error ("The image is stripped not tiled"); + + uint32NDArray coords = args(1).uint32_array_value (); + if (coords.dim2() < 2) + error ("Coordinates must be in the shape [row, col]"); + uint32_t row = coords(0, 0); + uint32_t col = coords(0, 1); + + tiff_image_data image_data (tif); + + if (col > image_data.width) + col = image_data.width; + if (row > image_data.height) + row = image_data.height; + + // Convert from 1-based to zero-based indexing but avoid underflow + if (row > 0) + row--; + if (col > 0) + col--; + + uint16_t plane; + if (nargin > 2) + { + plane = args(2).uint16_scalar_value (); + if (plane > image_data.samples_per_pixel) + plane = image_data.samples_per_pixel; + if (plane > 0) + plane--; + } + else + { + plane = 0; + } + + // TODO(maged): What is the behavior in matlab for using/not using plane? + // TODO(maged): what is the behavior for out of bounds? + double tile_number = TIFFComputeTile (tif, col, row, 0, plane) + 1; + if (tile_number > TIFFNumberOfTiles (tif)) + tile_number = TIFFNumberOfTiles (tif); + return octave_value_list (octave_value (tile_number)); +#else + err_disabled_feature ("computeTile", "Tiff"); #endif }
--- a/scripts/io/Tiff.m Sun Jul 31 22:32:02 2022 +0200 +++ b/scripts/io/Tiff.m Mon Aug 01 00:34:34 2022 +0200 @@ -134,14 +134,28 @@ if (t.closed) error ("Image file was closed"); endif - tf = __is_tiled__ (t.tiff_handle); + tf = __tiff_is_tiled__ (t.tiff_handle); endfunction function numStrips = numberOfStrips (t) if (t.closed) error ("Image file was closed"); endif - numStrips = __number_of_strips__ (t.tiff_handle); + numStrips = __tiff_number_of_strips__ (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 % TODO(maged): add documentation and make print_usage work @@ -795,4 +809,56 @@ %! setTag (img, "TileWidth", 16); %! fail ("numberOfStrips (img)", "The image is tiled not stripped"); %! endfunction -%! file_wrapper (@test_fn); \ No newline at end of file +%! file_wrapper (@test_fn); + +## test computeStrip returns the correct value +%!testif HAVE_TIFF +%! function test_fn (filename) +%! img = Tiff (filename, "w"); +%! setTag (img, struct ("ImageWidth", 10, "ImageLength", 10, +%! "RowsPerStrip", 2, "BitsPerSample", 8, +%! "SamplesPerPixel", 3, "PlanarConfiguration", 1)); +%! assert (computeStrip (img, 1), 1); +%! assert (computeStrip (img, 2), 1); +%! assert (computeStrip (img, 0), 1); +%! assert (computeStrip (img, 10), 5); +%! assert (computeStrip (img, 11), 5); +%! setTag (img, "PlanarConfiguration", 2); +%! ## This is need for the tag to take effect, should be +%! ## replaced by rewriteDirectory +%! writeEncodedStrip (img, 1, uint8 (reshape (1:20, [2, 10]))); +%! assert (computeStrip (img, 1, 2), 6); +%! assert (computeStrip (img, 100, 1), 5); +%! img = Tiff ("test.tif", "w"); +%! setTag (img, "TileWidth", 16); +%! setTag (img, "TileLength", 16); +%! fail ("computeStrip (img, 1, 1)", "The image is tiled not stripped"); +%! endfunction +%! file_wrapper (@test_fn); + +## test computeTile returns the correct value +%!testif HAVE_TIFF +%! function test_fn (filename) +%! img = Tiff (filename, "w"); +%! setTag (img, struct ("ImageWidth", 20, "ImageLength", 20, +%! "BitsPerSample", 8, "SamplesPerPixel", 3, +%! "TileLength", 16, "TileWidth", 16, +%! "PlanarConfiguration", 1)); +%! assert (computeTile (img, [1, 1]), 1); +%! assert (computeTile (img, [2, 2]), 1); +%! assert (computeTile (img, [0, 0]), 1); +%! assert (computeTile (img, [8, 17]), 2); +%! assert (computeTile (img, [19, 10]), 3); +%! assert (computeTile (img, [17, 17]), 4); +%! assert (computeTile (img, [100, 100]), 4); +%! setTag (img, "PlanarConfiguration", 2); +%! ## This is need for the tag to take effect, should be +%! ## replaced by rewriteDirectory +%! writeEncodedTile (img, 1, uint8 (reshape (1:256, [16, 16]))); +%! assert (computeTile (img, [1, 1], 2), 5); +%! assert (computeTile (img, [100, 100], 1), 4); +%! img = Tiff ("test.tif", "w"); +%! fail ("computeTile (img, 1, 1)", "The image is stripped not tiled"); +%! endfunction +%! file_wrapper (@test_fn); +