Commit graph

651 commits

Author SHA1 Message Date
Michael Niedermayer
302f198ba5
avcodec/mjpegdec: Check for multiple exif
Fixes: memleak
Fixes: 477993717/clusterfuzz-testcase-minimized-ffmpeg_AV_CODEC_ID_AMV_DEC_fuzzer-4515108431921152

Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
2026-02-23 23:52:37 +01:00
Ramiro Polla
a0b55a0491 avcodec/mjpegdec: fix indentation and some white spaces 2026-02-20 16:32:10 +01:00
Ramiro Polla
0accfde281 avcodec/jpeglsdec: fix decoding of jpegls files with restart markers 2026-02-20 16:32:10 +01:00
Ramiro Polla
5672c410a6 avcodec/mjpegdec: unescape data for each restart marker individually
Instead of unescaping the entire image data buffer in advance, and then
having to perform heuristics to skip over where the restart markers
would have been, unescape the image data for each restart marker
individually.
2026-02-20 16:32:10 +01:00
Ramiro Polla
22771117a0 avcodec/mjpegdec: move get_bits_left() checks after handling of restart count
This commit doesn't really change much on its own, but it's helpful in
preparation for the following commit.
2026-02-20 16:32:10 +01:00
Ramiro Polla
3783b8f5e1 avcodec/mjpegdec: move vpred initialization out of loop in ljpeg_decode_rgb_scan()
The initialization code was only being run when mb_y was 0, so it could
just as well be moved out of the loop.

I haven't been able to find a bayer sample that has restart markers to
check whether vpred should be reinitialized at every restart. It would
seem logical that it should, but I have left this out until we find a
sample that does have restart markers.
2026-02-20 16:32:10 +01:00
Ramiro Polla
3f2d4b49e6 avcodec/mjpegdec: split mjpeg_find_raw_scan_data() out of mjpeg_unescape_sos() 2026-02-20 16:32:10 +01:00
Ramiro Polla
bb48d2dba2 avcodec/mjpegdec: simplify decode_scan codepaths in ff_mjpeg_decode_sos()
This will be helpful for the next commit.
2026-02-20 16:32:10 +01:00
Ramiro Polla
179db32777 avcodec/mjpegdec: move MxPEG parameters from mjpeg_decode_scan() to MJpegDecodeContext 2026-02-20 16:32:10 +01:00
Ramiro Polla
14602cd999 avcodec/mjpegdec: move SOS header fields to MJpegDecodeContext
Use naming for SOS header fields from ISO/IEC 10918-1's non-lossless
mode of operation in ff_mjpeg_decode_sos() instead of mixing JPEG-LS
and lossless names. Each decode function still keeps its correct name
for each field.
2026-02-20 16:32:10 +01:00
Ramiro Polla
c1cd31320d avcodec/mjpegdec: find correct sizes for SOS fields
For hwaccel, find_marker() was being used to skip over the image data,
which could include multiple restart markers.

For MJPEG-B and THP, the field size was already correct since the image
data was already unescaped.

For the rest (mjpeg and jpegls), the buffer was being incremented by
the unescaped_buf_size, which could be smaller than the actual buffer
size.

Now the buffer is correctly incremented in all cases.
2026-02-20 16:32:10 +01:00
Ramiro Polla
cad555d0a4 avcodec/mjpegdec: improve unescaping of SOS fields
For non-jpegls:

Changes the behaviour to be more in line with IJG's reference implementation:
- optional 0xFF fill bytes in a stuffed zero byte sequence (which is an
  invalid pattern according to the standard) are now discarded:
    "FF (FF)? 00" => "FF" instead of "FF 00"
- sequences with optional 0xFF fill bytes and a marker are no longer copied:
    "FF (FF)? XX" => "" instead of "FF XX"
- a trailing 0xFF byte is no longer issued when a valid "0xFF 0xXX" marker
  is found:
    "FF XX" => "" instead of "FF"

For jpegls:

Changes the behaviour to be more in line with IJG's (non-jpegls) reference
implementation, similar to the changes above:
- optional 0xFF fill bytes in a stuffed zero bit sequence (which is an
  invalid pattern according to the standard) are now discarded:
  "FF (FF)? 0b0xxxxxxx" => "FF 0bxxxxxxx" instead of "FF 7F XX"
