libjxl

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

tone_map.cc (3589B)


      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/tone_mapping.h"
     11 #include "tools/args.h"
     12 #include "tools/cmdline.h"
     13 #include "tools/file_io.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 max_nits = 0;
     22   parser.AddOptionValue('m', "max_nits", "nits",
     23                         "maximum luminance in the image", &max_nits,
     24                         &jpegxl::tools::ParseFloat, 0);
     25   float target_nits = 0;
     26   auto target_nits_option = parser.AddOptionValue(
     27       't', "target_nits", "nits",
     28       "peak luminance of the display for which to tone map", &target_nits,
     29       &jpegxl::tools::ParseFloat, 0);
     30   float preserve_saturation = .1f;
     31   parser.AddOptionValue(
     32       's', "preserve_saturation", "0..1",
     33       "to what extent to try and preserve saturation over luminance",
     34       &preserve_saturation, &jpegxl::tools::ParseFloat, 0);
     35   bool pq = false;
     36   parser.AddOptionFlag('p', "pq",
     37                        "write the output with absolute luminance using PQ", &pq,
     38                        &jpegxl::tools::SetBooleanTrue, 0);
     39   const char* input_filename = nullptr;
     40   auto input_filename_option = parser.AddPositionalOption(
     41       "input", true, "input image", &input_filename, 0);
     42   const char* output_filename = nullptr;
     43   auto output_filename_option = parser.AddPositionalOption(
     44       "output", true, "output image", &output_filename, 0);
     45 
     46   if (!parser.Parse(argc, argv)) {
     47     fprintf(stderr, "See -h for help.\n");
     48     return EXIT_FAILURE;
     49   }
     50 
     51   if (parser.HelpFlagPassed()) {
     52     parser.PrintHelp();
     53     return EXIT_SUCCESS;
     54   }
     55 
     56   if (!parser.GetOption(target_nits_option)->matched()) {
     57     fprintf(stderr,
     58             "Missing required argument --target_nits.\nSee -h for help.\n");
     59     return EXIT_FAILURE;
     60   }
     61   if (!parser.GetOption(input_filename_option)->matched()) {
     62     fprintf(stderr, "Missing input filename.\nSee -h for help.\n");
     63     return EXIT_FAILURE;
     64   }
     65   if (!parser.GetOption(output_filename_option)->matched()) {
     66     fprintf(stderr, "Missing output filename.\nSee -h for help.\n");
     67     return EXIT_FAILURE;
     68   }
     69 
     70   jxl::CodecInOut image;
     71   jxl::extras::ColorHints color_hints;
     72   color_hints.Add("color_space", "RGB_D65_202_Rel_PeQ");
     73   std::vector<uint8_t> encoded;
     74   JXL_CHECK(jpegxl::tools::ReadFile(input_filename, &encoded));
     75   JXL_CHECK(jxl::SetFromBytes(jxl::Bytes(encoded), color_hints, &image, &pool));
     76   if (max_nits > 0) {
     77     image.metadata.m.SetIntensityTarget(max_nits);
     78   }
     79   JXL_CHECK(jxl::ToneMapTo({0, target_nits}, &image, &pool));
     80   JXL_CHECK(jxl::GamutMap(&image, preserve_saturation, &pool));
     81 
     82   jxl::ColorEncoding c_out = image.metadata.m.color_encoding;
     83   jxl::cms::TransferFunction tf =
     84       pq ? jxl::TransferFunction::kPQ : jxl::TransferFunction::kSRGB;
     85 
     86   if (jxl::extras::CodecFromPath(output_filename) == jxl::extras::Codec::kEXR) {
     87     tf = jxl::TransferFunction::kLinear;
     88     image.metadata.m.SetFloat16Samples();
     89   }
     90   c_out.Tf().SetTransferFunction(tf);
     91 
     92   JXL_CHECK(c_out.CreateICC());
     93   JXL_CHECK(jpegxl::tools::TransformCodecInOutTo(image, c_out, &pool));
     94   image.metadata.m.color_encoding = c_out;
     95   JXL_CHECK(jpegxl::tools::Encode(image, output_filename, &encoded, &pool));
     96   JXL_CHECK(jpegxl::tools::WriteFile(output_filename, encoded));
     97 }