Skip to content

Commit

Permalink
Merge 13d0694 into 8237f16
Browse files Browse the repository at this point in the history
  • Loading branch information
KelSolaar authored Aug 30, 2021
2 parents 8237f16 + 13d0694 commit 2688b35
Show file tree
Hide file tree
Showing 31 changed files with 536 additions and 442 deletions.
13 changes: 10 additions & 3 deletions .github/workflows/continuous-integration.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,20 +30,27 @@ jobs:
- name: Install Dependencies (macOS)
if: matrix.os == 'macOS-latest'
run: |
brew install gnu-sed
brew install gnu-sed graphviz
ln -s /usr/local/bin/gsed /usr/local/bin/sed
shell: bash
- name: Install Dependencies (Ubuntu)
if: matrix.os == 'ubuntu-18.04'
run: |
sudo apt-get --yes install libboost-all-dev libilmbase-dev libopenexr-dev libpng-dev libtiff5-dev
sudo apt-get --yes install graphviz graphviz-dev libboost-all-dev libilmbase-dev libopenexr-dev libpng-dev libtiff5-dev
- name: Install Poetry
run: |
curl -L https://raw.githubusercontent.com/sdispater/poetry/master/get-poetry.py -o get-poetry.py
python get-poetry.py --version 1.0.10
echo "$HOME/.poetry/bin" >> $GITHUB_PATH
shell: bash
- name: Install Package Dependencies
- name: Install Package Dependencies (macOS & Ubuntu)
if: matrix.os == 'macOS-latest' || matrix.os == 'ubuntu-18.04'
run: |
poetry install --extras "graphviz optional plotting"
poetry run python -c "import imageio;imageio.plugins.freeimage.download()"
shell: bash
- name: Install Package Dependencies (Windows)
if: matrix.os == 'windows-latest'
run: |
poetry install --extras "optional plotting"
poetry run python -c "import imageio;imageio.plugins.freeimage.download()"
Expand Down
4 changes: 2 additions & 2 deletions colour/colorimetry/dominant.py
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ def dominant_wavelength(xy, xy_n, cmfs=None, inverse=False):
is located on the line of purples:
>>> xy = np.array([0.37605506, 0.24452225])
>>> pprint(dominant_wavelength(xy, xy_n, cmfs)) # doctest: +ELLIPSIS
>>> pprint(dominant_wavelength(xy, xy_n)) # doctest: +ELLIPSIS
(array(-509.0),
array([ 0.4572314..., 0.1362814...]),
array([ 0.0104096..., 0.7320745...]))
Expand Down Expand Up @@ -263,7 +263,7 @@ def complementary_wavelength(xy, xy_n, cmfs=None):
the line of purples:
>>> xy = np.array([0.54369557, 0.32107944])
>>> pprint(complementary_wavelength(xy, xy_n, cmfs)) # doctest: +ELLIPSIS
>>> pprint(complementary_wavelength(xy, xy_n)) # doctest: +ELLIPSIS
(array(492.0),
array([ 0.0364795 , 0.3384712...]),
array([ 0.0364795 , 0.3384712...]))
Expand Down
32 changes: 13 additions & 19 deletions colour/colorimetry/tristimulus_values.py
Original file line number Diff line number Diff line change
Expand Up @@ -679,29 +679,23 @@ def sd_to_XYZ_tristimulus_weighting_factors_ASTME308(sd,
--------
>>> from colour import MSDS_CMFS, SDS_ILLUMINANTS, SpectralDistribution
>>> cmfs = MSDS_CMFS['CIE 1931 2 Degree Standard Observer']
>>> data = {
... 400: 0.0641,
... 420: 0.0645,
... 440: 0.0562,
... 460: 0.0537,
... 480: 0.0559,
... 500: 0.0651,
... 520: 0.0705,
... 540: 0.0772,
... 560: 0.0870,
... 580: 0.1128,
... 600: 0.1360,
... 620: 0.1511,
... 640: 0.1688,
... 660: 0.1996,
... 680: 0.2397,
... 700: 0.2852
... }
>>> sd = SpectralDistribution(data)
>>> illuminant = SDS_ILLUMINANTS['D65']
>>> shape = SpectralShape(400, 700, 20)
>>> data = np.array([
... 0.0641, 0.0645, 0.0562, 0.0537, 0.0559, 0.0651, 0.0705, 0.0772,
... 0.0870, 0.1128, 0.1360, 0.1511, 0.1688, 0.1996, 0.2397, 0.2852
... ])
>>> sd = SpectralDistribution(data, shape)
>>> sd_to_XYZ_tristimulus_weighting_factors_ASTME308(
... sd, cmfs, illuminant) # doctest: +ELLIPSIS
array([ 10.8405832..., 9.6844909..., 6.2155622...])
# The default CMFS are the "CIE 1931 2 Degree Standard Observer", and the
# default illuminant is "CIE Illuminant E":
>>> sd_to_XYZ_tristimulus_weighting_factors_ASTME308(sd)
... # doctest: +ELLIPSIS
array([ 11.7786111..., 9.9589055..., 5.7403205...])
"""

cmfs, illuminant = handle_spectral_arguments(
Expand Down
4 changes: 2 additions & 2 deletions colour/io/image.py
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,7 @@ def read_image_Imageio(path, bit_depth='float32', **kwargs):

from imageio import imread

image = imread(path, **kwargs)
image = np.squeeze(imread(path, **kwargs))

return convert_bit_depth(image, bit_depth)

Expand Down Expand Up @@ -452,7 +452,7 @@ def write_image_OpenImageIO(image, path, bit_depth='float32', attributes=None):

image_output = ImageOutput.create(path)

if VERSION_MAJOR == 1:
if VERSION_MAJOR == 1: # pragma: no cover
from OpenImageIO import ImageOutputOpenMode

image_output.open(path, specification, ImageOutputOpenMode.Create)
Expand Down
62 changes: 22 additions & 40 deletions colour/io/luts/cinespace_csp.py
Original file line number Diff line number Diff line change
Expand Up @@ -261,28 +261,24 @@ def write_LUT_Cinespace(LUT, path, decimals=7):
>>> write_LUT_Cinespace(LUT, 'My_LUT.cube') # doctest: +SKIP
"""

has_3D, has_3x1D, non_uniform = False, False, False
has_3D, has_3x1D = False, False

if isinstance(LUT, LUTSequence):
assert (len(LUT) == 2 and
(isinstance(LUT[0], LUT1D) or isinstance(LUT[0], LUT3x1D)) and
isinstance(LUT[1],
LUT3D)), 'LUTSequence must be 1D+3D or 3x1D+3D!'
isinstance(LUT[0], (LUT1D, LUT3x1D)) and isinstance(
LUT[1], LUT3D)), 'LUTSequence must be 1D+3D or 3x1D+3D!'
has_3x1D = True
has_3D = True
name = LUT[1].name
if isinstance(LUT[0], LUT1D):
non_uniform = LUT[0].is_domain_explicit()
LUT[0] = LUT[0].as_LUT(LUT3x1D)
LUT[0] = (LUT[0].as_LUT(LUT3x1D)
if isinstance(LUT[0], LUT1D) else LUT[0])
name = '{0} - {1}'.format(LUT[0].name, LUT[1].name)

elif isinstance(LUT, LUT1D):
non_uniform = LUT.is_domain_explicit()
name = LUT.name
LUT = LUTSequence(LUT.as_LUT(LUT3x1D), LUT3D())
has_3x1D = True

elif isinstance(LUT, LUT3x1D):
non_uniform = LUT.is_domain_explicit()
name = LUT.name
LUT = LUTSequence(LUT, LUT3D())
has_3x1D = True
Expand Down Expand Up @@ -350,35 +346,27 @@ def _format_tuple(array):

csp_file.write('END METADATA\n\n')

if has_3D or non_uniform:
if has_3D:
if has_3x1D:
for i in range(3):
if LUT[0].is_domain_explicit():
size = _ragged_size(LUT[0].domain)[i]
table_min = np.nanmin(LUT[0].table)
table_max = np.nanmax(LUT[0].table)
else:
size = LUT[0].size
size = (_ragged_size(LUT[0].domain)[i]
if LUT[0].is_domain_explicit() else LUT[0].size)

csp_file.write('{0}\n'.format(size))

for j in range(size):
if LUT[0].is_domain_explicit():
entry = LUT[0].domain[j][i]
else:
entry = (
LUT[0].domain[0][i] + j *
(LUT[0].domain[1][i] - LUT[0].domain[0][i]) /
(LUT[0].size - 1))
entry = (LUT[0].domain[j][i]
if LUT[0].is_domain_explicit() else
(LUT[0].domain[0][i] + j *
(LUT[0].domain[1][i] - LUT[0].domain[0][i]) /
(LUT[0].size - 1)))

csp_file.write('{0:.{1}f} '.format(entry, decimals))

csp_file.write('\n')

for j in range(size):
entry = LUT[0].table[j][i]
if non_uniform:
entry -= table_min
entry /= (table_max - table_min)
csp_file.write('{0:.{1}f} '.format(entry, decimals))

csp_file.write('\n')
Expand All @@ -390,20 +378,14 @@ def _format_tuple(array):
[LUT[1].domain[0][i], LUT[1].domain[1][i]])))
csp_file.write('{0:.{2}f} {1:.{2}f}\n'.format(
0, 1, decimals))
if non_uniform:
csp_file.write('\n{0}\n'.format(2))
row = [table_min, table_min, table_min]
csp_file.write('{0}\n'.format(_format_array(row)))
row = [table_max, table_max, table_max]
csp_file.write('{0}\n'.format(_format_array(row)))
else:
csp_file.write('\n{0} {1} {2}\n'.format(
LUT[1].table.shape[0], LUT[1].table.shape[1],
LUT[1].table.shape[2]))
table = LUT[1].table.reshape([-1, 3], order='F')

for row in table:
csp_file.write('{0}\n'.format(_format_array(row)))
csp_file.write('\n{0} {1} {2}\n'.format(LUT[1].table.shape[0],
LUT[1].table.shape[1],
LUT[1].table.shape[2]))
table = LUT[1].table.reshape([-1, 3], order='F')

for row in table:
csp_file.write('{0}\n'.format(_format_array(row)))

else:
for i in range(3):
Expand Down
4 changes: 2 additions & 2 deletions colour/io/luts/iridas_cube.py
Original file line number Diff line number Diff line change
Expand Up @@ -215,8 +215,8 @@ def write_LUT_IridasCube(LUT, path, decimals=7):
if isinstance(LUT, LUT1D):
LUT = LUT.as_LUT(LUT3x1D)

assert (isinstance(LUT, LUT3x1D) or
isinstance(LUT, LUT3D)), '"LUT" must be a 1D, 3x1D or 3D "LUT"!'
assert isinstance(
LUT, (LUT3x1D, LUT3D)), '"LUT" must be a 1D, 3x1D or 3D "LUT"!'

is_3x1D = isinstance(LUT, LUT3x1D)

Expand Down
2 changes: 1 addition & 1 deletion colour/io/luts/resolve_cube.py
Original file line number Diff line number Diff line change
Expand Up @@ -282,7 +282,7 @@ def write_LUT_ResolveCube(LUT, path, decimals=7):

has_3x1D = True
has_3D = True
name = LUT[1].name
name = '{0} - {1}'.format(LUT[0].name, LUT[1].name)
elif isinstance(LUT, LUT1D):
name = LUT.name
LUT = LUTSequence(LUT.as_LUT(LUT3x1D), LUT3D())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ CSPLUTV100
3D

BEGIN METADATA
ThreeDimensionalTable
LUT3D without My Shaper
END METADATA

2
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ CSPLUTV100
3D

BEGIN METADATA
LUT3D with My Shaper - Cube
LUT3D with My Shaper
A first "Shaper" comment.
A second "Shaper" comment.
A first "LUT3D" comment.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ CSPLUTV100
1D

BEGIN METADATA
lin to LogC
LogC to lin
Linear to LogC
LogC to Linear
END METADATA

5
Expand Down
42 changes: 30 additions & 12 deletions colour/io/luts/tests/test_cinespace_csp.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ def test_read_LUT_Cinespace(self):
self.assertEqual(LUT_3.size, 2)

LUT_4 = read_LUT_Cinespace(
os.path.join(LUTS_DIRECTORY, 'Non_Uniform.csp'))
os.path.join(LUTS_DIRECTORY, 'Explicit_Domain.csp'))
self.assertEqual(LUT_4[0].is_domain_explicit(), True)
self.assertEqual(LUT_4[1].table.shape, (2, 3, 4, 3))

