Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions BIBLIOGRAPHY.bib
Original file line number Diff line number Diff line change
Expand Up @@ -3533,6 +3533,14 @@ @incollection{Wyszecki2000z
isbn = {978-0-471-39918-6}
}

@misc{XiaomiInc2024,
title = {Xiaomi {{Log Profile White Paper}}},
author = {{Xiaomi Inc.}},
year = {2024},
month = {12},
langid = {english}
}

@misc{X-Rite2012a,
title = {Color {{iQC}} and {{Color iMatch Color Calculations Guide}}},
author = {{X-Rite} and {Pantone}},
Expand Down
4 changes: 2 additions & 2 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1535,7 +1535,7 @@ Log Encoding / Decoding

.. code-block:: text

['ACEScc', 'ACEScct', 'ACESproxy', 'ARRI LogC3', 'ARRI LogC4', 'Apple Log Profile', 'Canon Log', 'Canon Log 2', 'Canon Log 3', 'Cineon', 'D-Log', 'ERIMM RGB', 'F-Log', 'F-Log2', 'Filmic Pro 6', 'L-Log', 'Log2', 'Log3G10', 'Log3G12', 'N-Log', 'PLog', 'Panalog', 'Protune', 'REDLog', 'REDLogFilm', 'S-Log', 'S-Log2', 'S-Log3', 'T-Log', 'V-Log', 'ViperLog']
['ACEScc', 'ACEScct', 'ACESproxy', 'ARRI LogC3', 'ARRI LogC4', 'Apple Log Profile', 'Canon Log', 'Canon Log 2', 'Canon Log 3', 'Cineon', 'D-Log', 'ERIMM RGB', 'F-Log', 'F-Log2', 'Filmic Pro 6', 'L-Log', 'Log2', 'Log3G10', 'Log3G12', 'Mi-Log', 'N-Log', 'PLog', 'Panalog', 'Protune', 'REDLog', 'REDLogFilm', 'S-Log', 'S-Log2', 'S-Log3', 'T-Log', 'V-Log', 'ViperLog']

CCTFs Encoding / Decoding
*************************
Expand All @@ -1548,7 +1548,7 @@ CCTFs Encoding / Decoding

.. code-block:: text

['ACEScc', 'ACEScct', 'ACESproxy', 'ARIB STD-B67', 'ARRI LogC3', 'ARRI LogC4', 'Apple Log Profile', 'Blackmagic Film Generation 5', 'Canon Log', 'Canon Log 2', 'Canon Log 3', 'Cineon', 'D-Log', 'DCDM', 'DICOM GSDF', 'DaVinci Intermediate', 'ERIMM RGB', 'F-Log', 'F-Log2', 'Filmic Pro 6', 'Gamma 2.2', 'Gamma 2.4', 'Gamma 2.6', 'ITU-R BT.1886', 'ITU-R BT.2020', 'ITU-R BT.2100 HLG', 'ITU-R BT.2100 PQ', 'ITU-R BT.601', 'ITU-R BT.709', 'ITU-T H.273 IEC 61966-2', 'ITU-T H.273 Log', 'ITU-T H.273 Log Sqrt', 'ITU-T H.273 ST.428-1', 'L-Log', 'Log2', 'Log3G10', 'Log3G12', 'N-Log', 'PLog', 'Panalog', 'ProPhoto RGB', 'Protune', 'REDLog', 'REDLogFilm', 'RIMM RGB', 'ROMM RGB', 'S-Log', 'S-Log2', 'S-Log3', 'SMPTE 240M', 'ST 2084', 'T-Log', 'V-Log', 'ViperLog', 'sRGB']
['ACEScc', 'ACEScct', 'ACESproxy', 'ARIB STD-B67', 'ARRI LogC3', 'ARRI LogC4', 'Apple Log Profile', 'Blackmagic Film Generation 5', 'Canon Log', 'Canon Log 2', 'Canon Log 3', 'Cineon', 'D-Log', 'DCDM', 'DICOM GSDF', 'DaVinci Intermediate', 'ERIMM RGB', 'F-Log', 'F-Log2', 'Filmic Pro 6', 'Gamma 2.2', 'Gamma 2.4', 'Gamma 2.6', 'ITU-R BT.1886', 'ITU-R BT.2020', 'ITU-R BT.2100 HLG', 'ITU-R BT.2100 PQ', 'ITU-R BT.601', 'ITU-R BT.709', 'ITU-T H.273 IEC 61966-2', 'ITU-T H.273 Log', 'ITU-T H.273 Log Sqrt', 'ITU-T H.273 ST.428-1', 'L-Log', 'Log2', 'Log3G10', 'Log3G12', 'Mi-Log', 'N-Log', 'PLog', 'Panalog', 'ProPhoto RGB', 'Protune', 'REDLog', 'REDLogFilm', 'RIMM RGB', 'ROMM RGB', 'S-Log', 'S-Log2', 'S-Log3', 'SMPTE 240M', 'ST 2084', 'T-Log', 'V-Log', 'ViperLog', 'sRGB']

Recommendation ITU-T H.273 Code points for Video Signal Type Identification
***************************************************************************
Expand Down
4 changes: 4 additions & 0 deletions colour/hints/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,7 @@ def apply(self, RGB: ArrayLike, **kwargs: Any) -> NDArray: # noqa: D102
"Log2",
"Log3G10",
"Log3G12",
"Mi-Log",
"N-Log",
"PLog",
"Panalog",
Expand Down Expand Up @@ -371,6 +372,7 @@ def apply(self, RGB: ArrayLike, **kwargs: Any) -> NDArray: # noqa: D102
"Log2",
"Log3G10",
"Log3G12",
"Mi-Log",
"N-Log",
"PLog",
"Panalog",
Expand Down Expand Up @@ -475,6 +477,7 @@ def apply(self, RGB: ArrayLike, **kwargs: Any) -> NDArray: # noqa: D102
"Log2",
"Log3G10",
"Log3G12",
"Mi-Log",
"N-Log",
"PLog",
"Panalog",
Expand Down Expand Up @@ -533,6 +536,7 @@ def apply(self, RGB: ArrayLike, **kwargs: Any) -> NDArray: # noqa: D102
"Log2",
"Log3G10",
"Log3G12",
"Mi-Log",
"N-Log",
"PLog",
"Panalog",
Expand Down
4 changes: 4 additions & 0 deletions colour/models/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,8 @@
eotf_sRGB,
log_encoding_ViperLog,
log_decoding_ViperLog,
log_encoding_MiLog,
log_decoding_MiLog,
)
from .rgb import (
LOG_ENCODINGS,
Expand Down Expand Up @@ -696,6 +698,8 @@
"eotf_sRGB",
"log_encoding_ViperLog",
"log_decoding_ViperLog",
"log_encoding_MiLog",
"log_decoding_MiLog",
]
__all__ += [
"LOG_ENCODINGS",
Expand Down
4 changes: 4 additions & 0 deletions colour/models/rgb/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,8 @@
eotf_sRGB,
log_encoding_ViperLog,
log_decoding_ViperLog,
log_encoding_MiLog,
log_decoding_MiLog,
)
from .transfer_functions import (
LOG_ENCODINGS,
Expand Down Expand Up @@ -429,6 +431,8 @@
"eotf_sRGB",
"log_encoding_ViperLog",
"log_decoding_ViperLog",
"log_encoding_MiLog",
"log_decoding_MiLog",
]
__all__ += [
"LOG_ENCODINGS",
Expand Down
9 changes: 9 additions & 0 deletions colour/models/rgb/transfer_functions/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,7 @@
)
from .srgb import eotf_inverse_sRGB, eotf_sRGB
from .viper_log import log_encoding_ViperLog, log_decoding_ViperLog
from .xiaomi_mi_log import log_encoding_MiLog, log_decoding_MiLog
from .itut_h_273 import (
oetf_H273_Log,
oetf_inverse_H273_Log,
Expand Down Expand Up @@ -376,6 +377,10 @@
"log_encoding_ViperLog",
"log_decoding_ViperLog",
]
__all__ += [
"log_encoding_MiLog",
"log_decoding_MiLog",
]
__all__ += [
"oetf_H273_Log",
"oetf_inverse_H273_Log",
Expand Down Expand Up @@ -408,6 +413,7 @@
"Log2": log_encoding_Log2,
"Log3G10": log_encoding_Log3G10,
"Log3G12": log_encoding_Log3G12,
"Mi-Log": log_encoding_MiLog,
"N-Log": log_encoding_NLog,
"PLog": log_encoding_PivotedLog,
"Panalog": log_encoding_Panalog,
Expand Down Expand Up @@ -462,6 +468,7 @@ def log_encoding(
:func:`colour.models.log_encoding_Log2`,
:func:`colour.models.log_encoding_Log3G10`,
:func:`colour.models.log_encoding_Log3G12`,
:func:`colour.models.log_encoding_MiLog`,
:func:`colour.models.log_encoding_NLog`,
:func:`colour.models.log_encoding_PivotedLog`,
:func:`colour.models.log_encoding_Panalog`,
Expand Down Expand Up @@ -526,6 +533,7 @@ def log_encoding(
"Log2": log_decoding_Log2,
"Log3G10": log_decoding_Log3G10,
"Log3G12": log_decoding_Log3G12,
"Mi-Log": log_decoding_MiLog,
"N-Log": log_decoding_NLog,
"PLog": log_decoding_PivotedLog,
"Panalog": log_decoding_Panalog,
Expand Down Expand Up @@ -582,6 +590,7 @@ def log_decoding(
:func:`colour.models.log_decoding_Log2`,
:func:`colour.models.log_decoding_Log3G10`,
:func:`colour.models.log_decoding_Log3G12`,
:func:`colour.models.log_decoding_MiLog`,
:func:`colour.models.log_decoding_NLog`,
:func:`colour.models.log_decoding_PivotedLog`,
:func:`colour.models.log_decoding_Panalog`,
Expand Down
197 changes: 197 additions & 0 deletions colour/models/rgb/transfer_functions/tests/test_xiaomi_mi_log.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,197 @@
"""
Define the unit tests for the :mod:`colour.models.rgb.transfer_functions.\
xiaomi_mi_log` module.
"""

import numpy as np

from colour.constants import TOLERANCE_ABSOLUTE_TESTS
from colour.models.rgb.transfer_functions import (
log_decoding_MiLog,
log_encoding_MiLog,
)
from colour.utilities import domain_range_scale, ignore_numpy_errors

__author__ = "Colour Developers"
__copyright__ = "Copyright 2013 Colour Developers"
__license__ = "BSD-3-Clause - https://opensource.org/licenses/BSD-3-Clause"
__maintainer__ = "Colour Developers"
__email__ = "colour-developers@colour-science.org"
__status__ = "Production"

__all__ = [
"TestLogEncoding_MiLog",
"TestLogDecoding_MiLog",
]


class TestLogEncoding_MiLog:
"""
Define :func:`colour.models.rgb.transfer_functions.xiaomi_mi_log.\
log_encoding_MiLog` definition unit tests methods.
"""

def test_log_encoding_MiLog(self) -> None:
"""
Test :func:`colour.models.rgb.transfer_functions.xiaomi_mi_log.\
log_encoding_MiLog` definition.
"""

# Test values from the whitepaper
np.testing.assert_allclose(
log_encoding_MiLog(0.0),
0.14742742,
atol=TOLERANCE_ABSOLUTE_TESTS,
)

np.testing.assert_allclose(
log_encoding_MiLog(0.18),
0.45345968,
atol=TOLERANCE_ABSOLUTE_TESTS,
)

np.testing.assert_allclose(
log_encoding_MiLog(0.90),
0.66086763,
atol=TOLERANCE_ABSOLUTE_TESTS,
)

def test_n_dimensional_log_encoding_MiLog(self) -> None:
"""
Test :func:`colour.models.rgb.transfer_functions.xiaomi_mi_log.\
log_encoding_MiLog` definition n-dimensional arrays support.
"""

R = 0.18
P = log_encoding_MiLog(R)

R = np.tile(R, 6)
P = np.tile(P, 6)
np.testing.assert_allclose(
log_encoding_MiLog(R), P, atol=TOLERANCE_ABSOLUTE_TESTS
)

R = np.reshape(R, (2, 3))
P = np.reshape(P, (2, 3))
np.testing.assert_allclose(
log_encoding_MiLog(R), P, atol=TOLERANCE_ABSOLUTE_TESTS
)

R = np.reshape(R, (2, 3, 1))
P = np.reshape(P, (2, 3, 1))
np.testing.assert_allclose(
log_encoding_MiLog(R), P, atol=TOLERANCE_ABSOLUTE_TESTS
)

def test_domain_range_scale_log_encoding_MiLog(self) -> None:
"""
Test :func:`colour.models.rgb.transfer_functions.xiaomi_mi_log.\
log_encoding_MiLog` definition domain and range scale support.
"""

R = 0.18
P = log_encoding_MiLog(R)

d_r = (("reference", 1), ("1", 1), ("100", 100))
for scale, factor in d_r:
with domain_range_scale(scale):
np.testing.assert_allclose(
log_encoding_MiLog(R * factor),
P * factor,
atol=TOLERANCE_ABSOLUTE_TESTS,
)

@ignore_numpy_errors
def test_nan_log_encoding_MiLog(self) -> None:
"""
Test :func:`colour.models.rgb.transfer_functions.xiaomi_mi_log.\
log_encoding_MiLog` definition nan support.
"""

log_encoding_MiLog(np.array([-1.0, 0.0, 1.0, -np.inf, np.inf, np.nan]))


class TestLogDecoding_MiLog:
"""
Define :func:`colour.models.rgb.transfer_functions.xiaomi_mi_log.\
log_decoding_MiLog` definition unit tests methods.
"""

def test_log_decoding_MiLog(self) -> None:
"""
Test :func:`colour.models.rgb.transfer_functions.xiaomi_mi_log.\
log_decoding_MiLog` definition.
"""

# Test inverse of values from the whitepaper
np.testing.assert_allclose(
log_decoding_MiLog(0.14742742),
0.0,
atol=TOLERANCE_ABSOLUTE_TESTS,
)

np.testing.assert_allclose(
log_decoding_MiLog(0.45345968),
0.18,
atol=TOLERANCE_ABSOLUTE_TESTS,
)

np.testing.assert_allclose(
log_decoding_MiLog(0.66086763),
0.90,
atol=TOLERANCE_ABSOLUTE_TESTS,
)

def test_n_dimensional_log_decoding_MiLog(self) -> None:
"""
Test :func:`colour.models.rgb.transfer_functions.xiaomi_mi_log.\
log_decoding_MiLog` definition n-dimensional arrays support.
"""

P = 0.45345968
R = log_decoding_MiLog(P)

P = np.tile(P, 6)
R = np.tile(R, 6)
np.testing.assert_allclose(
log_decoding_MiLog(P), R, atol=TOLERANCE_ABSOLUTE_TESTS
)

P = np.reshape(P, (2, 3))
R = np.reshape(R, (2, 3))
np.testing.assert_allclose(
log_decoding_MiLog(P), R, atol=TOLERANCE_ABSOLUTE_TESTS
)

P = np.reshape(P, (2, 3, 1))
R = np.reshape(R, (2, 3, 1))
np.testing.assert_allclose(
log_decoding_MiLog(P), R, atol=TOLERANCE_ABSOLUTE_TESTS
)

def test_domain_range_scale_log_decoding_MiLog(self) -> None:
"""
Test :func:`colour.models.rgb.transfer_functions.xiaomi_mi_log.\
log_decoding_MiLog` definition domain and range scale support.
"""

P = 0.45345968
R = log_decoding_MiLog(P)

d_r = (("reference", 1), ("1", 1), ("100", 100))
for scale, factor in d_r:
with domain_range_scale(scale):
np.testing.assert_allclose(
log_decoding_MiLog(P * factor),
R * factor,
atol=TOLERANCE_ABSOLUTE_TESTS,
)

@ignore_numpy_errors
def test_nan_log_decoding_MiLog(self) -> None:
"""
Test :func:`colour.models.rgb.transfer_functions.xiaomi_mi_log.\
log_decoding_MiLog` definition nan support.
"""

log_decoding_MiLog(np.array([-1.0, 0.0, 1.0, -np.inf, np.inf, np.nan]))
Loading
Loading