1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210
|
# SPDX-FileCopyrightText: 2023 Blender Authors
#
# SPDX-License-Identifier: GPL-2.0-or-later
import os
import pathlib
import sys
import unittest
import bpy
sys.path.append(str(pathlib.Path(__file__).parent.absolute()))
from modules.colored_print import print_message
from modules.imbuf_test import AbstractImBufTest
args = None
class ImBufTest(AbstractImBufTest):
@classmethod
def setUpClass(cls):
AbstractImBufTest.init(args)
if cls.update:
os.makedirs(cls.reference_load_dir, exist_ok=True)
def _get_image_files(self, file_pattern):
return [f for f in pathlib.Path(self.reference_dir).glob(file_pattern)]
def _validate_metadata(self, img, ref_metadata_path, out_metadata_path):
channels = img.channels
is_float = img.is_float
colorspace = img.colorspace_settings.name
alpha_mode = img.alpha_mode
actual_metadata = f"{channels=} {is_float=} {colorspace=} {alpha_mode=}"
expected_metadata = ""
# Save actual metadata
out_metadata_path.write_text(actual_metadata, encoding="utf-8")
if ref_metadata_path.exists():
# Compare with expected
try:
expected_metadata = ref_metadata_path.read_text(encoding="utf-8")
failed = not (actual_metadata == expected_metadata)
except Exception as ex:
if self.verbose:
print_message(ex.output.decode("utf-8", 'ignore'))
failed = True
else:
if not self.update:
return False
failed = True
if failed:
if self.update:
# Update reference if requested.
ref_metadata_path.write_text(actual_metadata, encoding="utf-8")
failed = False
else:
print_message(
"Expected [{}] but got [{}]".format(expected_metadata, actual_metadata))
return not failed
def _save_exr(self, img, out_exr_path):
scene = bpy.data.scenes[0]
image_settings = scene.render.image_settings
image_settings.file_format = "OPEN_EXR"
image_settings.color_mode = "RGBA"
image_settings.color_depth = "32"
image_settings.exr_codec = "ZIP"
img.save_render(str(out_exr_path), scene=scene)
def _validate_pixels(self, img, ref_exr_path, out_exr_path):
self._save_exr(img, out_exr_path)
return self.call_idiff(ref_exr_path, out_exr_path)
def check(self, file_pattern):
image_files = self._get_image_files(file_pattern)
if len(image_files) == 0:
self.fail(f"No images found for pattern {file_pattern}")
for image_path in image_files:
print_message(image_path.name, 'SUCCESS', 'RUN')
# Load the image under test
bpy.ops.image.open(filepath=str(image_path))
img = bpy.data.images[image_path.name]
# Compare the image with our exr/metadata references
exr_filename = image_path.with_suffix(".exr").name
metadata_filename = image_path.with_suffix(".txt").name
ref_exr_path = self.reference_load_dir.joinpath(exr_filename)
ref_metadata_path = self.reference_load_dir.joinpath(metadata_filename)
out_exr_path = self.output_dir.joinpath(exr_filename)
out_metadata_path = self.output_dir.joinpath(metadata_filename)
res1 = self._validate_metadata(img, ref_metadata_path, out_metadata_path)
res2 = self._validate_pixels(img, ref_exr_path, out_exr_path)
if not res1 or not res2:
self.errors += 1
print_message("Results are different from reference data")
print_message(image_path.name, 'FAILURE', 'FAILED')
else:
print_message(image_path.name, 'SUCCESS', 'OK')
class ImBufLoadTest(ImBufTest):
def test_load_bmp(self):
self.check("*.bmp")
def test_load_png(self):
self.check("*.png")
def test_load_exr(self):
self.skip_if_format_missing("OPENEXR")
self.check("*.exr")
def test_load_hdr(self):
self.check("*.hdr")
def test_load_targa(self):
self.check("*.tga")
def test_load_tiff(self):
self.check("*.tif")
def test_load_jpeg(self):
self.check("*.jpg")
def test_load_jpeg2000(self):
self.skip_if_format_missing("OPENJPEG")
self.check("*.jp2")
self.check("*.j2c")
def test_load_dpx(self):
self.check("*.dpx")
def test_load_cineon(self):
self.skip_if_format_missing("CINEON")
self.check("*.cin")
def test_load_webp(self):
self.skip_if_format_missing("WEBP")
self.check("*.webp")
def test_load_psd(self):
self.check("*.psd")
class ImBufBrokenTest(AbstractImBufTest):
@classmethod
def setUpClass(cls):
AbstractImBufTest.init(args)
def _get_image_files(self, file_pattern):
return [f for f in (self.test_dir / "broken_images").glob(file_pattern)]
def check(self, file_pattern):
image_files = self._get_image_files(file_pattern)
print(image_files)
if len(image_files) == 0:
self.fail(f"No images found for pattern {file_pattern}")
for image_path in image_files:
print_message(image_path.name, 'SUCCESS', 'RUN')
bpy.ops.image.open(filepath=str(image_path))
class ImBufLoadBrokenTest(ImBufBrokenTest):
def test_load_exr(self):
self.skip_if_format_missing("OPENEXR")
self.check("*.exr")
def main():
global args
import argparse
if '--' in sys.argv:
argv = [sys.argv[0]] + sys.argv[sys.argv.index('--') + 1:]
else:
argv = sys.argv
parser = argparse.ArgumentParser()
parser.add_argument('-test_dir', required=True, type=pathlib.Path)
parser.add_argument('-output_dir', required=True, type=pathlib.Path)
parser.add_argument('-oiiotool', required=True, type=pathlib.Path)
parser.add_argument('-optional_formats', required=True)
args, remaining = parser.parse_known_args(argv)
unittest.main(argv=remaining)
if __name__ == '__main__':
main()
|