def test_clamp(x, lower_bound, upper_bound): if lower_bound > upper_bound: lower_bound, upper_bound = upper_bound, lower_bound new_x = clamp(x, lower_bound, upper_bound) # If x was already between the bounds, it shouldn't have changed if lower_bound <= x <= upper_bound: assert new_x == x assert lower_bound <= new_x <= upper_bound
def _calc_offsets_impl(off, scale, src_size, dst_size): assert scale >= 1 - 1e-5 if off >= 0: write_off = 0 else: write_off = math.ceil((-off - 0.5) / scale) read_off = round((write_off + 0.5) * scale - 0.5 + off) - round( 0.5 * (scale - 1.0)) # assuming read_size/write_size ~= scale if read_off >= src_size: return 0, 0, 0, 0 write_end = dst_size write_size = write_end - write_off read_end = read_off + round(write_size * scale) if read_end > src_size: # +0.5 below is a fudge that will return last row in more situations, but will change the scale more write_end = math.floor((src_size - off + 0.5) / scale) write_size = write_end - write_off read_end = clamp(read_off + round(write_size * scale), read_off, src_size) read_size = read_end - read_off return int(read_off), int(write_off), int(read_size), int(write_size)
def clamped_range(v1: float, v2: float, N: int) -> range: _in = clamp(math.floor(v1), 0, N) _out = clamp(math.ceil(v2), 0, N) return range(_in, _out)