Skip to content

TIFF import pixel rounding

Summary

y pixels can be off by one in TIFF import

What is the current bug behaviour?

When importing a TIFF, the y pixel is determined by calculating the double value given by _row_size - _y_res * (_y_off + y) - 1, and then implicitly casting it to an unsigned integer:

https://gitlab.dune-project.org/copasi/dune-copasi/-/blob/master/dune/copasi/common/tiff_grayscale.hh#L181

Here

  • y_dbl = y_res * (_y_off + y) is the desired location in the image with (0,0) in the bottom left of the image
  • _row_size - 1 - y_dbl flips the y axis such that (0,0) is in the top left to match the TIFF

However, if for example y_dbl = _row_size - 1.2, then _row_size - 1 - y_dbl = 0.2 -> implicitly cast to 0

What is the expected correct behaviour?

The desired value for this example is 1, since the point lies in the second row from the top of the image.

Ideas how to fix this?

This is caused by doing the subtraction to flip the y axis before casting to truncate the double.

If y_dbl is first explicitly cast to an unsigned int before subtraction, then we get the desired behaviour for the example case:

y_int = static_cast<T>(_row_size - 1.2) = _row_size - 2, and then _row_size - 1 - (_row_size - 2) = 1

Suggested change:

https://gitlab.dune-project.org/copasi/dune-copasi/-/blob/master/dune/copasi/common/tiff_grayscale.hh#L181

const T j = _row_size - static_cast<T>(_y_res * (_y_off + y)) - 1;