- loader: add available(), true only after load() has resolved every
required entry point (false at the start of load()). Program::from_source
and the other fallible constructors return ErrorCode::Unsupported while it
is false, so a failed load() with a partially populated table can no longer
fault on an unresolved entry point.
- caps: GL_CONTEXT_PROFILE_MASK only exists from 3.2, so query it only on
3.2+ contexts. A 3.0/3.1 query latches GL_INVALID_ENUM in the context, which
the next unrelated glGetError() (e.g. read_pixel) then reports as failure.
- tests: gate the dlsym/libGL.so.1 fallback assertions on libGL being
resolvable, so the GL suite also passes on a GLES-only host.
A zero pixel span previously produced sx/sy == 0, so to_data_* returned
NaN or +/-inf. axis_scale now substitutes a unit pixel span (1.0) when
|p1 - p0| <= 1e-12, keeping the mapping finite and invertible while
leaving non-collapsed spans byte-identical.
Add committed coverage for from_range (linear, flipped pixel axis, log x,
degenerate data range, collapsed pixel span) and log10_positive clamping.