- sequences with optional 0xFF fill bytes and a marker are no longer copied:
  "FF (FF)? 0b1xxxxxxx" => "" instead of "FF 7F"

Unescaping for jpegls is now done in one pass instead of two. The first
pass used to detect the length of the buffer, while the second pass would
copy up to the detected length.

Note that jpegls restart markers are still not supported.

There is also a speed up with the new implementations, mostly due to the
usage of memchr() as suggested by Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2026-02-20 16:32:10 +01:00
Ramiro Polla
8abb40a8d8 avcodec/mjpegdec: simplify away mjpeg_unescape_sos()'s parameters
The input is always obtained from s->gB and the output is always used
to initialize s->gb, so we can move that inside the function itself.
2026-02-20 16:32:10 +01:00
Ramiro Polla
3d90949d1e avcodec/mjpegdec: split mjpeg_unescape_sos() out of ff_mjpeg_find_marker()
Now only the image data is unescaped (and not the SOS header). As a
side-effect, this also provides a proper fix for decoding CJPG files
(issue #133).
2026-02-20 16:32:10 +01:00
Ramiro Polla
0ddb3e6af2 avcodec/mjpegdec: improve ff_mjpeg_find_marker() for non-SOS and for THP
There is no need to unescape the buffer for non-SOS fields and for THP.
2026-02-20 16:32:10 +01:00
Ramiro Polla
2d9023564b avcodec/mjpegdec: move handling of AVRn interlaced picture to mjpeg_decode_scan()
AVRn interlaced files are only present in sequential JPEG.
2026-02-20 16:32:10 +01:00
Ramiro Polla
51caa26a86 avcodec/mjpegdec: move initialization of last_dc field to mjpeg_decode_scan()
The last_dc field is only used in sequential JPEG and the DC coefficients
for progressive JPEG.
2026-02-20 16:32:10 +01:00
Ramiro Polla
44fd92c514 avcodec/mjpegdec: improve debug message in find_marker()
Use pointer arithmetic instead of an extra variable to keep track of
skipped bytes.
2026-02-20 16:32:10 +01:00
Ramiro Polla
8a0f1fd6ab avcodec/mjpegdec: remove commented out code 2026-02-20 16:32:10 +01:00
Ramiro Polla
fa4c24a8d9 avcodec/mjpegdec: remove unnecessary else 2026-02-20 16:32:10 +01:00
Ramiro Polla
9ee6136ece avcodec/mjpegdec: remove start_code field from MJpegDecodeContext
Instead, pass it as a parameter to the only function that uses it.
2026-02-09 17:52:01 +00:00
Ramiro Polla
96d8e19720 avcodec/mjpegdec: fix segfault on extern_huff and no extradata
Regression since 1debadd58e.
2026-01-21 03:26:02 +00:00
Ramiro Polla
2170f397ea Revert "avcodec/mjpegdec: Check for for the bitstream end in mjpeg_decode_scan_progressive_ac()"
This commit has been made redundant by 909faca929, which is run more
often (once per mb instead of once per line).

This reverts commit 3782656631.
2026-01-08 22:33:01 +00:00
Ramiro Polla
165448f7d1 avcodec/mjpegdec: remove buggy_avid field from MJpegDecodeContext
This field has been unused since b6c04b6821.
2026-01-08 16:29:32 +00:00
Ruikai Peng
f1dbef3e38 avcodec/mjpegdec: avoid negative len in APP parser
The APP parser can read a fixed number of bytes without checking len,
making len negative and passing it to bytestream2_skipu(), which takes
an unsigned size. This can advance the buffer by a huge amount and
results in undefined behavior.

Add small len guards in the fixed-size AVI1/LJIF paths and only skip
the tail if len > 0.

Signed-off-by: Ruikai Peng <ruikai@pwno.io>
2026-01-07 17:33:02 +00:00
Ramiro Polla
1debadd58e avcodec/mjpegdec: use GetByteContext instead of GetBitContext where possible
JPEG is mostly byte-aligned. We only really need GetBitContext while
decoding the image data.

Suggested-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2026-01-05 13:14:15 +00:00
Ramiro Polla
fdff03425b avcodec/mjpegdec: fix indentation for previous commit 2026-01-05 13:14:15 +00:00
Ramiro Polla
a84627aca9 avcodec/mjpegdec: add mjpeg_parse_len() helper
And check for length field in a consistent manner.
2026-01-05 13:14:15 +00:00
Ramiro Polla
abb0247017 avcodec/mjpegdec: improve check for length in ff_mjpeg_decode_dqt() 2026-01-05 13:14:15 +00:00
Ramiro Polla
aa80a7880b avcodec/jpegls: rename SOF48 to SOF55
SOF48 (0xf0) was used in a public draft of the standard (FCD 14495).
In the final specification it is called SOF55 (0xf7).
2025-12-30 17:30:45 +00:00
Ramiro Polla
7dda7f3b99 avcodec/mjpegdec: speed up find_marker()
Minimize number of reads and simplify conditionals.

Also use memchr(), as suggested by Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2025-12-29 21:44:07 +00:00
Ramiro Polla
254124f869 avcodec/mjpegdec: fix some error return codes 2025-12-29 17:22:34 +01:00
Michael Niedermayer
ecd2919174 avcodec/mjpegdec: only test the size bound in sequential mjpeg
The original fix was intended only for sequential mjpeg, but it was also used for progressive
which broke. This commit fixes this regression

Fixes: issue21225

The testcase 6381/clusterfuzz-testcase-minimized-ffmpeg_AV_CODEC_ID_JPEGLS_fuzzer-5665032743419904 still exits within 240ms

Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
2025-12-29 13:57:33 +00:00
Andreas Rheinhardt
5d9270df7f libavutil/internal: Remove {SIZE,PTRDIFF}_SPECIFIER
Possible since 222127418b.

Reviewed-by: Kacper Michajłow <kasper93@gmail.com>
Reviewed-by: Lynne <dev@lynne.ee>
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2025-12-03 11:52:54 +01:00
Andreas Rheinhardt
32f32537b6 avcodec/dvdec,mjpegdec: Remove emms_c
It is no longer necessary now that the IDCTDSP is always ABI-compliant
(and free of MMX).

Reviewed-by: Lynne <dev@lynne.ee>
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2025-11-08 18:48:54 +01:00
Andreas Rheinhardt
ce9d181444 avcodec/mjpegdec: Remove unnecessary reloads
Hint: The parts of this patch in decode_block_progressive()
and decode_block_refinement() rely on the fact that GET_VLC
returns -1 on error, so that it enters the codepaths for
actually coded block coefficients.

Reviewed-by: Ramiro Polla <ramiro.polla@gmail.com>
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2025-10-11 08:20:42 +02:00
Michael Niedermayer
61b6877637 avcodec/mjpegdec: Explain buf_size/width/height check
Suggested-by: Ramiro

Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
2025-10-02 12:52:43 +00:00
Andreas Rheinhardt
f33e62a8b4 avcodec/mjpegdec: Move reference dimension check to mxpegdec.c
Only the mxpeg sets reference at all.

Reviewed-by: Michael Niedermayer <michael@niedermayer.cc>
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2025-09-15 17:52:22 +02:00
Andreas Rheinhardt
b5cfabf0f5 avcodec/mjpegdec: Avoid using HpelDSPContext
It is quite big and we only need one function from it.

Reviewed-by: Michael Niedermayer <michael@niedermayer.cc>
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2025-09-15 17:52:22 +02:00
Andreas Rheinhardt
124c856d38 avcodec/mjpegdec: Move initializing HpelDSPContext to mxpegdec.c
Only the mxpeg decoder uses it (and the reference/bitmask feature
of ff_mjpeg_decode_sos()). So only initialize it for mxpeg which
allows to remove the mjpeg->hpeldsp dependency.

Reviewed-by: Michael Niedermayer <michael@niedermayer.cc>
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2025-09-15 17:52:22 +02:00
Andreas Rheinhardt
b11c8b76df avcodec/mjpegdec: Avoid mixing return value and error code, avoid branch
mjpeg_decode_dc() currently has a special return value (0xfffff)
for the case of invalid data; this value does not overlap with
the ordinary return values, yet the compiler can't prove this
(at least on x86 where an asm version of NEG_USR32 is used
inside get_xbits()), so the non-error return value has to be checked
for being the special value even if mjpeg_decode_dc() is inlined.

This commit avoids this by separating error code and ordinary return
value. It also means that the ljpeg functions return the proper
error code and not -1 in case of invalid data.

Reviewed-by: Michael Niedermayer <michael@niedermayer.cc>
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2025-09-15 17:52:22 +02:00
Andreas Rheinhardt
3b1673db6a avcodec/mjpegdec: Avoid superfluous secondary error message
Up until now, a DC error in decode_block() or decode_dc_progressive()
would lead to a warning from mjpeg_decode_dc() and a (less verbose)
error from the caller. Upgrade the former to an error status (all
callers treat is an error) and remove the latter.

Reviewed-by: Michael Niedermayer <michael@niedermayer.cc>
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2025-09-15 17:52:22 +02:00
Andreas Rheinhardt
a6c899bc6b avcodec/mjpegdec: Remove pointless information from logmessage
There is no reason to add the address of an element of
MJpegDecodeContext (which makes logmessage nonreproducible).
Also avoid always printing a zero.

Reviewed-by: Michael Niedermayer <michael@niedermayer.cc>
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2025-09-15 17:52:22 +02:00
Andreas Rheinhardt
1df63acdc4 avcodec: Add av_cold to flush,init,close functions missing it
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
2025-09-13 20:37:03 +00:00
Ramiro Polla
6696a9b8bd avcodec/mjpegdec: ignore APPx stubs unless AV_EF_EXPLODE is set
Consider APPx fields that are too short to contain an id field (32-bit)
as stubs, and ignore them if AV_EF_EXPLODE is not set.

This has been seen in the MJPEG output from some webcams (such as the
Logitech C270 and C920) and the JPEG images embedded in DNG images
from the Pentax K-1 camera.
2025-09-04 15:28:41 +00:00
Ramiro Polla
e207520b82 avcodec/mjpegdec: fix skipping of bytes for unknown APPx markers
The loop to skip the remaining bytes was off by one for all markers
except for Adob.

This patch uses post-decrement instead of pre-decrement in the while
loop to make the len value easier to understand, and updates the len
value to reflect this change for the Adob marker.
2025-09-04 15:28:41 +00:00
James Almer
5a9e5d8031 avcodec/exif: use ff_frame_new_side_data() to export display matrix
Otherwise, the user requested priority of packet side data will be ignored.
For this, move the relevant functions to decode.c, as they need access to an
AVCodecContext.

Signed-off-by: James Almer <jamrial@gmail.com>
2025-08-21 22:48:16 +00:00
Leo Izen
52dba25661
avcodec/mjpegdec: use new EXIF parse API
Switch over to the new API to parse EXIF metadata.

Signed-off-by: Leo Izen <leo.izen@gmail.com>
2025-08-19 11:26:47 -04:00
Leo Izen
ad77345a5d
avcodec/exif: add EXIF parser and struct API
This commit adds a structure to contain parsed EXIF metadata, as well
as code to read and write that struct from/to binary EXIF buffers. Some
internal functions have been moved to exif_internal.h. Code to read
from this new struct and write to an AVDictionary **dict has been added
as well in order to preserve interoperability with existing callers.
The only codec changes so far as of this commit are to call these
interop functions, but in future commits there will be codec changes to
use the new parsing routines instead.

Signed-off-by: Leo Izen <leo.izen@gmail.com>
2025-08-19 11:26:46 -04:00
Ramiro Polla
5733e08c97 avcodec/mjpegdec: decode only SOF fields when finding stream info
When called from avformat_find_stream_info(), we are only interested in
decoding SOF fields.

This patch makes the decoder skip all other fields (including SOI, SOS,
and EOI). This also prevents the decoder from incorrectly printing the
warning "EOI missing, emulating" (which is the case since 2ae82788).

Fixes: #20119
2025-08-11 21:23:38 +00:00