diff mbox series

[FFmpeg-devel,v2] avcodec/exr: add cineon lin2log trc

Message ID 20200306040629.11870-1-mindmark@gmail.com
State New
Headers show
Series [FFmpeg-devel,v2] avcodec/exr: add cineon lin2log trc | expand

Checks

Context Check Description
andriy/ffmpeg-patchwork success Make fate finished

Commit Message

Mark Reid March 6, 2020, 4:06 a.m. UTC
From: Mark Reid <mindmark@gmail.com>

Hi,
The following patch adds a cineon lin2log color transfer characteristic to exr.
The purpose of this patch is to allow preserving of the dynamic range of an
exr file when converting to DPX or when using video filter such as 3d luts.
I wasn't sure if adding it to the AVColorTransferCharacteristic enum was the
correct approach, as this might be a exr specific thing but I figured it was a good starting point.

changes since v1:
- updated fate test

---
 libavcodec/exr.c           |  2 ++
 libavutil/color_utils.c    | 14 ++++++++++++++
 libavutil/pixfmt.h         |  1 +
 tests/ref/fate/color_utils | 19 +++++++++++++++++++
 4 files changed, 36 insertions(+)

--
2.25.0
diff mbox series

Patch

diff --git a/libavcodec/exr.c b/libavcodec/exr.c
index 1db30a1ae0..f2900a7921 100644
--- a/libavcodec/exr.c
+++ b/libavcodec/exr.c
@@ -1938,6 +1938,8 @@  static const AVOption options[] = {
         AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_SMPTEST2084 },  INT_MIN, INT_MAX, VD, "apply_trc_type"},
     { "smpte428_1",   "SMPTE ST 428-1",   0,
         AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_SMPTEST428_1 }, INT_MIN, INT_MAX, VD, "apply_trc_type"},
+    { "lin2log",      "Default Cineon/DPX log",   0,
+        AV_OPT_TYPE_CONST, {.i64 = AVCOL_TRC_CINE_LIN2LOG }, INT_MIN, INT_MAX, VD, "apply_trc_type"},

     { NULL },
 };
diff --git a/libavutil/color_utils.c b/libavutil/color_utils.c
index eb8bc7b5fc..e33c019d4a 100644
--- a/libavutil/color_utils.c
+++ b/libavutil/color_utils.c
@@ -167,6 +167,16 @@  static double avpriv_trc_arib_std_b67(double Lc) {
         (Lc <= 1.0 / 12.0 ? sqrt(3.0 * Lc) : a * log(12.0 * Lc - b) + c);
 }

+static double avpriv_trc_cine_lin2log(double Lc) {
+    const double blackpoint =  95.0;
+    const double whitepoint = 685.0;
+    const double gamma      =   0.6;
+    const double offset =  pow(10, (blackpoint - whitepoint) * 0.002 / gamma);
+    const double gain   = 1.0 / (1.0 - offset);
+
+    return (log10((Lc + offset) / gain) / (0.002 / gamma) + whitepoint ) / 1023.0;
+}
+
 avpriv_trc_function avpriv_get_trc_function_from_trc(enum AVColorTransferCharacteristic trc)
 {
     avpriv_trc_function func = NULL;
@@ -225,6 +235,10 @@  avpriv_trc_function avpriv_get_trc_function_from_trc(enum AVColorTransferCharact
             func = avpriv_trc_arib_std_b67;
             break;

+        case AVCOL_TRC_CINE_LIN2LOG:
+            func = avpriv_trc_cine_lin2log;
+            break;
+
         case AVCOL_TRC_RESERVED0:
         case AVCOL_TRC_UNSPECIFIED:
         case AVCOL_TRC_RESERVED:
diff --git a/libavutil/pixfmt.h b/libavutil/pixfmt.h
index 1c625cfc8a..1f3f9988d7 100644
--- a/libavutil/pixfmt.h
+++ b/libavutil/pixfmt.h
@@ -499,6 +499,7 @@  enum AVColorTransferCharacteristic {
     AVCOL_TRC_SMPTE428     = 17, ///< SMPTE ST 428-1
     AVCOL_TRC_SMPTEST428_1 = AVCOL_TRC_SMPTE428,
     AVCOL_TRC_ARIB_STD_B67 = 18, ///< ARIB STD-B67, known as "Hybrid log-gamma"
+    AVCOL_TRC_CINE_LIN2LOG = 19, ///< Default Cineon/DPX linear to log 1D curve
     AVCOL_TRC_NB                 ///< Not part of ABI
 };

diff --git a/tests/ref/fate/color_utils b/tests/ref/fate/color_utils
index 10f8055916..41221c131a 100644
--- a/tests/ref/fate/color_utils
+++ b/tests/ref/fate/color_utils
@@ -302,3 +302,22 @@  AVColorTransferCharacteristic=18 calling func(15123.456700) expected=2.725380
 AVColorTransferCharacteristic=18 calling func(19845.889230) expected=2.773978
 AVColorTransferCharacteristic=18 calling func(98678.423100) expected=3.060803
 AVColorTransferCharacteristic=18 calling func(99999.899998) expected=3.063182
+AVColorTransferCharacteristic=19 calling func(-0.100000) expected=nan
+AVColorTransferCharacteristic=19 calling func(-0.018054) expected=nan
+AVColorTransferCharacteristic=19 calling func(-0.010000) expected=-0.240327
+AVColorTransferCharacteristic=19 calling func(-0.004490) expected=0.023018
+AVColorTransferCharacteristic=19 calling func(0.000000) expected=0.091481
+AVColorTransferCharacteristic=19 calling func(0.003162) expected=0.124195
+AVColorTransferCharacteristic=19 calling func(0.005000) expected=0.139945
+AVColorTransferCharacteristic=19 calling func(0.009000) expected=0.168690
+AVColorTransferCharacteristic=19 calling func(0.015000) expected=0.202405
+AVColorTransferCharacteristic=19 calling func(0.100000) expected=0.388020
+AVColorTransferCharacteristic=19 calling func(1.000000) expected=0.669584
+AVColorTransferCharacteristic=19 calling func(52.370000) expected=1.172373
+AVColorTransferCharacteristic=19 calling func(125.098765) expected=1.283258
+AVColorTransferCharacteristic=19 calling func(1999.111230) expected=1.636205
+AVColorTransferCharacteristic=19 calling func(6945.443000) expected=1.794815
+AVColorTransferCharacteristic=19 calling func(15123.456700) expected=1.893921
+AVColorTransferCharacteristic=19 calling func(19845.889230) expected=1.928531
+AVColorTransferCharacteristic=19 calling func(98678.423100) expected=2.132798
+AVColorTransferCharacteristic=19 calling func(99999.899998) expected=2.134492