# HG changeset patch # User magedrifaat # Date 1661990180 -7200 # Node ID 1604c8812b67ac5ab82267ba9b49c6c6509f5ce4 # Parent 1da6d747bf78424d5379a68ac61f2cce08d23c8b Tiff: added numberOfDirectories method. diff -r 1da6d747bf78 -r 1604c8812b67 libinterp/corefcn/__tiff__.cc --- a/libinterp/corefcn/__tiff__.cc Thu Sep 01 00:10:37 2022 +0200 +++ b/libinterp/corefcn/__tiff__.cc Thu Sep 01 01:56:20 2022 +0200 @@ -129,12 +129,6 @@ } bool - is_numeric_scalar (octave_value ov) - { - return ov.isnumeric () && ov.isreal () && ov.is_scalar_type (); - } - - bool is_colormap (octave_value ov) { return ov.isnumeric () && ov.isreal () && ov.isfloat () @@ -3188,6 +3182,30 @@ #endif } + DEFUN (__tiff_number_of_directories__, args, , + "Get the number of tiles in the image") + { +#if defined (HAVE_TIFF) + int nargin = args.length (); + + if (nargin == 0) + error ("No handle provided\n"); + + octave_tiff_handle *tiff_handle + = octave_tiff_handle::get_tiff_handle (args(0)); + check_closed (tiff_handle); + + set_internal_handlers (); + + TIFF *tif = tiff_handle->get_file (); + + double dir_count = static_cast (TIFFNumberOfDirectories (tif)); + return ovl (dir_count); +#else + err_disabled_feature ("numberOfDirectories", "Tiff"); +#endif + } + DEFUN (__tiff_compute_strip__, args, , "Get the strip index containing the given row") { diff -r 1da6d747bf78 -r 1604c8812b67 scripts/image/PKG_ADD --- a/scripts/image/PKG_ADD Thu Sep 01 00:10:37 2022 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,7 +0,0 @@ -if __have_feature__ ("TIFF") - format = imformats("tif"); - format.read = @__tiff_imread__; - format.write = @__tiff_imwrite__; - format.info = @__tiff_imfinfo__; - imformats("update", "tif", format); -endif \ No newline at end of file diff -r 1da6d747bf78 -r 1604c8812b67 scripts/image/private/__tiff_imread__.m --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/scripts/image/private/__tiff_imread__.m Thu Sep 01 01:56:20 2022 +0200 @@ -0,0 +1,150 @@ +function [A, cmap, alpha] = __tiff_imread__ (filename, varargin) + img = Tiff (filename); + dir_count = img.numberOfDirectories (); + + ## A lot of the input sanitising logic here is copied from + ## scripts/image/__imread__.m and adapted to the needs of the Tiff + ## interface + + pages = [1]; + offset = 1; + if (nargin > 1 && ! ischar (varargin{1})) + if (! is_valid_index_option (varargin {1})) + error ("imread: IDX must be a numeric vector"); + endif + pages = varargin{1}; + offset = 2; + endif + + if (rem (numel (varargin) - offset + 1, 2) != 0) + error ("imread: PARAM/VALUE arguments must occur in pairs"); + endif + + ## Check for Index/Frames argument + idx = strcmpi ("index", varargin) | strcmpi ("frames", varargin); + if (any (idx)) + if (sum (idx) > 1) + error ("imread: Index or Frames may only be specified once"); + endif + val = varargin{circshift (idx, 1)}; + if (! is_valid_index_option (val) && ! strcmpi (val, "all")) + error ("imread: %s must be a vector or the string 'all'", varargin{idx}); + endif + if (strcmpi (val, "all")) + pages = 1:dir_count; + else + pages = val; + endif + endif + + if (any ((pages < 1) | (pages > dir_count))) + error ("imread: index/frames specified are outside the number of images"); + endif + + img.setDirectory (pages(1)); + info = get_image_info (img); + + ## Verify that all images have the same dimensions, number of channels, + ## bit-depth, and data type + for page_idx = 2:numel (pages) + img.setDirectory (pages(page_idx)); + dir_info = get_image_info (img); + if (info.width != dir_info.width || info.height != dir_info.height) + error ("imread: all frames must have the same size but frame %d is different", + pages(page_idx)); + endif + if (info.bitdepth != dir_info.bitdepth) + error ("imread: all frames must have the same bit depth but frame %d is different", + pages(page_idx)); + endif + if (info.nchannels != dir_info.nchannels) + error ("imread: all frames must have the same number of channels but frame %d is different", + pages(page_idx)); + endif + if (info.datatype != dir_info.datatype) + error ("imread: all frames must have the same data type but frame %d is different", + pages(page_idx)); + endif + if (info.photometric != dir_info.photometric) + error ("imread: all frames must have the same photometric interpretation but frame %d is different", + pages(page_idx)); + endif + endfor + + region = {1:info.height, 1:info.width}; + for idx = offset:2:(numel (varargin) - offset + 1) + switch (tolower (varargin{idx})) + + case {"frames", "index"} + ## Do nothing. This option was already processed before the loop. + + case "pixelregion" + region = varargin{idx+1}; + if (! iscell (region) || numel (region) != 2) + error ("imread: %s must be a 2-element cell array", + varargin{idx}); + endif + for reg_idx = 1:2 + if (numel (region{reg_idx}) == 3) + ## do nothing + elseif (numel (region{reg_idx}) == 2) + region{reg_idx}(3) = region{reg_idx}(2); + region{reg_idx}(2) = 1; + else + error ("imread: range for %s must be a 2 or 3 element vector", + varargin{idx}); + endif + region{reg_idx} = floor (region{reg_idx}(1)): ... + floor (region{reg_idx}(2)): ... + floor (region{reg_idx}(3)); + endfor + if (region{1}(end) > info.height) + error ("imread: end ROWS for PixelRegions option is larger than image height"); + elseif (region{2}(end) > info.width) + error ("imread: end COLS for PixelRegions option is larger than image width"); + endif + + case "info" + ## We ignore this option. This parameter exists in Matlab to + ## speed up the reading of multipage TIFF by passing a structure + ## that contains information about the start on the file of each + ## page. We can't control it through GraphicsMagic but at least + ## we allow to load multiple pages with one command. + + otherwise + error ("imread: invalid PARAMETER '%s'", varargin{idx}); + + endswitch + endfor + + A = []; + cmap = []; + alpha = []; + for page_idx = 1:numel(pages) + img.setDirectory (pages(page_idx)); + ## FIXME: This an ineffecient way to read pixel regions because it + ## always reads the entire image first. A better way is to figure + ## out which strips/tiles are needed for the region and read only those. + data = img.read (); + data = data (region{1}, region{2}, :); + A = cat (4, A, data); + if (info.photometric == Tiff.Photometric.Palette) + cmap = cat (3, cmap, img.getTag (Tiff.TagID.ColorMap)); + endif + endfor + + img.close (); +endfunction + +function bool = is_valid_index_option (arg) + bool = isvector (arg) && isnumeric (arg) && isreal (arg); +endfunction + +function info = get_image_info (img) + info.height = img.getTag (Tiff.TagID.ImageLength); + info.width = img.getTag (Tiff.TagID.ImageWidth); + info.bitdepth = img.getTag (Tiff.TagID.BitsPerSample); + info.nchannels = img.getTag (Tiff.TagID.BitsPerSample); + info.datatype = img.getTag (Tiff.TagID.SampleFormat); + info.photometric = img.getTag (Tiff.TagID.Photometric); +endfunction \ No newline at end of file diff -r 1da6d747bf78 -r 1604c8812b67 scripts/io/Tiff.m --- a/scripts/io/Tiff.m Thu Sep 01 00:10:37 2022 +0200 +++ b/scripts/io/Tiff.m Thu Sep 01 01:56:20 2022 +0200 @@ -211,6 +211,10 @@ numTiles = __tiff_number_of_tiles__ (t.tiff_handle); endfunction + function numDirs = numberOfDirectories (t) + numDirs = __tiff_number_of_directories__ (t.tiff_handle); + endfunction + function stripNumber = computeStrip (t, varargin) stripNumber = __tiff_compute_strip__ (t.tiff_handle, varargin{:}); endfunction