Skip to content

Commit

Permalink
feat: bt2100 transfer, fix imports, bt_2446a tone mapping, window size
Browse files Browse the repository at this point in the history
  • Loading branch information
wisetarman committed Dec 9, 2023
1 parent baf6e41 commit 8bb5a9e
Show file tree
Hide file tree
Showing 9 changed files with 169 additions and 16 deletions.
93 changes: 93 additions & 0 deletions lib/hdrtoys/tone_mapping/bt_2446a.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
import 'dart:math';

import 'package:vector_math/vector_math.dart';

// ITU-R BT.2446 Conversion Method A
// https://www.itu.int/pub/R-REP-BT.2446

const L_hdr = 1000.0;

const L_sdr = 203.0;

//!HOOK OUTPUT
//!BIND HOOKED
//!DESC tone mapping (bt.2446a)

const double a = 0.2627002120112671;
const double b = 0.6779980715188708;
const double c = 0.05930171646986196;
const double d = 2.0 * (1.0 - c);
const double e = 2.0 * (1.0 - a);

Vector3 RGB_to_YCbCr(Vector3 RGB) {
double R = RGB.r;
double G = RGB.g;
double B = RGB.b;

double Y = RGB.dot(Vector3(a, b, c));
double Cb = (B - Y) / d;
double Cr = (R - Y) / e;

return Vector3(Y, Cb, Cr);
}

Vector3 YCbCr_to_RGB(Vector3 YCbCr) {
double Y = YCbCr.x;
double Cb = YCbCr.y;
double Cr = YCbCr.z;

double R = Y + e * Cr;
double G = Y - (a * e / b) * Cr - (c * d / b) * Cb;
double B = Y + d * Cb;

return Vector3(R, G, B);
}

double f(double Yin) {
var Y = pow(Yin, 1.0 / 2.4).toDouble();

double pHDR = 1.0 + 32.0 * pow(L_hdr / 10000.0, 1.0 / 2.4);
double pSDR = 1.0 + 32.0 * pow(L_sdr / 10000.0, 1.0 / 2.4);

double Yp = log(1.0 + (pHDR - 1.0) * Y) / log(pHDR);

double Yc;
if (Yp <= 0.7399)
Yc = Yp * 1.0770;
else if (Yp < 0.9909)
Yc = Yp * (-1.1510 * Yp + 2.7811) - 0.6302;
else
Yc = Yp * 0.5000 + 0.5000;

double Ysdr = (pow(pSDR, Yc) - 1.0) / (pSDR - 1.0);

Y = pow(Ysdr, 2.4).toDouble();

return Y;
}

Vector3 tone_mapping(Vector3 YCbCr) {
double W = L_hdr / L_sdr;
YCbCr /= W;

double Y = YCbCr.r;
double Cb = YCbCr.g;
double Cr = YCbCr.b;

double Ysdr = f(Y);

double Yr = Ysdr / (1.1 * Y + 1e-6);
Cb *= Yr;
Cr *= Yr;
Y = Ysdr - max(0.1 * Cr, 0.0);

return Vector3(Y, Cb, Cr);
}

Vector3 toneMap2446a(Vector3 color) {
color.rgb = RGB_to_YCbCr(color.rgb);
color.rgb = tone_mapping(color.rgb);
color.rgb = YCbCr_to_RGB(color.rgb);

return color;
}
56 changes: 56 additions & 0 deletions lib/hdrtoys/transfer_function/bt2100.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import 'dart:math';

import 'package:vector_math/vector_math.dart';

const s = 1;
const t = 0.2701;
const m = t;
const c = -0.0729;
const n = 0.4623;

double L(double V) {
final top = c - (V - m) * s * t;
final bottom = V - m - s;

return pow(top / (bottom + 1e-6), 1 / n).toDouble();
}

Vector3 transferBt2100(Vector3 color) {
return Vector3(
L(color.x),
L(color.y),
L(color.z),
);
}

double V(double L) {
final Ln = pow(L, n);

final top = s * Ln + c;
final bottom = Ln + s * t;

return (top / (bottom + 1e-6) + m);
}

Vector3 transferBt2100Inverse(Vector3 color) {
return Vector3(
V(color.x),
V(color.y),
V(color.z),
);
}

double normalizeV(double V) {
const p = 0;
const m = p;
const k = 1;

return (V - p) / k + m;
}

