Coverage for io/luts/sony_spimtx.py: 44%

27 statements  

« prev     ^ index     » next       coverage.py v7.11.0, created at 2025-11-16 22:49 +1300

1""" 

2Sony .spimtx LUT Format Input / Output Utilities 

3================================================ 

4 

5Define the *Sony* *.spimtx* *LUT* format related input / output utilities 

6objects: 

7 

8- :func:`colour.io.read_LUT_SonySPImtx` 

9- :func:`colour.io.write_LUT_SonySPImtx` 

10""" 

11 

12from __future__ import annotations 

13 

14import typing 

15 

16import numpy as np 

17 

18from colour.constants import DTYPE_FLOAT_DEFAULT 

19 

20if typing.TYPE_CHECKING: 

21 from colour.hints import PathLike 

22 

23from colour.io.luts import LUTOperatorMatrix 

24from colour.io.luts.common import path_to_title 

25 

26__author__ = "Colour Developers" 

27__copyright__ = "Copyright 2013 Colour Developers" 

28__license__ = "BSD-3-Clause - https://opensource.org/licenses/BSD-3-Clause" 

29__maintainer__ = "Colour Developers" 

30__email__ = "colour-developers@colour-science.org" 

31__status__ = "Production" 

32 

33__all__ = [ 

34 "read_LUT_SonySPImtx", 

35 "write_LUT_SonySPImtx", 

36] 

37 

38 

39def read_LUT_SonySPImtx(path: str | PathLike) -> LUTOperatorMatrix: 

40 """ 

41 Read the specified *Sony* *.spimtx* *LUT* file. 

42 

43 Parse the *.spimtx* format which contains a 3x4 matrix stored as 12 

44 values. Extract the 3x3 transformation matrix and offset vector from 

45 the fourth column (scaled by 65535) to create a 

46 :class:`colour.LUTOperatorMatrix` instance. 

47 

48 Parameters 

49 ---------- 

50 path 

51 *LUT* file path. 

52 

53 Returns 

54 ------- 

55 :class:`colour.LUTOperatorMatrix` 

56 *LUT* operator matrix instance containing the extracted 3x3 matrix 

57 and offset vector. 

58 

59 Examples 

60 -------- 

61 >>> import os 

62 >>> path = os.path.join( 

63 ... os.path.dirname(__file__), 

64 ... "tests", 

65 ... "resources", 

66 ... "sony_spimtx", 

67 ... "dt.spimtx", 

68 ... ) 

69 >>> print(read_LUT_SonySPImtx(path)) 

70 LUTOperatorMatrix - dt 

71 ---------------------- 

72 <BLANKLINE> 

73 Matrix : [[ 0.864274 0. 0. 0. ] 

74 [ 0. 0.864274 0. 0. ] 

75 [ 0. 0. 0.864274 0. ] 

76 [ 0. 0. 0. 1. ]] 

77 Offset : [ 0. 0. 0. 0.] 

78 """ 

79 

80 path = str(path) 

81 

82 matrix = np.loadtxt(path, dtype=DTYPE_FLOAT_DEFAULT) 

83 matrix = np.reshape(matrix, (3, 4)) 

84 offset = matrix[:, 3] / 65535 

85 matrix = matrix[:3, :3] 

86 

87 title = path_to_title(path) 

88 

89 return LUTOperatorMatrix(matrix, offset, name=title) 

90 

91 

92def write_LUT_SonySPImtx( 

93 LUT: LUTOperatorMatrix, 

94 path: str | PathLike | typing.IO[typing.Any], 

95 decimals: int = 7, 

96) -> bool: 

97 """ 

98 Write the specified *LUT* to the specified *Sony* *.spimtx* *LUT* file. 

99 

100 Parameters 

101 ---------- 

102 LUT 

103 :class:`LUTOperatorMatrix` class instance to write at the 

104 specified path. 

105 path 

106 *LUT* file path. 

107 decimals 

108 Number of decimal places for formatting numeric values. 

109 

110 Returns 

111 ------- 

112 :class:`bool` 

113 Definition success. 

114 

115 Examples 

116 -------- 

117 >>> matrix = np.array( 

118 ... [ 

119 ... [1.45143932, -0.23651075, -0.21492857], 

120 ... [-0.07655377, 1.1762297, -0.09967593], 

121 ... [0.00831615, -0.00603245, 0.9977163], 

122 ... ] 

123 ... ) 

124 >>> M = LUTOperatorMatrix(matrix) 

125 >>> write_LUT_SonySPImtx(M, "My_LUT.spimtx") # doctest: +SKIP 

126 """ 

127 

128 matrix, offset = LUT.matrix, LUT.offset 

129 offset *= 65535 

130 

131 array = np.hstack( 

132 [ 

133 np.reshape(matrix, (4, 4))[:3, :3], 

134 np.transpose(np.array([offset[:3]])), 

135 ] 

136 ) 

137 

138 np.savetxt(path, array, fmt=f"%.{decimals}f") 

139 

140 return True