In progressive mode, this functions will need to be called multiple time
on the same macroblocks, so it shouldn't create the vector every
time it's called.
This means that we should read markers in a loop instead of quiting on
the first scan. This is useless for now as `SOF0` frames only have one
scan, but this is a step forward `SOF2` support.
As a JPEG file can contain multiples scans, we should return from
`scan_huffman_stream` on all new markers (except restart markers) and
not only `JPEG_EOI`.
Miscellaneous and tables segments can also be placed between scans,
placing this code in a function will allow us to avoid duplication when
we get there.
While returning the same image is a cute optimization, it violates the
expectation that the returned Bitmap is a new bitmap, not shared with
anyone else.
Rename "reset_marker" to "restart_marker" as described by the spec. It
also concerns disambiguate the situation as the DRI was also called a
reset marker.
It only implements serialization of the 7-bit ASCII string, not yet
serialization of the UCS-2 and Macintosh ScriptCode strings.
With this, matrix-based v2 profiles can be reencoded :^)
The initial signs were wrong for the deltas of f(x), the ellipse
equation. This seemed to be fine for larger circles/ellipses but
broke things at a small scale, this was previously fixed with a
horrible "error = error / 4" hack. With this change, all ellipses
look a little better :^)
This also fixed a signed integer overflow Andreas found with UBSAN,
which happened for circles with a 1px radius.
With this, common v4 profiles, such as embedded into jpgs by iPhones
(when configured to write jpegs) or Pixel phones, are identical to
the input when reexported :^)
Restart markers are supposed to be applied every restart interval.
However, in these loops macroblocks are counted taking the luma sampling
factor into consideration. Meaning that we need to correct this factor
when testing if we should reset the DC.
Also, the decoder was discarding the first byte of every scan with a set
restart interval, as `0 % n == 0` is always true.
I'm not sure why this isn't caught on other people's setups or CI, but
when building on NixOS it fails with:
error: comparison of integer expressions of different signedness:
‘size_t’ {aka ‘long unsigned int’} and ‘int’ [-Werror=sign-compare]