# HG changeset patch # User magedrifaat # Date 1660659010 -7200 # Node ID 0abc9779f751cf28e5a5b5058796dae9cfd2b710 # Parent 3f5f1404af8a25cb38bca9bcfd929828d22e9f88 Tiff: modified readRGBAImage to use the orientation tag correctly * __tiff__.cc (F__tiff_read_rgba_image__): modified the way the image is read to use the orientation tag in the correct way. diff -r 3f5f1404af8a -r 0abc9779f751 libinterp/corefcn/__tiff__.cc --- a/libinterp/corefcn/__tiff__.cc Sun Aug 14 21:02:58 2022 +0200 +++ b/libinterp/corefcn/__tiff__.cc Tue Aug 16 16:10:10 2022 +0200 @@ -796,6 +796,8 @@ octave_value retval; // Apparently matlab converts scalar numerical values into double // but doesn't do the same for arrays + // TODO(maged): matlab returns double for array tags as well, except + // for a selected set of tags (e.g. StripByteCounts) if (count == 1 && tag_datatype != TIFF_ASCII) { retval = interpret_scalar_tag_data (data, tag_datatype); @@ -2360,14 +2362,30 @@ tiff_image_data image_data (tif); + uint16_t orientation; + if (! TIFFGetFieldDefaulted (tif, TIFFTAG_ORIENTATION, &orientation)) + orientation = ORIENTATION_LEFTTOP; + // Start with reversed dimensions to be aligned with LibTIFF and // permute to the correct order later 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)) + + TIFFRGBAImage img_config; + char emsg[1024]; + if (! TIFFRGBAImageOK (tif, emsg) + || ! TIFFRGBAImageBegin (&img_config, tif, 0, emsg)) + error ("Failed to read image"); + + img_config.orientation = ORIENTATION_TOPLEFT; + img_config.req_orientation = orientation; + + bool success = TIFFRGBAImageGet (&img_config, img_ptr, img_config.width, + img_config.height); + + TIFFRGBAImageEnd (&img_config); + if (!success) error ("Failed to read image"); // Permute to the correct Octave dimension order @@ -2406,8 +2424,10 @@ TIFF *tif = (TIFF *)(args(0).uint64_value ()); - // TODO(maged): check matlab behavior for missing/ wrong/ out of bounds row - // matlab row must be double (scalar or array), and checks bounds + // Matlab (R2022a) requires row to be double + if (! args(1).is_double_type ()) + error ("row must be double"); + uint32_t row = args (1).uint32_scalar_value (); tiff_image_data image_data (tif); @@ -2486,6 +2506,7 @@ TIFF *tif = (TIFF *)(args(0).uint64_value ()); // TODO(maged): check matlab behavior for missing/ wrong/ out of bounds vals + // matlab checks bounds and requires double vals (scalar or array) uint32_t row = args (1).uint32_scalar_value (); uint32_t col = args (2).uint32_scalar_value (); @@ -2498,7 +2519,6 @@ if (col < 1 || col > image_data.width) error ("Column out of bounds of the image"); - // TODO(maged): check if matlab require the first row,col in tile as well // Convert from 1-based indexing to zero-based row--; col--; @@ -2523,6 +2543,7 @@ = reinterpret_cast (tile_data.fortran_vec ()); // TODO(maged): check if matlab does anything with orientation tag + // matlab uses orientation tag to correct the data if (! TIFFReadRGBATile (tif, col, row, tile_ptr)) error ("Failed to read tile"); @@ -2902,6 +2923,7 @@ TIFF *tif = (TIFF *)(args(0).uint64_value ()); // TODO(maged): check matlab behavior + // matlab returns double and handles the special case as 0! uint16_t dir = TIFFCurrentDirectory (tif); if (dir == (uint16_t)-1) dir = 0; @@ -2942,8 +2964,6 @@ TIFF *tif = (TIFF *)(args(0).uint64_value ()); - // TODO(maged): check if matlab handles this case different from - // an erronous next IFD bool is_last = TIFFLastDirectory (tif); if (is_last) error ("Current directory is the last directory"); @@ -2968,8 +2988,6 @@ TIFF *tif = (TIFF *)(args(0).uint64_value ()); - // TODO(maged): check matlab behavior for wrong argument type - // and out of bounds index uint16_t dir = args(1).uint16_scalar_value (); if (dir < 1 || dir > TIFFNumberOfDirectories (tif)) error ("Directory index out of bounds"); @@ -2995,8 +3013,8 @@ error ("Wrong number of arguments\n"); TIFF *tif = (TIFF *)(args(0).uint64_value ()); - // TODO(maged): check if matlab errors for leaving a corrupt directory - // Check if mtalab always writes directories at the end for both w and a (And r+) + // TODO(maged): Check if mtalab always writes directories at the end for both w and a (And r+) + // it does if (! TIFFWriteDirectory(tif)) error ("Failed to write directory"); @@ -3016,8 +3034,7 @@ error ("Wrong number of arguments\n"); TIFF *tif = (TIFF *)(args(0).uint64_value ()); - // TODO(maged): check if matlab errors for leaving a corrupt directory - // check if matlab changes directory after the call or switches back + if (! TIFFRewriteDirectory(tif)) error ("Failed to rewrite directory"); @@ -3039,6 +3056,8 @@ TIFF *tif = (TIFF *)(args(0).uint64_value ()); // TODO(maged): check if matlab requires scalar double + // matlab expects double, uint32, or uint64 + // and checks the subIFD tag first uint64_t offset = args(1).uint64_scalar_value (); if (! TIFFSetSubDirectory (tif, offset)) error ("Failed to switch to the sub directory"); diff -r 3f5f1404af8a -r 0abc9779f751 scripts/io/Tiff.m --- a/scripts/io/Tiff.m Sun Aug 14 21:02:58 2022 +0200 +++ b/scripts/io/Tiff.m Tue Aug 16 16:10:10 2022 +0200 @@ -387,6 +387,10 @@ versionString = __tiff_version__ (); endfunction + function tagNames = getTagNames () + tagNames = fieldnames (Tiff.TagID); + endfunction + function setLibTIFFErrorsEnabled(state) __tiff_set_errors_enabled__ (state); endfunction