Short integer overflow in imageIO test
In the ImageIO module there is a group of test for the reading of tif
images from one type to another (for example read a 4 band Int32
image stored as a std::complex<float>
vector image). Many different combinations are tested from [Int16
, Int32
, Float32
, Float64
] to [short
, int
, float
and double
] with scalar and complex image as input and output and up to 4 bands images.
The input images of these test currently have N=10000
pixels (image of size 100x100), For scalar images the value x
of each pixel can be computed for each band k = [0 : NbBand -1]
with the formulae:
x[k] = pos(x) + N * k
Here pos(x)
denotes the position of pixel x
, e.g. 0 for pixel [0,0] and 10000 for pixel [100,100].
In a 4 band scalar image the first pixel has value [0,10000,20000,30000]
and the last one has value [9999, 19999, 29999, 39999]
.
For complex images, we have :
Re(x[k]) = pos(x) + 2 k * N
Im(x[k]) = pos(x) + (2 k + 1 ) * N
the first pixelof the 4 band image has value [0 +9999i ,20000 + 29999i ,40000 + 49999i ,60000+69999i]
The tests read and convert these image, and compare the value of some of the points to their actual value re-computed from these formulas.
The problem is that the maximum value for a signed short is 32 767
. This means that the value will overflow (undefined behavior !) in the test using short input and/or output with images with a lot of bands. Note that this doesn't means that the test will necessarily fail, the read and computed value might be the same if they have overflowed in the same manner, and on most platforms in does (cf CI). However this is the cause of these failing test on macOS mojave :
https://cdash.orfeo-toolbox.org/viewTest.php?onlyfailed&buildid=28686
These tests also use std::complex<short>
, which is also undefined behavior (see this discussion ). On this platform, the result of the initialization of a std::complex<short>
with large float (that causes overflow) seems quite random.
The purpose of these test is not to see what happens with overflow in OTB.
The problem is already partially solved for short image as input, the solution is to use image of size 50x50 instead of 100x100 and thus avoiding overflow. The problem appears when reading non short
image and converting them to short
.
A solution is to use 50x50 in all these tests. See MR !667 (merged)