Render an animated clct_animation.gif alongside the per-step PNGs.
Frames are loaded and colour-quantized in parallel via rayon, then
written sequentially with the gif crate. Also converts timestamps
to CET/CEST using chrono-tz.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Downloads clat/clon concurrently via rayon::join and all forecast steps
in parallel via par_iter, then renders frames sequentially. A separate
thread pool (up to 16 threads) is used for downloads to avoid blocking
the global pool during CPU-bound rendering.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace nearest-neighbour BFS flood fill with Delaunay triangulation
(spade) + barycentric interpolation for smooth cloud boundaries.
Add NaN-aware separable Gaussian blur (σ=8 px, rayon-parallelised) to
remove triangulation facets. Switch colour scheme from blue bands to a
continuous green-to-white opacity blend matching the DWD app style.
Pixel interpolation loop is also parallelised with rayon.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
GRIB2 encodes binary (E) and decimal (D) scale factors in sign-and-magnitude
format (MSB = sign bit, lower 15 bits = magnitude), not two's complement.
The previous read_i16 call misinterpreted 0x8009 as -32759 instead of -9,
causing 2^E to underflow to 0.0 in f32 and zeroing all decoded values.
Fix: replace read_i16 with read_grib_scale for E and D in
decode_simple_packing. Add regression tests covering sign-magnitude decoding
and a realistic DWD CLCT packing scenario.