libjxl

FORK: libjxl patches used on blog
git clone https://git.neptards.moe/blog/libjxl.git
Log | Files | Refs | Submodules | README | LICENSE

render_hlg.cc (3752B)


      1 // Copyright (c) the JPEG XL Project Authors. All rights reserved.
      2 //
      3 // Use of this source code is governed by a BSD-style
      4 // license that can be found in the LICENSE file.
      5 
      6 #include <stdio.h>
      7 #include <stdlib.h>
      8 
      9 #include "lib/extras/codec.h"
     10 #include "lib/extras/hlg.h"
     11 #include "lib/extras/tone_mapping.h"
     12 #include "tools/args.h"
     13 #include "tools/cmdline.h"
     14 #include "tools/hdr/image_utils.h"
     15 #include "tools/thread_pool_internal.h"
     16 
     17 int main(int argc, const char** argv) {
     18   jpegxl::tools::ThreadPoolInternal pool;
     19 
     20   jpegxl::tools::CommandLineParser parser;
     21   float target_nits = 0;
     22   auto target_nits_option = parser.AddOptionValue(
     23       't', "target_nits", "nits", "peak luminance of the target display",
     24       &target_nits, &jpegxl::tools::ParseFloat, 0);
     25   float surround_nits = 5;
     26   parser.AddOptionValue(
     27       's', "surround_nits", "nits",
     28       "surround luminance of the viewing environment (default: 5)",
     29       &surround_nits, &jpegxl::tools::ParseFloat, 0);
     30   float preserve_saturation = .1f;
     31   parser.AddOptionValue(
     32       '\0', "preserve_saturation", "0..1",
     33       "to what extent to try and preserve saturation over luminance if a gamma "
     34       "< 1 generates out-of-gamut colors",
     35       &preserve_saturation, &jpegxl::tools::ParseFloat, 0);
     36   bool pq = false;
     37   parser.AddOptionFlag('p', "pq",
     38                        "write the output with absolute luminance using PQ", &pq,
     39                        &jpegxl::tools::SetBooleanTrue, 0);
     40   const char* input_filename = nullptr;
     41   auto input_filename_option = parser.AddPositionalOption(
     42       "input", true, "input image", &input_filename, 0);
     43   const char* output_filename = nullptr;
     44   auto output_filename_option = parser.AddPositionalOption(
     45       "output", true, "output image", &output_filename, 0);
     46 
     47   if (!parser.Parse(argc, argv)) {
     48     fprintf(stderr, "See -h for help.\n");
     49     return EXIT_FAILURE;
     50   }
     51 
     52   if (parser.HelpFlagPassed()) {
     53     parser.PrintHelp();
     54     return EXIT_SUCCESS;
     55   }
     56 
     57   if (!parser.GetOption(target_nits_option)->matched()) {
     58     fprintf(stderr,
     59             "Missing required argument --target_nits.\nSee -h for help.\n");
     60     return EXIT_FAILURE;
     61   }
     62   if (!parser.GetOption(input_filename_option)->matched()) {
     63     fprintf(stderr, "Missing input filename.\nSee -h for help.\n");
     64     return EXIT_FAILURE;
     65   }
     66   if (!parser.GetOption(output_filename_option)->matched()) {
     67     fprintf(stderr, "Missing output filename.\nSee -h for help.\n");
     68     return EXIT_FAILURE;
     69   }
     70 
     71   jxl::CodecInOut image;
     72   jxl::extras::ColorHints color_hints;
     73   color_hints.Add("color_space", "RGB_D65_202_Rel_HLG");
     74   std::vector<uint8_t> encoded;
     75   JXL_CHECK(jpegxl::tools::ReadFile(input_filename, &encoded));
     76   JXL_CHECK(jxl::SetFromBytes(jxl::Bytes(encoded), color_hints, &image, &pool));
     77   // Ensures that conversions to linear by JxlCms will not apply the OOTF as we
     78   // apply it ourselves to control the subsequent gamut mapping.
     79   image.metadata.m.SetIntensityTarget(301);
     80   const float gamma = jxl::GetHlgGamma(target_nits, surround_nits);
     81   fprintf(stderr, "Using a system gamma of %g\n", gamma);
     82   JXL_CHECK(jxl::HlgOOTF(&image.Main(), gamma, &pool));
     83   JXL_CHECK(jxl::GamutMap(&image, preserve_saturation, &pool));
     84   image.metadata.m.SetIntensityTarget(target_nits);
     85 
     86   jxl::ColorEncoding c_out = image.metadata.m.color_encoding;
     87   jxl::cms::TransferFunction tf =
     88       pq ? jxl::TransferFunction::kPQ : jxl::TransferFunction::kSRGB;
     89   c_out.Tf().SetTransferFunction(tf);
     90   JXL_CHECK(c_out.CreateICC());
     91   JXL_CHECK(jpegxl::tools::TransformCodecInOutTo(image, c_out, &pool));
     92   image.metadata.m.color_encoding = c_out;
     93   JXL_CHECK(jpegxl::tools::Encode(image, output_filename, &encoded, &pool));
     94   JXL_CHECK(jpegxl::tools::WriteFile(output_filename, encoded));
     95 }