1
1
mirror of https://gitlab.gnome.org/GNOME/gimp.git synced 2025-10-06 05:22:40 +02:00

Compare commits

...

13 Commits

Author SHA1 Message Date
Jehan
d084f2adc0 app: more accurate test and reference file names. 2024-10-11 10:41:50 +02:00
Jehan
c8dd12034e More digests from CI. 2024-10-11 10:41:50 +02:00
Jehan
6cdb459c25 Hmmm… 2024-10-11 10:41:50 +02:00
Jehan
b94610f70c Again from CI.
Just a few pixels different, all perceptually identical!
2024-10-11 10:41:50 +02:00
Jehan
3af2db53c3 Plop. 2024-10-11 10:41:50 +02:00
Jehan
ebce835d79 gitlab, libgimp: also exporting as .data file and storing as artifact.
This will help debugging.
2024-10-11 10:41:50 +02:00
Jehan
7b8a83eaba app: some of the CI runners computes different digest.
The data is perceptually identical or off-by-one pixels, which means
these are very likely consequence of float computation slight
differences, which make off-by-one u8 integers when converted back.
2024-10-11 10:41:50 +02:00
Jehan
09a2098487 libgimp: allow using the download server as fallback for data comparison storage.
This way, we can have the CI run data comparison for layer mode unit
testing without pushing huge data file in the repository. I don't add
any textual output about this feature though, because it's not like
anyone else but maintainers/admins can upload any files there anyway.
2024-10-11 10:41:50 +02:00
Jehan
3055f1a191 Adding different digest with no-SSE2 codepath. 2024-10-11 10:38:31 +02:00
Jehan
9b1c0b438c app: adding unit testing for the non-legacy layer modes too.
There were just too many possible cases, so I created a script
tools/compute-layer-mode-digests.py which I am going to commit in the
`gimp-2-10` branch.

These are the digests generated this way with GIMP 2.10 with SSE2.
"Color Erase" testing is disabled currently because it is very broken
(digests are different at each export!).

Some modes (Anti Erase and Replace) are not introspected, therefore they
cannot be tested. Pass-through is not tested right now because it
requires special-casing and a little more thought.

"Behind" is not in the list of layer modes in the Layers dockable, and
it could not be set in GIMP 2.10 API, but it could be set in GIMP 3.0
API. So I don't have GIMP 2.10 data. Let's use GIMP 3 data as our
baseline for this blending mode testing, from now on.
2024-10-11 10:38:31 +02:00
Jehan
fbc296fc25 app: all legacy layer modes are now verified.
Some operations generate slightly different pixels but all differences
are minimal (in worst case, barely 0.3%) and the pixels are perceptually
identical, with basically off-by-one differences (e.g. in some case, I
had pixels whose value when converted to u8 would be 91.4999999…, which
meant that slight float computation different are enough to make it be
either 91 or 92).
Even more, in 2 builds of GIMP 2.10 (flatpak or custom build), I had
either the same result as 2.99 in one of the build, or sometimes a third
result.

But any case, none of these differences warrant being qualified as a
change in the render. Therefore I make the digest to compare to into a
list of digests. Hopefully we won't have to edit this list too often
with more slight variant renders.
2024-10-11 10:38:30 +02:00
Jehan
630aba1303 app, libgimp: improve debugging ability in the layer mode unit testing.
I add a feature so that one can drop a data file of the result as
expected in the build folder. Then the unit testing framework will
compare it to the layer mode render and will list of the problematic
pixels, additionally to some statistical data to discover if we are
likely just dealing with off-by-one issues, or some more drastic render
differences.
2024-10-11 10:38:30 +02:00
Jehan
bba0013f8c app, libgimp: WIP new infrastructure for testing layer modes.
One of the points we care most about is for XCF code stability over
time. In particular, loading an old XCF should render visually the same.

This unit-testing infrastructure allows testing that we do not deviate
when editing layer mode code. It works on u8 so that float computation
precision does not come into account as well.

For now, I only run it on legacy layer modes.

Note that 6 legacy modes have different hash from their 2.10
counterparts (difference, subtract and all 4 HSV/HSL layer modes). In a
next step, I will look more closely into them to determine if we are
talking of minor, not-too relevant, differences or if we broke their
implementations somehow.
2024-10-11 10:38:30 +02:00
9 changed files with 1110 additions and 40 deletions

View File

@@ -308,6 +308,8 @@ gimp-debian-x64:
- _build/meson-dist/
- _build/config.h
- _build/devel-docs/
#- _build/test-gimp-*.xcf
#- _build/test-gimp-*.data
reports:
junit: "_build/meson-logs/testlog.junit.xml"
expire_in: 2 days

View File

@@ -1,30 +1,130 @@
libapplayermodeslegacy_sources = [
'gimpcolor-legacy.c',
'gimpoperationadditionlegacy.c',
'gimpoperationburnlegacy.c',
'gimpoperationdarkenonlylegacy.c',
'gimpoperationdifferencelegacy.c',
'gimpoperationdividelegacy.c',
'gimpoperationdodgelegacy.c',
'gimpoperationgrainextractlegacy.c',
'gimpoperationgrainmergelegacy.c',
'gimpoperationhardlightlegacy.c',
'gimpoperationhslcolorlegacy.c',
'gimpoperationhsvhuelegacy.c',
'gimpoperationhsvsaturationlegacy.c',
'gimpoperationhsvvaluelegacy.c',
'gimpoperationlightenonlylegacy.c',
'gimpoperationmultiplylegacy.c',
'gimpoperationscreenlegacy.c',
'gimpoperationsoftlightlegacy.c',
'gimpoperationsubtractlegacy.c',
]
# We do not test algorithm correctness but algorithm stability: an old
# XCF should look the same when loaded with a newer GIMP.
#
# Current hashes were made based on renders in GIMP 2.10. To check how
# they were made, look at the script tools/compute-layer-mode-digests.py
# in `gimp-2-10` branch.
#
# In other words: DO NOT just change a hash to make the test pass. If
# one of the test starts failing, this is very bad as it will break
# renders of existing XCF files.
# If bugs need to be fixed in one of the blend modes, they need to be
# fixed for further versions while still loading XCF done with older
# versions of GIMP the same way as they used to.
#
# When adding a new mode, here is how to add a new hash:
#
# 1. First add it without any hash and run the test.
# 2. The unit testing will fail telling you which keys are needed (it
# can be keys like "auto:auto:auto" for non-mutable modes, or
# "linear:union:perceptual", etc. for every possible case). Add this
# key with an empty hash.
# 3. Run the test again.
# 4. The test again will fail again, this time telling you the found
# hash. If you consider your implementation to be correct, this hash
# is what you want to store in this dictionnary.
#
# If somehow, you want the hash to come from an older implementation,
# you can do this:
#
# 1. In the second test run, the test will generate a XCF on failure
# (and will display its path in the test log).
# 2. Load this XCF with your reference implementations. E.g. initially
# I loaded them with latest GIMP 2.10.
# 3. Export as data in "Contiguous" configuration.
# 4. Call sha256sum on the data file.
# 5. The returned checksum is your reference.
legacy_layer_modes = {
'addition-legacy': {
'auto:auto:auto': [ '5294fa2036be51d218a6c980cb9cff149c9b3f6934d1de1fcc2cd0785ce29a05' ]
},
'burn-legacy': {
'auto:auto:auto': [ 'ae23f7a31fd31f197b89d03d1018e970baae32517a6f95f8772641fbe6d8b041' ]
},
'darken-only-legacy': {
'auto:auto:auto': [ 'ac27e33b4832709fb39aa7631bd035683a6bbf32a275e325f144093b04fcc5e7' ]
},
'difference-legacy': {
'auto:auto:auto': [ '4feed6e676a3f4d83bcf5457bdc8cdf804b1996c36e38ebaeff014b1e197bf3f',
'55a1b0ef78c91a6b78e652433d5bca3178f2d594197ca2531355bac8f0ffbc52' ]
},
'divide-legacy': {
'auto:auto:auto': [ 'd946379074f86378088e35524f956a1c4280d81ac6081e546197229b49deb20c' ]
},
'dodge-legacy': {
'auto:auto:auto': [ '45d34e25cf6dd194ce944bdc404091892b86c7e77b860250b1d1c41b4d0ad076' ]
},
'grain-extract-legacy': {
'auto:auto:auto': [ '578a6f958eddb8af5a4d85dc71b85e27df411935ebd880021cb779e0c37daac1' ]
},
'grain-merge-legacy': {
'auto:auto:auto': [ '5dc0fb0e4b7243e0bb917595c4146eb63282d402341d25dc136957df56eefd41' ]
},
'hardlight-legacy': {
'auto:auto:auto': [ '956db3eeae96a9cddaddcbe5aa71787e6f546b0b1a5c298da04ec91b22c9ec5c' ]
},
'hsl-color-legacy': {
'auto:auto:auto': [ '5126b7eebbdaa0315f0a94fb6184fef41a95cb79577d5b633c2d1a6dc5680661',
'31f182e50286b6088a819c6a81d70f145c0ca7307c15726515cfb6ac51efe2d5',
'70be349d74a1c21b446b67064dde5a620b4181df600ae64e10ecad30b95de1a8',
'877860c90b20a83c1a374cc811af60767d0ba78511ed0033f4d25ef9665e24c1' ]
},
'hsv-hue-legacy': {
'auto:auto:auto': [ '07f188536bf2e2da2341424e8a9c54156cfce11af419f806a5d0c63e0c84c8d0',
'f395f8eec0248abd3e541aed569d73504c7ea569134753cfc4743594ca8ec83b',
'157ccba9bc9091702574aef4300db460d0a998b67f58cbb56175ad1cbe04c0e3' ]
},
'hsv-saturation-legacy': {
'auto:auto:auto': [ '2192d50ed4a2eeb07400c44144e54dc027dcba6e90a86dd5c84015f7885a3eab',
'466465f04dcb260626b8ba7734578a262365a13c6e99af436d81ec8385e0db02',
'1e28b43fa8ac650a2f78d7d664512b3e446d73569c04d2626a143cf4130d2e61' ]
},
'hsv-value-legacy': {
'auto:auto:auto': [ 'a2e2be54ef11400fb8a48657a939fa36ef634b5eef103fe3c1fa498bf60207d9',
'778de64b0117ad23dc1976a830f6f10eb5e6f98b783afc6704c2add181eed59f' ]
},
'lighten-only-legacy': {
'auto:auto:auto': [ '77b6589a27083b4ce8c70ccf83c9240e58f207df08e597fad2d05bfdcd2efa78' ]
},
'multiply-legacy': {
'auto:auto:auto': [ 'ba64bd7e41883302d47b2c2af63efcce47ff478f2c69e17119955bba7e345bd5' ]
},
'screen-legacy': {
'auto:auto:auto': [ 'e36091c1d5ecf0ed4f299087755cd7154551cc66d975898ee15acb98248e7800' ]
},
'softlight-legacy': {
'auto:auto:auto': [ '0e2dd784a05cfe23bfcb01098d9a1145ec2163a36b1435bddc58e04a071e3c51' ]
},
'subtract-legacy': {
'auto:auto:auto': [ 'cb7ebdd57b6648bf9dafdc927f162ad40917b15fee7e608a4630806dffa00d24',
'695359aea6a932a4db11bf44d679763120a975de8b7acdc023969e97ba3f63be' ]
},
}
libapplayermodeslegacy_sources = []
foreach mode, _ : legacy_layer_modes
libapplayermodeslegacy_sources += [ 'gimpoperation' + mode.replace('-', '') + '.c' ]
endforeach
libapplayermodeslegacy = static_library('applayermodeslegacy',
libapplayermodeslegacy_sources,
libapplayermodeslegacy_sources + [ 'gimpcolor-legacy.c' ],
include_directories: [ rootInclude, rootAppInclude, ],
c_args: '-DG_LOG_DOMAIN="Gimp-Layer-Modes-Legacy"',
dependencies: [
cairo, gegl, gdk_pixbuf,
],
)
# These modes do not make additional source includes and are only listed
# for unit testing.
dup_legacy_layer_modes = {
# "Normal (legacy)" is in fact the same as "Normal" in "auto:union:perceptual".
# I still test it separately in order not to miss any bug.
'normal-legacy': {
'auto:auto:auto': [ '298ded67bad7508caf29eb2718712ecbfece87592e6e4b006e460a03070a0ebf' ]
},
# A.k.a. "Old broken Overlay": this is the same as softlight-legacy and is not visible in the GUI.
'overlay-legacy': {
'auto:auto:auto': [ '0e2dd784a05cfe23bfcb01098d9a1145ec2163a36b1435bddc58e04a071e3c51' ]
},
}

View File

@@ -0,0 +1,35 @@
if not meson.can_run_host_binaries()
warning('Legacy layer mode unit testing disabled in cross-building or similar environments.')
subdir_done()
endif
pycode = ''
foreach mode, submodes : legacy_layer_modes + dup_legacy_layer_modes
op_name = 'gimp:' + mode
op_enum = 'Gimp.LayerMode.' + mode.replace('-', '_').to_upper()
pycode += ' "@0@": {\n'.format(op_name) +\
' "enum": @0@,\n'.format(op_enum)
foreach spaces, sha256sums : submodes
pycode += ' "@0@": [\n'.format(spaces)
foreach sha256sum : sha256sums
pycode += ' "@0@",\n'.format(sha256sum)
endforeach
pycode += ' ]\n'
endforeach
pycode += ' },\n'
endforeach
test_ops_conf = configuration_data()
test_ops_conf.set('OPS', pycode)
test_ops_conf.set('OUTDIR', meson.project_build_root())
test_ops_py = configure_file(input : 'test-operations.py.in',
output : 'test-operations.py',
configuration : test_ops_conf)
test('legacy-layer-modes', run_python_test,
args: [ gimp_exe.full_path(), test_ops_py ],
env: test_env,
suite: ['operations/layer-modes-legacy', 'python3'],
timeout: 1000)

View File

