swscale assumes limited (MPEG, 16-235) input range by default. Mapping a
full-range JPEG format (YUVJ*) to its non-J equivalent for the conversion
therefore washes the colours out, because full-range luma/chroma gets
treated as limited.
Add pix_fmt_is_jpeg_range() and zm_sws_set_input_range(), which sets
srcRange=1 on the context when the original source format was full range.
Apply it at every conversion site that takes decoded frames: Image::Assign
and both SWScale::Convert overloads. Monitor::setupConvertContext already
did this inline with a hand-rolled switch and colorspace block; replace
that with the shared helpers to remove the duplication.
Add tests/zm_swscale_range.cpp: converting a Y=16 YUVJ420P image to RGB24
keeps luma ~16 (full range) rather than being crushed to ~0 (limited).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>