From 8a614ec80e0d2e96bdecf3681fcfabe14d1bd1b5 Mon Sep 17 00:00:00 2001 From: Jonathan Brown Date: Tue, 3 Jun 2025 15:39:56 +0100 Subject: [PATCH 1/2] Default 444 --- lib/jpegli/encode.cc | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/lib/jpegli/encode.cc b/lib/jpegli/encode.cc index ac4917d2..f74c3b65 100644 --- a/lib/jpegli/encode.cc +++ b/lib/jpegli/encode.cc @@ -795,6 +795,7 @@ void jpegli_set_colorspace(j_compress_ptr cinfo, J_COLOR_SPACE colorspace) { jpeg_component_info* comp = &cinfo->comp_info[c]; comp->component_index = c; comp->component_id = c + 1; + // Default is no chroma subsampling. comp->h_samp_factor = 1; comp->v_samp_factor = 1; comp->quant_tbl_no = 0; @@ -806,10 +807,6 @@ void jpegli_set_colorspace(j_compress_ptr cinfo, J_COLOR_SPACE colorspace) { cinfo->comp_info[1].component_id = 'G'; cinfo->comp_info[2].component_id = 'B'; if (cinfo->master->xyb_mode) { - // Subsample blue channel. - cinfo->comp_info[0].h_samp_factor = cinfo->comp_info[0].v_samp_factor = 2; - cinfo->comp_info[1].h_samp_factor = cinfo->comp_info[1].v_samp_factor = 2; - cinfo->comp_info[2].h_samp_factor = cinfo->comp_info[2].v_samp_factor = 1; // Use separate quantization tables for each component cinfo->comp_info[1].quant_tbl_no = 1; cinfo->comp_info[2].quant_tbl_no = 2; @@ -825,11 +822,6 @@ void jpegli_set_colorspace(j_compress_ptr cinfo, J_COLOR_SPACE colorspace) { cinfo->comp_info[2].quant_tbl_no = 1; cinfo->comp_info[1].dc_tbl_no = cinfo->comp_info[1].ac_tbl_no = 1; cinfo->comp_info[2].dc_tbl_no = cinfo->comp_info[2].ac_tbl_no = 1; - // Use chroma subsampling by default - cinfo->comp_info[0].h_samp_factor = cinfo->comp_info[0].v_samp_factor = 2; - if (colorspace == JCS_YCCK) { - cinfo->comp_info[3].h_samp_factor = cinfo->comp_info[3].v_samp_factor = 2; - } } } From d68556377d77c1942731c339ee7b5af83f9e6271 Mon Sep 17 00:00:00 2001 From: Jonathan Brown Date: Tue, 3 Jun 2025 15:45:30 +0100 Subject: [PATCH 2/2] Fix XYB subsampling --- lib/extras/enc/jpegli.cc | 34 ++++++++++++++++++++++++++-------- 1 file changed, 26 insertions(+), 8 deletions(-) diff --git a/lib/extras/enc/jpegli.cc b/lib/extras/enc/jpegli.cc index 14a7a398..11ce5af1 100644 --- a/lib/extras/enc/jpegli.cc +++ b/lib/extras/enc/jpegli.cc @@ -434,6 +434,8 @@ Status EncodeJpeg(const PackedPixelFile& ppf, const JpegSettings& jpeg_settings, } jpegli_set_cicp_transfer_function(&cinfo, cicp_tf); jpegli_set_defaults(&cinfo); + // All factors need to be specified to subsample the blue channel + // for XYB. H and V are swapped between YCbCr and XYB. if (!jpeg_settings.chroma_subsampling.empty()) { if (jpeg_settings.chroma_subsampling == "444") { cinfo.comp_info[0].h_samp_factor = 1; @@ -441,23 +443,39 @@ Status EncodeJpeg(const PackedPixelFile& ppf, const JpegSettings& jpeg_settings, } else if (jpeg_settings.chroma_subsampling == "440") { cinfo.comp_info[0].h_samp_factor = 1; cinfo.comp_info[0].v_samp_factor = 2; + if (jpeg_settings.xyb) { + cinfo.comp_info[0].h_samp_factor = 2; + cinfo.comp_info[0].v_samp_factor = 2; + cinfo.comp_info[1].h_samp_factor = 2; + cinfo.comp_info[1].v_samp_factor = 2; + cinfo.comp_info[2].h_samp_factor = 2; + cinfo.comp_info[2].v_samp_factor = 1; + } } else if (jpeg_settings.chroma_subsampling == "422") { cinfo.comp_info[0].h_samp_factor = 2; cinfo.comp_info[0].v_samp_factor = 1; + if (jpeg_settings.xyb) { + cinfo.comp_info[0].h_samp_factor = 2; + cinfo.comp_info[0].v_samp_factor = 2; + cinfo.comp_info[1].h_samp_factor = 2; + cinfo.comp_info[1].v_samp_factor = 2; + cinfo.comp_info[2].h_samp_factor = 1; + cinfo.comp_info[2].v_samp_factor = 2; + } } else if (jpeg_settings.chroma_subsampling == "420") { cinfo.comp_info[0].h_samp_factor = 2; cinfo.comp_info[0].v_samp_factor = 2; + if (jpeg_settings.xyb) { + cinfo.comp_info[0].h_samp_factor = 2; + cinfo.comp_info[0].v_samp_factor = 2; + cinfo.comp_info[1].h_samp_factor = 2; + cinfo.comp_info[1].v_samp_factor = 2; + cinfo.comp_info[2].h_samp_factor = 1; + cinfo.comp_info[2].v_samp_factor = 1; + } } else { return false; } - for (int i = 1; i < cinfo.num_components; ++i) { - cinfo.comp_info[i].h_samp_factor = 1; - cinfo.comp_info[i].v_samp_factor = 1; - } - } else if (!jpeg_settings.xyb) { - // Default is no chroma subsampling. - cinfo.comp_info[0].h_samp_factor = 1; - cinfo.comp_info[0].v_samp_factor = 1; } jpegli_enable_adaptive_quantization( &cinfo, TO_JXL_BOOL(jpeg_settings.use_adaptive_quantization));