Compare commits
4 commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5963802d87 | ||
|
|
4ee22d2808 | ||
|
|
95c02f0c1b | ||
|
|
bbdca6f5b2 |
6 changed files with 881 additions and 12 deletions
4
.gitignore
vendored
4
.gitignore
vendored
|
|
@ -4,3 +4,7 @@
|
|||
/third_party-0.5.tar.gz
|
||||
/jpegxl-0.6.1.tar.gz
|
||||
/third_party-0.6.1.tar.gz
|
||||
/jpegxl-0.7.0.tar.gz
|
||||
/third_party-0.7.0.tar.gz
|
||||
/jpegxl-0.7.2.tar.gz
|
||||
/third_party-0.7.2.tar.gz
|
||||
|
|
|
|||
579
795b363120bbcfdbb2e2e4fa85146ac6d385137d.patch
Normal file
579
795b363120bbcfdbb2e2e4fa85146ac6d385137d.patch
Normal file
|
|
@ -0,0 +1,579 @@
|
|||
From 795b363120bbcfdbb2e2e4fa85146ac6d385137d Mon Sep 17 00:00:00 2001
|
||||
From: Jon Sneyers <jon@cloudinary.com>
|
||||
Date: Mon, 29 Aug 2022 08:37:24 +0200
|
||||
Subject: [PATCH] SSIMULACRA 2 (#1646)
|
||||
|
||||
---
|
||||
tools/CMakeLists.txt | 2 +
|
||||
tools/ssimulacra2.cc | 424 ++++++++++++++++++++++++++++++++++++++
|
||||
tools/ssimulacra2.h | 32 +++
|
||||
tools/ssimulacra2_main.cc | 70 +++++++
|
||||
4 files changed, 528 insertions(+)
|
||||
create mode 100644 tools/ssimulacra2.cc
|
||||
create mode 100644 tools/ssimulacra2.h
|
||||
create mode 100644 tools/ssimulacra2_main.cc
|
||||
|
||||
diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt
|
||||
index 739d4bcede..0d6a28f55a 100644
|
||||
--- a/tools/CMakeLists.txt
|
||||
+++ b/tools/CMakeLists.txt
|
||||
@@ -171,6 +171,7 @@ if(JPEGXL_ENABLE_DEVTOOLS)
|
||||
texture_to_cube
|
||||
generate_lut_template
|
||||
ssimulacra_main
|
||||
+ ssimulacra2
|
||||
xyb_range
|
||||
jxl_from_tree
|
||||
)
|
||||
@@ -178,6 +179,7 @@ if(JPEGXL_ENABLE_DEVTOOLS)
|
||||
add_executable(fuzzer_corpus fuzzer_corpus.cc)
|
||||
|
||||
add_executable(ssimulacra_main ssimulacra_main.cc ssimulacra.cc)
|
||||
+ add_executable(ssimulacra2 ssimulacra2_main.cc ssimulacra2.cc)
|
||||
add_executable(butteraugli_main butteraugli_main.cc)
|
||||
add_executable(decode_and_encode decode_and_encode.cc)
|
||||
add_executable(display_to_hlg hdr/display_to_hlg.cc)
|
||||
diff --git a/tools/ssimulacra2.cc b/tools/ssimulacra2.cc
|
||||
new file mode 100644
|
||||
index 0000000000..8bc31b87e7
|
||||
--- /dev/null
|
||||
+++ b/tools/ssimulacra2.cc
|
||||
@@ -0,0 +1,424 @@
|
||||
+// 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.
|
||||
+
|
||||
+/*
|
||||
+SSIMULACRA 2 - Structural SIMilarity Unveiling Local And Compression Related
|
||||
+Artifacts
|
||||
+
|
||||
+Perceptual metric developed by Jon Sneyers (Cloudinary) in July 2022.
|
||||
+Design:
|
||||
+- XYB color space (X+0.5, Y, Y-B+1.0)
|
||||
+- SSIM map
|
||||
+- 'blockiness/ringing' map (distorted has edges where original is smooth)
|
||||
+- 'smoothing' map (distorted is smooth where original has edges)
|
||||
+- error maps are computed at 6 scales (1:1 to 1:32) for each component (X,Y,B)
|
||||
+- for all 6*3*3=54 maps, two norms are computed: 1-norm (mean) and 4-norm
|
||||
+- a weighted sum of these 54*2=108 norms leads to the final score
|
||||
+- weights were tuned based on a large set of subjective scores for images
|
||||
+ compressed with JPEG, JPEG 2000, JPEG XL, WebP, AVIF, and HEIC.
|
||||
+*/
|
||||
+
|
||||
+#include "tools/ssimulacra2.h"
|
||||
+
|
||||
+#include <stdio.h>
|
||||
+
|
||||
+#include <cmath>
|
||||
+
|
||||
+#include "lib/jxl/enc_color_management.h"
|
||||
+#include "lib/jxl/enc_xyb.h"
|
||||
+#include "lib/jxl/gauss_blur.h"
|
||||
+#include "lib/jxl/image_ops.h"
|
||||
+
|
||||
+namespace {
|
||||
+
|
||||
+using jxl::Image3F;
|
||||
+using jxl::ImageF;
|
||||
+
|
||||
+static const float kC1 = 0.0001f;
|
||||
+static const float kC2 = 0.0003f;
|
||||
+static const int kNumScales = 6;
|
||||
+
|
||||
+Image3F Downsample(const Image3F& in, size_t fx, size_t fy) {
|
||||
+ const size_t out_xsize = (in.xsize() + fx - 1) / fx;
|
||||
+ const size_t out_ysize = (in.ysize() + fy - 1) / fy;
|
||||
+ Image3F out(out_xsize, out_ysize);
|
||||
+ const float normalize = 1.0f / (fx * fy);
|
||||
+ for (size_t c = 0; c < 3; ++c) {
|
||||
+ for (size_t oy = 0; oy < out_ysize; ++oy) {
|
||||
+ float* JXL_RESTRICT row_out = out.PlaneRow(c, oy);
|
||||
+ for (size_t ox = 0; ox < out_xsize; ++ox) {
|
||||
+ float sum = 0.0f;
|
||||
+ for (size_t iy = 0; iy < fy; ++iy) {
|
||||
+ for (size_t ix = 0; ix < fx; ++ix) {
|
||||
+ const size_t x = std::min(ox * fx + ix, in.xsize() - 1);
|
||||
+ const size_t y = std::min(oy * fy + iy, in.ysize() - 1);
|
||||
+ sum += in.PlaneRow(c, y)[x];
|
||||
+ }
|
||||
+ }
|
||||
+ row_out[ox] = sum * normalize;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ return out;
|
||||
+}
|
||||
+
|
||||
+void Multiply(const Image3F& a, const Image3F& b, Image3F* mul) {
|
||||
+ for (size_t c = 0; c < 3; ++c) {
|
||||
+ for (size_t y = 0; y < a.ysize(); ++y) {
|
||||
+ const float* JXL_RESTRICT in1 = a.PlaneRow(c, y);
|
||||
+ const float* JXL_RESTRICT in2 = b.PlaneRow(c, y);
|
||||
+ float* JXL_RESTRICT out = mul->PlaneRow(c, y);
|
||||
+ for (size_t x = 0; x < a.xsize(); ++x) {
|
||||
+ out[x] = in1[x] * in2[x];
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+// Temporary storage for Gaussian blur, reused for multiple images.
|
||||
+class Blur {
|
||||
+ public:
|
||||
+ Blur(const size_t xsize, const size_t ysize)
|
||||
+ : rg_(jxl::CreateRecursiveGaussian(1.5)), temp_(xsize, ysize) {}
|
||||
+
|
||||
+ void operator()(const ImageF& in, ImageF* JXL_RESTRICT out) {
|
||||
+ jxl::ThreadPool* null_pool = nullptr;
|
||||
+ FastGaussian(rg_, in, null_pool, &temp_, out);
|
||||
+ }
|
||||
+
|
||||
+ Image3F operator()(const Image3F& in) {
|
||||
+ Image3F out(in.xsize(), in.ysize());
|
||||
+ operator()(in.Plane(0), &out.Plane(0));
|
||||
+ operator()(in.Plane(1), &out.Plane(1));
|
||||
+ operator()(in.Plane(2), &out.Plane(2));
|
||||
+ return out;
|
||||
+ }
|
||||
+
|
||||
+ // Allows reusing across scales.
|
||||
+ void ShrinkTo(const size_t xsize, const size_t ysize) {
|
||||
+ temp_.ShrinkTo(xsize, ysize);
|
||||
+ }
|
||||
+
|
||||
+ private:
|
||||
+ hwy::AlignedUniquePtr<jxl::RecursiveGaussian> rg_;
|
||||
+ ImageF temp_;
|
||||
+};
|
||||
+
|
||||
+double tothe4th(double x) {
|
||||
+ x *= x;
|
||||
+ x *= x;
|
||||
+ return x;
|
||||
+}
|
||||
+void SSIMMap(const Image3F& m1, const Image3F& m2, const Image3F& s11,
|
||||
+ const Image3F& s22, const Image3F& s12, double* plane_averages) {
|
||||
+ const double onePerPixels = 1.0 / (m1.ysize() * m1.xsize());
|
||||
+ for (size_t c = 0; c < 3; ++c) {
|
||||
+ double sum1[2] = {0.0};
|
||||
+ for (size_t y = 0; y < m1.ysize(); ++y) {
|
||||
+ const float* JXL_RESTRICT row_m1 = m1.PlaneRow(c, y);
|
||||
+ const float* JXL_RESTRICT row_m2 = m2.PlaneRow(c, y);
|
||||
+ const float* JXL_RESTRICT row_s11 = s11.PlaneRow(c, y);
|
||||
+ const float* JXL_RESTRICT row_s22 = s22.PlaneRow(c, y);
|
||||
+ const float* JXL_RESTRICT row_s12 = s12.PlaneRow(c, y);
|
||||
+ for (size_t x = 0; x < m1.xsize(); ++x) {
|
||||
+ float mu1 = row_m1[x];
|
||||
+ float mu2 = row_m2[x];
|
||||
+ float mu11 = mu1 * mu1;
|
||||
+ float mu22 = mu2 * mu2;
|
||||
+ float mu12 = mu1 * mu2;
|
||||
+ float num_m = 2 * mu12 + kC1;
|
||||
+ float num_s = 2 * (row_s12[x] - mu12) + kC2;
|
||||
+ float denom_m = mu11 + mu22 + kC1;
|
||||
+ float denom_s = (row_s11[x] - mu11) + (row_s22[x] - mu22) + kC2;
|
||||
+ double d = 1.0 - ((num_m * num_s) / (denom_m * denom_s));
|
||||
+ d = std::max(d, 0.0);
|
||||
+ sum1[0] += d;
|
||||
+ sum1[1] += tothe4th(d);
|
||||
+ }
|
||||
+ }
|
||||
+ plane_averages[c * 2] = onePerPixels * sum1[0];
|
||||
+ plane_averages[c * 2 + 1] = sqrt(sqrt(onePerPixels * sum1[1]));
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+void EdgeDiffMap(const Image3F& img1, const Image3F& mu1, const Image3F& img2,
|
||||
+ const Image3F& mu2, double* plane_averages) {
|
||||
+ const double onePerPixels = 1.0 / (img1.ysize() * img1.xsize());
|
||||
+ for (size_t c = 0; c < 3; ++c) {
|
||||
+ double sum1[4] = {0.0};
|
||||
+ for (size_t y = 0; y < img1.ysize(); ++y) {
|
||||
+ const float* JXL_RESTRICT row1 = img1.PlaneRow(c, y);
|
||||
+ const float* JXL_RESTRICT row2 = img2.PlaneRow(c, y);
|
||||
+ const float* JXL_RESTRICT rowm1 = mu1.PlaneRow(c, y);
|
||||
+ const float* JXL_RESTRICT rowm2 = mu2.PlaneRow(c, y);
|
||||
+ for (size_t x = 0; x < img1.xsize(); ++x) {
|
||||
+ double d1 = (1.0 + std::abs(row2[x] - rowm2[x])) /
|
||||
+ (1.0 + std::abs(row1[x] - rowm1[x])) -
|
||||
+ 1.0;
|
||||
+ // d1 > 0: distorted has an edge where original is smooth
|
||||
+ // (indicating ringing, color banding, blockiness, etc)
|
||||
+ // d1 < 0: original has an edge where distorted is smooth
|
||||
+ // (indicating smoothing, blurring, smearing, etc)
|
||||
+ double artifact = std::max(d1, 0.0);
|
||||
+ sum1[0] += artifact;
|
||||
+ sum1[1] += tothe4th(artifact);
|
||||
+ double detail_lost = std::max(-d1, 0.0);
|
||||
+ sum1[2] += detail_lost;
|
||||
+ sum1[3] += tothe4th(detail_lost);
|
||||
+ }
|
||||
+ }
|
||||
+ plane_averages[c * 4] = onePerPixels * sum1[0];
|
||||
+ plane_averages[c * 4 + 1] = sqrt(sqrt(onePerPixels * sum1[1]));
|
||||
+ plane_averages[c * 4 + 2] = onePerPixels * sum1[2];
|
||||
+ plane_averages[c * 4 + 3] = sqrt(sqrt(onePerPixels * sum1[3]));
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+// Add 0.5 to X and turn B into 1 + B-Y
|
||||
+// (SSIM expects non-negative ranges)
|
||||
+void MakePositiveXYB(jxl::Image3F& img) {
|
||||
+ for (size_t y = 0; y < img.ysize(); ++y) {
|
||||
+ const float* JXL_RESTRICT rowY = img.PlaneRow(1, y);
|
||||
+ float* JXL_RESTRICT rowB = img.PlaneRow(2, y);
|
||||
+ float* JXL_RESTRICT rowX = img.PlaneRow(0, y);
|
||||
+ for (size_t x = 0; x < img.xsize(); ++x) {
|
||||
+ rowB[x] += 1.0f - rowY[x];
|
||||
+ rowX[x] += 0.5f;
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+void AlphaBlend(jxl::ImageBundle& img, float bg) {
|
||||
+ for (size_t y = 0; y < img.ysize(); ++y) {
|
||||
+ float* JXL_RESTRICT r = img.color()->PlaneRow(0, y);
|
||||
+ float* JXL_RESTRICT g = img.color()->PlaneRow(1, y);
|
||||
+ float* JXL_RESTRICT b = img.color()->PlaneRow(2, y);
|
||||
+ const float* JXL_RESTRICT a = img.alpha()->Row(y);
|
||||
+ for (size_t x = 0; x < img.xsize(); ++x) {
|
||||
+ r[x] = a[x] * r[x] + (1.f - a[x]) * bg;
|
||||
+ g[x] = a[x] * g[x] + (1.f - a[x]) * bg;
|
||||
+ b[x] = a[x] * b[x] + (1.f - a[x]) * bg;
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+} // namespace
|
||||
+
|
||||
+/*
|
||||
+The final score is based on a weighted sum of 108 sub-scores:
|
||||
+- for 6 scales (1:1 to 1:32)
|
||||
+- for 3 components (X + 0.5, Y, B - Y + 1.0)
|
||||
+- using 2 norms (the 1-norm and the 4-norm)
|
||||
+- over 3 error maps:
|
||||
+ - SSIM
|
||||
+ - "ringing" (distorted edges where there are no orig edges)
|
||||
+ - "blurring" (orig edges where there are no distorted edges)
|
||||
+
|
||||
+The weights were obtained by running Nelder-Mead simplex search,
|
||||
+optimizing to minimize MSE and maximize Kendall and Pearson correlation
|
||||
+for training data consisting of 17611 subjective quality scores,
|
||||
+validated on separate validation data consisting of 4292 scores.
|
||||
+*/
|
||||
+double Msssim::Score() const {
|
||||
+ double ssim = 0.0;
|
||||
+
|
||||
+ constexpr double weight[108] = {-0.4887721343447775,
|
||||
+ 0.023424809409418046,
|
||||
+ -2.030114616889109,
|
||||
+ 0.09295054976135864,
|
||||
+ -0.6104037165108389,
|
||||
+ -1.5043796645843681,
|
||||
+ 0.7157171902116809,
|
||||
+ 0.021100488642748494,
|
||||
+ 0.020230927541050825,
|
||||
+ 0.2133671136286971,
|
||||
+ 2.907924945735136,
|
||||
+ 0.022228357764969564,
|
||||
+ -0.5071214811492599,
|
||||
+ 0.02509144129036578,
|
||||
+ 0.022718837619484678,
|
||||
+ 0.06120691522596422,
|
||||
+ 0.30589062196252637,
|
||||
+ 1.0329845093332668,
|
||||
+ 0.014860334913185502,
|
||||
+ 0.01765439482987108,
|
||||
+ 0.015223496420421201,
|
||||
+ 0.3352969449271075,
|
||||
+ 0.022351073746802674,
|
||||
+ 4.920455953428159,
|
||||
+ 0.024538210211043743,
|
||||
+ 0.019983582316880577,
|
||||
+ 0.03292085152661295,
|
||||
+ 0.030445280321387935,
|
||||
+ 10.0,
|
||||
+ 0.018398131276209817,
|
||||
+ 0.01980139702737216,
|
||||
+ 0.01896441623922851,
|
||||
+ 0.022574971070788208,
|
||||
+ 0.01961469275632899,
|
||||
+ 0.017925070068654958,
|
||||
+ 0.022549199991725777,
|
||||
+ 0.042694824314348456,
|
||||
+ -1.1040485020844724,
|
||||
+ -0.8328856967713545,
|
||||
+ 0.010486287554451912,
|
||||
+ -0.15815014109963288,
|
||||
+ 0.5276802305511856,
|
||||
+ -0.16586473934630663,
|
||||
+ -1.6713862869185236,
|
||||
+ -0.5685528568072895,
|
||||
+ 0.015496263249374809,
|
||||
+ 0.3313776030981479,
|
||||
+ 0.5841917745193543,
|
||||
+ 0.9532541813860999,
|
||||
+ 1.6364826627594853,
|
||||
+ -1.4297400383069743,
|
||||
+ 0.054491944876914444,
|
||||
+ 0.17913906220820508,
|
||||
+ 0.44577334447914807,
|
||||
+ 0.5681719372906395,
|
||||
+ 3.32951901196007,
|
||||
+ 0.020829537529045927,
|
||||
+ -0.5816250842771562,
|
||||
+ -0.45135245825393433,
|
||||
+ -0.7025952973955096,
|
||||
+ 0.4838975315421883,
|
||||
+ 8.711509549878194,
|
||||
+ 0.791270929375639,
|
||||
+ 0.581356024160242,
|
||||
+ 0.3922969596921355,
|
||||
+ -0.7387562349132657,
|
||||
+ -1.2614352370812663,
|
||||
+ -0.8858225265098523,
|
||||
+ 0.019758617519097244,
|
||||
+ 0.14685779225447715,
|
||||
+ -1.8664586782764085,
|
||||
+ 0.17359675572073996,
|
||||
+ 0.03043962244431553,
|
||||
+ 1.68973994737285,
|
||||
+ 0.14241547168885893,
|
||||
+ -0.006681229849861969,
|
||||
+ 0.035286585384673774,
|
||||
+ -0.1867844252373887,
|
||||
+ -0.05325949297845933,
|
||||
+ -0.6188421202762768,
|
||||
+ 0.019256498690954693,
|
||||
+ 0.011261488314097567,
|
||||
+ -0.8734726170866911,
|
||||
+ 0.2611408152583321,
|
||||
+ 0.018228313151663178,
|
||||
+ 0.9920747746816749,
|
||||
+ -1.9939450259663953,
|
||||
+ -0.010909816645386039,
|
||||
+ 0.8744010916528506,
|
||||
+ 0.3484037761057752,
|
||||
+ 0.01700115030331162,
|
||||
+ 0.0200509230497925,
|
||||
+ 0.9049230270226147,
|
||||
+ -0.03502086486907441,
|
||||
+ -0.13860433328031307,
|
||||
+ -0.5008190311548453,
|
||||
+ 0.13113827477880657,
|
||||
+ 3.814948743048878,
|
||||
+ 3.369522386056538,
|
||||
+ 0.002328237048341175,
|
||||
+ 0.9372362537216947,
|
||||
+ 0.9359420764223362,
|
||||
+ -1.0601842054652018,
|
||||
+ 0.01621181769404767,
|
||||
+ -0.4876602083027073,
|
||||
+ 0.1933464422710256,
|
||||
+ -2.10812470816676,
|
||||
+ 0.018569908820821213};
|
||||
+ size_t i = 0;
|
||||
+ for (size_t c = 0; c < 3; ++c) {
|
||||
+ for (size_t scale = 0; scale < scales.size(); ++scale) {
|
||||
+ for (size_t n = 0; n < 2; n++) {
|
||||
+#ifdef SSIMULACRA2_OUTPUT_RAW_SCORES_FOR_WEIGHT_TUNING
|
||||
+ printf("%.12f,%.12f,%.12f,", scales[scale].avg_ssim[c * 2 + n],
|
||||
+ scales[scale].avg_edgediff[c * 4 + n],
|
||||
+ scales[scale].avg_edgediff[c * 4 + 2 + n]);
|
||||
+#endif
|
||||
+ ssim += weight[i++] * std::abs(scales[scale].avg_ssim[c * 2 + n]);
|
||||
+ ssim += weight[i++] * std::abs(scales[scale].avg_edgediff[c * 4 + n]);
|
||||
+ ssim +=
|
||||
+ weight[i++] * std::abs(scales[scale].avg_edgediff[c * 4 + n + 2]);
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ ssim *= 272.58355078216107;
|
||||
+ ssim += -0.12953872587232876;
|
||||
+
|
||||
+ if (ssim > 0) {
|
||||
+ ssim = 100.0 - 10.0 * pow(ssim, 0.6940375837127916);
|
||||
+ } else {
|
||||
+ ssim = 100.0;
|
||||
+ }
|
||||
+ return ssim;
|
||||
+}
|
||||
+
|
||||
+Msssim ComputeSSIMULACRA2(const jxl::ImageBundle& orig,
|
||||
+ const jxl::ImageBundle& dist, float bg) {
|
||||
+ Msssim msssim;
|
||||
+
|
||||
+ jxl::Image3F img1(orig.xsize(), orig.ysize());
|
||||
+ jxl::Image3F img2(img1.xsize(), img1.ysize());
|
||||
+
|
||||
+ if (orig.HasAlpha()) {
|
||||
+ jxl::ImageBundle orig2 = orig.Copy();
|
||||
+ AlphaBlend(orig2, bg);
|
||||
+ jxl::ToXYB(orig2, nullptr, &img1, jxl::GetJxlCms(), nullptr);
|
||||
+ } else {
|
||||
+ jxl::ToXYB(orig, nullptr, &img1, jxl::GetJxlCms(), nullptr);
|
||||
+ }
|
||||
+ if (dist.HasAlpha()) {
|
||||
+ jxl::ImageBundle dist2 = dist.Copy();
|
||||
+ AlphaBlend(dist2, bg);
|
||||
+ jxl::ToXYB(dist2, nullptr, &img2, jxl::GetJxlCms(), nullptr);
|
||||
+ } else {
|
||||
+ jxl::ToXYB(dist, nullptr, &img2, jxl::GetJxlCms(), nullptr);
|
||||
+ }
|
||||
+ MakePositiveXYB(img1);
|
||||
+ MakePositiveXYB(img2);
|
||||
+
|
||||
+ Image3F mul(img1.xsize(), img1.ysize());
|
||||
+ Blur blur(img1.xsize(), img1.ysize());
|
||||
+
|
||||
+ for (int scale = 0; scale < kNumScales; scale++) {
|
||||
+ if (img1.xsize() < 8 || img1.ysize() < 8) {
|
||||
+ break;
|
||||
+ }
|
||||
+ if (scale) {
|
||||
+ img1 = Downsample(img1, 2, 2);
|
||||
+ img2 = Downsample(img2, 2, 2);
|
||||
+ }
|
||||
+ mul.ShrinkTo(img1.xsize(), img2.ysize());
|
||||
+ blur.ShrinkTo(img1.xsize(), img2.ysize());
|
||||
+
|
||||
+ Multiply(img1, img1, &mul);
|
||||
+ Image3F sigma1_sq = blur(mul);
|
||||
+
|
||||
+ Multiply(img2, img2, &mul);
|
||||
+ Image3F sigma2_sq = blur(mul);
|
||||
+
|
||||
+ Multiply(img1, img2, &mul);
|
||||
+ Image3F sigma12 = blur(mul);
|
||||
+
|
||||
+ Image3F mu1 = blur(img1);
|
||||
+ Image3F mu2 = blur(img2);
|
||||
+
|
||||
+ MsssimScale sscale;
|
||||
+ SSIMMap(mu1, mu2, sigma1_sq, sigma2_sq, sigma12, sscale.avg_ssim);
|
||||
+ EdgeDiffMap(img1, mu1, img2, mu2, sscale.avg_edgediff);
|
||||
+ msssim.scales.push_back(sscale);
|
||||
+ }
|
||||
+ return msssim;
|
||||
+}
|
||||
+
|
||||
+Msssim ComputeSSIMULACRA2(const jxl::ImageBundle& orig,
|
||||
+ const jxl::ImageBundle& distorted) {
|
||||
+ return ComputeSSIMULACRA2(orig, distorted, 0.5f);
|
||||
+}
|
||||
diff --git a/tools/ssimulacra2.h b/tools/ssimulacra2.h
|
||||
new file mode 100644
|
||||
index 0000000000..36d1193112
|
||||
--- /dev/null
|
||||
+++ b/tools/ssimulacra2.h
|
||||
@@ -0,0 +1,32 @@
|
||||
+// 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.
|
||||
+
|
||||
+#ifndef TOOLS_SSIMULACRA2_H_
|
||||
+#define TOOLS_SSIMULACRA2_H_
|
||||
+
|
||||
+#include <vector>
|
||||
+
|
||||
+#include "lib/jxl/image_bundle.h"
|
||||
+
|
||||
+struct MsssimScale {
|
||||
+ double avg_ssim[3 * 2];
|
||||
+ double avg_edgediff[3 * 4];
|
||||
+};
|
||||
+
|
||||
+struct Msssim {
|
||||
+ std::vector<MsssimScale> scales;
|
||||
+
|
||||
+ double Score() const;
|
||||
+};
|
||||
+
|
||||
+// Computes the SSIMULACRA 2 score between reference image 'orig' and
|
||||
+// distorted image 'distorted'. In case of alpha transparency, assume
|
||||
+// a gray background if intensity 'bg' (in range 0..1).
|
||||
+Msssim ComputeSSIMULACRA2(const jxl::ImageBundle &orig,
|
||||
+ const jxl::ImageBundle &distorted, float bg);
|
||||
+Msssim ComputeSSIMULACRA2(const jxl::ImageBundle &orig,
|
||||
+ const jxl::ImageBundle &distorted);
|
||||
+
|
||||
+#endif // TOOLS_SSIMULACRA2_H_
|
||||
diff --git a/tools/ssimulacra2_main.cc b/tools/ssimulacra2_main.cc
|
||||
new file mode 100644
|
||||
index 0000000000..35e284b5dc
|
||||
--- /dev/null
|
||||
+++ b/tools/ssimulacra2_main.cc
|
||||
@@ -0,0 +1,70 @@
|
||||
+// 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 "lib/extras/codec.h"
|
||||
+#include "lib/jxl/color_management.h"
|
||||
+#include "lib/jxl/enc_color_management.h"
|
||||
+#include "tools/ssimulacra2.h"
|
||||
+
|
||||
+int PrintUsage(char** argv) {
|
||||
+ fprintf(stderr, "Usage: %s orig.png distorted.png\n", argv[0]);
|
||||
+ fprintf(stderr,
|
||||
+ "Returns a score in range -inf..100, which correlates to subjective "
|
||||
+ "visual quality:\n");
|
||||
+ fprintf(stderr,
|
||||
+ " 30 = low quality (p10 worst output of mozjpeg -quality 30)\n");
|
||||
+ fprintf(stderr,
|
||||
+ " 50 = medium quality (average output of cjxl -q 40 or mozjpeg "
|
||||
+ "-quality 40,\n");
|
||||
+ fprintf(stderr,
|
||||
+ " p10 output of cjxl -q 50 or mozjpeg "
|
||||
+ "-quality 60)\n");
|
||||
+ fprintf(stderr,
|
||||
+ " 70 = high quality (average output of cjxl -q 70 or mozjpeg "
|
||||
+ "-quality 70,\n");
|
||||
+ fprintf(stderr,
|
||||
+ " p10 output of cjxl -q 75 or mozjpeg "
|
||||
+ "-quality 80)\n");
|
||||
+ fprintf(stderr,
|
||||
+ " 90 = very high quality (impossible to distinguish from "
|
||||
+ "original at 1:1,\n");
|
||||
+ fprintf(stderr,
|
||||
+ " average output of cjxl -q 90 or "
|
||||
+ "mozjpeg -quality 90)\n");
|
||||
+ return 1;
|
||||
+}
|
||||
+
|
||||
+int main(int argc, char** argv) {
|
||||
+ if (argc != 3) return PrintUsage(argv);
|
||||
+
|
||||
+ jxl::CodecInOut io1;
|
||||
+ jxl::CodecInOut io2;
|
||||
+ JXL_CHECK(SetFromFile(argv[1], jxl::extras::ColorHints(), &io1));
|
||||
+
|
||||
+ if (io1.xsize() < 8 || io1.ysize() < 8) {
|
||||
+ fprintf(stderr, "Minimum image size is 8x8 pixels\n");
|
||||
+ return 1;
|
||||
+ }
|
||||
+
|
||||
+ JXL_CHECK(SetFromFile(argv[2], jxl::extras::ColorHints(), &io2));
|
||||
+ if (io1.xsize() != io2.xsize() || io1.ysize() != io2.ysize()) {
|
||||
+ fprintf(stderr, "Image size mismatch\n");
|
||||
+ return 1;
|
||||
+ }
|
||||
+
|
||||
+ if (!io1.Main().HasAlpha()) {
|
||||
+ Msssim msssim = ComputeSSIMULACRA2(io1.Main(), io2.Main());
|
||||
+ printf("%.8f\n", msssim.Score());
|
||||
+ } else {
|
||||
+ // in case of alpha transparency: blend against dark and bright backgrounds
|
||||
+ // and return the worst of both scores
|
||||
+ Msssim msssim0 = ComputeSSIMULACRA2(io1.Main(), io2.Main(), 0.1f);
|
||||
+ Msssim msssim1 = ComputeSSIMULACRA2(io1.Main(), io2.Main(), 0.9f);
|
||||
+ printf("%.8f\n", std::min(msssim0.Score(), msssim1.Score()));
|
||||
+ }
|
||||
+ return 0;
|
||||
+}
|
||||
234
873890998bb151ba54a865cdbd61df22af29774c.patch
Normal file
234
873890998bb151ba54a865cdbd61df22af29774c.patch
Normal file
|
|
@ -0,0 +1,234 @@
|
|||
From 873890998bb151ba54a865cdbd61df22af29774c Mon Sep 17 00:00:00 2001
|
||||
From: Sami Boukortt <sboukortt@google.com>
|
||||
Date: Mon, 22 Aug 2022 16:08:20 +0200
|
||||
Subject: [PATCH] Tool for converting EXR images to PQ PNGs
|
||||
|
||||
---
|
||||
lib/extras/dec/exr.cc | 2 +-
|
||||
tools/CMakeLists.txt | 2 +
|
||||
tools/hdr/README.md | 16 +++++
|
||||
tools/hdr/exr_to_pq.cc | 155 +++++++++++++++++++++++++++++++++++++++++
|
||||
4 files changed, 174 insertions(+), 1 deletion(-)
|
||||
create mode 100644 tools/hdr/exr_to_pq.cc
|
||||
|
||||
diff --git a/lib/extras/dec/exr.cc b/lib/extras/dec/exr.cc
|
||||
index ddb6d534e5..e63c005628 100644
|
||||
--- a/lib/extras/dec/exr.cc
|
||||
+++ b/lib/extras/dec/exr.cc
|
||||
@@ -87,7 +87,7 @@ Status DecodeImageEXR(Span<const uint8_t> bytes, const ColorHints& color_hints,
|
||||
|
||||
const float intensity_target = OpenEXR::hasWhiteLuminance(input.header())
|
||||
? OpenEXR::whiteLuminance(input.header())
|
||||
- : kDefaultIntensityTarget;
|
||||
+ : 0;
|
||||
|
||||
auto image_size = input.displayWindow().size();
|
||||
// Size is computed as max - min, but both bounds are inclusive.
|
||||
diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt
|
||||
index ed773190ec..739d4bcede 100644
|
||||
--- a/tools/CMakeLists.txt
|
||||
+++ b/tools/CMakeLists.txt
|
||||
@@ -164,6 +164,7 @@ if(JPEGXL_ENABLE_DEVTOOLS)
|
||||
butteraugli_main
|
||||
decode_and_encode
|
||||
display_to_hlg
|
||||
+ exr_to_pq
|
||||
pq_to_hlg
|
||||
render_hlg
|
||||
tone_map
|
||||
@@ -180,6 +181,7 @@ if(JPEGXL_ENABLE_DEVTOOLS)
|
||||
add_executable(butteraugli_main butteraugli_main.cc)
|
||||
add_executable(decode_and_encode decode_and_encode.cc)
|
||||
add_executable(display_to_hlg hdr/display_to_hlg.cc)
|
||||
+ add_executable(exr_to_pq hdr/exr_to_pq.cc)
|
||||
add_executable(pq_to_hlg hdr/pq_to_hlg.cc)
|
||||
add_executable(render_hlg hdr/render_hlg.cc)
|
||||
add_executable(tone_map hdr/tone_map.cc)
|
||||
diff --git a/tools/hdr/README.md b/tools/hdr/README.md
|
||||
index 227b22b3e4..85eb1bd774 100644
|
||||
--- a/tools/hdr/README.md
|
||||
+++ b/tools/hdr/README.md
|
||||
@@ -99,6 +99,22 @@ This is the mathematical inverse of `tools/render_hlg`. Furthermore,
|
||||
`tools/pq_to_hlg` is equivalent to `tools/tone_map -t 1000` followed by
|
||||
`tools/display_to_hlg -m 1000`.
|
||||
|
||||
+## OpenEXR to PQ
|
||||
+
|
||||
+`tools/exr_to_pq` converts an OpenEXR image into a Rec. 2020 + PQ image, which
|
||||
+can be saved as a PNG or PPM file. Luminance information is taken from the
|
||||
+`whiteLuminance` tag if the input has it, and otherwise defaults to treating
|
||||
+(1, 1, 1) as 100 cd/m². It is also possible to override this using the
|
||||
+`--luminance` (`-l`) flag, in two different ways:
|
||||
+
|
||||
+```shell
|
||||
+# Specifies that the brightest pixel in the image happens to be 1500 cd/m².
|
||||
+$ tools/exr_to_pq --luminance='max=1500' input.exr output.png
|
||||
+
|
||||
+# Specifies that (1, 1, 1) in the input file is 203 cd/m².
|
||||
+$ tools/exr_to_pq --luminance='white=203' input.exr output.png
|
||||
+```
|
||||
+
|
||||
# LUT generation
|
||||
|
||||
There are additionally two tools that can be used to generate look-up tables
|
||||
diff --git a/tools/hdr/exr_to_pq.cc b/tools/hdr/exr_to_pq.cc
|
||||
new file mode 100644
|
||||
index 0000000000..6162b72221
|
||||
--- /dev/null
|
||||
+++ b/tools/hdr/exr_to_pq.cc
|
||||
@@ -0,0 +1,155 @@
|
||||
+// 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 <stdlib.h>
|
||||
+
|
||||
+#include "lib/extras/codec.h"
|
||||
+#include "lib/extras/dec/decode.h"
|
||||
+#include "lib/extras/packed_image_convert.h"
|
||||
+#include "lib/jxl/base/file_io.h"
|
||||
+#include "lib/jxl/base/thread_pool_internal.h"
|
||||
+#include "lib/jxl/enc_color_management.h"
|
||||
+#include "tools/cmdline.h"
|
||||
+
|
||||
+namespace {
|
||||
+
|
||||
+struct LuminanceInfo {
|
||||
+ enum class Kind { kWhite, kMaximum };
|
||||
+ Kind kind = Kind::kWhite;
|
||||
+ float luminance = 100.f;
|
||||
+};
|
||||
+
|
||||
+bool ParseLuminanceInfo(const char* argument, LuminanceInfo* luminance_info) {
|
||||
+ if (strncmp(argument, "white=", 6) == 0) {
|
||||
+ luminance_info->kind = LuminanceInfo::Kind::kWhite;
|
||||
+ argument += 6;
|
||||
+ } else if (strncmp(argument, "max=", 4) == 0) {
|
||||
+ luminance_info->kind = LuminanceInfo::Kind::kMaximum;
|
||||
+ argument += 4;
|
||||
+ } else {
|
||||
+ fprintf(stderr,
|
||||
+ "Invalid prefix for luminance info, expected white= or max=\n");
|
||||
+ return false;
|
||||
+ }
|
||||
+ return jpegxl::tools::ParseFloat(argument, &luminance_info->luminance);
|
||||
+}
|
||||
+
|
||||
+} // namespace
|
||||
+
|
||||
+int main(int argc, const char** argv) {
|
||||
+ jxl::ThreadPoolInternal pool;
|
||||
+
|
||||
+ jpegxl::tools::CommandLineParser parser;
|
||||
+ LuminanceInfo luminance_info;
|
||||
+ auto luminance_option =
|
||||
+ parser.AddOptionValue('l', "luminance", "<max|white=N>",
|
||||
+ "luminance information (defaults to whiteLuminance "
|
||||
+ "header if present, otherwise to white=100)",
|
||||
+ &luminance_info, &ParseLuminanceInfo, 0);
|
||||
+ const char* input_filename = nullptr;
|
||||
+ auto input_filename_option = parser.AddPositionalOption(
|
||||
+ "input", true, "input image", &input_filename, 0);
|
||||
+ const char* output_filename = nullptr;
|
||||
+ auto output_filename_option = parser.AddPositionalOption(
|
||||
+ "output", true, "output image", &output_filename, 0);
|
||||
+
|
||||
+ if (!parser.Parse(argc, argv)) {
|
||||
+ fprintf(stderr, "See -h for help.\n");
|
||||
+ return EXIT_FAILURE;
|
||||
+ }
|
||||
+
|
||||
+ if (parser.HelpFlagPassed()) {
|
||||
+ parser.PrintHelp();
|
||||
+ return EXIT_SUCCESS;
|
||||
+ }
|
||||
+
|
||||
+ if (!parser.GetOption(input_filename_option)->matched()) {
|
||||
+ fprintf(stderr, "Missing input filename.\nSee -h for help.\n");
|
||||
+ return EXIT_FAILURE;
|
||||
+ }
|
||||
+ if (!parser.GetOption(output_filename_option)->matched()) {
|
||||
+ fprintf(stderr, "Missing output filename.\nSee -h for help.\n");
|
||||
+ return EXIT_FAILURE;
|
||||
+ }
|
||||
+
|
||||
+ jxl::extras::PackedPixelFile ppf;
|
||||
+ std::vector<uint8_t> input_bytes;
|
||||
+ JXL_CHECK(jxl::ReadFile(input_filename, &input_bytes));
|
||||
+ JXL_CHECK(jxl::extras::DecodeBytes(jxl::Span<const uint8_t>(input_bytes),
|
||||
+ jxl::extras::ColorHints(),
|
||||
+ jxl::SizeConstraints(), &ppf));
|
||||
+
|
||||
+ jxl::CodecInOut image;
|
||||
+ JXL_CHECK(
|
||||
+ jxl::extras::ConvertPackedPixelFileToCodecInOut(ppf, &pool, &image));
|
||||
+ image.metadata.m.bit_depth.exponent_bits_per_sample = 0;
|
||||
+ jxl::ColorEncoding linear_rec_2020 = image.Main().c_current();
|
||||
+ linear_rec_2020.primaries = jxl::Primaries::k2100;
|
||||
+ linear_rec_2020.tf.SetTransferFunction(jxl::TransferFunction::kLinear);
|
||||
+ JXL_CHECK(linear_rec_2020.CreateICC());
|
||||
+ JXL_CHECK(image.TransformTo(linear_rec_2020, jxl::GetJxlCms(), &pool));
|
||||
+
|
||||
+ float primaries_xyz[9];
|
||||
+ const jxl::PrimariesCIExy primaries = image.Main().c_current().GetPrimaries();
|
||||
+ const jxl::CIExy white_point = image.Main().c_current().GetWhitePoint();
|
||||
+ JXL_CHECK(jxl::PrimariesToXYZ(primaries.r.x, primaries.r.y, primaries.g.x,
|
||||
+ primaries.g.y, primaries.b.x, primaries.b.y,
|
||||
+ white_point.x, white_point.y, primaries_xyz));
|
||||
+
|
||||
+ float max_value = 0.f;
|
||||
+ float max_relative_luminance = 0.f;
|
||||
+ float white_luminance = ppf.info.intensity_target != 0 &&
|
||||
+ !parser.GetOption(luminance_option)->matched()
|
||||
+ ? ppf.info.intensity_target
|
||||
+ : luminance_info.kind == LuminanceInfo::Kind::kWhite
|
||||
+ ? luminance_info.luminance
|
||||
+ : 0.f;
|
||||
+ bool out_of_gamut = false;
|
||||
+ for (size_t y = 0; y < image.ysize(); ++y) {
|
||||
+ const float* const rows[3] = {image.Main().color()->ConstPlaneRow(0, y),
|
||||
+ image.Main().color()->ConstPlaneRow(1, y),
|
||||
+ image.Main().color()->ConstPlaneRow(2, y)};
|
||||
+ for (size_t x = 0; x < image.xsize(); ++x) {
|
||||
+ if (!out_of_gamut &&
|
||||
+ (rows[0][x] < 0 || rows[1][x] < 0 || rows[2][x] < 0)) {
|
||||
+ out_of_gamut = true;
|
||||
+ fprintf(stderr,
|
||||
+ "WARNING: found colors outside of the Rec. 2020 gamut.\n");
|
||||
+ }
|
||||
+ max_value = std::max(
|
||||
+ max_value, std::max(rows[0][x], std::max(rows[1][x], rows[2][x])));
|
||||
+ const float luminance = primaries_xyz[1] * rows[0][x] +
|
||||
+ primaries_xyz[4] * rows[1][x] +
|
||||
+ primaries_xyz[7] * rows[2][x];
|
||||
+ if (luminance_info.kind == LuminanceInfo::Kind::kMaximum &&
|
||||
+ luminance > max_relative_luminance) {
|
||||
+ max_relative_luminance = luminance;
|
||||
+ white_luminance = luminance_info.luminance / luminance;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ jxl::ScaleImage(1.f / max_value, image.Main().color());
|
||||
+ white_luminance *= max_value;
|
||||
+ image.metadata.m.SetIntensityTarget(white_luminance);
|
||||
+ if (white_luminance > 10000) {
|
||||
+ fprintf(stderr,
|
||||
+ "WARNING: the image is too bright for PQ (would need (1, 1, 1) to "
|
||||
+ "be %g cd/m^2).\n",
|
||||
+ white_luminance);
|
||||
+ } else {
|
||||
+ fprintf(stderr,
|
||||
+ "The resulting image should be compressed with "
|
||||
+ "--intensity_target=%g.\n",
|
||||
+ white_luminance);
|
||||
+ }
|
||||
+
|
||||
+ jxl::ColorEncoding pq = image.Main().c_current();
|
||||
+ pq.tf.SetTransferFunction(jxl::TransferFunction::kPQ);
|
||||
+ JXL_CHECK(pq.CreateICC());
|
||||
+ JXL_CHECK(image.TransformTo(pq, jxl::GetJxlCms(), &pool));
|
||||
+ image.metadata.m.color_encoding = pq;
|
||||
+ JXL_CHECK(jxl::EncodeToFile(image, output_filename, &pool));
|
||||
+}
|
||||
11
jpegxl-0.7.2-missing-include.patch
Normal file
11
jpegxl-0.7.2-missing-include.patch
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
diff -up libjxl-0.7.2/lib/jxl/fast_dct-inl.h.orig libjxl-0.7.2/lib/jxl/fast_dct-inl.h
|
||||
--- libjxl-0.7.2/lib/jxl/fast_dct-inl.h.orig 2024-11-27 18:45:37.000000000 +0100
|
||||
+++ libjxl-0.7.2/lib/jxl/fast_dct-inl.h 2025-08-12 14:55:41.725697497 +0200
|
||||
@@ -10,6 +10,7 @@
|
||||
#define LIB_JXL_FAST_DCT_INL_H_
|
||||
#endif
|
||||
|
||||
+#include <cmath>
|
||||
#include <hwy/aligned_allocator.h>
|
||||
#include <hwy/highway.h>
|
||||
|
||||
61
jpegxl.spec
61
jpegxl.spec
|
|
@ -1,7 +1,11 @@
|
|||
# epel 8 need this other already have it
|
||||
%undefine __cmake_in_source_build
|
||||
|
||||
|
||||
# Uncomment for special build to rebuild aom on bumped soname.
|
||||
#global new_soname 1
|
||||
# %%global new_soname 0
|
||||
%global sover_old 0.6
|
||||
%global sover 0.6
|
||||
%global sover 0.7
|
||||
|
||||
%global gdk_pixbuf_moduledir $(pkgconf gdk-pixbuf-2.0 --variable=gdk_pixbuf_moduledir)
|
||||
|
||||
|
|
@ -15,7 +19,7 @@ This package contains a reference implementation of JPEG XL (encoder and
|
|||
decoder).}
|
||||
|
||||
Name: jpegxl
|
||||
Version: 0.6.1
|
||||
Version: 0.7.2
|
||||
Release: %autorelease %{?new_soname:-p -e 0~sonamebump}
|
||||
Summary: JPEG XL image format reference implementation
|
||||
|
||||
|
|
@ -23,19 +27,25 @@ Summary: JPEG XL image format reference implementation
|
|||
# lodepng: zlib
|
||||
# sjpeg: ASL 2.0
|
||||
# skcms: BSD
|
||||
License: BSD and ASL 2.0 and zlib
|
||||
License: BSD-3-Clause AND Apache-2.0 AND Zlib
|
||||
URL: https://jpeg.org/jpegxl/
|
||||
VCS: https://github.com/libjxl/libjxl
|
||||
Source0: %vcs/archive/v%{version}/%{name}-%{version}.tar.gz
|
||||
# exr_to_pq
|
||||
Patch0: https://github.com/libjxl/libjxl/commit/873890998bb151ba54a865cdbd61df22af29774c.patch
|
||||
# Ssimulacra 2
|
||||
Patch1: https://github.com/libjxl/libjxl/commit/795b363120bbcfdbb2e2e4fa85146ac6d385137d.patch
|
||||
# fix missing include on aarch64
|
||||
Patch2: %{name}-0.7.2-missing-include.patch
|
||||
|
||||
# git clone https://github.com/libjxl/libjxl
|
||||
# cd libjxl/
|
||||
# git checkout v%%{version}
|
||||
# git submodule init ; git submodule update
|
||||
# rm -r third_party/brotli/ third_party/difftest_ng/ third_party/googletest/
|
||||
# rm -r third_party/brotli/ third_party/googletest/
|
||||
# rm -r third_party/HEVCSoftware/ third_party/highway/
|
||||
# rm -r third_party/IQA-optimization/ third_party/lcms/
|
||||
# rm -r third_party/skcms/profiles/ third_party/vmaf/ third_party/testdata/
|
||||
# rm -r third_party/lcms/ third_party/libpng/
|
||||
# rm -r third_party/skcms/profiles/ third_party/zlib
|
||||
# tar -zcvf ../third_party-%%{version}.tar.gz third_party/
|
||||
Source1: third_party-%{version}.tar.gz
|
||||
|
||||
|
|
@ -54,6 +64,7 @@ BuildRequires: pkgconfig(gimp-2.0)
|
|||
%endif
|
||||
BuildRequires: (pkgconfig(glut) or pkgconfig(freeglut))
|
||||
BuildRequires: gtest-devel
|
||||
BuildRequires: gflags-devel
|
||||
BuildRequires: pkgconfig(libhwy)
|
||||
BuildRequires: pkgconfig(libbrotlicommon)
|
||||
BuildRequires: pkgconfig(libjpeg)
|
||||
|
|
@ -63,12 +74,12 @@ BuildRequires: pkgconfig(OpenEXR)
|
|||
BuildRequires: pkgconfig(Qt5)
|
||||
BuildRequires: pkgconfig(Qt5X11Extras)
|
||||
BuildRequires: pkgconfig(zlib)
|
||||
# epel 8 need this other already have it
|
||||
BuildRequires: python3-devel
|
||||
%if 0%{?new_soname}
|
||||
BuildRequires: libjxl < %{version}
|
||||
%endif
|
||||
|
||||
# Header-only library to be directly included in the project's source tree
|
||||
Provides: bundled(lodepng) = 0-0.1.20210522git48e5364
|
||||
# No official release
|
||||
Provides: bundled(sjpeg) = 0-0.1.20210522git868ab55
|
||||
# Build system is Bazel, which is not packaged by Fedora
|
||||
|
|
@ -87,6 +98,15 @@ Obsoletes: jpegxl-utils < 0.3.7-5
|
|||
%description -n libjxl-utils
|
||||
%{common_description}
|
||||
|
||||
%package -n libjxl-devtools
|
||||
Summary: Development tools for JPEG-XL
|
||||
Requires: libjxl%{?_isa} = %{version}-%{release}
|
||||
|
||||
%description -n libjxl-devtools
|
||||
%{common_description}
|
||||
|
||||
Development tools for JPEG-XL
|
||||
|
||||
%package doc
|
||||
Summary: Documentation for JPEG-XL
|
||||
BuildArch: noarch
|
||||
|
|
@ -151,7 +171,10 @@ rm -rf third_party/
|
|||
-DJPEGXL_FORCE_SYSTEM_GTEST:BOOL=ON \
|
||||
-DJPEGXL_FORCE_SYSTEM_HWY:BOOL=ON \
|
||||
-DJPEGXL_WARNINGS_AS_ERRORS:BOOL=OFF \
|
||||
-DBUILD_SHARED_LIBS:BOOL=OFF
|
||||
-DBUILD_SHARED_LIBS:BOOL=ON \
|
||||
-DBUNDLE_LIBPNG_DEFAULT:BOOL=OFF \
|
||||
-DBUNDLE_GFLAGS_DEFAULT:BOOL=OFF \
|
||||
-DJPEGXL_ENABLE_DEVTOOLS=ON
|
||||
%cmake_build -- all doc
|
||||
|
||||
%install
|
||||
|
|
@ -168,9 +191,27 @@ cp -p %{_libdir}/libjxl.so.%{sover_old}* \
|
|||
%doc CONTRIBUTING.md CONTRIBUTORS README.md
|
||||
%{_bindir}/cjxl
|
||||
%{_bindir}/djxl
|
||||
%{_bindir}/cjpeg_hdr
|
||||
%{_bindir}/jxlinfo
|
||||
%{_mandir}/man1/cjxl.1*
|
||||
%{_mandir}/man1/djxl.1*
|
||||
|
||||
%files -n libjxl-devtools
|
||||
%{_bindir}/fuzzer_corpus
|
||||
%{_bindir}/butteraugli_main
|
||||
%{_bindir}/decode_and_encode
|
||||
%{_bindir}/display_to_hlg
|
||||
%{_bindir}/exr_to_pq
|
||||
%{_bindir}/pq_to_hlg
|
||||
%{_bindir}/render_hlg
|
||||
%{_bindir}/tone_map
|
||||
%{_bindir}/texture_to_cube
|
||||
%{_bindir}/generate_lut_template
|
||||
%{_bindir}/ssimulacra_main
|
||||
%{_bindir}/ssimulacra2
|
||||
%{_bindir}/xyb_range
|
||||
%{_bindir}/jxl_from_tree
|
||||
|
||||
%files doc
|
||||
%doc doc/*.md
|
||||
%doc %{_vpath_builddir}/html
|
||||
|
|
|
|||
4
sources
4
sources
|
|
@ -1,2 +1,2 @@
|
|||
SHA512 (jpegxl-0.6.1.tar.gz) = 302935d722160b0b288ac63301f9e95caf82eccf6ad76c4f4da6316a0314ee3562115932b1ceacb0d02708de0a07788992d3478cae73af0b90193f5769f9fb52
|
||||
SHA512 (third_party-0.6.1.tar.gz) = 7e416daf97e1cc54da00ec9b58636151308371d223fe29fcc22f6e9087852fd6fe9784a4e2f3e191a85a6f907a2732520ee7c8fd387292e19b5cc0b8a9d9392b
|
||||
SHA512 (jpegxl-0.7.2.tar.gz) = f7a5321b6c2ce5b9dfef759df3419728c0a5bc399d030d1a7636953bb3f432be1bfd264f38b674e789ab77accb16ac6b03d5e78f6f3c86c91a782e61bf2747ae
|
||||
SHA512 (third_party-0.7.2.tar.gz) = 27923ec78bec22d2580404f05c15005ff2a3efe951f97e0a3281be78298e99b8eee065a6d836eb1a77e70dbd0241dd82b376e015c2c54d334491e9017428a3ef
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue