diff --git a/README.rst b/README.rst index 7fc19b0fd6..c98c4577ff 100644 --- a/README.rst +++ b/README.rst @@ -901,7 +901,8 @@ RGB Colourspaces 'ACEScct', 'ACEScg', 'ACESproxy', - 'ALEXA Wide Gamut', + 'ARRI Wide Gamut 3', + 'ARRI Wide Gamut 4', 'Adobe RGB (1998)', 'Adobe Wide Gamut RGB', 'Apple RGB', @@ -1017,7 +1018,8 @@ Log Encoding / Decoding ['ACEScc', 'ACEScct', 'ACESproxy', - 'ALEXA Log C', + 'ARRI LogC3', + 'ARRI LogC4', 'Canon Log', 'Canon Log 2', 'Canon Log 3', @@ -1052,7 +1054,8 @@ CCTFs Encoding / Decoding ['ACEScc', 'ACEScct', 'ACESproxy', - 'ALEXA Log C', + 'ARRI LogC3', + 'ARRI LogC4', 'ARIB STD-B67', 'Canon Log', 'Canon Log 2', diff --git a/colour/models/__init__.py b/colour/models/__init__.py index 75ae6e1363..a7d96fdfcc 100644 --- a/colour/models/__init__.py +++ b/colour/models/__init__.py @@ -126,8 +126,10 @@ log_decoding_ACEScct, oetf_ARIBSTDB67, oetf_inverse_ARIBSTDB67, - log_encoding_ALEXALogC, - log_decoding_ALEXALogC, + log_encoding_ARRILogC3, + log_decoding_ARRILogC3, + log_encoding_ARRILogC4, + log_decoding_ARRILogC4, oetf_BlackmagicFilmGeneration5, oetf_inverse_BlackmagicFilmGeneration5, log_encoding_CanonLog, @@ -270,7 +272,8 @@ RGB_COLOURSPACE_ACESCG, RGB_COLOURSPACE_ADOBE_RGB1998, RGB_COLOURSPACE_ADOBE_WIDE_GAMUT_RGB, - RGB_COLOURSPACE_ALEXA_WIDE_GAMUT, + RGB_COLOURSPACE_ARRI_WIDE_GAMUT_3, + RGB_COLOURSPACE_ARRI_WIDE_GAMUT_4, RGB_COLOURSPACE_APPLE_RGB, RGB_COLOURSPACE_BEST_RGB, RGB_COLOURSPACE_BETA_RGB, @@ -524,8 +527,10 @@ "log_decoding_ACEScct", "oetf_ARIBSTDB67", "oetf_inverse_ARIBSTDB67", - "log_encoding_ALEXALogC", - "log_decoding_ALEXALogC", + "log_encoding_ARRILogC3", + "log_decoding_ARRILogC3", + "log_encoding_ARRILogC4", + "log_decoding_ARRILogC4", "oetf_BlackmagicFilmGeneration5", "oetf_inverse_BlackmagicFilmGeneration5", "log_encoding_CanonLog", @@ -668,7 +673,8 @@ "RGB_COLOURSPACE_ACESCG", "RGB_COLOURSPACE_ADOBE_RGB1998", "RGB_COLOURSPACE_ADOBE_WIDE_GAMUT_RGB", - "RGB_COLOURSPACE_ALEXA_WIDE_GAMUT", + "RGB_COLOURSPACE_ARRI_WIDE_GAMUT_3", + "RGB_COLOURSPACE_ARRI_WIDE_GAMUT_4", "RGB_COLOURSPACE_APPLE_RGB", "RGB_COLOURSPACE_BEST_RGB", "RGB_COLOURSPACE_BETA_RGB", @@ -804,6 +810,10 @@ def __getattr__(self, attribute) -> Any: # v0.4.2 API_CHANGES["ObjectRenamed"].extend( [ + [ + "colour.models.RGB_COLOURSPACE_ALEXA_WIDE_GAMUT", + "colour.models.RGB_COLOURSPACE_ARRI_WIDE_GAMUT_3", + ], [ "colour.models.eotf_inverse_BT2020", "colour.models.oetf_BT2020", @@ -860,6 +870,14 @@ def __getattr__(self, attribute) -> Any: "colour.models.ootf_inverse_HLG_BT2100", "colour.models.ootf_inverse_BT2100_HLG", ], + [ + "colour.models.log_decoding_ALEXALogC", + "colour.models.log_decoding_ARRILogC3", + ], + [ + "colour.models.log_encoding_ALEXALogC", + "colour.models.log_encoding_ARRILogC3", + ], ] ) """Defines the *colour.models* sub-package API changes.""" diff --git a/colour/models/rgb/__init__.py b/colour/models/rgb/__init__.py index 967eaf0921..e1e7558744 100644 --- a/colour/models/rgb/__init__.py +++ b/colour/models/rgb/__init__.py @@ -21,8 +21,10 @@ log_decoding_ACEScct, oetf_ARIBSTDB67, oetf_inverse_ARIBSTDB67, - log_encoding_ALEXALogC, - log_decoding_ALEXALogC, + log_encoding_ARRILogC3, + log_decoding_ARRILogC3, + log_encoding_ARRILogC4, + log_decoding_ARRILogC4, oetf_BlackmagicFilmGeneration5, oetf_inverse_BlackmagicFilmGeneration5, log_encoding_CanonLog, @@ -165,7 +167,8 @@ RGB_COLOURSPACE_ACESCG, RGB_COLOURSPACE_ADOBE_RGB1998, RGB_COLOURSPACE_ADOBE_WIDE_GAMUT_RGB, - RGB_COLOURSPACE_ALEXA_WIDE_GAMUT, + RGB_COLOURSPACE_ARRI_WIDE_GAMUT_3, + RGB_COLOURSPACE_ARRI_WIDE_GAMUT_4, RGB_COLOURSPACE_APPLE_RGB, RGB_COLOURSPACE_BEST_RGB, RGB_COLOURSPACE_BETA_RGB, @@ -286,8 +289,10 @@ "log_decoding_ACEScct", "oetf_ARIBSTDB67", "oetf_inverse_ARIBSTDB67", - "log_encoding_ALEXALogC", - "log_decoding_ALEXALogC", + "log_encoding_ARRILogC3", + "log_decoding_ARRILogC3", + "log_encoding_ARRILogC4", + "log_decoding_ARRILogC4", "oetf_BlackmagicFilmGeneration5", "oetf_inverse_BlackmagicFilmGeneration5", "log_encoding_CanonLog", @@ -430,7 +435,8 @@ "RGB_COLOURSPACE_ACESCG", "RGB_COLOURSPACE_ADOBE_RGB1998", "RGB_COLOURSPACE_ADOBE_WIDE_GAMUT_RGB", - "RGB_COLOURSPACE_ALEXA_WIDE_GAMUT", + "RGB_COLOURSPACE_ARRI_WIDE_GAMUT_3", + "RGB_COLOURSPACE_ARRI_WIDE_GAMUT_4", "RGB_COLOURSPACE_APPLE_RGB", "RGB_COLOURSPACE_BEST_RGB", "RGB_COLOURSPACE_BETA_RGB", diff --git a/colour/models/rgb/datasets/__init__.py b/colour/models/rgb/datasets/__init__.py index a448f4e230..0cae684fe1 100644 --- a/colour/models/rgb/datasets/__init__.py +++ b/colour/models/rgb/datasets/__init__.py @@ -1,6 +1,6 @@ from __future__ import annotations -from colour.utilities import CanonicalMapping +from colour.utilities import LazyCanonicalMapping, usage_warning from .aces import ( RGB_COLOURSPACE_ACES2065_1, RGB_COLOURSPACE_ACESCC, @@ -11,7 +11,10 @@ from .adobe_rgb_1998 import RGB_COLOURSPACE_ADOBE_RGB1998 from .adobe_wide_gamut_rgb import RGB_COLOURSPACE_ADOBE_WIDE_GAMUT_RGB from .apple_rgb import RGB_COLOURSPACE_APPLE_RGB -from .arri_alexa_wide_gamut import RGB_COLOURSPACE_ALEXA_WIDE_GAMUT +from .arri import ( + RGB_COLOURSPACE_ARRI_WIDE_GAMUT_3, + RGB_COLOURSPACE_ARRI_WIDE_GAMUT_4, +) from .best_rgb import RGB_COLOURSPACE_BEST_RGB from .beta_rgb import RGB_COLOURSPACE_BETA_RGB from .blackmagic_design import RGB_COLOURSPACE_BLACKMAGIC_WIDE_GAMUT @@ -74,7 +77,7 @@ from colour.models.rgb import RGB_Colourspace -RGB_COLOURSPACES: CanonicalMapping = CanonicalMapping( +RGB_COLOURSPACES: LazyCanonicalMapping = LazyCanonicalMapping( dict( sorted( (colourspace.name, colourspace) @@ -112,7 +115,8 @@ "RGB_COLOURSPACE_ACESCG", "RGB_COLOURSPACE_ADOBE_RGB1998", "RGB_COLOURSPACE_ADOBE_WIDE_GAMUT_RGB", - "RGB_COLOURSPACE_ALEXA_WIDE_GAMUT", + "RGB_COLOURSPACE_ARRI_WIDE_GAMUT_3", + "RGB_COLOURSPACE_ARRI_WIDE_GAMUT_4", "RGB_COLOURSPACE_APPLE_RGB", "RGB_COLOURSPACE_BEST_RGB", "RGB_COLOURSPACE_BETA_RGB", @@ -169,3 +173,20 @@ "RGB_COLOURSPACE_XTREME_RGB", "RGB_COLOURSPACE_F_GAMUT", ] + + +# ----------------------------------------------------------------------------# +# --- API Changes and Deprecation Management ---# +# ----------------------------------------------------------------------------# +# v0.4.2 +def _alexa_wide_gamut(): + usage_warning( + 'The "ALEXA Wide Gamut" RGB colourspace has been renamed to ' + '"ARRI Wide Gamut 3" for consistency with "ARRI" new naming ' + "convention." + ) + + return RGB_COLOURSPACE_ARRI_WIDE_GAMUT_3 + + +RGB_COLOURSPACES["ALEXA Wide Gamut"] = _alexa_wide_gamut diff --git a/colour/models/rgb/datasets/arri.py b/colour/models/rgb/datasets/arri.py new file mode 100644 index 0000000000..452307c5c1 --- /dev/null +++ b/colour/models/rgb/datasets/arri.py @@ -0,0 +1,156 @@ +""" +ARRI Colourspaces +================= + +Defines the *ARRI* colourspaces: + +- :attr:`colour.models.RGB_COLOURSPACE_ARRI_WIDE_GAMUT_3`. +- :attr:`colour.models.RGB_COLOURSPACE_ARRI_WIDE_GAMUT_4`. + +References +---------- +- :cite:`ARRI2012a` : ARRI. (2012). ALEXA - Log C Curve - Usage in VFX. + https://drive.google.com/open?id=1t73fAG_QpV7hJxoQPYZDWvOojYkYDgvn +- :cite:`Cooper2022` : Cooper, S., & Brendel, H. (2022). ARRI LogC4 + Logarithmic Color Space SPECIFICATION. Retrieved October 24, 2022, from + https://www.arri.com/resource/blob/278790/bea879ac0d041a925bed27a096ab3ec2/\ +2022-05-arri-logc4-specification-data.pdf +""" + +from __future__ import annotations + +import numpy as np + +from colour.colorimetry import CCS_ILLUMINANTS +from colour.hints import NDArray +from colour.models.rgb import ( + RGB_Colourspace, + log_encoding_ARRILogC3, + log_decoding_ARRILogC3, + log_encoding_ARRILogC4, + log_decoding_ARRILogC4, +) + +__author__ = "Colour Developers" +__copyright__ = "Copyright 2013 Colour Developers" +__license__ = "New BSD License - https://opensource.org/licenses/BSD-3-Clause" +__maintainer__ = "Colour Developers" +__email__ = "colour-developers@colour-science.org" +__status__ = "Production" + +__all__ = [ + "PRIMARIES_ARRI_WIDE_GAMUT_3", + "WHITEPOINT_NAME_ARRI_WIDE_GAMUT_3", + "CCS_WHITEPOINT_ARRI_WIDE_GAMUT_3", + "MATRIX_ARRI_WIDE_GAMUT_3_TO_XYZ", + "MATRIX_XYZ_TO_ARRI_WIDE_GAMUT_3", + "RGB_COLOURSPACE_ARRI_WIDE_GAMUT_3", + "PRIMARIES_ARRI_WIDE_GAMUT_4", + "WHITEPOINT_NAME_ARRI_WIDE_GAMUT_4", + "CCS_WHITEPOINT_ARRI_WIDE_GAMUT_4", + "MATRIX_ARRI_WIDE_GAMUT_4_TO_XYZ", + "MATRIX_XYZ_TO_ARRI_WIDE_GAMUT_4", + "RGB_COLOURSPACE_ARRI_WIDE_GAMUT_4", +] + +PRIMARIES_ARRI_WIDE_GAMUT_3: NDArray = np.array( + [ + [0.6840, 0.3130], + [0.2210, 0.8480], + [0.0861, -0.1020], + ] +) +"""*ARRI Wide Gamut 3* colourspace primaries.""" + +WHITEPOINT_NAME_ARRI_WIDE_GAMUT_3: str = "D65" +"""*ARRI Wide Gamut 3* colourspace whitepoint name.""" + +CCS_WHITEPOINT_ARRI_WIDE_GAMUT_3: NDArray = CCS_ILLUMINANTS[ + "CIE 1931 2 Degree Standard Observer" +][WHITEPOINT_NAME_ARRI_WIDE_GAMUT_3] +"""*ARRI Wide Gamut 3* colourspace whitepoint chromaticity coordinates.""" + +MATRIX_ARRI_WIDE_GAMUT_3_TO_XYZ: NDArray = np.array( + [ + [0.638008, 0.214704, 0.097744], + [0.291954, 0.823841, -0.115795], + [0.002798, -0.067034, 1.153294], + ] +) +"""*ARRI Wide Gamut 3* colourspace to *CIE XYZ* tristimulus values matrix.""" + +MATRIX_XYZ_TO_ARRI_WIDE_GAMUT_3: NDArray = np.array( + [ + [1.789066, -0.482534, -0.200076], + [-0.639849, 1.396400, 0.194432], + [-0.041532, 0.082335, 0.878868], + ] +) +"""*CIE XYZ* tristimulus values to *ARRI Wide Gamut 3* colourspace matrix.""" + +RGB_COLOURSPACE_ARRI_WIDE_GAMUT_3: RGB_Colourspace = RGB_Colourspace( + "ARRI Wide Gamut 3", + PRIMARIES_ARRI_WIDE_GAMUT_3, + CCS_WHITEPOINT_ARRI_WIDE_GAMUT_3, + WHITEPOINT_NAME_ARRI_WIDE_GAMUT_3, + MATRIX_ARRI_WIDE_GAMUT_3_TO_XYZ, + MATRIX_XYZ_TO_ARRI_WIDE_GAMUT_3, + log_encoding_ARRILogC3, + log_decoding_ARRILogC3, +) +RGB_COLOURSPACE_ARRI_WIDE_GAMUT_3.__doc__ = """ +*ARRI Wide Gamut 3* colourspace. + +References +---------- +:cite:`ARRI2012a` +""" + +PRIMARIES_ARRI_WIDE_GAMUT_4: NDArray = np.array( + [ + [0.7347, 0.2653], + [0.1424, 0.8576], + [0.0991, -0.0308], + ] +) +"""*ARRI Wide Gamut 4* colourspace primaries.""" + +WHITEPOINT_NAME_ARRI_WIDE_GAMUT_4: str = "D65" +"""*ARRI Wide Gamut 4* colourspace whitepoint name.""" + +CCS_WHITEPOINT_ARRI_WIDE_GAMUT_4: NDArray = CCS_ILLUMINANTS[ + "CIE 1931 2 Degree Standard Observer" +][WHITEPOINT_NAME_ARRI_WIDE_GAMUT_4] +"""*ARRI Wide Gamut 4* colourspace whitepoint chromaticity coordinates.""" + +MATRIX_ARRI_WIDE_GAMUT_4_TO_XYZ: NDArray = np.array( + [ + [0.7048583204, 0.1297602952, 0.1158373115], + [0.2545241764, 0.7814777327, -0.0360019091], + [0.0000000000, 0.0000000000, 1.0890577508], + ] +) +"""*ARRI Wide Gamut 4* colourspace to *CIE XYZ* tristimulus values matrix.""" + +MATRIX_XYZ_TO_ARRI_WIDE_GAMUT_4: NDArray = np.linalg.inv( + MATRIX_ARRI_WIDE_GAMUT_4_TO_XYZ +) +"""*CIE XYZ* tristimulus values to *ARRI Wide Gamut 4* colourspace matrix.""" + +RGB_COLOURSPACE_ARRI_WIDE_GAMUT_4: RGB_Colourspace = RGB_Colourspace( + "ARRI Wide Gamut 4", + PRIMARIES_ARRI_WIDE_GAMUT_4, + CCS_WHITEPOINT_ARRI_WIDE_GAMUT_4, + WHITEPOINT_NAME_ARRI_WIDE_GAMUT_4, + MATRIX_ARRI_WIDE_GAMUT_4_TO_XYZ, + MATRIX_XYZ_TO_ARRI_WIDE_GAMUT_4, + log_encoding_ARRILogC4, + log_decoding_ARRILogC4, +) +RGB_COLOURSPACE_ARRI_WIDE_GAMUT_4.__doc__ = """ +*ARRI Wide Gamut 4* colourspace. + +References +---------- +:cite:`Cooper2022` +""" diff --git a/colour/models/rgb/datasets/arri_alexa_wide_gamut.py b/colour/models/rgb/datasets/arri_alexa_wide_gamut.py deleted file mode 100644 index af0da06aaf..0000000000 --- a/colour/models/rgb/datasets/arri_alexa_wide_gamut.py +++ /dev/null @@ -1,94 +0,0 @@ -""" -ARRI ALEXA Wide Gamut Colourspace -================================= - -Defines the *ARRI ALEXA Wide Gamut* colourspace: - -- :attr:`colour.models.RGB_COLOURSPACE_ALEXA_WIDE_GAMUT`. - -References ----------- -- :cite:`ARRI2012a` : ARRI. (2012). ALEXA - Log C Curve - Usage in VFX. - https://drive.google.com/open?id=1t73fAG_QpV7hJxoQPYZDWvOojYkYDgvn -""" - -from __future__ import annotations - -import numpy as np - -from colour.colorimetry import CCS_ILLUMINANTS -from colour.hints import NDArray -from colour.models.rgb import ( - RGB_Colourspace, - log_encoding_ALEXALogC, - log_decoding_ALEXALogC, -) - -__author__ = "Colour Developers" -__copyright__ = "Copyright 2013 Colour Developers" -__license__ = "New BSD License - https://opensource.org/licenses/BSD-3-Clause" -__maintainer__ = "Colour Developers" -__email__ = "colour-developers@colour-science.org" -__status__ = "Production" - -__all__ = [ - "PRIMARIES_ALEXA_WIDE_GAMUT", - "WHITEPOINT_NAME_ALEXA_WIDE_GAMUT", - "CCS_WHITEPOINT_ALEXA_WIDE_GAMUT", - "MATRIX_ALEXA_WIDE_GAMUT_TO_XYZ", - "MATRIX_XYZ_TO_ALEXA_WIDE_GAMUT", - "RGB_COLOURSPACE_ALEXA_WIDE_GAMUT", -] - -PRIMARIES_ALEXA_WIDE_GAMUT: NDArray = np.array( - [ - [0.6840, 0.3130], - [0.2210, 0.8480], - [0.0861, -0.1020], - ] -) -"""*ARRI ALEXA Wide Gamut* colourspace primaries.""" - -WHITEPOINT_NAME_ALEXA_WIDE_GAMUT: str = "D65" -"""*ARRI ALEXA Wide Gamut* colourspace whitepoint name.""" - -CCS_WHITEPOINT_ALEXA_WIDE_GAMUT: NDArray = CCS_ILLUMINANTS[ - "CIE 1931 2 Degree Standard Observer" -][WHITEPOINT_NAME_ALEXA_WIDE_GAMUT] -"""*ARRI ALEXA Wide Gamut* colourspace whitepoint chromaticity coordinates.""" - -MATRIX_ALEXA_WIDE_GAMUT_TO_XYZ: NDArray = np.array( - [ - [0.638008, 0.214704, 0.097744], - [0.291954, 0.823841, -0.115795], - [0.002798, -0.067034, 1.153294], - ] -) -"""*ARRI ALEXA Wide Gamut* colourspace to *CIE XYZ* tristimulus values matrix.""" - -MATRIX_XYZ_TO_ALEXA_WIDE_GAMUT: NDArray = np.array( - [ - [1.789066, -0.482534, -0.200076], - [-0.639849, 1.396400, 0.194432], - [-0.041532, 0.082335, 0.878868], - ] -) -"""*CIE XYZ* tristimulus values to *ARRI ALEXA Wide Gamut* colourspace matrix.""" - -RGB_COLOURSPACE_ALEXA_WIDE_GAMUT: RGB_Colourspace = RGB_Colourspace( - "ALEXA Wide Gamut", - PRIMARIES_ALEXA_WIDE_GAMUT, - CCS_WHITEPOINT_ALEXA_WIDE_GAMUT, - WHITEPOINT_NAME_ALEXA_WIDE_GAMUT, - MATRIX_ALEXA_WIDE_GAMUT_TO_XYZ, - MATRIX_XYZ_TO_ALEXA_WIDE_GAMUT, - log_encoding_ALEXALogC, - log_decoding_ALEXALogC, -) -RGB_COLOURSPACE_ALEXA_WIDE_GAMUT.__doc__ = """ -*ARRI ALEXA Wide Gamut* colourspace. - -References ----------- -:cite:`ARRI2012a` -""" diff --git a/colour/models/rgb/datasets/tests/test__init__.py b/colour/models/rgb/datasets/tests/test__init__.py index 39ec8b674c..2d8bbacf20 100644 --- a/colour/models/rgb/datasets/tests/test__init__.py +++ b/colour/models/rgb/datasets/tests/test__init__.py @@ -39,7 +39,7 @@ def test_transformation_matrices(self): tolerances = { "Adobe RGB (1998)": 1e-5, - "ALEXA Wide Gamut": 1e-6, + "ARRI Wide Gamut 3": 1e-6, "DJI D-Gamut": 1e-4, "ERIMM RGB": 1e-3, "ProPhoto RGB": 1e-3, diff --git a/colour/models/rgb/transfer_functions/__init__.py b/colour/models/rgb/transfer_functions/__init__.py index e518cbd32c..7cb70589b7 100644 --- a/colour/models/rgb/transfer_functions/__init__.py +++ b/colour/models/rgb/transfer_functions/__init__.py @@ -27,7 +27,12 @@ log_decoding_ACEScct, ) from .arib_std_b67 import oetf_ARIBSTDB67, oetf_inverse_ARIBSTDB67 -from .arri_alexa_log_c import log_encoding_ALEXALogC, log_decoding_ALEXALogC +from .arri import ( + log_encoding_ARRILogC3, + log_decoding_ARRILogC3, + log_encoding_ARRILogC4, + log_decoding_ARRILogC4, +) from .blackmagic_design import ( oetf_BlackmagicFilmGeneration5, oetf_inverse_BlackmagicFilmGeneration5, @@ -158,8 +163,10 @@ "oetf_inverse_ARIBSTDB67", ] __all__ += [ - "log_encoding_ALEXALogC", - "log_decoding_ALEXALogC", + "log_encoding_ARRILogC3", + "log_decoding_ARRILogC3", + "log_encoding_ARRILogC4", + "log_decoding_ARRILogC4", ] __all__ += [ "oetf_BlackmagicFilmGeneration5", @@ -343,7 +350,8 @@ "ACEScc": log_encoding_ACEScc, "ACEScct": log_encoding_ACEScct, "ACESproxy": log_encoding_ACESproxy, - "ALEXA Log C": log_encoding_ALEXALogC, + "ARRI LogC3": log_encoding_ARRILogC3, + "ARRI LogC4": log_encoding_ARRILogC4, "Canon Log 2": log_encoding_CanonLog2, "Canon Log 3": log_encoding_CanonLog3, "Canon Log": log_encoding_CanonLog, @@ -382,7 +390,8 @@ def log_encoding( "ACEScc", "ACEScct", "ACESproxy", - "ALEXA Log C", + "ARRI LogC3", + "ARRI LogC4", "Canon Log 2", "Canon Log 3", "Canon Log", @@ -429,7 +438,8 @@ def log_encoding( {:func:`colour.models.log_encoding_ACEScc`, :func:`colour.models.log_encoding_ACEScct`, :func:`colour.models.log_encoding_ACESproxy`, - :func:`colour.models.log_encoding_ALEXALogC`, + :func:`colour.models.log_encoding_ARRILogC3`, + :func:`colour.models.log_encoding_ARRILogC4`, :func:`colour.models.log_encoding_CanonLog2`, :func:`colour.models.log_encoding_CanonLog3`, :func:`colour.models.log_encoding_CanonLog`, @@ -490,7 +500,8 @@ def log_encoding( "ACEScc": log_decoding_ACEScc, "ACEScct": log_decoding_ACEScct, "ACESproxy": log_decoding_ACESproxy, - "ALEXA Log C": log_decoding_ALEXALogC, + "ARRI LogC3": log_decoding_ARRILogC3, + "ARRI LogC4": log_decoding_ARRILogC4, "Canon Log 2": log_decoding_CanonLog2, "Canon Log 3": log_decoding_CanonLog3, "Canon Log": log_decoding_CanonLog, @@ -529,7 +540,8 @@ def log_decoding( "ACEScc", "ACEScct", "ACESproxy", - "ALEXA Log C", + "ARRI LogC3", + "ARRI LogC4", "Canon Log 2", "Canon Log 3", "Canon Log", @@ -576,7 +588,8 @@ def log_decoding( {:func:`colour.models.log_decoding_ACEScc`, :func:`colour.models.log_decoding_ACEScct`, :func:`colour.models.log_decoding_ACESproxy`, - :func:`colour.models.log_decoding_ALEXALogC`, + :func:`colour.models.log_decoding_ARRILogC3`, + :func:`colour.models.log_decoding_ARRILogC4`, :func:`colour.models.log_decoding_CanonLog2`, :func:`colour.models.log_decoding_CanonLog3`, :func:`colour.models.log_decoding_CanonLog`, @@ -1041,7 +1054,8 @@ def cctf_encoding( "ACEScc", "ACEScct", "ACESproxy", - "ALEXA Log C", + "ARRI LogC3", + "ARRI LogC4", "ARIB STD-B67", "Blackmagic Film Generation 5", "Canon Log 2", @@ -1195,7 +1209,8 @@ def cctf_decoding( "ACEScc", "ACEScct", "ACESproxy", - "ALEXA Log C", + "ARRI LogC3", + "ARRI LogC4", "ARIB STD-B67", "Blackmagic Film Generation 5", "Canon Log 2", diff --git a/colour/models/rgb/transfer_functions/arri_alexa_log_c.py b/colour/models/rgb/transfer_functions/arri.py similarity index 81% rename from colour/models/rgb/transfer_functions/arri_alexa_log_c.py rename to colour/models/rgb/transfer_functions/arri.py index 40eed841cf..e2c156b307 100644 --- a/colour/models/rgb/transfer_functions/arri_alexa_log_c.py +++ b/colour/models/rgb/transfer_functions/arri.py @@ -1,16 +1,20 @@ """ -ARRI ALEXA Log C Log Encoding -============================= +ARRI Log Encodings +================== -Defines the *ARRI ALEXA Log C* log encoding: +Defines the *ARRI LogC3* log encoding: -- :func:`colour.models.log_encoding_ALEXALogC` -- :func:`colour.models.log_decoding_ALEXALogC` +- :func:`colour.models.log_encoding_ARRILogC3` +- :func:`colour.models.log_decoding_ARRILogC3` References ---------- - :cite:`ARRI2012a` : ARRI. (2012). ALEXA - Log C Curve - Usage in VFX. https://drive.google.com/open?id=1t73fAG_QpV7hJxoQPYZDWvOojYkYDgvn +- :cite:`Cooper2022` : Cooper, S., & Brendel, H. (2022). ARRI LogC4 + Logarithmic Color Space SPECIFICATION. Retrieved October 24, 2022, from + https://www.arri.com/resource/blob/278790/bea879ac0d041a925bed27a096ab3ec2/\ +2022-05-arri-logc4-specification-data.pdf """ from __future__ import annotations @@ -20,6 +24,7 @@ from colour.hints import FloatingOrArrayLike, FloatingOrNDArray, Literal, Union from colour.utilities import ( CanonicalMapping, + Structure, as_float, from_range_1, to_domain_1, @@ -36,8 +41,11 @@ __all__ = [ "DATA_ALEXA_LOG_C_CURVE_BCL", "DATA_ALEXA_LOG_C_CURVE_CONVERSION", - "log_encoding_ALEXALogC", - "log_decoding_ALEXALogC", + "log_encoding_ARRILogC3", + "log_decoding_ARRILogC3", + "CONSTANTS_ARRILOGC4", + "log_encoding_ARRILogC4", + "log_decoding_ARRILogC4", ] DATA_ALEXA_LOG_C_CURVE_BCL: CanonicalMapping = CanonicalMapping( @@ -73,7 +81,7 @@ }, } ) -"""*ARRI ALEXA Log C* curve *Ei, Black, Clipping Level* data.""" +"""*ARRI LogC3* curve *Ei, Black, Clipping Level* data.""" DATA_ALEXA_LOG_C_CURVE_CONVERSION: CanonicalMapping = CanonicalMapping( { @@ -536,13 +544,13 @@ } ) """ -*ARRI ALEXA Log C* curve conversion data between signal and linear scene +*ARRI LogC3* curve conversion data between signal and linear scene exposure factor for *SUP 3.x* and signal and normalised sensor signal for *SUP 2.x*. """ -def log_encoding_ALEXALogC( +def log_encoding_ARRILogC3( x: FloatingOrArrayLike, firmware: Union[Literal["SUP 2.x", "SUP 3.x"], str] = "SUP 3.x", method: Union[ @@ -554,8 +562,8 @@ def log_encoding_ALEXALogC( ] = 800, ) -> FloatingOrNDArray: """ - Define the *ARRI ALEXA Log C* log encoding curve / opto-electronic - transfer function. + Define the *ARRI LogC3* log encoding curve / opto-electronic transfer + function. Parameters ---------- @@ -571,7 +579,7 @@ def log_encoding_ALEXALogC( Returns ------- :class:`numpy.floating` or :class:`numpy.ndarray` - *ARRI ALEXA Log C* encoded data :math:`t`. + *ARRI LogC3* encoded data :math:`t`. References ---------- @@ -593,7 +601,7 @@ def log_encoding_ALEXALogC( Examples -------- - >>> log_encoding_ALEXALogC(0.18) # doctest: +ELLIPSIS + >>> log_encoding_ARRILogC3(0.18) # doctest: +ELLIPSIS 0.3910068... """ @@ -612,7 +620,7 @@ def log_encoding_ALEXALogC( return as_float(from_range_1(t)) -def log_decoding_ALEXALogC( +def log_decoding_ARRILogC3( t: FloatingOrArrayLike, firmware: Union[Literal["SUP 2.x", "SUP 3.x"], str] = "SUP 3.x", method: Union[ @@ -624,13 +632,13 @@ def log_decoding_ALEXALogC( ] = 800, ) -> FloatingOrNDArray: """ - Define the *ARRI ALEXA Log C* log decoding curve / electro-optical - transfer function. + Define the *ARRI LogC3* log decoding curve / electro-optical transfer + function. Parameters ---------- t - *ARRI ALEXA Log C* encoded data :math:`t`. + *ARRI LogC3* encoded data :math:`t`. firmware Alexa firmware version. method @@ -663,7 +671,7 @@ def log_decoding_ALEXALogC( Examples -------- - >>> log_decoding_ALEXALogC(0.391006832034084) # doctest: +ELLIPSIS + >>> log_decoding_ARRILogC3(0.391006832034084) # doctest: +ELLIPSIS 0.18... """ @@ -679,3 +687,142 @@ def log_decoding_ALEXALogC( x = np.where(t > e * cut + f, (10 ** ((t - d) / c) - b) / a, (t - f) / e) return as_float(from_range_1(x)) + + +CONSTANTS_ARRILOGC4: Structure = Structure( + a=(2**18 - 16) / 117.45, + b=(1023 - 95) / 1023, + c=95 / 1023, +) +"""*ARRI LogC4* constants.""" + +_a = CONSTANTS_ARRILOGC4.a +_b = CONSTANTS_ARRILOGC4.b +_c = CONSTANTS_ARRILOGC4.c + +CONSTANTS_ARRILOGC4.s = (7 * np.log(2) * 2 ** (7 - 14 * _c / _b)) / (_a * _b) +CONSTANTS_ARRILOGC4.t = (2 ** (14 * (-_c / _b) + 6) - 64) / _a + +del _a, _b, _c + + +def log_encoding_ARRILogC4( + E_scene: FloatingOrArrayLike, + constants: Structure = CONSTANTS_ARRILOGC4, +) -> FloatingOrNDArray: + """ + Define the *ARRI LogC4* log encoding curve / opto-electronic transfer + function. + + Parameters + ---------- + E_scene + Relative scene linear signal :math:`E_{scene}`. + constants + *ARRI LogC4* constants. + + Returns + ------- + :class:`numpy.floating` or :class:`numpy.ndarray` + *ARRI LogC4* encoded signal :math:`E'`. + + References + ---------- + :cite:`Cooper2022` + + Notes + ----- + +-------------+-----------------------+---------------+ + | **Domain** | **Scale - Reference** | **Scale - 1** | + +=============+=======================+===============+ + | ``E_scene`` | [0, 1] | [0, 1] | + +-------------+-----------------------+---------------+ + + +------------+-----------------------+---------------+ + | **Range** | **Scale - Reference** | **Scale - 1** | + +============+=======================+===============+ + | ``E_p`` | [0, 1] | [0, 1] | + +------------+-----------------------+---------------+ + + Examples + -------- + >>> log_encoding_ARRILogC4(0.18) # doctest: +ELLIPSIS + 0.2783958... + """ + + E_scene = to_domain_1(E_scene) + + a = constants.a + b = constants.b + c = constants.c + s = constants.s + t = constants.t + + E_p = np.where( + E_scene >= t, + (np.log2(a * E_scene + 64) - 6) / 14 * b + c, + (E_scene - t) / s, + ) + + return as_float(from_range_1(E_p)) + + +def log_decoding_ARRILogC4( + E_p: FloatingOrArrayLike, + constants: Structure = CONSTANTS_ARRILOGC4, +) -> FloatingOrNDArray: + """ + Define the *ARRI LogC4* log decoding curve / electro-optical transfer + function. + + Parameters + ---------- + E_p + *ARRI LogC4* encoded signal :math:`E'`. + constants + *ARRI LogC4* constants. + + Returns + ------- + :class:`numpy.floating` or :class:`numpy.ndarray` + Linear data :math:`E_{scene}`. + + Notes + ----- + +------------+-----------------------+---------------+ + | **Domain** | **Scale - Reference** | **Scale - 1** | + +============+=======================+===============+ + | ``E_p`` | [0, 1] | [0, 1] | + +------------+-----------------------+---------------+ + + +-------------+-----------------------+---------------+ + | **Range** | **Scale - Reference** | **Scale - 1** | + +=============+=======================+===============+ + | ``E_scene`` | [0, 1] | [0, 1] | + +-------------+-----------------------+---------------+ + + References + ---------- + :cite:`Cooper2022` + + Examples + -------- + >>> log_decoding_ARRILogC4(0.27839583654826527) # doctest: +ELLIPSIS + 0.18... + """ + + E_p = to_domain_1(E_p) + + a = constants.a + b = constants.b + c = constants.c + s = constants.s + t = constants.t + + E_scene = np.where( + E_p >= 0, + (2 ** (14 * ((E_p - c) / b) + 6) - 64) / a, + E_p * s + t, + ) + + return as_float(from_range_1(E_scene)) diff --git a/colour/models/rgb/transfer_functions/tests/test_arri.py b/colour/models/rgb/transfer_functions/tests/test_arri.py new file mode 100644 index 0000000000..b5c8452294 --- /dev/null +++ b/colour/models/rgb/transfer_functions/tests/test_arri.py @@ -0,0 +1,347 @@ +""" +Define the unit tests for the +:mod:`colour.models.rgb.transfer_functions.arri` module. +""" + +import numpy as np +import unittest + +from colour.models.rgb.transfer_functions import ( + log_encoding_ARRILogC3, + log_decoding_ARRILogC3, + log_encoding_ARRILogC4, + log_decoding_ARRILogC4, +) +from colour.utilities import domain_range_scale, ignore_numpy_errors + +__author__ = "Colour Developers" +__copyright__ = "Copyright 2013 Colour Developers" +__license__ = "New BSD License - https://opensource.org/licenses/BSD-3-Clause" +__maintainer__ = "Colour Developers" +__email__ = "colour-developers@colour-science.org" +__status__ = "Production" + +__all__ = [ + "TestLogEncoding_ARRILogC3", + "TestLogDecoding_ARRILogC3", + "TestLogEncoding_ARRILogC4", + "TestLogDecoding_ARRILogC4", +] + + +class TestLogEncoding_ARRILogC3(unittest.TestCase): + """ + Define :func:`colour.models.rgb.transfer_functions.arri.\ +log_encoding_ARRILogC3` definition unit tests methods. + """ + + def test_log_encoding_ARRILogC3(self): + """ + Test :func:`colour.models.rgb.transfer_functions.arri.\ +log_encoding_ARRILogC3` definition. + """ + + self.assertAlmostEqual( + log_encoding_ARRILogC3(0.0), 0.092809000000000, places=7 + ) + + self.assertAlmostEqual( + log_encoding_ARRILogC3(0.18), 0.391006832034084, places=7 + ) + + self.assertAlmostEqual( + log_encoding_ARRILogC3(1.0), 0.570631558120417, places=7 + ) + + def test_n_dimensional_log_encoding_ARRILogC3(self): + """ + Test :func:`colour.models.rgb.transfer_functions.arri.\ +log_encoding_ARRILogC3` definition n-dimensional arrays support. + """ + + x = 0.18 + t = log_encoding_ARRILogC3(x) + + x = np.tile(x, 6) + t = np.tile(t, 6) + np.testing.assert_array_almost_equal( + log_encoding_ARRILogC3(x), t, decimal=7 + ) + + x = np.reshape(x, (2, 3)) + t = np.reshape(t, (2, 3)) + np.testing.assert_array_almost_equal( + log_encoding_ARRILogC3(x), t, decimal=7 + ) + + x = np.reshape(x, (2, 3, 1)) + t = np.reshape(t, (2, 3, 1)) + np.testing.assert_array_almost_equal( + log_encoding_ARRILogC3(x), t, decimal=7 + ) + + def test_domain_range_scale_log_encoding_ARRILogC3(self): + """ + Test :func:`colour.models.rgb.transfer_functions.arri.\ +log_encoding_ARRILogC3` definition domain and range scale support. + """ + + x = 0.18 + t = log_encoding_ARRILogC3(x) + + d_r = (("reference", 1), ("1", 1), ("100", 100)) + for scale, factor in d_r: + with domain_range_scale(scale): + np.testing.assert_array_almost_equal( + log_encoding_ARRILogC3(x * factor), t * factor, decimal=7 + ) + + @ignore_numpy_errors + def test_nan_log_encoding_ARRILogC3(self): + """ + Test :func:`colour.models.rgb.transfer_functions.arri.\ +log_encoding_ARRILogC3` definition nan support. + """ + + log_encoding_ARRILogC3( + np.array([-1.0, 0.0, 1.0, -np.inf, np.inf, np.nan]) + ) + + +class TestLogDecoding_ARRILogC3(unittest.TestCase): + """ + Define :func:`colour.models.rgb.transfer_functions.arri.\ +log_decoding_ARRILogC3` definition unit tests methods. + """ + + def test_log_decoding_ARRILogC3(self): + """ + Test :func:`colour.models.rgb.transfer_functions.arri.\ +log_decoding_ARRILogC3` definition. + """ + + self.assertAlmostEqual(log_decoding_ARRILogC3(0.092809), 0.0, places=7) + + self.assertAlmostEqual( + log_decoding_ARRILogC3(0.391006832034084), 0.18, places=7 + ) + + self.assertAlmostEqual( + log_decoding_ARRILogC3(0.570631558120417), 1.0, places=7 + ) + + def test_n_dimensional_log_decoding_ARRILogC3(self): + """ + Test :func:`colour.models.rgb.transfer_functions.arri.\ +log_decoding_ARRILogC3` definition n-dimensional arrays support. + """ + + t = 0.391006832034084 + x = log_decoding_ARRILogC3(t) + + t = np.tile(t, 6) + x = np.tile(x, 6) + np.testing.assert_array_almost_equal( + log_decoding_ARRILogC3(t), x, decimal=7 + ) + + t = np.reshape(t, (2, 3)) + x = np.reshape(x, (2, 3)) + np.testing.assert_array_almost_equal( + log_decoding_ARRILogC3(t), x, decimal=7 + ) + + t = np.reshape(t, (2, 3, 1)) + x = np.reshape(x, (2, 3, 1)) + np.testing.assert_array_almost_equal( + log_decoding_ARRILogC3(t), x, decimal=7 + ) + + def test_domain_range_scale_log_decoding_ARRILogC3(self): + """ + Test :func:`colour.models.rgb.transfer_functions.arri.\ +log_decoding_ARRILogC3` definition domain and range scale support. + """ + + t = 0.391006832034084 + x = log_decoding_ARRILogC3(t) + + d_r = (("reference", 1), ("1", 1), ("100", 100)) + for scale, factor in d_r: + with domain_range_scale(scale): + np.testing.assert_array_almost_equal( + log_decoding_ARRILogC3(t * factor), x * factor, decimal=7 + ) + + @ignore_numpy_errors + def test_nan_log_decoding_ARRILogC3(self): + """ + Test :func:`colour.models.rgb.transfer_functions.arri.\ +log_decoding_ARRILogC3` definition nan support. + """ + + log_decoding_ARRILogC3( + np.array([-1.0, 0.0, 1.0, -np.inf, np.inf, np.nan]) + ) + + +class TestLogEncoding_ARRILogC4(unittest.TestCase): + """ + Define :func:`colour.models.rgb.transfer_functions.arri.\ +log_encoding_ARRILogC4` definition unit tests methods. + """ + + def test_log_encoding_ARRILogC4(self): + """ + Test :func:`colour.models.rgb.transfer_functions.arri.\ +log_encoding_ARRILogC4` definition. + """ + + self.assertAlmostEqual( + log_encoding_ARRILogC4(0.0), 0.092864125122190, places=7 + ) + + self.assertAlmostEqual( + log_encoding_ARRILogC4(0.18), 0.278395836548265, places=7 + ) + + self.assertAlmostEqual( + log_encoding_ARRILogC4(1.0), 0.427519364835306, places=7 + ) + + def test_n_dimensional_log_encoding_ARRILogC4(self): + """ + Test :func:`colour.models.rgb.transfer_functions.arri.\ +log_encoding_ARRILogC4` definition n-dimensional arrays support. + """ + + x = 0.18 + t = log_encoding_ARRILogC4(x) + + x = np.tile(x, 6) + t = np.tile(t, 6) + np.testing.assert_array_almost_equal( + log_encoding_ARRILogC4(x), t, decimal=7 + ) + + x = np.reshape(x, (2, 3)) + t = np.reshape(t, (2, 3)) + np.testing.assert_array_almost_equal( + log_encoding_ARRILogC4(x), t, decimal=7 + ) + + x = np.reshape(x, (2, 3, 1)) + t = np.reshape(t, (2, 3, 1)) + np.testing.assert_array_almost_equal( + log_encoding_ARRILogC4(x), t, decimal=7 + ) + + def test_domain_range_scale_log_encoding_ARRILogC4(self): + """ + Test :func:`colour.models.rgb.transfer_functions.arri.\ +log_encoding_ARRILogC4` definition domain and range scale support. + """ + + x = 0.18 + t = log_encoding_ARRILogC4(x) + + d_r = (("reference", 1), ("1", 1), ("100", 100)) + for scale, factor in d_r: + with domain_range_scale(scale): + np.testing.assert_array_almost_equal( + log_encoding_ARRILogC4(x * factor), t * factor, decimal=7 + ) + + @ignore_numpy_errors + def test_nan_log_encoding_ARRILogC4(self): + """ + Test :func:`colour.models.rgb.transfer_functions.arri.\ +log_encoding_ARRILogC4` definition nan support. + """ + + log_encoding_ARRILogC4( + np.array([-1.0, 0.0, 1.0, -np.inf, np.inf, np.nan]) + ) + + +class TestLogDecoding_ARRILogC4(unittest.TestCase): + """ + Define :func:`colour.models.rgb.transfer_functions.arri.\ +log_decoding_ARRILogC4` definition unit tests methods. + """ + + def test_log_decoding_ARRILogC4(self): + """ + Test :func:`colour.models.rgb.transfer_functions.arri.\ +log_decoding_ARRILogC4` definition. + """ + + self.assertAlmostEqual( + log_decoding_ARRILogC4(0.092864125122190), 0.0, places=7 + ) + + self.assertAlmostEqual( + log_decoding_ARRILogC4(0.278395836548265), 0.18, places=7 + ) + + self.assertAlmostEqual( + log_decoding_ARRILogC4(0.427519364835306), 1.0, places=7 + ) + + def test_n_dimensional_log_decoding_ARRILogC4(self): + """ + Test :func:`colour.models.rgb.transfer_functions.arri.\ +log_decoding_ARRILogC4` definition n-dimensional arrays support. + """ + + t = 0.278395836548265 + x = log_decoding_ARRILogC4(t) + + t = np.tile(t, 6) + x = np.tile(x, 6) + np.testing.assert_array_almost_equal( + log_decoding_ARRILogC4(t), x, decimal=7 + ) + + t = np.reshape(t, (2, 3)) + x = np.reshape(x, (2, 3)) + np.testing.assert_array_almost_equal( + log_decoding_ARRILogC4(t), x, decimal=7 + ) + + t = np.reshape(t, (2, 3, 1)) + x = np.reshape(x, (2, 3, 1)) + np.testing.assert_array_almost_equal( + log_decoding_ARRILogC4(t), x, decimal=7 + ) + + def test_domain_range_scale_log_decoding_ARRILogC4(self): + """ + Test :func:`colour.models.rgb.transfer_functions.arri.\ +log_decoding_ARRILogC4` definition domain and range scale support. + """ + + t = 0.278395836548265 + x = log_decoding_ARRILogC4(t) + + d_r = (("reference", 1), ("1", 1), ("100", 100)) + for scale, factor in d_r: + with domain_range_scale(scale): + np.testing.assert_array_almost_equal( + log_decoding_ARRILogC4(t * factor), x * factor, decimal=7 + ) + + @ignore_numpy_errors + def test_nan_log_decoding_ARRILogC4(self): + """ + Test :func:`colour.models.rgb.transfer_functions.arri.\ +log_decoding_ARRILogC4` definition nan support. + """ + + log_decoding_ARRILogC4( + np.array([-1.0, 0.0, 1.0, -np.inf, np.inf, np.nan]) + ) + + +if __name__ == "__main__": + unittest.main() diff --git a/colour/models/rgb/transfer_functions/tests/test_arri_alexa_log_c.py b/colour/models/rgb/transfer_functions/tests/test_arri_alexa_log_c.py deleted file mode 100644 index a4e756031e..0000000000 --- a/colour/models/rgb/transfer_functions/tests/test_arri_alexa_log_c.py +++ /dev/null @@ -1,185 +0,0 @@ -""" -Define the unit tests for the -:mod:`colour.models.rgb.transfer_functions.arri_alexa_log_c` module. -""" - -import numpy as np -import unittest - -from colour.models.rgb.transfer_functions import ( - log_encoding_ALEXALogC, - log_decoding_ALEXALogC, -) -from colour.utilities import domain_range_scale, ignore_numpy_errors - -__author__ = "Colour Developers" -__copyright__ = "Copyright 2013 Colour Developers" -__license__ = "New BSD License - https://opensource.org/licenses/BSD-3-Clause" -__maintainer__ = "Colour Developers" -__email__ = "colour-developers@colour-science.org" -__status__ = "Production" - -__all__ = [ - "TestLogEncoding_ALEXALogC", - "TestLogDecoding_ALEXALogC", -] - - -class TestLogEncoding_ALEXALogC(unittest.TestCase): - """ - Define :func:`colour.models.rgb.transfer_functions.arri_alexa_log_c.\ -log_encoding_ALEXALogC` definition unit tests methods. - """ - - def test_log_encoding_ALEXALogC(self): - """ - Test :func:`colour.models.rgb.transfer_functions.arri_alexa_log_c.\ -log_encoding_ALEXALogC` definition. - """ - - self.assertAlmostEqual( - log_encoding_ALEXALogC(0.0), 0.092809000000000, places=7 - ) - - self.assertAlmostEqual( - log_encoding_ALEXALogC(0.18), 0.391006832034084, places=7 - ) - - self.assertAlmostEqual( - log_encoding_ALEXALogC(1.0), 0.570631558120417, places=7 - ) - - def test_n_dimensional_log_encoding_ALEXALogC(self): - """ - Test :func:`colour.models.rgb.transfer_functions.arri_alexa_log_c.\ -log_encoding_ALEXALogC` definition n-dimensional arrays support. - """ - - x = 0.18 - t = log_encoding_ALEXALogC(x) - - x = np.tile(x, 6) - t = np.tile(t, 6) - np.testing.assert_array_almost_equal( - log_encoding_ALEXALogC(x), t, decimal=7 - ) - - x = np.reshape(x, (2, 3)) - t = np.reshape(t, (2, 3)) - np.testing.assert_array_almost_equal( - log_encoding_ALEXALogC(x), t, decimal=7 - ) - - x = np.reshape(x, (2, 3, 1)) - t = np.reshape(t, (2, 3, 1)) - np.testing.assert_array_almost_equal( - log_encoding_ALEXALogC(x), t, decimal=7 - ) - - def test_domain_range_scale_log_encoding_ALEXALogC(self): - """ - Test :func:`colour.models.rgb.transfer_functions.arri_alexa_log_c.\ -log_encoding_ALEXALogC` definition domain and range scale support. - """ - - x = 0.18 - t = log_encoding_ALEXALogC(x) - - d_r = (("reference", 1), ("1", 1), ("100", 100)) - for scale, factor in d_r: - with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - log_encoding_ALEXALogC(x * factor), t * factor, decimal=7 - ) - - @ignore_numpy_errors - def test_nan_log_encoding_ALEXALogC(self): - """ - Test :func:`colour.models.rgb.transfer_functions.arri_alexa_log_c.\ -log_encoding_ALEXALogC` definition nan support. - """ - - log_encoding_ALEXALogC( - np.array([-1.0, 0.0, 1.0, -np.inf, np.inf, np.nan]) - ) - - -class TestLogDecoding_ALEXALogC(unittest.TestCase): - """ - Define :func:`colour.models.rgb.transfer_functions.arri_alexa_log_c.\ -log_decoding_ALEXALogC` definition unit tests methods. - """ - - def test_log_decoding_ALEXALogC(self): - """ - Test :func:`colour.models.rgb.transfer_functions.arri_alexa_log_c.\ -log_decoding_ALEXALogC` definition. - """ - - self.assertAlmostEqual(log_decoding_ALEXALogC(0.092809), 0.0, places=7) - - self.assertAlmostEqual( - log_decoding_ALEXALogC(0.391006832034084), 0.18, places=7 - ) - - self.assertAlmostEqual( - log_decoding_ALEXALogC(0.570631558120417), 1.0, places=7 - ) - - def test_n_dimensional_log_decoding_ALEXALogC(self): - """ - Test :func:`colour.models.rgb.transfer_functions.arri_alexa_log_c.\ -log_decoding_ALEXALogC` definition n-dimensional arrays support. - """ - - t = 0.391006832034084 - x = log_decoding_ALEXALogC(t) - - t = np.tile(t, 6) - x = np.tile(x, 6) - np.testing.assert_array_almost_equal( - log_decoding_ALEXALogC(t), x, decimal=7 - ) - - t = np.reshape(t, (2, 3)) - x = np.reshape(x, (2, 3)) - np.testing.assert_array_almost_equal( - log_decoding_ALEXALogC(t), x, decimal=7 - ) - - t = np.reshape(t, (2, 3, 1)) - x = np.reshape(x, (2, 3, 1)) - np.testing.assert_array_almost_equal( - log_decoding_ALEXALogC(t), x, decimal=7 - ) - - def test_domain_range_scale_log_decoding_ALEXALogC(self): - """ - Test :func:`colour.models.rgb.transfer_functions.arri_alexa_log_c.\ -log_decoding_ALEXALogC` definition domain and range scale support. - """ - - t = 0.391006832034084 - x = log_decoding_ALEXALogC(t) - - d_r = (("reference", 1), ("1", 1), ("100", 100)) - for scale, factor in d_r: - with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - log_decoding_ALEXALogC(t * factor), x * factor, decimal=7 - ) - - @ignore_numpy_errors - def test_nan_log_decoding_ALEXALogC(self): - """ - Test :func:`colour.models.rgb.transfer_functions.arri_alexa_log_c.\ -log_decoding_ALEXALogC` definition nan support. - """ - - log_decoding_ALEXALogC( - np.array([-1.0, 0.0, 1.0, -np.inf, np.inf, np.nan]) - ) - - -if __name__ == "__main__": - unittest.main() diff --git a/docs/basics.rst b/docs/basics.rst index 2147d93a5a..d67f7baad6 100644 --- a/docs/basics.rst +++ b/docs/basics.rst @@ -42,7 +42,7 @@ Similarly, all the RGB colourspaces can be individually accessed from the RGB_COLOURSPACE_ACES2065_1 RGB_COLOURSPACE_ACESPROXY RGB_COLOURSPACE_APPLE_RGB RGB_COLOURSPACE_BT470_525 RGB_COLOURSPACE_ACESCC RGB_COLOURSPACE_ADOBE_RGB1998 RGB_COLOURSPACE_BEST_RGB RGB_COLOURSPACE_BT470_625 RGB_COLOURSPACE_ACESCCT RGB_COLOURSPACE_ADOBE_WIDE_GAMUT_RGB RGB_COLOURSPACE_BETA_RGB RGB_COLOURSPACE_BT709 > - RGB_COLOURSPACE_ACESCG RGB_COLOURSPACE_ALEXA_WIDE_GAMUT RGB_COLOURSPACE_BT2020 RGB_COLOURSPACE_CIE_RGB + RGB_COLOURSPACE_ACESCG RGB_COLOURSPACE_ARRI_WIDE_GAMUT_3 RGB_COLOURSPACE_BT2020 RGB_COLOURSPACE_CIE_RGB Abbreviations ------------- diff --git a/docs/colour.models.rst b/docs/colour.models.rst index 94cb678d6f..738041bd9c 100644 --- a/docs/colour.models.rst +++ b/docs/colour.models.rst @@ -414,7 +414,8 @@ RGB Colourspaces RGB_COLOURSPACE_ACESCG RGB_COLOURSPACE_ADOBE_RGB1998 RGB_COLOURSPACE_ADOBE_WIDE_GAMUT_RGB - RGB_COLOURSPACE_ALEXA_WIDE_GAMUT + RGB_COLOURSPACE_ARRI_WIDE_GAMUT_3 + RGB_COLOURSPACE_ARRI_WIDE_GAMUT_4 RGB_COLOURSPACE_APPLE_RGB RGB_COLOURSPACE_BEST_RGB RGB_COLOURSPACE_BETA_RGB @@ -669,8 +670,8 @@ Log Encoding and Decoding log_decoding_ACEScct log_encoding_ACESproxy log_decoding_ACESproxy - log_encoding_ALEXALogC - log_decoding_ALEXALogC + log_encoding_ARRILogC3 + log_decoding_ARRILogC3 log_encoding_CanonLog2 log_decoding_CanonLog2 log_encoding_CanonLog3 diff --git a/docs/index.rst b/docs/index.rst index 1d29f33d92..1ddf641894 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -682,7 +682,8 @@ RGB Colourspaces 'ACEScct', 'ACEScg', 'ACESproxy', - 'ALEXA Wide Gamut', + 'ARRI Wide Gamut 3', + 'ARRI Wide Gamut 4', 'Adobe RGB (1998)', 'Adobe Wide Gamut RGB', 'Apple RGB', @@ -799,7 +800,8 @@ Log Encoding / Decoding ['ACEScc', 'ACEScct', 'ACESproxy', - 'ALEXA Log C', + 'ARRI LogC3', + 'ARRI LogC4', 'Canon Log', 'Canon Log 2', 'Canon Log 3', @@ -834,7 +836,8 @@ CCTFs Encoding / Decoding ['ACEScc', 'ACEScct', 'ACESproxy', - 'ALEXA Log C', + 'ARRI LogC3', + 'ARRI LogC4', 'ARIB STD-B67', 'Canon Log', 'Canon Log 2',