# HG changeset patch # User magedrifaat # Date 1660665672 -7200 # Node ID 1f19e9a06f2df31f258afcb38395dc0934d0193e # Parent 0abc9779f751cf28e5a5b5058796dae9cfd2b710 Tiff: modified readRGBAStrip/Tile to correctly use the orientation tag * __tiff__.cc (F__tiff_read_rgba_strip__, F__read_rgba_tile__): modified the logic to use the orientation tag correctly. diff -r 0abc9779f751 -r 1f19e9a06f2d libinterp/corefcn/__tiff__.cc --- a/libinterp/corefcn/__tiff__.cc Tue Aug 16 16:10:10 2022 +0200 +++ b/libinterp/corefcn/__tiff__.cc Tue Aug 16 18:01:12 2022 +0200 @@ -2455,6 +2455,10 @@ uint32_t strip_no = TIFFComputeStrip (tif, row, 0); rows_in_strip = get_rows_in_strip (strip_no, TIFFNumberOfStrips (tif), rows_in_strip, &image_data); + + 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 @@ -2465,7 +2469,25 @@ // TODO(maged): check if matlab does anything with orientation tag // matlab uses the orientation tag to correct the data - if (! TIFFReadRGBAStrip (tif, row, strip_ptr)) + // if (! TIFFReadRGBAStrip (tif, row, strip_ptr)) + // error ("Failed to read strip"); + + TIFFRGBAImage img_config; + char emsg[1024]; + if (! TIFFRGBAImageOK (tif, emsg) + || ! TIFFRGBAImageBegin (&img_config, tif, 0, emsg)) + error ("Failed to read strip"); + + img_config.orientation = ORIENTATION_TOPLEFT; + img_config.req_orientation = orientation; + img_config.row_offset = row; + img_config.col_offset = 0; + + bool success = TIFFRGBAImageGet (&img_config, strip_ptr, img_config.width, + rows_in_strip); + + TIFFRGBAImageEnd (&img_config); + if (!success) error ("Failed to read strip"); // Permute to the correct order of dimensions for Octave @@ -2476,9 +2498,9 @@ strip_data = strip_data.permute (perm); // Slice the data into RGB and alpha - // The rows are reversed because LibTIFF assumes a bottom-left orientation + // TODO(maged): refactor into a function Array idx (dim_vector (3, 1)); - idx(0) = idx_vector (rows_in_strip - 1, -1, -1); + idx(0) = idx_vector (':'); idx(1) = idx_vector (':'); idx(2) = idx_vector (0, 3); uint8NDArray rgb = uint8NDArray (strip_data.index (idx)); @@ -2535,16 +2557,46 @@ row -= row % tile_height; col -= col % tile_width; + uint16_t orientation; + if (! TIFFGetFieldDefaulted (tif, TIFFTAG_ORIENTATION, &orientation)) + orientation = ORIENTATION_LEFTTOP; + + // Calculate the correct dimensions for boundary tiles + uint32_t corrected_height = tile_height; + uint32_t corrected_width = tile_width; + if (row + tile_height > image_data.height) + corrected_height = image_data.height - row; + if (col + tile_width > image_data.width) + corrected_width = image_data.width - col; + // Start with reversed dimensions to be aligned with LibTIFF and // permute to the correct order later - dim_vector tile_dims (4, tile_width, tile_height); + dim_vector tile_dims (4, corrected_width, corrected_height); uint8NDArray tile_data (tile_dims); uint32_t *tile_ptr = 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)) + // if (! TIFFReadRGBATile (tif, col, row, tile_ptr)) + // error ("Failed to read tile"); + + TIFFRGBAImage img_config; + char emsg[1024]; + if (! TIFFRGBAImageOK (tif, emsg) + || ! TIFFRGBAImageBegin (&img_config, tif, 0, emsg)) + error ("Failed to read tile"); + + img_config.orientation = ORIENTATION_TOPLEFT; + img_config.req_orientation = orientation; + img_config.row_offset = row; + img_config.col_offset = col; + + bool success = TIFFRGBAImageGet (&img_config, tile_ptr, corrected_width, + corrected_height); + + TIFFRGBAImageEnd (&img_config); + if (!success) error ("Failed to read tile"); // Permute to the correct order of dimensions for Octave @@ -2553,25 +2605,11 @@ perm(1) = 1; perm(2) = 0; tile_data = tile_data.permute (perm); - - // Calculate the correct dimensions for boundary tiles - uint32_t corrected_height = tile_height; - uint32_t corrected_width = tile_width; - if (row + tile_height > image_data.height) - corrected_height = image_data.height - row; - if (col + tile_width > image_data.width) - corrected_width = image_data.width - col; // Slice the data into RGB and alpha - // LibTIFF assumes the image has bottom-left orientation and returns - // the rows flipped vertically, so we need to reverse them and remove - // the padding which is at the top since the rows are flipped Array idx (dim_vector (3, 1)); - // Must cast the unsigned values to signed because otherwise the output - // can't be negative (C++ is the best). - idx(0) = idx_vector (tile_height - 1, - int64_t(tile_height - corrected_height) - 1, -1); - idx(1) = idx_vector (0, corrected_width); + idx(0) = idx_vector (':'); + idx(1) = idx_vector (':'); idx(2) = idx_vector (0, 3); uint8NDArray rgb = uint8NDArray (tile_data.index (idx)); idx(2) = idx_vector (3);