diff options
author | Moonchild <moonchild@palemoon.org> | 2022-11-12 18:34:07 +0000 |
---|---|---|
committer | Moonchild <moonchild@palemoon.org> | 2022-11-12 18:34:07 +0000 |
commit | 31308126938487207d675825f04f265f37b3d4fa (patch) | |
tree | 59c0cb6fc945af9ff7264c472f8c3116d4c0eee3 /media/libjxl/src/tools/cjxl_main.cc | |
parent | 71ae69aea85ec8ddb9bf7baa93ae3926990a3693 (diff) | |
parent | fb0c204f2b59485e796b93ce89f73af552b05c2b (diff) | |
download | uxp-31308126938487207d675825f04f265f37b3d4fa.tar.gz |
Merge branch 'master' into release
Diffstat (limited to 'media/libjxl/src/tools/cjxl_main.cc')
-rw-r--r-- | media/libjxl/src/tools/cjxl_main.cc | 151 |
1 files changed, 151 insertions, 0 deletions
diff --git a/media/libjxl/src/tools/cjxl_main.cc b/media/libjxl/src/tools/cjxl_main.cc new file mode 100644 index 0000000000..157400a13d --- /dev/null +++ b/media/libjxl/src/tools/cjxl_main.cc @@ -0,0 +1,151 @@ +// Copyright (c) the JPEG XL Project Authors. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +#include <stdio.h> + +#include "jxl/encode.h" +#include "lib/jxl/base/file_io.h" +#include "lib/jxl/base/profiler.h" +#include "lib/jxl/jpeg/enc_jpeg_data.h" +#include "tools/box/box.h" +#include "tools/cjxl.h" +#include "tools/codec_config.h" + +namespace jpegxl { +namespace tools { + +enum CjxlRetCode : int { + OK = 0, + ERR_PARSE, + ERR_INVALID_ARG, + ERR_LOAD_INPUT, + ERR_INVALID_INPUT, + ERR_ENCODING, + ERR_CONTAINER, + ERR_WRITE, + DROPPED_JBRD, +}; + +int CompressJpegXlMain(int argc, const char* argv[]) { + CommandLineParser cmdline; + CompressArgs args; + args.AddCommandLineOptions(&cmdline); + + if (!cmdline.Parse(argc, argv)) { + // Parse already printed the actual error cause. + fprintf(stderr, "Use '%s -h' for more information\n", argv[0]); + return CjxlRetCode::ERR_PARSE; + } + + if (args.version) { + fprintf(stdout, "cjxl %s\n", + CodecConfigString(JxlEncoderVersion()).c_str()); + fprintf(stdout, "Copyright (c) the JPEG XL Project\n"); + return CjxlRetCode::OK; + } + + if (!args.quiet) { + fprintf(stderr, "JPEG XL encoder %s\n", + CodecConfigString(JxlEncoderVersion()).c_str()); + } + + if (cmdline.HelpFlagPassed()) { + cmdline.PrintHelp(); + return CjxlRetCode::OK; + } + + if (!args.ValidateArgs(cmdline)) { + // ValidateArgs already printed the actual error cause. + fprintf(stderr, "Use '%s -h' for more information\n", argv[0]); + return CjxlRetCode::ERR_INVALID_ARG; + } + + jxl::PaddedBytes compressed; + + jxl::ThreadPoolInternal pool(args.num_threads); + jxl::CodecInOut io; + double decode_mps = 0; + if (!LoadAll(args, &pool, &io, &decode_mps)) { + return CjxlRetCode::ERR_LOAD_INPUT; + } + + // need to validate again because now we know the input + if (!args.ValidateArgsAfterLoad(cmdline, io)) { + fprintf(stderr, "Use '%s -h' for more information\n", argv[0]); + return CjxlRetCode::ERR_INVALID_INPUT; + } + if (!args.file_out && !args.quiet) { + fprintf(stderr, + "No output file specified.\n" + "Encoding will be performed, but the result will be discarded.\n"); + } + if (!CompressJxl(io, decode_mps, &pool, args, &compressed, !args.quiet)) { + return CjxlRetCode::ERR_ENCODING; + } + + int ret = CjxlRetCode::OK; + if (args.use_container) { + JpegXlContainer container; + container.codestream = std::move(compressed); + if (!io.blobs.exif.empty()) { + container.exif = io.blobs.exif.data(); + container.exif_size = io.blobs.exif.size(); + } + auto append_xml = [&container](const std::vector<uint8_t>& bytes) { + if (bytes.empty()) return; + container.xml.emplace_back(bytes.data(), bytes.size()); + }; + append_xml(io.blobs.xmp); + if (!io.blobs.jumbf.empty()) { + container.jumb = io.blobs.jumbf.data(); + container.jumb_size = io.blobs.jumbf.size(); + } + jxl::PaddedBytes jpeg_data; + if (args.store_jpeg_metadata && io.Main().IsJPEG()) { + jxl::jpeg::JPEGData data_in = *io.Main().jpeg_data; + if (EncodeJPEGData(data_in, &jpeg_data, args.params)) { + container.jpeg_reconstruction = jpeg_data.data(); + container.jpeg_reconstruction_size = jpeg_data.size(); + } else { + fprintf(stderr, "Warning: failed to create JPEG reconstruction data\n"); + ret = CjxlRetCode::DROPPED_JBRD; + } + } + compressed = {}; + if (!EncodeJpegXlContainerOneShot(container, &compressed)) { + fprintf(stderr, "Failed to encode container format\n"); + return CjxlRetCode::ERR_CONTAINER; + } + if (!args.quiet) { + const size_t pixels = io.xsize() * io.ysize(); + const double bpp = + static_cast<double>(compressed.size() * jxl::kBitsPerByte) / pixels; + fprintf(stderr, "Including container: %llu bytes (%.3f bpp%s).\n", + static_cast<long long unsigned>(compressed.size()), + bpp / io.frames.size(), io.frames.size() == 1 ? "" : "/frame"); + } + } + if (args.file_out) { + if (!jxl::WriteFile(compressed, args.file_out)) { + fprintf(stderr, "Failed to write to \"%s\"\n", args.file_out); + return CjxlRetCode::ERR_WRITE; + } + } + + if (args.print_profile == jxl::Override::kOn) { + PROFILER_PRINT_RESULTS(); + } + if (!args.quiet && cmdline.verbosity > 0) { + jxl::CacheAligned::PrintStats(); + } + return ret; +} + +} // namespace tools +} // namespace jpegxl + +int main(int argc, const char** argv) { + return jpegxl::tools::CompressJpegXlMain(argc, argv); +} |