double normalizeL(double L) {
const a = 1;
const b = 0;

return (L - b) / a;
}
2 changes: 1 addition & 1 deletion lib/hdrtoys/transfer_function/bt709.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import 'dart:math';

import 'package:vector_math/vector_math_64.dart';
import 'package:vector_math/vector_math.dart';

const beta = 0.018053968510807;
const alpha = 1.0 + 5.5 * beta;
Expand Down
2 changes: 1 addition & 1 deletion lib/hdrtoys/transfer_function/bt709_inv.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import 'dart:math';

import 'package:vector_math/vector_math_64.dart';
import 'package:vector_math/vector_math.dart';

const beta = 0.018053968510807;
const alpha = 1.0 + 5.5 * beta;
Expand Down
4 changes: 3 additions & 1 deletion lib/hdrtoys/transfer_function/srgb.dart
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@ double moncurve_r(double y, double gamma, double offs) {
pow(offs * gamma / ((gamma - 1.0) * (1.0 + offs)), gamma).toDouble();
double rs = pow((gamma - 1.0) / offs, gamma - 1.0).toDouble() *
pow((1.0 + offs) / gamma, gamma);
return y >= yb ? (1.0 + offs) * pow(y, 1.0 / gamma) - offs : y * rs;
return (y >= yb ? (1.0 + offs) * pow(y, 1.0 / gamma) - offs : y * rs) *
1000 /
203;
}

Vector3 transferSrgb(Vector3 color) {
Expand Down
1 change: 1 addition & 0 deletions lib/image.dart
Original file line number Diff line number Diff line change
Expand Up @@ -1505,6 +1505,7 @@ Vector3 applyGammaFilter(Vector3 color) {
// color = chromaCorrectionColor(color);

color = transferPqInverse(color);
// color = transferPq(color);

// color = bt2020rgbToXyz(color);
// color = XYZ_to_xyY(color);
Expand Down
3 changes: 1 addition & 2 deletions native/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,4 @@ jxl-oxide = "0.5.1"
jxl-color = "0.4.0"
lazy_static = "1.4.0"
cmake = "=0.1.48"
maplibre = "0.0.3"
statrs = "0.16.0"
cint = "0.3.1"
22 changes: 12 additions & 10 deletions native/src/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ use std::{
thread,
};

use cint::Bt2020;
use flutter_rust_bridge::{frb, ZeroCopyBuffer};
pub use jxl_oxide::{CropInfo, JxlImage};
use maplibre::style::Bt2020;

lazy_static::lazy_static! {
static ref DECODERS: RwLock<HashMap<String, JxlDecoder>> = {
Expand Down Expand Up @@ -227,7 +227,7 @@ fn _get_next_frame(decoder: &mut Decoder, crop: Option<CropInfo>) -> CodecRespon

return CodecResponse {
frame: Frame {
data: ZeroCopyBuffer(convert_to_bt2020_and_apply_pq_gamma(_data)),
data: ZeroCopyBuffer(apply_pq_gamma(_data)),
duration: render.duration() as f64,
width: render_image.width() as u32,
height: render_image.height() as u32,
Expand All @@ -247,21 +247,23 @@ fn _get_next_frame(decoder: &mut Decoder, crop: Option<CropInfo>) -> CodecRespon
}
}

fn convert_to_bt2020_and_apply_pq_gamma(input: Vec<f32>) -> Vec<f32> {
fn apply_pq_gamma(input: Vec<f32>) -> Vec<f32> {
let mut output = Vec::new();

for color in input {
for color in input.chunks(3) {
// Convert to BT.2020
let bt2020 = Bt2020 {
r: color,
g: color,
b: color,
r: color[0],
g: color[1],
b: color[2],
};

// Apply PQ gamma correction
let pq_gamma_corrected = pq_gamma_correction(bt2020.r);
// let colorConvert = CintTy;

output.push(pq_gamma_corrected);
// Apply PQ gamma correction
output.push(pq_gamma_correction(bt2020.r));
output.push(pq_gamma_correction(bt2020.g));
output.push(pq_gamma_correction(bt2020.b));
}

output
Expand Down
2 changes: 1 addition & 1 deletion windows/runner/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ int APIENTRY wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev,

FlutterWindow window(project);
Win32Window::Point origin(10, 10);
Win32Window::Size size(1280, 720);
Win32Window::Size size(734, 976);
if (!window.Create(L"flutter_rust_bridge_template", origin, size)) {
return EXIT_FAILURE;
}
Expand Down

0 comments on commit 8bb5a9e

Please sign in to comment.