[FFmpeg-devel] [PATCH v2 08/18] avcodec/libjxl: set correct alpha mode

Niklas Haas ffmpeg at haasn.xyz
Wed Jul 23 16:47:11 EEST 2025


From: Niklas Haas <git at haasn.dev>

JPEG XL supports both premultiplied and straight alpha, and the basic info
struct contains signalling for this. Forward the correct tagging on decode
and encode.
---
 libavcodec/libjxldec.c |  6 ++++++
 libavcodec/libjxlenc.c | 15 +++++++++++++++
 2 files changed, 21 insertions(+)

diff --git a/libavcodec/libjxldec.c b/libavcodec/libjxldec.c
index 96c338d1b4..0c4091850c 100644
--- a/libavcodec/libjxldec.c
+++ b/libavcodec/libjxldec.c
@@ -433,6 +433,12 @@ static int libjxl_receive_frame(AVCodecContext *avctx, AVFrame *frame)
             if (ctx->basic_info.have_animation)
                 ctx->anim_timebase = av_make_q(ctx->basic_info.animation.tps_denominator,
                                                ctx->basic_info.animation.tps_numerator);
+            if (ctx->basic_info.alpha_bits) {
+                if (ctx->basic_info.alpha_premultiplied)
+                    avctx->alpha_mode = AVALPHA_MODE_PREMULTIPLIED;
+                else
+                    avctx->alpha_mode = AVALPHA_MODE_STRAIGHT;
+            }
             continue;
         case JXL_DEC_COLOR_ENCODING:
             av_log(avctx, AV_LOG_DEBUG, "COLOR_ENCODING event emitted\n");
diff --git a/libavcodec/libjxlenc.c b/libavcodec/libjxlenc.c
index 823abcafb8..924a835436 100644
--- a/libavcodec/libjxlenc.c
+++ b/libavcodec/libjxlenc.c
@@ -351,6 +351,15 @@ static int libjxl_preprocess_stream(AVCodecContext *avctx, const AVFrame *frame,
         jxl_fmt->data_type = info.bits_per_sample <= 8 ? JXL_TYPE_UINT8 : JXL_TYPE_UINT16;
     }
 
+    if (info.alpha_bits) {
+        if (avctx->alpha_mode == AVALPHA_MODE_PREMULTIPLIED ||
+            avctx->alpha_mode == AVALPHA_MODE_UNSPECIFIED && frame->alpha_mode == AVALPHA_MODE_PREMULTIPLIED) {
+            info.alpha_premultiplied = 1;
+        } else if (avctx->alpha_mode != AVALPHA_MODE_STRAIGHT && frame->alpha_mode != AVALPHA_MODE_STRAIGHT) {
+            av_log(avctx, AV_LOG_WARNING, "Unknown alpha mode, assuming straight (independent)\n");
+        }
+    }
+
 #if JPEGXL_NUMERIC_VERSION >= JPEGXL_COMPUTE_NUMERIC_VERSION(0, 8, 0)
     jxl_bit_depth.bits_per_sample = bits_per_sample;
     jxl_bit_depth.type = JXL_BIT_DEPTH_FROM_PIXEL_FORMAT;
@@ -713,6 +722,9 @@ const FFCodec ff_libjxl_encoder = {
                         FF_CODEC_CAP_AUTO_THREADS | FF_CODEC_CAP_INIT_CLEANUP |
                         FF_CODEC_CAP_ICC_PROFILES,
     CODEC_PIXFMTS_ARRAY(libjxl_supported_pixfmts),
+    .alpha_modes    = (const enum AVAlphaMode[]) {
+        AVALPHA_MODE_STRAIGHT, AVALPHA_MODE_PREMULTIPLIED, AVALPHA_MODE_UNSPECIFIED
+    },
     .p.priv_class     = &libjxl_encode_class,
     .p.wrapper_name   = "libjxl",
 };
@@ -733,6 +745,9 @@ const FFCodec ff_libjxl_anim_encoder = {
                         FF_CODEC_CAP_AUTO_THREADS | FF_CODEC_CAP_INIT_CLEANUP |
                         FF_CODEC_CAP_ICC_PROFILES,
     CODEC_PIXFMTS_ARRAY(libjxl_supported_pixfmts),
+    .alpha_modes    = (const enum AVAlphaMode[]) {
+        AVALPHA_MODE_STRAIGHT, AVALPHA_MODE_PREMULTIPLIED, AVALPHA_MODE_UNSPECIFIED
+    },
     .p.priv_class     = &libjxl_encode_class,
     .p.wrapper_name   = "libjxl",
 };
-- 
2.50.1



More information about the ffmpeg-devel mailing list