in tensorflow_compression/cc/lib/range_coder.cc [325:365]
absl::Status RangeDecoder::CheckForErrorInternal(absl::Span<const T> cdf,
int precision,
bool allow_zero) const {
if (ABSL_PREDICT_FALSE(!(0 < precision && precision <= 16))) {
return absl::InvalidArgumentError(absl::StrCat(
"precision not in (0, 16]: ", precision));
}
if (ABSL_PREDICT_FALSE(cdf.size() <= 1)) {
return absl::InvalidArgumentError(absl::StrCat(
"cdf.size() = ", cdf.size(), " <= 1"));
}
for (typename absl::Span<const T>::size_type i = 0; i + 1 < cdf.size(); ++i) {
bool monotonic = cdf[i] < cdf[i + 1];
monotonic |= (allow_zero && cdf[i] == cdf[i + 1]);
if (ABSL_PREDICT_FALSE(!monotonic)) {
return absl::InvalidArgumentError("cdf is not monotonic");
}
}
const T first = cdf[0];
const T last = cdf[cdf.size() - 1];
if (ABSL_PREDICT_FALSE(!(0 <= first && last <= (1 << precision)))) {
return absl::InvalidArgumentError(absl::StrCat(
"cdf values must be between 0 and ", 1 << precision));
}
const uint64_t size = static_cast<uint64_t>(size_minus1_) + 1;
const uint64_t smallest = (static_cast<uint64_t>(value_ - base_) + 1)
<< precision;
if (ABSL_PREDICT_FALSE(!(size * static_cast<uint64_t>(first) < smallest))) {
return absl::InvalidArgumentError(absl::StrCat(
"cdf[0]=", first, " is too large and there was a decode error"));
}
if (ABSL_PREDICT_FALSE(!(smallest <= size * static_cast<uint64_t>(last)))) {
return absl::InvalidArgumentError(absl::StrCat(
"cdf[^1]=", last, " is too small and there was a decode error"));
}
return absl::OkStatus();
}