This is an automated email from the git hooks/post-receive script. Git pushed a commit to branch master in repository ffmpeg.
commit 42344c7cbb7d03a8ba64bcb0aa6439702037442b Author: Niklas Haas <[email protected]> AuthorDate: Fri Oct 2 17:20:38 2026 +0200 Commit: James Almer <[email protected]> CommitDate: Fri Oct 23 20:33:53 2026 +0000 avcodec: implement ISO 21496 gain map parsing The parsing logic for this already existed in libavcodec, but was unused until now. This commit adds the APP2 extraction logic and the necessary scaffolding to make this metadata survive the decoder. Since the base layer of a JPEG Ultra HDR image also contains a stub copy of the same gain map params struct, we ignore that one here. (It's only useful for the demuxer, not the decoder) Signed-off-by: Niklas Haas <[email protected]> --- libavcodec/Makefile | 2 +- libavcodec/mjpegdec.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ libavcodec/mjpegdec.h | 4 ++++ 3 files changed, 53 insertions(+), 1 deletion(-) diff --git a/libavcodec/Makefile b/libavcodec/Makefile index 53c638c878..2ea4f9417e 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -535,7 +535,7 @@ OBJS-$(CONFIG_METASOUND_DECODER) += metasound.o twinvq.o OBJS-$(CONFIG_MICRODVD_DECODER) += microdvddec.o ass.o OBJS-$(CONFIG_MIMIC_DECODER) += mimic.o OBJS-$(CONFIG_MISC4_DECODER) += misc4.o -OBJS-$(CONFIG_MJPEG_DECODER) += mjpegdec.o mjpegdec_common.o +OBJS-$(CONFIG_MJPEG_DECODER) += mjpegdec.o mjpegdec_common.o gain_map.o OBJS-$(CONFIG_MJPEG_QSV_DECODER) += qsvdec.o OBJS-$(CONFIG_MJPEG_ENCODER) += mjpegenc.o mjpegenc_common.o \ mjpegenc_huffman.o gain_map.o diff --git a/libavcodec/mjpegdec.c b/libavcodec/mjpegdec.c index cbb7268ed9..3716bbf753 100644 --- a/libavcodec/mjpegdec.c +++ b/libavcodec/mjpegdec.c @@ -44,6 +44,7 @@ #include "decode.h" #include "exif.h" #include "exif_internal.h" +#include "gain_map.h" #include "hwaccel_internal.h" #include "hwconfig.h" #include "idctdsp.h" @@ -2126,6 +2127,38 @@ static int mjpeg_decode_app(MJpegDecodeContext *s, int start_code) av_log(s->avctx, AV_LOG_WARNING, "Read more ICC markers than are supposed to be coded\n"); } + if (start_code == APP2 && id == AV_RB32("urn:")) { + bytestream2_seek(&s->gB, -4, SEEK_CUR); /* include `urn:` in the string */ + len += 4; + + if (len >= sizeof(AV_ISO21496_IDENTIFIER) && + !memcmp(s->gB.buffer, AV_ISO21496_IDENTIFIER, sizeof(AV_ISO21496_IDENTIFIER))) + { + bytestream2_skipu(&s->gB, sizeof(AV_ISO21496_IDENTIFIER)); + len -= sizeof(AV_ISO21496_IDENTIFIER); + + /* Discard gain map version stubs from base layer */ + if (len <= sizeof(uint16_t[2])) + goto out; + else if (s->gain_map) { + av_log(s->avctx, AV_LOG_WARNING, "Multiple ISO 21496 gain map headers\n"); + goto out; + } + + s->gain_map = av_gain_map_params_alloc(&s->gain_map_size); + if (!s->gain_map) + return AVERROR(ENOMEM); + + ret = av_gain_map_params_from_iso21496(s->gain_map, s->gB.buffer, len); + if (ret < 0) { + av_log(s->avctx, AV_LOG_WARNING, "Failed to parse ISO 21496 gain map header\n"); + av_freep(&s->gain_map); + s->gain_map_size = 0; + goto out; + } + } + } + out: /* slow but needed for extreme adobe jpegs */ if (len < 0) @@ -2399,6 +2432,7 @@ int ff_mjpeg_decode_frame_from_buf(AVCodecContext *avctx, AVFrame *frame, av_exif_free(&s->exif_metadata); av_freep(&s->stereo3d); + av_freep(&s->gain_map); s->adobe_transform = -1; if (s->iccnum != 0) @@ -2831,6 +2865,18 @@ the_end: av_freep(&s->stereo3d); } + if (s->gain_map) { + AVFrameSideData *sd; + ret = ff_frame_new_side_data(avctx, frame, AV_FRAME_DATA_GAIN_MAP_PARAMS, s->gain_map_size, &sd); + if (ret < 0) + return ret; + + if (sd) + memcpy(sd->data, s->gain_map, s->gain_map_size); + av_freep(&s->gain_map); + s->gain_map_size = 0; + } + if (s->iccnum != 0 && s->iccnum == s->iccread) { AVFrameSideData *sd; size_t offset = 0; @@ -2904,6 +2950,8 @@ av_cold int ff_mjpeg_decode_end(AVCodecContext *avctx) av_freep(&s->stereo3d); av_freep(&s->ljpeg_buffer); s->ljpeg_buffer_size = 0; + av_freep(&s->gain_map); + s->gain_map_size = 0; for (i = 0; i < 3; i++) { for (j = 0; j < 4; j++) diff --git a/libavcodec/mjpegdec.h b/libavcodec/mjpegdec.h index 9162de851f..30f6947eaa 100644 --- a/libavcodec/mjpegdec.h +++ b/libavcodec/mjpegdec.h @@ -29,6 +29,7 @@ #ifndef AVCODEC_MJPEGDEC_H #define AVCODEC_MJPEGDEC_H +#include "libavutil/gain_map.h" #include "libavutil/log.h" #include "libavutil/mem_internal.h" #include "libavutil/pixdesc.h" @@ -153,6 +154,9 @@ typedef struct MJpegDecodeContext { AVStereo3D *stereo3d; ///!< stereoscopic information (cached, since it is read before frame allocation) + AVGainMapParams *gain_map; + size_t gain_map_size; + const AVPixFmtDescriptor *pix_desc; ICCEntry *iccentries; -- To stop receiving notification emails like this one, please contact [email protected]. _______________________________________________ ffmpeg-cvslog mailing list -- [email protected] To unsubscribe send an email to [email protected]