Expand Down Expand Up @@ -168,42 +168,60 @@ def test_write_LUT_Cinespace(self):
np.array([-0.1, 0.5, 1.0, np.nan, np.nan, np.nan]),
np.array([-1.0, -0.5, 0.0, 0.5, 1.0, np.nan]),
))
LUT_4_t = LUT3x1D(domain=domain, table=domain * 2)
LUT_4_t = LUT3x1D(
domain=domain, table=domain * 2, name='Ragged Domain')
write_LUT_Cinespace(
LUT_4_t, os.path.join(self._temporary_directory,
'RaggedDomain.csp'))
LUT_4_t,
os.path.join(self._temporary_directory, 'Ragged_Domain.csp'))
LUT_4_r = read_LUT_Cinespace(
os.path.join(self._temporary_directory, 'RaggedDomain.csp'))
os.path.join(LUTS_DIRECTORY, 'Ragged_Domain.csp'))
np.testing.assert_almost_equal(LUT_4_t.domain, LUT_4_r.domain)
np.testing.assert_almost_equal(LUT_4_t.table, LUT_4_r.table, decimal=6)

LUT_5_r = read_LUT_Cinespace(
os.path.join(LUTS_DIRECTORY,
'Three_Dimensional_Table_With_Shaper.csp'))
LUT_5_r.sequence[0] = LUT_5_r.sequence[0].as_LUT(
LUT3x1D, force_conversion=True)
LUT1D, force_conversion=True)
write_LUT_Cinespace(
LUT_5_r,
os.path.join(self._temporary_directory,
'Three_Dimensional_Table_With_Shaper.csp'))
LUT_5_t = read_LUT_Cinespace(
os.path.join(self._temporary_directory,
'Three_Dimensional_Table_With_Shaper.csp'))
LUT_5_r = read_LUT_Cinespace(
os.path.join(LUTS_DIRECTORY,
'Three_Dimensional_Table_With_Shaper.csp'))
LUT_5_t = read_LUT_Cinespace(
os.path.join(self._temporary_directory,
'Three_Dimensional_Table_With_Shaper.csp'))
self.assertEqual(LUT_5_r, LUT_5_t)

LUT_6_r = read_LUT_Cinespace(
os.path.join(LUTS_DIRECTORY,
'Three_Dimensional_Table_With_Shaper.csp'))
LUT_6_r.sequence[0] = LUT_6_r.sequence[0].as_LUT(
LUT3x1D, force_conversion=True)
write_LUT_Cinespace(
LUT_6_r,
os.path.join(self._temporary_directory,
'Three_Dimensional_Table_With_Shaper.csp'))
LUT_6_r = read_LUT_Cinespace(
os.path.join(LUTS_DIRECTORY,
'Three_Dimensional_Table_With_Shaper.csp'))
LUT_6_t = read_LUT_Cinespace(
os.path.join(self._temporary_directory,
'Three_Dimensional_Table_With_Shaper.csp'))
self.assertEqual(LUT_6_r, LUT_6_t)

LUT_7_r = read_LUT_Cinespace(
os.path.join(LUTS_DIRECTORY, 'ACES_Proxy_10_to_ACES.csp'))
write_LUT_Cinespace(
LUT_6_r.as_LUT(LUT1D, force_conversion=True),
LUT_7_r.as_LUT(LUT1D, force_conversion=True),
os.path.join(self._temporary_directory,
'ACES_Proxy_10_to_ACES.csp'))
LUT_6_t = read_LUT_Cinespace(
LUT_7_t = read_LUT_Cinespace(
os.path.join(self._temporary_directory,
'ACES_Proxy_10_to_ACES.csp'))
self.assertEqual(LUT_6_r, LUT_6_t)
self.assertEqual(LUT_7_r, LUT_7_t)

def test_raise_exception_write_LUT_Cinespace(self):
"""
Expand Down
3 changes: 0 additions & 3 deletions colour/io/luts/tests/test_sony_spi3d.py
Original file line number Diff line number Diff line change
Expand Up @@ -216,9 +216,6 @@ def test_write_LUT_SonySPI3D(self):
lines = filter(None,
(line.strip() for line in spi3d_file.readlines()))
for line in lines:
if line.startswith('#'):
continue

tokens = line.split()
if len(tokens) == 6:
indexes.append(as_int_array(tokens[:3]))
Expand Down
Binary file added colour/io/tests/resources/Overflowing_Gradient.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit 2688b35

Please sign in to comment.