@@ -0,0 +1,149 @@
#!/usr/bin/env python3
import hashlib
import re
NEW_IMAGE_WIDTH=4096
NEW_IMAGE_HEIGHT=4096
template_image = Gimp.Image.new(NEW_IMAGE_WIDTH, NEW_IMAGE_HEIGHT, Gimp.ImageBaseType.RGB)
layer1 = Gimp.Layer.new(template_image, None, NEW_IMAGE_WIDTH, NEW_IMAGE_HEIGHT,
Gimp.ImageType.RGBA_IMAGE, 100.0, Gimp.LayerMode.NORMAL)
template_image.insert_layer(layer1, None, 0)
layer2 = Gimp.Layer.new(template_image, None, NEW_IMAGE_WIDTH, NEW_IMAGE_HEIGHT,
Gimp.ImageType.RGBA_IMAGE, 100.0, Gimp.LayerMode.HSV_VALUE)
template_image.insert_layer(layer2, None, 0)
#display = Gimp.Display.new(template_image)
def fill_layer(layer, shift):
shadow_buffer = layer.get_shadow_buffer()
n_pixels = NEW_IMAGE_WIDTH * NEW_IMAGE_HEIGHT
data = []
start_r = 0
start_g = 0
start_b = 0
start_a = 0
for loop1 in range(8):
for loop2 in range(8):
for loop3 in range(8):
for loop4 in range(8):
for i in range(8):
for j in range(8):
for k in range(8):
for l in range(8):
ri = (i + start_r) % 8
rj = (j + start_g) % 8
rk = (k + start_b) % 8
rl = (l + start_a) % 8
r = min(255, int(256 / 7 * ri))
g = min(255, int(256 / 7 * rj))
b = min(255, int(256 / 7 * rk))
a = min(255, int(256 / 7 * rl))
data += [r, g, b, a]
if shift:
start_r += 1
if shift:
start_g += 1
if shift:
start_b += 1
if shift:
start_a += 1
rect = shadow_buffer.get_extent()
shadow_buffer.set(rect, "R'G'B'A u8", data)
shadow_buffer.flush()
layer.merge_shadow(True)
layer.update(rect.x, rect.y, rect.width, rect.height)
# We create an image with 2 layers, using 8 values per channel, created
# so that every pixel combination is blended/composited with every pixel
# combination, by shifting the second layer by one value at each loop.
# This is why we have (8x8x8x8)^2 combinations, hence a 4096x4096 image.
fill_layer(layer1, True)
fill_layer(layer2, False)
#Gimp.displays_flush()
modes = {
@OPS@
}
def compare_with_reference(mode, blend_space, composite_mode, composite_space):
image = template_image.duplicate()
result = image.merge_visible_layers(Gimp.MergeType.CLIP_TO_IMAGE)
buffer = result.get_buffer()
rect = buffer.get_extent()
data = buffer.get(rect, 1.0, "R'G'B'A u8", Gegl.AbyssPolicy.BLACK)
## TODO: struct.unpack('f', data[8:12]) -> second float!
m = hashlib.sha256()
m.update(bytes(data))
spaces_id = ':'.join([blend_space, composite_mode, composite_space])
test_title = 'Layer mode "{}" can be set in {} composited as {} in {}'.format(mode, blend_space, composite_mode, composite_space)
test_title += ' but layer_modes[{}] has no hash for "{}".\n'.format(mode, spaces_id)
test_title += 'Fix: app/operations/layer-modes-legacy/meson.build'
gimp_assert(test_title, spaces_id in modes[mode])
possible_digests = modes[mode][spaces_id]
file_name = 'test-' + re.sub(r'([_:\'"]|\s)+', '-', mode) + '-{}-{}-{}.xcf'.format(blend_space, composite_mode, composite_space)
file_path = os.path.join('@OUTDIR@', file_name)
ref_name = 'ref-' + re.sub(r'([_:\'"]|\s)+', '-', mode) + '-{}-{}-{}.data'.format(blend_space, composite_mode, composite_space)
ref_path = os.path.join('@OUTDIR@', ref_name)
gimp_assert('"{}" ({}) - '.format(mode, blend_space) +
'composite {} ({}) - '.format(composite_mode, composite_space) +
'hash: {} (expected: {})'.format(m.hexdigest(),
possible_digests),
m.hexdigest() in possible_digests, template_image, file_path, ref_path)
image.delete()
for mode in modes:
layer2.set_mode(modes[mode]['enum'])
layer2.set_blend_space(Gimp.LayerColorSpace.RGB_LINEAR)
if layer2.get_blend_space() == Gimp.LayerColorSpace.AUTO:
blend_spaces = {
'auto': Gimp.LayerColorSpace.AUTO
}
else:
blend_spaces = {
'linear': Gimp.LayerColorSpace.RGB_LINEAR,
'perceptual': Gimp.LayerColorSpace.RGB_PERCEPTUAL
}
layer2.set_composite_mode(Gimp.LayerCompositeMode.UNION)
if layer2.get_composite_mode() == Gimp.LayerCompositeMode.AUTO:
composite_modes = {
'auto': Gimp.LayerCompositeMode.AUTO
}
else:
composite_modes = {
'union': Gimp.LayerCompositeMode.UNION,
'clip-to-backdrop': Gimp.LayerCompositeMode.CLIP_TO_BACKDROP,
'clip-to-layer': Gimp.LayerCompositeMode.CLIP_TO_LAYER,
'intersection': Gimp.LayerCompositeMode.INTERSECTION
}
layer2.set_composite_space(Gimp.LayerColorSpace.RGB_LINEAR)
if layer2.get_composite_space() == Gimp.LayerColorSpace.AUTO:
composite_spaces = {
'auto': Gimp.LayerColorSpace.AUTO
}
else:
composite_spaces = {
'linear': Gimp.LayerColorSpace.RGB_LINEAR,
'perceptual': Gimp.LayerColorSpace.RGB_PERCEPTUAL
}
for blend_space in blend_spaces:
layer2.set_blend_space(blend_spaces[blend_space])
for composite_mode in composite_modes:
layer2.set_composite_mode(composite_modes[composite_mode])
for composite_space in composite_spaces:
layer2.set_composite_space(composite_spaces[composite_space])
compare_with_reference(mode, blend_space, composite_mode, composite_space)
template_image.delete()

View File

@@ -21,24 +21,83 @@ libapplayermodes_normal = simd.check('gimpoperationnormal-simd',
],
)
libapplayermodes_sources = files(
'gimp-layer-modes.c',
'gimpoperationantierase.c',
'gimpoperationbehind.c',
'gimpoperationdissolve.c',
'gimpoperationerase.c',
'gimpoperationlayermode-blend.c',
'gimpoperationlayermode-composite.c',
'gimpoperationlayermode.c',
'gimpoperationmerge.c',
'gimpoperationnormal.c',
'gimpoperationpassthrough.c',
'gimpoperationreplace.c',
'gimpoperationsplit.c',
)
# The layer modes with their own operations.
layer_modes_own_ops = {
# This mode could not be tested with GIMP 2.10. These are the digests
# for GIMP 3.0.
'behind': {
'auto:union:linear': [ '99abf5f6be3dd50821928bb1a2231aeada73e2a62e8957430c1b5d64a9df313c' ],
'auto:union:perceptual': [ '399b9f5bd1fcd649c2adf2d28cb956b6004f7bbdaada2e7fab12e0d8eb6c956a' ],
'auto:clip-to-backdrop:linear': [ 'f27e055965b00bd0ed2b7ff741392a2bb0e5768fac7767305b5616641f78369f' ],
'auto:clip-to-backdrop:perceptual': [ 'efd45a0ebd42e558a738219a071a533e74dc33daf590368a7e8304644af6f12a' ],
'auto:clip-to-layer:linear': [ '568abcc056b3d5144792aeabf3ec90640d496cebfb80aca613f132d7c2683606' ],
'auto:clip-to-layer:perceptual': [ 'b513f1a1082de8c044df87b5d5f7c34237a166baad9b5cadc9f3a3ea0ae78507' ],
'auto:intersection:linear': [ 'aa6c1a8a5c3aa97468d66a46c2b2abcc04515f45daab65248b13762c8759e74c' ],
'auto:intersection:perceptual': [ '2993e3c0fc6ae1045f34a187f00fbee02ef32352d88f5b2a2c22a0b1fcb76758' ]
},
'dissolve': {
'auto:union:auto': [ 'f12d0b0c50804ec9fb109a96d40e68b4f9dba539744dda9c2a288d6579015b0f' ],
'auto:clip-to-backdrop:auto': [ 'b485d26b4733c3bf88bbfd3b57aece5a76d7b0c606e4fc884401bf63d88630dd' ],
'auto:clip-to-layer:auto': [ 'cc4ae651f96af9cfe8ed8e44aa412653e06aa4ac191f5b43909b9629125bce2b' ],
'auto:intersection:auto': [ 'ff90eab452e86b87f63e46b6812399ad3858530fdb84c38aea98b96fb34a0129' ]
},
'erase': {
'auto:union:linear': [ '64f9bd0c9a3262fac02a17b829b7d0d43c4c1d52421a8936590288160125b630' ],
'auto:union:perceptual': [ '007bf35c2507c81dfe66fbea6aabfcad1ae3bf3708588fca7bd95f2d58ef596a' ],
'auto:clip-to-backdrop:linear': [ '8453fd393160cb79f649a3af363cf844c2502ea080c4b2e836cd79830609c0bf' ],
'auto:clip-to-backdrop:perceptual': [ '8453fd393160cb79f649a3af363cf844c2502ea080c4b2e836cd79830609c0bf' ],
'auto:clip-to-layer:linear': [ 'bf0b5674596be2c231f54884b047e62d5fd97513b2b4ef5bd24d3470ed49c625' ],
'auto:clip-to-layer:perceptual': [ 'bf0b5674596be2c231f54884b047e62d5fd97513b2b4ef5bd24d3470ed49c625' ],
'auto:intersection:linear': [ '927369a9f1ba06dadd4a1a61a76e54d95f2c3943d74f93009da7486b4ad03e47' ],
'auto:intersection:perceptual': [ '927369a9f1ba06dadd4a1a61a76e54d95f2c3943d74f93009da7486b4ad03e47' ]
},
'merge': {
'auto:union:linear': [ 'd196d3110b9448ed466e91dda68b5b7869d90b6be7da03ddfeb05d5ec4479702' ],
'auto:union:perceptual': [ '0c95741a7c0841ebb9303ae54095c74e81d3a970db5790fccdcc95c2149e76d0' ],
'auto:clip-to-backdrop:linear': [ '312cf51c459b750fa3ae95b2ba0695e09bc443c1b99663921a34e0471b4c7135' ],
'auto:clip-to-backdrop:perceptual': [ 'fe7510bbe3f92b65884a3d47305308d6cf1dd281a6ca00cb0b2ce47356968442' ],
'auto:clip-to-layer:linear': [ 'bb914713756664493e944c536ed70d34dbff4be29574a9e2c6e09791e2255736' ],
'auto:clip-to-layer:perceptual': [ 'bb914713756664493e944c536ed70d34dbff4be29574a9e2c6e09791e2255736' ],
'auto:intersection:linear': [ 'cf85185590c211a57d78ac9fab60909e919ee37c094cf0c4590155fbbe332679' ],
'auto:intersection:perceptual': [ 'cf85185590c211a57d78ac9fab60909e919ee37c094cf0c4590155fbbe332679' ]
},
'normal': {
'auto:union:linear': [ '890159ff6ac92cac90b244ee21cb6765c0ff6a8a6a364f6e6f071f61702ef874' ],
'auto:union:perceptual': [ '298ded67bad7508caf29eb2718712ecbfece87592e6e4b006e460a03070a0ebf' ],
'auto:clip-to-backdrop:linear': [ 'db17777b641a8ec888adb31ac6d19e687dea9b993a524ffe4ec3367223ef9ad0' ],
'auto:clip-to-backdrop:perceptual': [ 'b1ebf537f21697cceb61ddca2e9f7072611de187392b6a4ebf82ad8d8d6d4e03' ],
'auto:clip-to-layer:linear': [ 'bb914713756664493e944c536ed70d34dbff4be29574a9e2c6e09791e2255736' ],
'auto:clip-to-layer:perceptual': [ 'bb914713756664493e944c536ed70d34dbff4be29574a9e2c6e09791e2255736' ],
'auto:intersection:linear': [ '3153c3dba57d3ea399e7d30e80152df275b6516abb5dfd7839d30fb631b08af7' ],
'auto:intersection:perceptual': [ '3153c3dba57d3ea399e7d30e80152df275b6516abb5dfd7839d30fb631b08af7' ]
},
'split': {
'auto:union:auto': [ '2cb8b9526d2a73d18d77b063e90e13d03d6668cdf0c10a797014f9596fdbf884' ],
'auto:clip-to-backdrop:auto': [ '9f5e737032ade4e044b91c491e49557111896bb89f4da26ca8a45c9c761a5f8d' ],
'auto:clip-to-layer:auto': [ '628577cf8f41bedd40a70886800d5364c928ace7cfee94e4f9c8e14e5e41cc18' ],
'auto:intersection:auto': [ '927369a9f1ba06dadd4a1a61a76e54d95f2c3943d74f93009da7486b4ad03e47' ]
},
}
libapplayermodes_sources = []
foreach mode, _ : layer_modes_own_ops
libapplayermodes_sources += [ 'gimpoperation' + mode.replace('-', '') + '.c' ]
endforeach
libapplayermodes = static_library('applayermodes',
libapplayermodes_sources,
libapplayermodes_sources +
[ 'gimp-layer-modes.c',
# GIMP_LAYER_MODE_ANTI_ERASE and GIMP_LAYER_MODE_ANTI_ERASE are
# internal, not introspected and not available as actual layer modes.
'gimpoperationantierase.c',
'gimpoperationreplace.c',
# GIMP_LAYER_MODE_PASS_THROUGH is for group layers only. We'll need
# to special-case this test later.
'gimpoperationpassthrough.c',
'gimpoperationlayermode-blend.c',
'gimpoperationlayermode-composite.c',
'gimpoperationlayermode.c' ],
link_with: [
libapplayermodes_composite[0],
libapplayermodes_normal[0],
@@ -51,3 +110,567 @@ libapplayermodes = static_library('applayermodes',
gdk_pixbuf,
],
)
# All the other layer modes hidden behind the "gimp:layer-mode"
# operation.
layer_modes_shared_op = {
'addition': {
'linear:union:linear': [ '435897637dd7eb110b39f45fa5b2c21a7c8580bee815da6cc17d0a29d52b95d9' ],
'linear:union:perceptual': [ '6e2c4130e601d035c1cd51648f62a311a04ba97dd3158537fa3cf12807d81908' ],
'linear:clip-to-backdrop:linear': [ '8abf89a9a0a025e277ceed2c26dae9ae4dfc5967034d0af9eea31a5791e48566' ],
'linear:clip-to-backdrop:perceptual': [ 'ee246412d8f45339ce043993b22033bcd1be8b60da7cfab46c867d9524c21929' ],
'linear:clip-to-layer:linear': [ '53e1b2156d95a6f663205b67c441b6d402c7fb56c7e7d4886959a71ed96015f1' ],
'linear:clip-to-layer:perceptual': [ '8fd6f4fbc26a39d2365d41f52c6c7ee67915a609f854613f0b4e7d14d3e88e5a' ],
'linear:intersection:linear': [ 'e321e8b52f9a29513fb77ca39511c6ff694e3fe25bfabfa741885bdd6b547601' ],
'linear:intersection:perceptual': [ 'e321e8b52f9a29513fb77ca39511c6ff694e3fe25bfabfa741885bdd6b547601' ],
'perceptual:union:linear': [ '8aa19401c7a85397fa571bcab003ccc189d0faf3db04cc2487fcf2607235f1c5' ],
'perceptual:union:perceptual': [ '1b873331014dced89594ebea93416685991e7fece376f2d3ccabf51cc056f1da' ],
'perceptual:clip-to-backdrop:linear': [ 'fb3562b4aa8a6a3176ab67e9e8453fa58da3d99ee6f0ae7eadcb43b060434c66' ],
'perceptual:clip-to-backdrop:perceptual': [ '6c2525c833d8b97154b36699b296e4465f2bd75489678b18b2383870ed1ba545' ],
'perceptual:clip-to-layer:linear': [ '2c55d1f55610054e3dc4304e1af2b48444acc40003ee751151e59e0e4cf32d87' ],
'perceptual:clip-to-layer:perceptual': [ '47fa8065628088dfb3cf4c9e9d39eb0cd9009df4325238aaa8fdb0920ce2faa2' ],
'perceptual:intersection:linear': [ '65ade70a7179df95d853b861609ee807cda91ee12233e7c60e07c3b32ec61489' ],
'perceptual:intersection:perceptual': [ '65ade70a7179df95d853b861609ee807cda91ee12233e7c60e07c3b32ec61489' ]
},
'burn': {
'linear:union:linear': [ '2fdc815da222ac0ff34bf82477cf3e0c34648f148a0d19fe773db0125bb85301' ],
'linear:union:perceptual': [ '21d77c51f8ac0781455d11093a3d19a64b71d1239869c097c4f5418f5dcd5df5' ],
'linear:clip-to-backdrop:linear': [ '562ed7e68b3ab217858c966435f60a8b1aa526a845ba1c9707b7a6ef076bfd5f' ],
'linear:clip-to-backdrop:perceptual': [ '490e837cf4abdf76ed3449c0c90eba4f5d038bd22f89d54e6476d2cb2da53c44' ],
'linear:clip-to-layer:linear': [ 'abf05d4b84279c772a5b64faa0919833d53a972257cd9e61aac11e2c13b0ed4a' ],
'linear:clip-to-layer:perceptual': [ 'af4df044223f8ce9b17f45b50864fb858ba30227781d0d5f362c9a8b341d4429' ],
'linear:intersection:linear': [ '0b067a83fda65a3be65cc663fea6bbb7789896839fc5b6ec0dd762b98b283094' ],
'linear:intersection:perceptual': [ '0b067a83fda65a3be65cc663fea6bbb7789896839fc5b6ec0dd762b98b283094' ],
'perceptual:union:linear': [ '3f768e90e0e968e29a50a0650aa18a74e228923d15ec7e3671826e279ee1aa26' ],
'perceptual:union:perceptual': [ 'cde2a19501a3efb467b64628c63d3c1be31291010593e01d0baf887d2cfea293' ],
'perceptual:clip-to-backdrop:linear': [ 'f0ed2f2bb5f264e1aeaf8ba74a24fb7b9553366c5580f47638eaf4b970aeadf6' ],
'perceptual:clip-to-backdrop:perceptual': [ 'ffba37ec62aabf0635d100fe6493fc8e3d82cb622de7acb84d7361197626bf1a' ],
'perceptual:clip-to-layer:linear': [ 'fa0f74236e29e0dcecb86f7b7362efe551647135edcbabdb717fbeff38729fa4' ],
'perceptual:clip-to-layer:perceptual': [ '07c5cacde86079a98c112d24d9539305516a8841b4087c839e94694809356d1e' ],
'perceptual:intersection:linear': [ '60a5c89204018e2babf613e63291772a6292e98b69891d3f56e4655665180033' ],
'perceptual:intersection:perceptual': [ '7814522fa601932e6caca971801cfb1994da576843dd84831514c8cbf82ec453' ]
},
# 'color-erase': {
# 'linear:union:linear': [ '68d0dd2283cc48dac525c2af868d96f138cbf66c6c580cc26473d1398d32b201' ],
# 'linear:union:perceptual': [ '7c1defdc383de6ed2c930965071f9de24a449861c83624955dd42b32ed98f7f8' ],
# 'linear:clip-to-backdrop:linear': [ 'e1adc225888b3636981995fd55b1be29fb6be53acb57e507212e176783b927fd' ],
# 'linear:clip-to-backdrop:perceptual': [ '486057ff086201390c6639f3275f8b74e5094916308a59a47d5fffbdabdfc070' ],
# #'linear:clip-to-layer:linear': [ 'f46b4af489c429ebd9d5ae78b10389dd2554638d286c855565473014b8c8f9ef' ],
# 'linear:clip-to-layer:linear': [ '8d981b33fa7fc5e40801a2401febc5abc6f5c6ad2f269293f076d60193fe3e76' ],
# 'linear:clip-to-layer:perceptual': [ 'ab3f620146d5714393c9f22195cf1f37d9e2ec291bd8515c178a8d018139ea00' ],
# 'linear:intersection:linear': [ 'f06eb75ce01350a234837dd5eacbc660d62bc8977e399943afc68d8ee2c4c8b4' ],
# 'linear:intersection:perceptual': [ '37eb39ad5d10b01dc1e6164cc66bc79ddeee4dec410da71a9cc263173738b395' ],
# 'perceptual:union:linear': [ 'a4bae8ab48cab0be257c68216f88a152476012feddbc1c13c5312744dcc66995' ],
# 'perceptual:union:perceptual': [ 'd2672b8761bac4064916f6219eeb434c1bc4abe8dd23ac98912cfbbd061fd6f1' ],
# 'perceptual:clip-to-backdrop:linear': [ 'b5b1c824f8300644152e4398ad92138fd4a828c2e6d10a549b2de8085a734c77' ],
# 'perceptual:clip-to-backdrop:perceptual': [ 'd008ad97f2d774ed11f6f6d2750768bd3c9203d142d59d2c659d40147e5bfcaa' ],
# 'perceptual:clip-to-layer:linear': [ '4da54f669a1cc714ae68c833abc9663d3bd5ef2b45e5165ce98d60a452932309' ],
# #'perceptual:clip-to-layer:linear': [ 'e05493ff935468225cf0a8b442c34e66b1fd5dd4db6d1d28d9633464e1e8e72e' ],
# 'perceptual:clip-to-layer:perceptual': [ '833d559bda30761bffe8bbc26de23257ec74f390c092cd10afb8c463fcd3dd3a' ],
# 'perceptual:intersection:linear': [ 'a01bcb4a51078de82636fb32fd2d84f817795ac9207c6fd12b47b17e8ac73772' ],
# 'perceptual:intersection:perceptual': [ 'cf2b39fd17deef94f3c70a451925c3913e5662adaac9911e33dedf248dae0b30' ]
# },
'darken-only': {
'auto:union:linear': [ 'a8f4deea7406d00162eaf56bc94923a325345098f611321ca31a77e87a23b516' ],
'auto:union:perceptual': [ 'b8ef1a01bbbafd980c2cd1070dcd0382f6f7f2c4a5324d64ae28e00c356baa57' ],
'auto:clip-to-backdrop:linear': [ 'af606b3796c0493e9ec46d74f9f53ffd6a14726fd08dfc0a5f7dca938b2ac3c3' ],
'auto:clip-to-backdrop:perceptual': [ '5718031bb9111fe584ff04baa699edc8e6b1ea4044f362fe02784574ebb3e28e' ],
'auto:clip-to-layer:linear': [ '32ea45bc7c34d35b7083aeddf76b8ac5ba6aa0da4d27ffafc1ceb7c290fa8dfe' ],
'auto:clip-to-layer:perceptual': [ 'bd501c47d508e7796c84bf42cca01511decd1ec28d113b66dde4bf737ec0860b' ],
'auto:intersection:linear': [ '64033c5b99938528677500f44a6cbcfb05634f7f3d356c59b370b8383a8cdb7a' ],
'auto:intersection:perceptual': [ '64033c5b99938528677500f44a6cbcfb05634f7f3d356c59b370b8383a8cdb7a' ]
},
'difference': {
'linear:union:linear': [ '0b270b40793e1cbdd78c268122126af7aed4a41277f5d322c89762e1a26af19c' ],
'linear:union:perceptual': [ 'fb53ff7f86052b9b9ae60590c0bf3c720d6ba94dd15d6f768ec0afbd7372658b' ],
'linear:clip-to-backdrop:linear': [ '57386435f5df79c64a6c70a0b6d08bbdc00df9b388695d2257be6b38c83b5291' ],
'linear:clip-to-backdrop:perceptual': [ '9e1021dd5b4c08bee8fdc0477272d2be37efad22ff83bc571f1800894ad4071b' ],
'linear:clip-to-layer:linear': [ 'cd9cce8e6681381eb00d5f6033b7de064c99f4285432b4689fbc5ecc9d4d3c79' ],
'linear:clip-to-layer:perceptual': [ 'c54ece64a22e17ed3ed411d8210a714956021e64452274f11b64f37d612c13a8' ],
'linear:intersection:linear': [ 'b96174610d5dad47ed0af5fb0ddd3cf61e8f853dcb3f179090611c873e734a95' ],
'linear:intersection:perceptual': [ 'b96174610d5dad47ed0af5fb0ddd3cf61e8f853dcb3f179090611c873e734a95' ],
'perceptual:union:linear': [ '98080b8a7508c6b773856a459ed4c0e337df8a4d0442dff2ad1e5886b9666d6c' ],
'perceptual:union:perceptual': [ '84f9d07f4c7c05d5fdc2f0a978c211ad1c7fd9404098bb87bc6a5e84ddc3126c' ],
'perceptual:clip-to-backdrop:linear': [ '0165c715fb42f8a46a82894b454797163f9b79904acdd71323e1d34e06f85a52' ],
'perceptual:clip-to-backdrop:perceptual': [ '53ec08bc08efd619f4777b7649c1699bc57ed7995720c73c6c6d7d02c8a9c561' ],
'perceptual:clip-to-layer:linear': [ 'c463e889a4290a81d64704b2b5e7bce2d8f6bb7f17bbd02e5c8dcca7f09921e1' ],
'perceptual:clip-to-layer:perceptual': [ '8d6694db440587ae7e6b114d320d6cc97be0437383979d02a523a000c6748f6d' ],
'perceptual:intersection:linear': [ '66119df983cd69a8544fdedefdf9e0e702d30c5201544de39fab0ed0e814c347' ],
'perceptual:intersection:perceptual': [ '66119df983cd69a8544fdedefdf9e0e702d30c5201544de39fab0ed0e814c347' ]
},
'divide': {
'linear:union:linear': [ '55d7a65d31575696d5250fc76f56478d9e27cd539d78674e50b6c815b82effa6' ],
'linear:union:perceptual': [ '09b0d15d6e365e696e26350e3634ac5a15c2de24aa08b8878e143117a4c0dee1' ],
'linear:clip-to-backdrop:linear': [ '6e26794b74d0c76b83bf981e72e318049e3d439c80a98e217eb1f4ce0d077b8a' ],
'linear:clip-to-backdrop:perceptual': [ 'cc9954c781418d8026c65f0952a9e0749748ba981e6ea22d974d66f4b3474761' ],
'linear:clip-to-layer:linear': [ 'a0fba8f9c4daacf4013ab209bcf75a93e20eb6525d26014ef7ab730303522f2a' ],
'linear:clip-to-layer:perceptual': [ '7d170e5f01c6122e7ec8cef6669bfab645b2e739167e581366572152ec5e5465' ],
'linear:intersection:linear': [ 'b98ec0c8995dca9b9653893ab886231db8a8c95f841d627445eb6db5048a6496' ],
'linear:intersection:perceptual': [ 'b98ec0c8995dca9b9653893ab886231db8a8c95f841d627445eb6db5048a6496' ],
'perceptual:union:linear': [ 'e93231a9f00dfcaee855cd9a7bb37269b4addbae7042c04ec66f2a1991f12d58' ],
'perceptual:union:perceptual': [ '672e9091e41d767bdb839e48ecc731b9bf0e07bebfb8e87744fdd2b328cfeeb6' ],
'perceptual:clip-to-backdrop:linear': [ '3c2102b55412db0e9a389e1464ed5abed04770c163a1c68eb8dcb8d51620ec69' ],
'perceptual:clip-to-backdrop:perceptual': [ '5560a4e8e199d391aef07a0aea1c530926dd984c464d809d6d9ddf7163ccf6b9' ],
'perceptual:clip-to-layer:linear': [ 'a9e1486ae7ea10714684b2e9a35b3a7b4ae38788583a2a04b085f969fbc5e6e9' ],
'perceptual:clip-to-layer:perceptual': [ 'e68a67a8dc17c7c8b434d995fbdd5c785e0a8708bef0cb002872cc1405471758' ],
'perceptual:intersection:linear': [ '53126818fa16b14bb3ec89477109b944276524a0f92fbce2dba92cc2e43b08e1' ],
'perceptual:intersection:perceptual': [ '3650323abca0a9b43b2b4503297fc6a9e05ea4455e4e76279833c8b3632bba2f' ]
},
'dodge': {
'linear:union:linear': [ 'f0762f4bcb445fbba78dd4d45d8f8ed436521c772fa52b0b9afdd3d907c1c1c7' ],
'linear:union:perceptual': [ '2c3e88bdd8e42e670c794fa422a0730d3ffa7dffa26c1e118c55e0cafecea347' ],
'linear:clip-to-backdrop:linear': [ 'cdc6c74834c45f47f245bf5ebe339c71c383d88b5cc6e173d0d3c4fe21421592' ],
'linear:clip-to-backdrop:perceptual': [ '7a7456ab61085f6ecc02dd74279bbdf99e670f71d5cbb34c414e00695c7b13ae' ],
'linear:clip-to-layer:linear': [ '9bc157e8969460a3432d76a1fdbc1f943f22dc4a40e32aefcaafb699a1435427' ],
'linear:clip-to-layer:perceptual': [ '14559a4212fe657e8471682199a419fffe404241a2e16e66dd76c62add3c2f7d' ],
'linear:intersection:linear': [ '24135e3fdb93dce3b15a4721be03f025101f48f57fc4233952086eeb5eb35ce7' ],
'linear:intersection:perceptual': [ '24135e3fdb93dce3b15a4721be03f025101f48f57fc4233952086eeb5eb35ce7' ],
'perceptual:union:linear': [ '4823db8cbcde714ada5a27232d41354d5b1f54c8a4cd5304a230e3f1152eb9ae' ],
'perceptual:union:perceptual': [ '018e944f5a7a20a09ab3c178e1ab8c04ce9f586b6dc8c13c68d033900f61023e' ],
'perceptual:clip-to-backdrop:linear': [ 'f2c7c09dff9ceae198583088ba8c9a5ac75c35a0137863ffa82fd79841a04258' ],
'perceptual:clip-to-backdrop:perceptual': [ 'c8b0dfa7c8b61cf0005507cc68d99bf099cd6a3ca7171751441743057c889042' ],
'perceptual:clip-to-layer:linear': [ 'c2fd737b27a5e544d827af122aa4c4a9760de70b56359b3ce6f108d8afb79e2d' ],
'perceptual:clip-to-layer:perceptual': [ '73f5e040b684389a5ea2c645c5823db722c3dcbb344250e0a099eff973f08b0c' ],
'perceptual:intersection:linear': [ '72c1af1658fd3769a80aba51844f775f273f49242950a0ec1cc1f6ab8191b7e4' ],
'perceptual:intersection:perceptual': [ '003edfd61bb8bd93df3183e8decc7f01ad3eaa2485cb11d83624e2790bfc58ae' ]
},
'exclusion': {
'linear:union:linear': [ '67433f1067559f806736c3dc8cacb5e0c936069e229ec621384291d602f8ab99' ],
'linear:union:perceptual': [ '82753b5cfe422aabd6a75c7612fd072ea9bbb92cdd90d1021c621895bcad27ef' ],
'linear:clip-to-backdrop:linear': [ '13fc3fb83e3a21f2028f2f1f9675ce915d960256d2d91f01a1564fdcd493bda9' ],
'linear:clip-to-backdrop:perceptual': [ 'df43e2b32bf525058bf49c745d07f5b9b120f7761b230f5cd141ab66ef499036' ],
'linear:clip-to-layer:linear': [ '00522bdc843d54ad99136582bfa8ffe73c778dc5c86601834a8fde271a83138f' ],
'linear:clip-to-layer:perceptual': [ '755a353b949afaeccf647fa768eea35f85a3762fbd17ed6ed269084c3d9c6dcc' ],
'linear:intersection:linear': [ 'beac9decd163abd8e6acb2a86979dc6dcb78d097ed2281ef349cd529c3caa915' ],
'linear:intersection:perceptual': [ 'beac9decd163abd8e6acb2a86979dc6dcb78d097ed2281ef349cd529c3caa915' ],
'perceptual:union:linear': [ 'd9353d88f46b00292373cf15d65b14317df03b60f820e5338a9758a7323277a6' ],
'perceptual:union:perceptual': [ '4e0717eed1bce1d866b3497c222c3098b01f585bcabee27b7dadae5c8d33c283' ],
'perceptual:clip-to-backdrop:linear': [ '218c793e22a1669217ca0cabd8a153d044b1a48919f47458eba66f3276005e69' ],
'perceptual:clip-to-backdrop:perceptual': [ '7d4903ac1521816e199d4af3a5d9c51831e9bd93ea6502d2dbb92ad45e4f6d6d' ],
'perceptual:clip-to-layer:linear': [ '7e36ad9738acce6ad8a0b795aa9e704e7d35a32ea655affdc5c764b4631de9ef' ],
'perceptual:clip-to-layer:perceptual': [ '1e1972dc353932202123f342a3121888ab9e40f98e37f21a5f2a892285cd281e' ],
'perceptual:intersection:linear': [ 'a326e6d3d8f2a0250825e255e9ad23435e9fec22ff50d4eeb61517a3df4ac320' ],
'perceptual:intersection:perceptual': [ 'a326e6d3d8f2a0250825e255e9ad23435e9fec22ff50d4eeb61517a3df4ac320' ]
},
'grain-extract': {
'linear:union:linear': [ 'e8b97c57cdb92594de0f1eb631a4efce91711c77aa608f53edf5e9e33e416d39' ],
'linear:union:perceptual': [ 'a603657ea1010eba79f7ee97c2b95dba1b0dd62e4078ca7be549dc59810639ef' ],
'linear:clip-to-backdrop:linear': [ '63eb55baef157ec4f8b2fa06da467ead2007b38b30c450f305f3f660a1bb5e1c' ],
'linear:clip-to-backdrop:perceptual': [ '809ed1f935ef04ca1208025fa12cc29d4c688cdce4a8e88e81dfde917f891ed9' ],
'linear:clip-to-layer:linear': [ '71926b8acade447f0be77bec29a57cc792523bc48db6825cfa2e531180a6966f' ],
'linear:clip-to-layer:perceptual': [ '14f41df7f980b2a679fe8e4f285f62a56746b146da3c5ad71d26d679838910df' ],
'linear:intersection:linear': [ 'ac6188e8b7ef332f351519f74310a9345e5bf891ed21018f67d5654f8c2c2705' ],
'linear:intersection:perceptual': [ 'ac6188e8b7ef332f351519f74310a9345e5bf891ed21018f67d5654f8c2c2705' ],
'perceptual:union:linear': [ '3807ccb0745cca67d162a2eb28b7bbc6f90fa1f523ad76d12da81c577de2abd8' ],
'perceptual:union:perceptual': [ 'fdd888b6abb5b5536945ac5a4bd7f3e218fde2452c1eaec98b7a7c96373d0175' ],
'perceptual:clip-to-backdrop:linear': [ '93ee9196450bab4796d64b5156a6aca688d30d5b4a73de42af5729f691b69a3e' ],
'perceptual:clip-to-backdrop:perceptual': [ 'bc674500f5452e2047a41198ad62dd5e59b6a899c6ac511d581abf1fef38ded3' ],
'perceptual:clip-to-layer:linear': [ 'ece5bce20702e3662e8a8ddc2978a6a043983b1d9725f88dd051b64db5c88849' ],
'perceptual:clip-to-layer:perceptual': [ 'debb6d9a53924f86dfaf96be2b50443fe20f8dbc98b9bcc90d30b875197b20b2' ],
'perceptual:intersection:linear': [ 'bd23b4aab0172b59bf29a9d0c126f3e80cc8d68900b7a8f9265781ebe7b685d8' ],
'perceptual:intersection:perceptual': [ '721971c54cbe337105ed21d3158ae94a491370adee20029a7a0127834778bec3' ]
},
'grain-merge': {
'linear:union:linear': [ '362ae437af5f039e762df2bf87a7c864745e78152ca97c533175d60c4d530d53' ],
'linear:union:perceptual': [ 'f4e4536d177c1629a3a6e1e57af1662a86fc7350b02382585e511a94980084c3' ],
'linear:clip-to-backdrop:linear': [ 'f513ae55b970107f96922ab7d973bbd897ffba92ef87f4992779bc43afc5a59d' ],
'linear:clip-to-backdrop:perceptual': [ '4df82c7e951e6c1faa58ea9cb717e745951402e5b4bfa599890d93c6ff936f0a' ],
'linear:clip-to-layer:linear': [ '61fe7e1b8f29efbf1ee562ea7315ce821f8cf0b37057e319b769d6b4b73d00fc' ],
'linear:clip-to-layer:perceptual': [ '66234dd0ec07df99b093c63cdfadb284dda0396e7cecc1e37919056335ea714a' ],
'linear:intersection:linear': [ 'ad275ca2c11f5ce3703acb40dda330975d3c7fa0b6eb4cd73c8f693bcb839254' ],
'linear:intersection:perceptual': [ 'ad275ca2c11f5ce3703acb40dda330975d3c7fa0b6eb4cd73c8f693bcb839254' ],
'perceptual:union:linear': [ '7a7bbc9eb2d02d8dd8f10893a1b14b97f7f14b961e8e59c5f572f57078ad53cd' ],
'perceptual:union:perceptual': [ '7c79c6c6df3dcee8b684bffe38e20ed6a544bd7512995a93bfc55fc666cd9234' ],
'perceptual:clip-to-backdrop:linear': [ '3fadad316b79bbe059ba3835822cf5462ce1226fc4143b6278a753dbc43ad5a7' ],
'perceptual:clip-to-backdrop:perceptual': [ 'b82be17183c0ed60ca6a7b2b277322c2cb9efae2cb655cdd1da2ddc7b1c1d4b6' ],
'perceptual:clip-to-layer:linear': [ 'e8df57a5b3a75a8cde39ead6b797f240260eaa9e0c6a427beb7f5e87b46695ad' ],
'perceptual:clip-to-layer:perceptual': [ 'f0509c500c400840cd4b365bb11bdde71dfe82234adb3d0e171b42bc47c69069' ],
'perceptual:intersection:linear': [ '9bd4cff3f4dc404df56b00b467d6630a4730a6785138e97ace149ee99bd20eda' ],
'perceptual:intersection:perceptual': [ 'ae7ec7e0fa9daa7c98792b81364acc56dd8b473de5c7244201001e5bde163fa5' ]
},
'hard-mix': {
'linear:union:linear': [ '3b2a75b370dc72cf13193b6e7470635eab891c6466eed528b6460946358a053c' ],
'linear:union:perceptual': [ 'bb57472a8d14e2226a8b8efdaaf841bc57032c480264fd88513b0c9ea47df032' ],
'linear:clip-to-backdrop:linear': [ 'a90e44affa6ef28a9b769ba094395cf9a4ca369554f0cd76fe35badfab006c51' ],
'linear:clip-to-backdrop:perceptual': [ 'cbd79ed6ccd8daf66b590e809d990d6515fce7c1b712fe4b2a41ba0f2317acf2' ],
'linear:clip-to-layer:linear': [ 'c68fcc0614f6f4ff1330e3315e8fb640c7889c0346a53aec4a2eba729660d047' ],
'linear:clip-to-layer:perceptual': [ '1322c07116461501a22cafc2b3ff53f54e95256f8b4f9bef5f529a3984e82783' ],
'linear:intersection:linear': [ 'efa04f9890d81d58513507859a7a6728ca8ab52abf4388b810f12f56b169cb8e' ],
'linear:intersection:perceptual': [ 'efa04f9890d81d58513507859a7a6728ca8ab52abf4388b810f12f56b169cb8e' ],
'perceptual:union:linear': [ '02c91de615e62fcef0a5999ab4e4d960ebd8156511f99dba40bb9483f50e7db8' ],
'perceptual:union:perceptual': [ '927be5df63d57ec9efe943b2f5c8ee80cc0e1a8d60634c5456fbc1fd8ee74d8b' ],
'perceptual:clip-to-backdrop:linear': [ '7e1c58cc15c23ed0203ac019e3bbc84026d49ce7530fa570e11c5064134f3dde' ],
'perceptual:clip-to-backdrop:perceptual': [ 'a2834523f31b93b9c35d56da4605661ba56a5a2a1f2a5ced79f646a7aa65d3be' ],
'perceptual:clip-to-layer:linear': [ '97ce4337b96dbdd470f14d7fb127447e74c9a9debf8e117f361f4f5cf3674d70' ],
'perceptual:clip-to-layer:perceptual': [ '7763f4e62ed488befe348f0197414fc794f5756055c90f9155e058cbb7138f38' ],
'perceptual:intersection:linear': [ '9f2833cc611f302891cfac169c1e44b6aa479c7299f2250db944d7508e52898e' ],
'perceptual:intersection:perceptual': [ '9f2833cc611f302891cfac169c1e44b6aa479c7299f2250db944d7508e52898e' ]
},
'hardlight': {
'linear:union:linear': [ '5d3124da803b96e656e01349f178ace5391677726676352557a4ed6752b8c23e' ],
'linear:union:perceptual': [ 'c0723394a27cec8aeda43c2748a1bdef32fdcb191db11f639b3ecc86c5b80fcb' ],
'linear:clip-to-backdrop:linear': [ '1fb88058b8b312c5e21fb6db8f7dd948bafcf3f1e269096a5dd84f96753b9cfd' ],
'linear:clip-to-backdrop:perceptual': [ '93c931d35169e0a38240d8a9c2b779f89f767fab971fd3846ed0a2ffff9a4a95' ],
'linear:clip-to-layer:linear': [ 'd57134279ba24ca50af6faf39aeb38ad295e2f22a87f679a4aa1ab1432dd6597' ],
'linear:clip-to-layer:perceptual': [ 'e62ba4ef8347ec175d478f365be227c531ecb2ffc400e7631ced1077e59e14a0' ],
'linear:intersection:linear': [ 'ae18760809c762a958a7750cffe0790ee5a5d7fee476df2867eb6873495ed693' ],
'linear:intersection:perceptual': [ 'ae18760809c762a958a7750cffe0790ee5a5d7fee476df2867eb6873495ed693' ],
'perceptual:union:linear': [ 'a086f3e0ede8c4cfa7d063ffb32cc4ebb612c900639784feb1ccaae59f8cdaef' ],
'perceptual:union:perceptual': [ '3264a3deb11a471b2293cb9246bf78f4cc7d78fc6fb29bf1fe0f8fa24d1ebce2' ],
'perceptual:clip-to-backdrop:linear': [ '226bf333e4759671901fa656d09531ba8da46309c7fbd9a7444128518375376a' ],
'perceptual:clip-to-backdrop:perceptual': [ '5a175db8036bcb244effd713153478e0572af755546fdcc4d3bed7db63a95fe5' ],
'perceptual:clip-to-layer:linear': [ 'cbed77c0e78e89f7ef7231c1cb1ce345ee28fd322bd7af1b9ee6fb02a09c3a2b' ],
'perceptual:clip-to-layer:perceptual': [ 'd3beaa2990642164f2631f183d910e3acb41624e68aa2771a4605a9664ebb372' ],
'perceptual:intersection:linear': [ '5d1789406f6ebb9ef9c3d1dbddc988dba7b45bef033d11c46a4cc11bef2702fb' ],
'perceptual:intersection:perceptual': [ '5d1789406f6ebb9ef9c3d1dbddc988dba7b45bef033d11c46a4cc11bef2702fb' ]
},
'hsl-color': {
'auto:union:linear': [ 'dc4b469481e7f2a13b28c79c665ff2cf6327582b6c4036ed7a0b627e86f09d2b',
# Non-SSE2 digest.
'1bcc39ddace42fc1bd51a19ced62095d1d31d7d12625eac868b1644eef8ed030',
'ecb86eee4546f7b0103509af6bab98b54cc7ddec8aeaa79e2882a0e64a1c677b',
'087a66852013cda71f5e16c4d4cb155cf69623cc4f6002bf53e47d11d7c4a097' ],
'auto:union:perceptual': [ 'e82f46d57193ab82ceb243df3783e589939a1d57bb31de9639eed9068e61adea' ],
'auto:clip-to-backdrop:linear': [ '95d4f7474308197b9a6979225163cc0f0f90e29f2cc931e06803f908626119e7',
'594d63b34485be623e3ab1b47532df9c4fba86d9a35e5f7ef29410b31a5d8a97' ],
'auto:clip-to-backdrop:perceptual': [ '103ed86dedc5992c33fc689e3c9d1c944ec35136b19d0c8b61338ae61d3750a2' ],
'auto:clip-to-layer:linear': [ 'a877fc334daa9e93f3acd4423b99252922d11b98d029a62bcad82fa7ebc90c5f' ],
'auto:clip-to-layer:perceptual': [ 'dc5eef64de3555a543c0b7bbe98a1d195ceada726ee8f45423d86fb262ded6a4' ],
'auto:intersection:linear': [ '19c2f679832d61ce33d1d33780d0dae30d7592f52cfd493a449e35b1dbb5a07b' ],
'auto:intersection:perceptual': [ '2c365b0a8c69a4924a782684cdc4c783a237df88cc34be028c3456b0c926d1cc' ]
},
'hsv-hue': {
'auto:union:linear': [ '10dbb0751dbedfe6a5c9ba9c15282373da9be5db3091985ddf97158ff8dd2e73',
# Non-SSE2 digest.
'4e79b1b80110a71663e4cc17438da63804ac7217a7b59bd85168799407617c62' ],
'auto:union:perceptual': [ 'c372878221e3b992c58914d55f9953235c8c32af942f009ca24295eb0aae861b' ],
'auto:clip-to-backdrop:linear': [ 'ddd0759c73ab8a3a6943e248a6cb3cd35c518a2b112fe265967997ac5b100658' ],
'auto:clip-to-backdrop:perceptual': [ 'b4d38f8e83487279b7376fea823be6a132ae5a575a70c4c9ddd11a96a3cc060e' ],
'auto:clip-to-layer:linear': [ '4126dcae9ba4c6938bed1a5f7b633349e4c428091b842cae9257941c38ade457' ],
'auto:clip-to-layer:perceptual': [ '04598ed8c875c41ba259095103ff9f078468b0ca7977ca094a46ff416a093046' ],
'auto:intersection:linear': [ '7c702b7fc9085b83cf0d04d5ed0b6f33f65bfa8f760d49cb0c9f63e78d9ef439' ],
'auto:intersection:perceptual': [ 'e97ab4ab6344fdb776a463a52f067a4a0f1a0b8f164c044aee1897b205384a73' ]
},
'hsv-saturation': {
'auto:union:linear': [ 'e694947cccf3836d488d336c94d7cfb41b6cc671b4a1884609ecdd374c280266' ,
# Non-SSE2 digest.
'fff8d1d3876a9f1b38d5c90c38018e60f98a4c7576973b5676e0893c1ef1fb4a' ],
'auto:union:perceptual': [ 'f6d9d77739a595a8a99b2160a42586e24505d1bda52e48b8aec70e9075531e67' ],
'auto:clip-to-backdrop:linear': [ '3d5202114900bc3ef9b79cd3ff0fbf656a471c4ff14ec4734d5cd3086fe52d86' ],
'auto:clip-to-backdrop:perceptual': [ '2d61acd031742fad429441ebf4c904305a8e991091c9752d437a410d4507f174' ],
'auto:clip-to-layer:linear': [ 'be995fe50809c950fe87649f2911151219b46381be0df089b56cc1782fd80987' ],
'auto:clip-to-layer:perceptual': [ '35c5131cf284c1589639e32858c2f389d1f1667aceec4a10c9aaf450155d9270' ],
'auto:intersection:linear': [ '3d4e25be2ebcafcc8fd1a30f8e5d77424f828f998b8bc3cfa5c93e1fd19d9f43' ],
'auto:intersection:perceptual': [ 'cfdd4702ea02c79ff560816afc0820a39cb8818e3ff020aa89f47ebcc41594d6' ]
},
'hsv-value': {
'auto:union:linear': [ '99abf5f6be3dd50821928bb1a2231aeada73e2a62e8957430c1b5d64a9df313c' ],
'auto:union:perceptual': [ '399b9f5bd1fcd649c2adf2d28cb956b6004f7bbdaada2e7fab12e0d8eb6c956a' ],
'auto:clip-to-backdrop:linear': [ 'f27e055965b00bd0ed2b7ff741392a2bb0e5768fac7767305b5616641f78369f' ],
'auto:clip-to-backdrop:perceptual': [ 'efd45a0ebd42e558a738219a071a533e74dc33daf590368a7e8304644af6f12a' ],
'auto:clip-to-layer:linear': [ '568abcc056b3d5144792aeabf3ec90640d496cebfb80aca613f132d7c2683606' ],
'auto:clip-to-layer:perceptual': [ 'b513f1a1082de8c044df87b5d5f7c34237a166baad9b5cadc9f3a3ea0ae78507' ],
'auto:intersection:linear': [ 'aa6c1a8a5c3aa97468d66a46c2b2abcc04515f45daab65248b13762c8759e74c' ],
'auto:intersection:perceptual': [ '2993e3c0fc6ae1045f34a187f00fbee02ef32352d88f5b2a2c22a0b1fcb76758' ]
},
'lch-chroma': {
'auto:union:linear': [ 'e264c514956119cd46825a470c6a7365af1c8a23b107f665c113872eb51480b7',
'b1721f29f7ade730667635b6150961720d53f6d737af5a64c2f5313d5d415d8f' ],
'auto:union:perceptual': [ '3c7b7d780c671c0ffb768d22e47b904a601f6ccf139807976217f410a40d0d13',
'f7dc7ae56040f8ea8f909348e0887beb10b9e0ebab37095a4e12becf7810ec32' ],
'auto:clip-to-backdrop:linear': [ '65a75daad3689e53a7a61535c025aeed546f117a20901e58b439247c7bf7cdc0',
'c9846f492bca6ff005c730e3d5e1374307344b0798380a099b09b7321ce220b9' ],
'auto:clip-to-backdrop:perceptual': [ 'fb0000a80c0bd871c14222dd99b6fe993ed449633a2883694f28765cc32a7fa5',
'625d375e2bf299a34683d2e2e03340bc19d5d040cd68db363a6616794ce5938d' ],
'auto:clip-to-layer:linear': [ '11e65e38240e1ba40d689d5665043dcb95d416201e17af60cb24574011e834be',
'0da344ff37c715cd3863ec90d995dbd95a4520dc6df07e166bd69d13ec8363bc' ],
'auto:clip-to-layer:perceptual': [ '0a12b36abedd2114de44dc40ce7290bca011509ce8c1bb86c3a5c33713ce1552',
'9db2635081f2f82bf5e598b887ec9133c2b751a1343016638550676a705fa273' ],
'auto:intersection:linear': [ '7240d3c3614b64a6d80e18a4309c398b75e7e91655c0cb3a65c326d54bc2187d',
'3cf83a9e7075ca04287f4de7c8517bd08e26c8facb8a050c542a87e6f9ee03be' ],
'auto:intersection:perceptual': [ 'dbb8801625212c6bc40de88bfff1cbb06cac3bce9566b49e4db5fd985f86f177',
'79314c1fd011515e31effdd6f1540b702479b79d3c9dee7f546fc11902928631' ]
},
'lch-color': {
'auto:union:linear': [ 'a9b6a939ce0aa02b42428f3e9ada9cadf0dbbaf3adf65226a999f1e1129c9020',
'a140645e392a230b22198a9f072a36d6071a5f66b2635dc31914c66a212307dc' ],
'auto:union:perceptual': [ 'b21471fa3e0143e930b3a20b794dcd38c069a5217b779998e1c15b41cc651e40',
'07ea184390b9d0bbeb640da882d1439f3d3fd2a9b1303e1603426a16468c7c2d' ],
'auto:clip-to-backdrop:linear': [ '3aafa9604358a6edeb0c913fb87e8a4a944b9b31647c1b3734657c75b8b627d8',
'ce58aa8d94fc5b4b125291920f20854fb1969c68832d4b67fb96f5b5334aa357' ],
'auto:clip-to-backdrop:perceptual': [ 'a8a741b9e6f924b5140f5194158c7b79115b1d1f35cc8f815599edb409d3e2e2',
'3f013306c7d69052cc1ac4faff7a2606976baa30811862553badb9e1425bbf65' ],
'auto:clip-to-layer:linear': [ '74f1939137c90cff1f3060828cc2fed64dcbcaa72a3a53133f48bbf43f6915d6',
'43a49b8d43b8d66a6df6cf77953385e9205aa14d5bf2e9db871a13ace36f01fb' ],
'auto:clip-to-layer:perceptual': [ '202b98a2b6c9172af1a57aec47e20ae0d49958f7dba7051829de47404f2fe03e',
'433bdc153cd8981d3674d08519c471b8a549c4dd75ff93596554a6c91dcc9211' ],
'auto:intersection:linear': [ '808bad3f6c98d7873fef9f94ea7674c88a1d7dddc7e2df61ae7b21192256651e',
'b9f732450f1402b0cff6f22a5524c45222bdb6b27ced5084edd951ec33cee4ab' ],
'auto:intersection:perceptual': [ 'e783556d60128d09f17e06c89f0ebab8e6d452c8065a4927b8eed3f79d837926',
'803c0429b1613c6ed0a600ebabbc59ac6a8d7583dae05d6afec930abf86f7c15' ]
},
'lch-hue': {
'auto:union:linear': [ 'bde1e02d9389345f20eb36111bde5ee974105a3ebf182567197cd9e7d6a0d61c',
'd653b1a795206ec72ffd70f10df5801cce55547cb45fa65f8062a97451c6efd0' ],
'auto:union:perceptual': [ '9008bca1babf8cbe42388470a80dc9247905170a58f482e95af17e0bc706a094',
'a65dfe476d328a70e480d50c95f75c2bca7ac5667ad69f43b0d7227dbc9aafde' ],
'auto:clip-to-backdrop:linear': [ '113111624751e164e7f1194830629609eb94fa28747f265e1db0e9bb0d61f03f',
'89bc6767eba0b2608d87042f3e2ac6c80f29970229de194c82b23878b0424ba1' ],
'auto:clip-to-backdrop:perceptual': [ 'dcae48c98cdb69a5125ebb53c3a4b5ebd7dfa3d59ed67f88af2f12f3c21353a9',
'3e47701dd20b53c9dfc4767a714cb79c81ff8c042aea121d886364b27fd62053' ],
'auto:clip-to-layer:linear': [ '6db014aa57a7e754541149fcefc77dc8105d25f25077ed3f72b12d872c40169c',
'3008fe9ee6607107f6daf303720c4d92c759642cf4031926bfedebae283a2b68' ],
'auto:clip-to-layer:perceptual': [ '33971acf071e5e6d777a48b1a1a3e8a0de573c4c985a82b727eb2507ba560880',
'3b1eba0fb3648cf0c5d2318b1db4a4e67aeaa5fb377924444d8a942b422d53ad' ],
'auto:intersection:linear': [ 'f7dfeb2624dc8a6894525d17d017e6e0bf11598545e132fcc0cab06be94af85a',
'9f2ce51472e68eabca7ffa35e91e55ce7d4109aa0d182fc624b899c1abc44b00' ],
'auto:intersection:perceptual': [ '103db86e1442d659424ff1b13d2fd8a36e7b99481fc5470aa2218b4bcc8c638e',
'b3ee12658e50968c6415622fa0b44bceca9b196c33b4fa73a21eee7a2eec717a' ]
},
'lch-lightness': {
'auto:union:linear': [ 'e689b1d2f207067151282a3b9b19d1822aa5def8c25e1705e33ef3e03bfeec49',
'4500a36aa44a4480f7d99e4ab02eef0cda790faecc59be8c96ed00f35715cc98' ],
'auto:union:perceptual': [ '6e0578f3c33574428f261d7d2545296ecb2df981a8f1a67b6a1075bf3d4536a2',
'21d9797794e420c97728c5f867b2748b9da8744693af2cb62eca7447d43ffd61' ],
'auto:clip-to-backdrop:linear': [ '87be28379f221ec96a3953bbcc8a03d5e0fa2b517754b3012fe3bf9c624b9ddf',
'e948a572e267fab10cab5c72690e68b181cece2668f16b3144507054ee91334b' ],
'auto:clip-to-backdrop:perceptual': [ 'cd3dccab084822353fc58793eb83e04c7c1c98d3d9dc8486e29ead9b978a0935',
'f2297cef0b03f34e9c6faf29c09bb5d8d0fa886973a74e143c8f01f983f035c0' ],
'auto:clip-to-layer:linear': [ '6de97b167687c502ab126a6a4c34f19a12680dbdd9eabfc98357b901f00ba52a',
'a1dd21b5959e49467342b300d2ba63a4ea6515f35cb833304fefb371fd47117a' ],
'auto:clip-to-layer:perceptual': [ 'ab13aa1b5a0513cd334bfc64e09d3e144cb2526f49d099046432865e57dd92bf',
'e332337afac78cda49115d0a62c16ce6339b81ed92c5690164596a30c42dda4b' ],
'auto:intersection:linear': [ '8500f93966da5370b943fae0dc7434231ae15943599f7f3bb103554e8127abb1',
'93375b18e1231737d5b450711445df90a9a9237cbe5463664e23699c8d979368' ],
'auto:intersection:perceptual': [ 'dc723c285b7caf3fcf4640de7baf6c86756b097a301e2596123c4c4a3cd847c8',
'a552ff43a052d49df8d98d657833fe155b9425c0f280ccc0493a171179e1402a' ]
},
'lighten-only': {
'auto:union:linear': [ 'de4edbd8761838e5e3663eaed4b197956e28dc63eaf9e40b1abd2ceaf8a88bdc' ],
'auto:union:perceptual': [ '1f5370fc2ecda5d047e105d537d47a144b8437463681ab630f07ca7d008c3db0' ],
'auto:clip-to-backdrop:linear': [ 'c419b5062fec64185804c339b4d121cea470454ac2f318b4d09d3ce461fbbc14' ],
'auto:clip-to-backdrop:perceptual': [ '86fcdea8c5d2d6b6b1ec3da20c565840a7039c280d368e75c04d181f53f8306d' ],
'auto:clip-to-layer:linear': [ 'fd084acacec91a33aaaa1ec160355ea8c79067cab5b5a879947a2da65c34f683' ],
'auto:clip-to-layer:perceptual': [ 'a7b97a035014e263166f5c43a05f47adf173c5c8ee0760e1218c9c3d05f1ecbf' ],
'auto:intersection:linear': [ 'ba75d698971e6239f2ce0b214b5ee480357bb84c4ead64424d37d4f44d077ec9' ],
'auto:intersection:perceptual': [ 'ba75d698971e6239f2ce0b214b5ee480357bb84c4ead64424d37d4f44d077ec9' ]
},
'linear-burn': {
'linear:union:linear': [ 'ed2c3e2f684dbb64f3becb83cb28b216b7425d1723f589c24e8d231e0bed0284' ],
'linear:union:perceptual': [ 'c8ddd617c52291b6e22f3ec54c8d9ef78322e3dfb8ee63a58e5e64ff8843a2f4' ],
'linear:clip-to-backdrop:linear': [ '5d8c25911b9fa6b2675a3c40d88b800e9ca36a26d405a3bb8ead327eae2cfb84' ],
'linear:clip-to-backdrop:perceptual': [ '78766ce875460cd0950f12fcac549216f33789b1a6f2ab92c8da0b394ff78895' ],
'linear:clip-to-layer:linear': [ '3b7a63e2f9bb683b2f1c66da05d6ef1d13e05190af7fa4a944055496ac666c5b' ],
'linear:clip-to-layer:perceptual': [ '9486161f0cb391fa845f96616c6da015089505ed2317842b886c98f115127419' ],
'linear:intersection:linear': [ 'c9ca3ba5f9b79ffa0d09f7d8700067856bcdfca3f63a8ccc09c1ef143c0e6f39' ],
'linear:intersection:perceptual': [ 'c9ca3ba5f9b79ffa0d09f7d8700067856bcdfca3f63a8ccc09c1ef143c0e6f39' ],
'perceptual:union:linear': [ '62af40ee48bb3ae696104471be759d0be69763df4bee2aa74eb01836245434f8' ],
'perceptual:union:perceptual': [ 'bbf0c464f0304dd86bc707303ed4ff015d5596dce76ff176785cfd7b2926fa7a' ],
'perceptual:clip-to-backdrop:linear': [ '4aaef30b9d47d607247c107eb64e49f3527732a95d6a62650290e2be61a25a4d' ],
'perceptual:clip-to-backdrop:perceptual': [ '507809808e6d96fdde70d18fe2ecdab3aaf0752341308af69522888b61d639f8' ],
'perceptual:clip-to-layer:linear': [ '2246474d37f8693479295ffded18578fa3fd2073c88a8a56438035f02a99eb39' ],
'perceptual:clip-to-layer:perceptual': [ 'b8311ef75fe6e8d1fb7adb29cb0b8dfa34074c3834e9cae258400158ce9a3c9a' ],
'perceptual:intersection:linear': [ 'b246dffe46e608a2c2825f38246b69e8d3387129b63d88005e774e69971ed4d7' ],
'perceptual:intersection:perceptual': [ 'b246dffe46e608a2c2825f38246b69e8d3387129b63d88005e774e69971ed4d7' ]
},
'linear-light': {
'linear:union:linear': [ 'b51200b2068e33bc3ce1af22f1194f5ffccb9e5bc7bd01604d1d1b5a2818e20c' ],
'linear:union:perceptual': [ 'e6c8f8b043eea2f45b508ec59e1657b7b7da2e78e14d7b2581c9c172420436f9' ],
'linear:clip-to-backdrop:linear': [ '57bde6e5fdf8f382a76fb23397c7bda49a1cc04ea3bebc0fac4d6d92280ed9ba' ],
'linear:clip-to-backdrop:perceptual': [ '42cd5005db66857e9b44fd35ea249a39183bd2d01a16c209fc5bb7e260f10b5a' ],
'linear:clip-to-layer:linear': [ 'd1efbc186b7f94637e37cf74c93ac416baa68faa9efcdb859d35e0104ef6882e' ],
'linear:clip-to-layer:perceptual': [ 'ed67c1106e0c0743f4f3c9149d81e39aec9ceaa722d7ae3c1b40966fec133cbc' ],
'linear:intersection:linear': [ '7abdbce554f57833284ba1b785ba95b0858e9167e4b540c39bafd9a341dd9a10' ],
'linear:intersection:perceptual': [ '7abdbce554f57833284ba1b785ba95b0858e9167e4b540c39bafd9a341dd9a10' ],
'perceptual:union:linear': [ '09c2f60836969c26430b9ae69d168d38a8da0c7cf4ed06c02122a6827bf7abac' ],
'perceptual:union:perceptual': [ 'ea92504043c38615aec087dd62593f9c656123425d2ca5f4a4cd1352bd5cc5f3' ],
'perceptual:clip-to-backdrop:linear': [ '837fe9bf7f08a50908c219c09bc48fd376bc40656ffa75b4e78c605e18eefa55' ],
'perceptual:clip-to-backdrop:perceptual': [ '6da7c6c2ca5146424430ab5ff3632042a06c0f8c7eb3102d3f7fd387e2c30abe' ],
'perceptual:clip-to-layer:linear': [ 'f1c89c9268089e1d59f1108c23b046f7b812609bae7128f34f43c17d60f58312' ],
'perceptual:clip-to-layer:perceptual': [ 'ca66a6db17bff47bfdc14f83ee3548773273b81a8ff8c93b13ff358d4d9cb1da' ],
'perceptual:intersection:linear': [ '8f33304da2c218f6826f3d42252536dc84bce93265796950b049077206d7bbec' ],
'perceptual:intersection:perceptual': [ '8f33304da2c218f6826f3d42252536dc84bce93265796950b049077206d7bbec' ]
},
'luma-darken-only': {
'linear:union:linear': [ 'b6ba8de9924b753b3c1984165fbabb2c2963c9a1636d5506e71a45fa1cd262a4' ],
'linear:union:perceptual': [ '97a8b3ebbd8f767a42c91b6c51bf2e8b4c8f654785cd4d068eb89304b5a11bb9' ],
'linear:clip-to-backdrop:linear': [ '7e814e849ebb3bc6d12fcebce603a85171e9582bdcc9415b3e2dc79309545242' ],
'linear:clip-to-backdrop:perceptual': [ '20d51133d7308a665276e7e88f6fd8cd000828e769f428ade4880743fb30a389' ],
'linear:clip-to-layer:linear': [ '41d9c880e860c990e1423cef64e2aa572be7608aabcc0927a4051bcda2ab8a89' ],
'linear:clip-to-layer:perceptual': [ '8bee2c0e1d3fcaed97eddafdcb51551b79bd76e11bc49c9e5fc0d38602a1b0da' ],
'linear:intersection:linear': [ 'fe7f74802badbbb075b8090853d3b496a533ec0caf941f10af84918ab76adf6c' ],
'linear:intersection:perceptual': [ 'fe7f74802badbbb075b8090853d3b496a533ec0caf941f10af84918ab76adf6c' ],
'perceptual:union:linear': [ '8fc756574d39ccf64266420d15b2eababb22a0f6c0539f93009250fd8ac4a909' ],
'perceptual:union:perceptual': [ '22b4ceb2dbc2e36ef3f0b32c637f150fd799c570cb547d29e6a7729b8d3c59ce' ],
'perceptual:clip-to-backdrop:linear': [ 'd9be04571671350d00196b8f768104aec21f7d253743b848c2eb2ca05dac4491' ],
'perceptual:clip-to-backdrop:perceptual': [ '2a1e245bb6b296f4cef9d99caa393b0c2afd288035c169ca368f07cb2a665e3a' ],
'perceptual:clip-to-layer:linear': [ '28861f6e9dd4021ddb3380b449bca24e1d21f2b3951d9954d457d1e861c98483' ],
'perceptual:clip-to-layer:perceptual': [ '84ed581dff02e730470d9aff7b00496b7671b36700bb79d76b607b266ef8ae0d' ],
'perceptual:intersection:linear': [ '41942864c2c0e9f5f23324f84ccadfdd1af97bc7bf25f6c19cf48ad71567d560' ],
'perceptual:intersection:perceptual': [ '41942864c2c0e9f5f23324f84ccadfdd1af97bc7bf25f6c19cf48ad71567d560' ]
},
'luma-lighten-only': {
'linear:union:linear': [ '1467987f5728fa5b6142b67dc481d2a6dc55bab4c007dd8b401b40066b9153a9' ],
'linear:union:perceptual': [ '15e258ff19eea7474a1dba5df688ade20bb72a3cc646b5a020679ff578455d80' ],
'linear:clip-to-backdrop:linear': [ 'b104732deb02808ff7050f6678eb7ca168e6c26263808beabb7a6894985ffc0a' ],
'linear:clip-to-backdrop:perceptual': [ '31fb2ad839276f4d76c170ca64754877c424d6300a6d9a7de7718ba66347439e' ],
'linear:clip-to-layer:linear': [ '879b2c3e22dd5b15e8484f714bcbd86b5b898abf472bf1292bda50dd9d97b66d' ],
'linear:clip-to-layer:perceptual': [ '6d5f242bc4bb02bc8a20153ae1df141c88e18247fb44054432e4976a7bfa0bb5' ],
'linear:intersection:linear': [ '8c6454283bd5b1d162f6708bf9b3a40ad60ff2944e9a1accb257d7da8d6f39a9' ],
'linear:intersection:perceptual': [ '8c6454283bd5b1d162f6708bf9b3a40ad60ff2944e9a1accb257d7da8d6f39a9' ],
'perceptual:union:linear': [ 'b494f65356baf266d6967cda30dbbc1f97c9728b1f318090389a0695c0105321' ],
'perceptual:union:perceptual': [ '96f5b7aba4d31ead80d251a10206d6001c3a9814c42dde493f8bbc6d30f15309' ],
'perceptual:clip-to-backdrop:linear': [ 'b28e6325a6c1c80799bc8b9c144570fb0b29f968694de6d01238ea1ca6aaad15' ],
'perceptual:clip-to-backdrop:perceptual': [ 'ab700b8005e1977554441ec9f09c78c48b2e32307f57c652e786691ce8081e81' ],
'perceptual:clip-to-layer:linear': [ 'a09bfeef9f9202a7022e38880ee18ac18905d4f39637115a5e0a6831173db08c' ],
'perceptual:clip-to-layer:perceptual': [ 'dfa44bdb2a87231dd98afaeeab3ef17f6654a08f3b629868f36534c8e5029f86' ],
'perceptual:intersection:linear': [ '83fc3db22dd3398f76a8fbbadd5bff9f8ca1143aefaeb16ae55ef0163ec00b28' ],
'perceptual:intersection:perceptual': [ '83fc3db22dd3398f76a8fbbadd5bff9f8ca1143aefaeb16ae55ef0163ec00b28' ]
},
'luminance': {
'auto:union:linear': [ '2f2ad9a0472f3db755fd4aff7dad8bbfd36cc4dbf65b71e3c1c7c50e088e36dd' ],
'auto:union:perceptual': [ '73c63c8489f657113003edbcde98b4838ea1e0048b07cdfb0de21aa7ce4338c1' ,
# Non-SSE2 digest.
'dcfca1ae9a18aee8aae284eaf9171257f70860996945aca97cb9eb731d53bb58' ],
'auto:clip-to-backdrop:linear': [ '9f6f19ceb5d2a56202a9c2a99262e7a437677b37d3e46dbf409d275d3fac6fca' ],
'auto:clip-to-backdrop:perceptual': [ '8df997a5646670e2ab8da40413e72262125d0aa2031bf1b96f03142ff49d1c34' ,
# Non-SSE2 digest.
'088487cb38d58667baae9e83ab831f7aad5e36393ad2a45e405f43bf712d4f94' ],
'auto:clip-to-layer:linear': [ '4170c59e790babf7f3925d2390ef5a250cc6c5cb3e1d6de027f3dafe5c30a9c5' ],
'auto:clip-to-layer:perceptual': [ '584ecbd6a740258bbe2f741be4169c7ce809f4de72f02538868b2a6a16da67ab' ,
# Non-SSE2 digest.
'2f5e66a33befd68a03b9bf63afc66f1ed0cc59d303a9a76eaa456a4bb3120c69' ],
'auto:intersection:linear': [ '2743c459cf357bb1f4bb2371c30ea82c4dca382b75f5cf07a0d3dbc71c51a2f3' ],
'auto:intersection:perceptual': [ '474e2da5f2e2c5d26c5a167db7141f74ad511c3b939494529e76863fcd110f78',
# Non-SSE2 digest.
'58d89ddb58e25aa662a15edec69661fdc9704204622a5adbed69ec11023cc73b' ]
},
'multiply': {
'linear:union:linear': [ '4a9b964c4f1dbde6ddce2524d83b7095f292fe6cb0afc18b6f750bc44a9b2657' ],
'linear:union:perceptual': [ '7b568de38896b48b22811434b5aa16f7dc625edbc4451391aa84adf56551c54a' ],
'linear:clip-to-backdrop:linear': [ 'ac6089b7dbf719059730ed548b873978289fa096bf6c0a288c59f1c743d6b19e' ],
'linear:clip-to-backdrop:perceptual': [ '34d0ab24031ee571598d41b89d60dff580f50e456ad3e4feb0d9052a3d8cfb07' ],
'linear:clip-to-layer:linear': [ '766cee039258431489ad0f9c701aefbdf71209e1678ef8d5584ec09deac825d8' ],
'linear:clip-to-layer:perceptual': [ '4e51175a22fbf4f2ff04691908bff2ae1d66633d0ed777d9d18ee721ea6fd42b' ],
'linear:intersection:linear': [ 'a82aafff16670720bf7feac02476e70ae5120ec84f99bde6e8be64371320b411' ],
'linear:intersection:perceptual': [ 'a82aafff16670720bf7feac02476e70ae5120ec84f99bde6e8be64371320b411' ],
'perceptual:union:linear': [ '5e331fc8f44f4b0595e4476b7fcf225dcd57b002cbdc9cca0db42bfb5fbcd816' ],
'perceptual:union:perceptual': [ 'f779e92ef00411a7b8858e2c782b18274cbece3f25163d230aa65d7da417efdd' ],
'perceptual:clip-to-backdrop:linear': [ 'b115e84e0ce6458b20b4909310622f092dc6652a4c82b6776f7a54f1b5cd4a6f' ],
'perceptual:clip-to-backdrop:perceptual': [ 'ce971c6a7b9e3adc29a257b2fa950f63829fdc71ca383e2754d43540e3d0d8a9' ],
'perceptual:clip-to-layer:linear': [ '02f4f153f1b1cac4f09694c43cae368d161ddebb2985064939f098f54f6e410f' ],
'perceptual:clip-to-layer:perceptual': [ 'ea9d5b25a126d24ef29267729d94a97bc1756d562cc727cd9fb05a348b4dcbda' ],
'perceptual:intersection:linear': [ 'f872f2a51bf893ae3270b29b952d0f5803b6256b96e74342e44262fb3595a9a5' ],
'perceptual:intersection:perceptual': [ 'f872f2a51bf893ae3270b29b952d0f5803b6256b96e74342e44262fb3595a9a5' ]
},
'overlay': {
'linear:union:linear': [ '4daab160ed0ea3d80a6e0c0853ce11efa6ca09fe364164fcaf946cfb8191afd6' ],
'linear:union:perceptual': [ '94fa7e93b048a15f98d5138deaebf09d8c12a914b0ba17173418ab46cd3e347e' ],
'linear:clip-to-backdrop:linear': [ '1ced7626495b52b93e447e483cd8a9fc9ee644ddb3e9a518ae6f8ddb12e3d257' ],
'linear:clip-to-backdrop:perceptual': [ '596d35be74a31ef78af4453fe094d411f794692ca451d8304e9c893341feb453' ],
'linear:clip-to-layer:linear': [ '6d884886a0f98174a691bfafdba94040e35753cb3d4e4966b2643efc233b84c6' ],
'linear:clip-to-layer:perceptual': [ '344b439a251335a28aba5034edfc774047bfbccc7f265221cc7eb6c7a33945c7' ],
'linear:intersection:linear': [ 'cb277c8aaad1925316bf7a94462248824cb543a836b635c4364d1039dc2ebd4a' ],
'linear:intersection:perceptual': [ 'cb277c8aaad1925316bf7a94462248824cb543a836b635c4364d1039dc2ebd4a' ],
'perceptual:union:linear': [ '4a3a5e70c42ba4d467920470657b4390a70673c1b2a802aad3a186bb4e85061f' ],
'perceptual:union:perceptual': [ '70b15a04701991a0b9498e9361dce19f41a41447896c0c8d619cb4b5dd9a8341' ],
'perceptual:clip-to-backdrop:linear': [ 'cae6174d92f3439c962e9367fb562faa160c19bf39b5341e94023f4be4e92d4b' ],
'perceptual:clip-to-backdrop:perceptual': [ 'f8ccff7d692629496c6b7a8e1f98fde0fac06593635c656d9ce1fda11732dc99' ],
'perceptual:clip-to-layer:linear': [ 'd4d5cae05f57649da5b425314215670d4ef6caa479f7d676afbe449faadfabd1' ],
'perceptual:clip-to-layer:perceptual': [ '1c92ae84066352b2d545420ee9666d2493120aeaed18853c57302a32dbf61ff5' ],
'perceptual:intersection:linear': [ '2b182c96a2cb6c7bdeb5d6a04295af3f5dc5480072a481c79a27b7649301553c' ],
'perceptual:intersection:perceptual': [ '2b182c96a2cb6c7bdeb5d6a04295af3f5dc5480072a481c79a27b7649301553c' ]
},
'pin-light': {
'linear:union:linear': [ 'f3f2e314b1fa1e0f5f24cd91fd3ff60fb1d2ffb542a8fe74fb09da2e16a3dce0' ],
'linear:union:perceptual': [ 'aa2bc0173cd0da8e349b0047aaf6e2daeedec4662175d5c2599036a1e142f68a' ],
'linear:clip-to-backdrop:linear': [ '86f71811ce23501080f8072b7744832a0956c38c74c6349251b89f2c735db70d' ],
'linear:clip-to-backdrop:perceptual': [ 'ae18d156b424177ae8e1898224fed97d7cf2d358b1be3e4bc1f389139bc3d240' ],
'linear:clip-to-layer:linear': [ 'a10add4c5addffe9b6939a64e63d93e1b4b68b652e184382b10d6b99867d6e76' ],
'linear:clip-to-layer:perceptual': [ 'deaded5c044a69f5ab50fd8ed90fce10173be45a9f979277cd291a56a4daae1d' ],
'linear:intersection:linear': [ 'ffb062096a3041bc497e0015078663a8436e1e8b47ea1deee8c4b2650e9f3d64' ],
'linear:intersection:perceptual': [ 'ffb062096a3041bc497e0015078663a8436e1e8b47ea1deee8c4b2650e9f3d64' ],
'perceptual:union:linear': [ '20d7880ebd58cd0d1c5b39e1b26e9120b6f0b88ef4b543d638aeac6c533982f1' ],
'perceptual:union:perceptual': [ '519ff62a73f319d2761c1e6bfb507f88f6802aa9044d3a91fc950214fd0cae62' ],
'perceptual:clip-to-backdrop:linear': [ '806ddcf07edd8a4cba4850a1697dd13cc6a05ce82eae320158fef3d9d9f22794' ],
'perceptual:clip-to-backdrop:perceptual': [ 'b5c08cb252a1945ef6668b14e65a271a89cfbfa9a3134bcc8fe379a8f457f40a' ],
'perceptual:clip-to-layer:linear': [ '56cf9342bcf381ec434ee6dacce7c2488e7262b0c793e81a7d1190b91ab57bb8' ],
'perceptual:clip-to-layer:perceptual': [ '3ef6fb5d379e2d37b94ddcc171a8850273c293a468395a6e7c6c416c7f46faf6' ],
'perceptual:intersection:linear': [ '51c0454eede7fa854af23955c6210ce5ca123171edfeb9f7f5a9d5ec926c34cf' ],
'perceptual:intersection:perceptual': [ '51c0454eede7fa854af23955c6210ce5ca123171edfeb9f7f5a9d5ec926c34cf' ]
},
'screen': {
'linear:union:linear': [ 'caeebd8b2d402a78bfc54d87592d07dd92a233b9327ec7f1f29558346ff2d247' ],
'linear:union:perceptual': [ 'bdfd1d0ab325fce61fc988fc50dc17dd2fbdb9a3f55fc198ba152e27d085567e' ],
'linear:clip-to-backdrop:linear': [ '1e3ffe6365879d697a82dd93a00c1bd57be49042fbff1e8c178dcae2831d4f07' ],
'linear:clip-to-backdrop:perceptual': [ 'ec2afa93292cd105971bfc0c63834d296e79444d2a9ee4757d75e762b61217af' ],
'linear:clip-to-layer:linear': [ 'fdba96e6257fe23f11b5d3eaa03e60285a2f1e002493501240d733763e886ff8' ],
'linear:clip-to-layer:perceptual': [ '59abc43a02c29de4e715f1d14ceb7e898f65f4e95a9e49bd2d9fd4fa52652f31' ],
'linear:intersection:linear': [ '7fce1cf27b5866e41fe44eed2509ddb54925347c7a50e79b1a142678bb363516' ],
'linear:intersection:perceptual': [ '7fce1cf27b5866e41fe44eed2509ddb54925347c7a50e79b1a142678bb363516' ],
'perceptual:union:linear': [ 'aaefe8c90bc9e87a7292e20da2d442816aaf76ff9fbf3b9dd36535a592f75191' ],
#'perceptual:union:linear': [ '5e331fc8f44f4b0595e4476b7fcf225dcd57b002cbdc9cca0db42bfb5fbcd816' ],
#'perceptual:union:perceptual': [ 'f779e92ef00411a7b8858e2c782b18274cbece3f25163d230aa65d7da417efdd' ],
'perceptual:union:perceptual': [ 'd01826d7b6d0ac1c2cc57adbf1517d721c8aa092e1043c770ebdb6727ae149cd' ],
'perceptual:clip-to-backdrop:linear': [ '907bb765b2ca1d0440e57ebcd20b54d017e202032a4b2ba66324b439c570202d' ],
'perceptual:clip-to-backdrop:perceptual': [ '42d2a2f103f24e4f6966a8ef134994cce932120d275daedd07b9ca4bff40f707' ],
'perceptual:clip-to-layer:linear': [ '0f6d297cde5714833fb373b6f16b531ec03746478916ffa7ff3eeacf9f39cdc4' ],
'perceptual:clip-to-layer:perceptual': [ '7f4606639fbb945b57c61df31d0b9236c347beb19f454f8547894b5f296fc292' ],
'perceptual:intersection:linear': [ 'ab1b9f2d5f84ea648e513ddd3a8a72bed65233b35334029996dfd24bb882588f' ],
'perceptual:intersection:perceptual': [ 'ab1b9f2d5f84ea648e513ddd3a8a72bed65233b35334029996dfd24bb882588f' ]
},
'softlight': {
'linear:union:linear': [ 'a4bcaa4a1b9792183dcfbb54fae2a4404072cffec54c44ed80165cb7f801f325' ],
'linear:union:perceptual': [ '71814581cb2008f233bcf871d1ba900cfcb87b363fc773095171788069cc5bc4' ],
'linear:clip-to-backdrop:linear': [ '7cc7d919564ed5f95dcbf8015163f4d543dd1d859f89078627670b989194f14d' ],
'linear:clip-to-backdrop:perceptual': [ 'c2831ca304b45a8b33265be6ff9acd6b4b93dd7894d443e9b85dcf83b4bdc7dc' ],
'linear:clip-to-layer:linear': [ '3c3aa48461e2780310842c9bfb383c87de7d3fa00b4d366de7f1f167adc1fda4' ],
'linear:clip-to-layer:perceptual': [ '54738b72f976797834dfc7fe4b2dbce3626eb98940a9325ebfd050303bd9fdb8' ],
'linear:intersection:linear': [ '135162ac987e3532f98647e9a144c1fbe7f7aadb8d5b8c34e3ced65c9c020c10' ],
'linear:intersection:perceptual': [ '135162ac987e3532f98647e9a144c1fbe7f7aadb8d5b8c34e3ced65c9c020c10' ],
'perceptual:union:linear': [ 'a879d733d10ff932ca8721f0de0b27478cf2f2925a99c965e44ee22018ca0b62' ],
'perceptual:union:perceptual': [ '33bce07481189020c3b9d68ee19267974f42977e3e1dd0b02b030e7c8ba88719' ],
'perceptual:clip-to-backdrop:linear': [ '7cab3239d38ae183b4a8f4e287046f988e5eeb56a7ab06bb92195ef0e549a59b' ],
'perceptual:clip-to-backdrop:perceptual': [ '542f0b4bd1c5a9eb83610b8c2d3575e1c02ddb83d7032b3a4f720ad6a1fd125b' ],
'perceptual:clip-to-layer:linear': [ '952ad321d00b58a7b8b7389b6fbcd8a143f1f31d2b274ae0b199faab930eb7a1' ],
'perceptual:clip-to-layer:perceptual': [ '472fbccc6bfc0f25969405106ea1d4be6b25e4fcb5ecef654f19ac70b03538ac' ],
'perceptual:intersection:linear': [ '537630f9fa83db4adac30d311d9281044e15c5161ab21b741be3de3719d02312' ],
'perceptual:intersection:perceptual': [ '537630f9fa83db4adac30d311d9281044e15c5161ab21b741be3de3719d02312' ]
},
'subtract': {
'linear:union:linear': [ '2769912ce750f1bba8d2d1cdf5e3b88297e2cf464aac136ab89ec495d8ce2ab2' ],
'linear:union:perceptual': [ 'a48aee59d32ad0aea2fdddba3332e99cca276ee36e35263aeda6a7c14d8a7cb4' ],
'linear:clip-to-backdrop:linear': [ '0a8521c0ec78fd0c06bade3882d2120dd7e95f82fbacdde48055d8a96288d308' ],
'linear:clip-to-backdrop:perceptual': [ 'd8111e97361d209c55c92546f1611958dcc0877c9bbe601f973f2141031d6367' ],
'linear:clip-to-layer:linear': [ '5bf2cedd9df68dceb0950b6ddd7a88662f340c55bc13a020153f4a992c00d449' ],
'linear:clip-to-layer:perceptual': [ '414cab557a9ba318bc3c7dc1d78412dba14e50e070097761ae2949941039f523' ],
'linear:intersection:linear': [ 'f018d79a7c0b1239725336ac0275a0da3d10ef78ca510d6aa010419798ae03aa' ],
'linear:intersection:perceptual': [ 'f018d79a7c0b1239725336ac0275a0da3d10ef78ca510d6aa010419798ae03aa' ],
'perceptual:union:linear': [ '1ba9a935dcce42e53ad2740dd9e9e51f10e1ffd99e468c4e05fabd87798fa349' ],
'perceptual:union:perceptual': [ 'cf7fab835b0d99ce7c9c8a5e53176a3a08149c61686fea8a0416ae03e5c97fe1' ],
'perceptual:clip-to-backdrop:linear': [ '7df56f7c9b5c3af823d3d50990694b333453c6f8989648692b70029fc4bc78d6' ],
'perceptual:clip-to-backdrop:perceptual': [ 'f44467112b62c58e77c3ffa9664c694f6661c23284cd5026c84869c02fea16be' ],
'perceptual:clip-to-layer:linear': [ '460052b7c5aed56f4c31367a27ad32bf8a5449e2814413d0f29644bce7adba52' ],
'perceptual:clip-to-layer:perceptual': [ '4dabe2d260e7da99e6c8ffab850a6314451664108bfde3e85ea3812e181c5063' ],
'perceptual:intersection:linear': [ '29a562eb9d1971cf5d6999baec5979580a48c75d1c0844d588ccf04b9e5905ae' ],
'perceptual:intersection:perceptual': [ '29a562eb9d1971cf5d6999baec5979580a48c75d1c0844d588ccf04b9e5905ae' ]
},
'vivid-light': {
'linear:union:linear': [ 'dac333038e93abdc2e35a4f56afbcade82ea8d7c11b0aee3c62718af3df8fc7b' ],
'linear:union:perceptual': [ '61ff19daddd147201534bbcbf8d5a19e1f65d30e0060541f76d89127e503f924' ],
'linear:clip-to-backdrop:linear': [ '6c229bd9a4fc188b3209a55ac6ccc1881a9f89bddb0bceb8050b18f97798f7a7' ],
'linear:clip-to-backdrop:perceptual': [ '0ad76183d5dcab2034bd102785c0681ba20c00f4fba81be8c1de1387a4ca1333' ],
'linear:clip-to-layer:linear': [ '9800b8905a5c4246694c1fb6a21aaf84e518539585d232a888836e809262d230' ],
'linear:clip-to-layer:perceptual': [ 'b4f97ffcdd856f95b9ff87fd6c5b0715f234c0ca82f1729b84656fcdbd2f3cf7' ],
'linear:intersection:linear': [ 'aff9137b2e6e268090597779ffce993894dba1b04f2f6e606b3e8ed3cf639ef7' ],
'linear:intersection:perceptual': [ 'aff9137b2e6e268090597779ffce993894dba1b04f2f6e606b3e8ed3cf639ef7' ],
'perceptual:union:linear': [ '996e5ea9223f5801484e7e30e63ba3f430a0848f3954ebe3175d321d72778021' ],
'perceptual:union:perceptual': [ 'fb97384c539bd4d3936f249e3ec11c182b13d0b158a91a2af9b2040ff6fa6266' ],
'perceptual:clip-to-backdrop:linear': [ 'b7aee5d4fda820c5c73ec55890d572fee2a8d050b474c78c6e69569cf9b1145b' ],
'perceptual:clip-to-backdrop:perceptual': [ '53afe7496c6ecb3ca8651a46deb2899c57ca674c79aabb0307ed5179af55fc4d' ],
'perceptual:clip-to-layer:linear': [ '74f8d553d429eb1544d3b4dd3c4a640a5b5610056bec75f8a5abbf0c67074ec7' ],
'perceptual:clip-to-layer:perceptual': [ '6d4eac0e393931751a68aea90acefd1378e183db5474691ca296e71ec3f96cdc' ],
'perceptual:intersection:linear': [ 'b1df3e91a2121dffaa4429e75b613227ebb3a50bdab06989d350413e7f8f8a1e' ],
'perceptual:intersection:perceptual': [ '1bef57cca5d42a53ea59f222ed8233abed30ab8fd174ff244a5095a78cafa320' ]
},
}

View File

@@ -0,0 +1,36 @@
if not meson.can_run_host_binaries()
warning('Legacy layer mode unit testing disabled in cross-building or similar environments.')
subdir_done()
endif
pycode = ''
foreach mode, submodes : layer_modes_own_ops + layer_modes_shared_op
op_name = 'gimp:' + mode
op_enum = 'Gimp.LayerMode.' + mode.replace('-', '_').to_upper()
pycode += ' "@0@": {\n'.format(op_name) +\
' "enum": @0@,\n'.format(op_enum)
foreach spaces, sha256sums : submodes
pycode += ' "@0@": [\n'.format(spaces)
foreach sha256sum : sha256sums
pycode += ' "@0@",\n'.format(sha256sum)
endforeach
pycode += ' ],\n'
endforeach
pycode += ' },\n'
endforeach
test_ops_conf = configuration_data()
test_ops_conf.set('OPS', pycode)
test_ops_conf.set('OUTDIR', meson.project_build_root())
test_ops_py = configure_file(input : '../../layer-modes-legacy/tests/test-operations.py.in',
output : 'test-operations.py',
configuration : test_ops_conf)
test('layer-modes', run_python_test,
args: [ gimp_exe.full_path(), test_ops_py ],
env: test_env,
suite: ['operations/layer-modes', 'python3'],
timeout: 1000)

View File

@@ -4,6 +4,8 @@ GIMP_EXE=$1
TEST_FILE=$2
SRC_DIR=`dirname $TEST_FILE`
SRC_DIR=`realpath $SRC_DIR`
PYGIMP_DIR=`dirname $0`
PYGIMP_DIR=`realpath $PYGIMP_DIR`
if [ ! -f "$TEST_FILE" ]; then
echo "ERROR: file '$TEST_FILE' does not exist!"
@@ -21,7 +23,7 @@ if [ $first_char != '#' ]; then
return 1;
fi
header="import os; import sys; sys.path.insert(0, '$SRC_DIR'); from pygimp.utils import gimp_assert;"
header="import os; import sys; sys.path.insert(0, '$PYGIMP_DIR'); sys.path.insert(0, '$SRC_DIR'); from pygimp.utils import gimp_assert;"
header="$header import pygimp.utils; pygimp.utils.gimp_test_filename = '$TEST_FILE'"
(echo "$header" && tail -n +2 "$TEST_FILE") | "$GIMP_EXE" -nis --batch-interpreter "python-fu-eval" -b - --quit

View File

@@ -1,11 +1,18 @@
#!/usr/bin/env python3
import gi
from gi.repository import Babl, Gegl, Gimp, Gio
import inspect
import re
import os
import sys
import tempfile
import urllib.request
gimp_test_filename = ''
def gimp_assert(subtest_name, test):
def gimp_assert(subtest_name, test, image=None, outpath=None, cmp_data_path=None):
'''
Please call me like this, for instance, if I were testing if gimp_image_new()
succeeded:
@@ -17,6 +24,120 @@ def gimp_assert(subtest_name, test):
sys.stderr.write("ERROR: {} - line {}: {}\n".format(gimp_test_filename,
frames[1].lineno,
subtest_name))
if image is not None and outpath is not None:
Gimp.file_save(Gimp.RunMode.NONINTERACTIVE, image,
Gio.file_new_for_path(outpath),
None)
sys.stderr.write(" Test file saved as: {}\n".format(outpath))
if outpath[-4:] == '.xcf':
data_path = outpath[:-4] + '.data'
Gimp.file_save(Gimp.RunMode.NONINTERACTIVE, image,
Gio.file_new_for_path(data_path),
None)
sys.stderr.write(" Render file saved as: {}\n".format(data_path))
if cmp_data_path is not None:
cmp_img = None
img_width = image.get_width()
img_height = image.get_height()
proc = Gimp.get_pdb().lookup_procedure('file-raw-load')
config = proc.create_config()
config.set_property('run-mode', Gimp.RunMode.NONINTERACTIVE)
config.set_property('width', img_width)
config.set_property('height', img_height)
config.set_property('pixel-format', 'rgba-8bpc')
cmp_data_uri = None
result = None
if os.path.isfile(cmp_data_path):
config.set_property('file', Gio.file_new_for_path(cmp_data_path))
result = proc.run(config)
else:
cmp_data_basename = os.path.basename(cmp_data_path)
cmp_data_uri = os.path.join('https://download.gimp.org/users/jehan/unit-tests/', cmp_data_basename)
# Unfortunately this doesn't work with a remote file directly.
# TODO.
#config.set_property('file', Gio.file_new_for_uri(cmp_data_uri))
try:
with urllib.request.urlopen(cmp_data_uri) as remote:
with tempfile.NamedTemporaryFile() as tmpfile:
tmpfile.write(remote.read())
config.set_property('file', Gio.file_new_for_path(tmpfile.name))
result = proc.run(config)
tmpfile.close()
except urllib.error.HTTPError:
pass
status = None
if result is not None:
status = result.index(0)
if status == Gimp.PDBStatusType.SUCCESS:
cmp_img = result.index(1)
elif os.path.isfile(cmp_data_path):
sys.stderr.write(" Failed to load for statistical comparison: {}\n".format(cmp_data_path))
if cmp_img is None:
sys.stderr.write(" To get statistical comparison, store reference data in: {}\n".format(cmp_data_path))
else:
layer = image.merge_visible_layers(Gimp.MergeType.CLIP_TO_IMAGE)
buffer = layer.get_buffer()
rect = buffer.get_extent()
data = buffer.get(rect, 1.0, "R'G'B'A u8", Gegl.AbyssPolicy.BLACK)
cmp_buffer = cmp_img.get_layers()[0].get_buffer()
cmp_data = cmp_buffer.get(rect, 1.0, "R'G'B'A u8", Gegl.AbyssPolicy.BLACK)
sys.stderr.write(" Comparison with {}:\n".format(cmp_data_path if cmp_data_uri is None else cmp_data_uri))
n_diff_pixels = 0
n_perceptually_identical = 0
n_one_off = 0
num_samples = 4
num_identical_samples = 4
num_one_off_samples = 4
for x in range(img_width):
for y in range(img_height):
pos = (x + y * img_width) * 4
r1 = data[pos]
r2 = cmp_data[pos]
g1 = data[pos + 1]
g2 = cmp_data[pos + 1]
b1 = data[pos + 2]
b2 = cmp_data[pos + 2]
a1 = data[pos + 3]
a2 = cmp_data[pos + 3]
if r1 != r2 or g1 != g2 or b1 != b2 or a1 != a2:
c1 = Gegl.Color.new("black")
c1.set_rgba_with_space(r1/255, g1/255, b1/255, a1/255, Babl.space("sRGB"))
c2 = Gegl.Color.new("black")
c2.set_rgba_with_space(r2/256, g2/255, b2/255, a2/255, Babl.space("sRGB"))
n_diff_pixels += 1
if Gimp.color_is_perceptually_identical(c1, c2):
if num_identical_samples > 0:
sys.stderr.write(" - Example of differing pixel (yet perceptually identical) at {}x{}: ({}, {}, {}, {}) vs. ({}, {}, {}, {})\n".format(x, y, r1, g1, b1, a1, r2, g2, b2, a2))
num_identical_samples -= 1
n_perceptually_identical += 1
elif abs(r1 - r2) < 2 and abs(g1 - g2) < 2 and abs(b1 - b2) < 2 and abs(a1 - a2) < 2:
if num_one_off_samples > 0:
sys.stderr.write(" - Example of differing pixel (off-by-one) at {}x{}: ({}, {}, {}, {}) vs. ({}, {}, {}, {})\n".format(x, y, r1, g1, b1, a1, r2, g2, b2, a2))
num_one_off_samples -= 1
n_one_off += 1
else:
if num_samples > 0:
sys.stderr.write(" - Example of differing pixel at {}x{}: ({}, {}, {}, {}) vs. ({}, {}, {}, {})\n".format(x, y, r1, g1, b1, a1, r2, g2, b2, a2))
num_samples -= 1
sys.stderr.write(" - {} pixels are different\n".format(n_diff_pixels))
sys.stderr.write(" - Among them {} different pixels are perceptually identical\n".format(n_perceptually_identical))
sys.stderr.write(" - Among them {} different pixels are off by one\n".format(n_one_off))
if n_diff_pixels == n_perceptually_identical + n_one_off:
sys.stderr.write(" - All different pixels are either perceptually identical or off by one\n")
cmp_img.delete()
if image is not None:
image.delete()
sys.stderr.write("***** END FAILED SUBTEST ******\n\n")
assert test

View File

@@ -1997,6 +1997,8 @@ subdir('gimp-data/images/')
# Unit testing
subdir('libgimp/tests')
subdir('app/operations/layer-modes-legacy/tests')
subdir('app/operations/layer-modes/tests')
# Docs
subdir('docs')