# HG changeset patch # User magedrifaat # Date 1660404972 -7200 # Node ID 72a159bc5a4ca44410c8448578db3c04dd09d519 # Parent ae41e14bf5c7571cfd5e8ff8ca4081951e70e951 Tiff: added readRGBAImage method to read image using the RGBA interface * __tiff__.cc(F__tiff_reag_rgba_image__): implemented logic for reading images using LibTIFF's RGBA interface. * Tiff.m: added method readRGBAImage and added unit tests for the new method. diff -r ae41e14bf5c7 -r 72a159bc5a4c libinterp/corefcn/__tiff__.cc --- a/libinterp/corefcn/__tiff__.cc Sat Aug 13 02:45:51 2022 +0200 +++ b/libinterp/corefcn/__tiff__.cc Sat Aug 13 17:36:12 2022 +0200 @@ -2272,7 +2272,7 @@ int nargin = args.length (); if (nargin != 2) - error ("rong number of arguments"); + error ("Wrong number of arguments"); TIFF *tif = (TIFF *)(args(0).uint64_value ()); @@ -2307,7 +2307,7 @@ int nargin = args.length (); if (nargin != 2) - error ("rong number of arguments"); + error ("Wrong number of arguments"); TIFF *tif = (TIFF *)(args(0).uint64_value ()); @@ -2335,6 +2335,50 @@ #endif } + DEFUN (__tiff_read_rgba_image__, args, , + "Read the image data in rgba mode") + { +#if defined (HAVE_TIFF) + int nargin = args.length (); + + if (nargin != 1) + error ("Wrong number of arguments"); + + TIFF *tif = (TIFF *)(args(0).uint64_value ()); + + tiff_image_data image_data (tif); + + dim_vector img_dims (4, image_data.width, image_data.height); + uint8NDArray img (img_dims); + uint32_t *img_ptr = reinterpret_cast (img.fortran_vec ()); + // Matlab (R2022a) uses a top-left orientation ignoring the tag if present + if (! TIFFReadRGBAImageOriented (tif, image_data.width, image_data.height, + img_ptr, 1)) + error ("Failed to read image"); + + Array perm (dim_vector (3, 1)); + perm(0) = 2; + perm(1) = 1; + perm(2) = 0; + img = img.permute (perm); + + Array idx (dim_vector (3, 1)); + idx(0) = idx_vector (':'); + idx(1) = idx_vector (':'); + idx(2) = idx_vector (0, 3); + uint8NDArray rgb = uint8NDArray (img.index (idx)); + idx(2) = idx_vector (3); + uint8NDArray alpha = uint8NDArray (img.index (idx)); + + octave_value_list retval (2); + retval(0) = octave_value (rgb); + retval(1) = octave_value (alpha); + return retval; +#else + err_disabled_feature ("readEncodedTile", "Tiff"); +#endif + } + DEFUN (__tiff_write__, args, , "Write the image data to the current IFD") { diff -r ae41e14bf5c7 -r 72a159bc5a4c scripts/io/Tiff.m --- a/scripts/io/Tiff.m Sat Aug 13 02:45:51 2022 +0200 +++ b/scripts/io/Tiff.m Sat Aug 13 17:36:12 2022 +0200 @@ -253,6 +253,13 @@ 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 write (t, imageData) if (t.closed) error ("Image file was closed"); @@ -1450,3 +1457,40 @@ %! img.close(); %! endfunction %! file_wrapper (@test_fn); + +## test readRGBAImage +%!testif HAVE_TIFF +%! function test_fn (filename) +%! img = Tiff (filename, "w"); +%! setTag(img, struct ( +%! "ImageLength", 10, "ImageWidth", 10, +%! "BitsPerSample", 8, "SamplesPerPixel", 3, +%! "PhotometricInterpretation", 2, +%! "PlanarConfiguration", 1 +%! )); +%! data = uint8 (reshape (1:300, [10, 10, 3])); +%! write (img, data); +%! [rgb, alpha] = readRGBAImage (img); +%! assert (rgb, data); +%! assert (alpha, uint8 (repmat ([255], [10, 10]))); +%! endfunction +%! file_wrapper (@test_fn); + +## test readRGBAImage with alpha +%!testif HAVE_TIFF +%! function test_fn (filename) +%! img = Tiff (filename, "w"); +%! setTag(img, struct ( +%! "ImageLength", 10, "ImageWidth", 10, +%! "BitsPerSample", 8, "SamplesPerPixel", 4, +%! "PhotometricInterpretation", 2, +%! "PlanarConfiguration", 1, +%! "ExtraSamples", 1 +%! )); +%! data = uint8 (randi ([0,255], [10, 10, 4])); +%! write (img, data); +%! [rgb, alpha] = readRGBAImage (img); +%! assert (rgb, data(:,:,1:3)); +%! assert (alpha, data(:,:,4)); +%! endfunction +%! file_wrapper (@test_fn);