UI: Asset Shelf (Experimental Feature) #104831
|
@ -933,6 +933,49 @@ if(WITH_CODEC_FFMPEG)
|
|||
)
|
||||
endif()
|
||||
|
||||
if(NOT OPENIMAGEIO_IDIFF)
|
||||
message(STATUS "Disabling ImBuf image format tests because OIIO idiff does not exist")
|
||||
else()
|
||||
SET(OPTIONAL_FORMATS "")
|
||||
if(WITH_IMAGE_CINEON)
|
||||
set(OPTIONAL_FORMATS "${OPTIONAL_FORMATS} CINEON")
|
||||
endif()
|
||||
if(WITH_IMAGE_HDR)
|
||||
set(OPTIONAL_FORMATS "${OPTIONAL_FORMATS} HDR")
|
||||
endif()
|
||||
if(WITH_IMAGE_OPENEXR)
|
||||
set(OPTIONAL_FORMATS "${OPTIONAL_FORMATS} OPENEXR")
|
||||
endif()
|
||||
if(WITH_IMAGE_OPENJPEG)
|
||||
set(OPTIONAL_FORMATS "${OPTIONAL_FORMATS} OPENJPEG")
|
||||
endif()
|
||||
if(WITH_IMAGE_TIFF)
|
||||
set(OPTIONAL_FORMATS "${OPTIONAL_FORMATS} TIFF")
|
||||
endif()
|
||||
if(WITH_IMAGE_WEBP)
|
||||
set(OPTIONAL_FORMATS "${OPTIONAL_FORMATS} WEBP")
|
||||
endif()
|
||||
|
||||
add_blender_test(
|
||||
bf_imbuf_save
|
||||
--python ${CMAKE_CURRENT_LIST_DIR}/bl_imbuf_save.py
|
||||
--
|
||||
-test_dir "${TEST_SRC_DIR}/imbuf_io"
|
||||
-output_dir "${TEST_OUT_DIR}/imbuf_io/save"
|
||||
-idiff "${OPENIMAGEIO_IDIFF}"
|
||||
-optional_formats "${OPTIONAL_FORMATS}"
|
||||
)
|
||||
|
||||
add_blender_test(
|
||||
bf_imbuf_load
|
||||
--python ${CMAKE_CURRENT_LIST_DIR}/bl_imbuf_load.py
|
||||
--
|
||||
-test_dir "${TEST_SRC_DIR}/imbuf_io"
|
||||
-output_dir "${TEST_OUT_DIR}/imbuf_io/load"
|
||||
-idiff "${OPENIMAGEIO_IDIFF}"
|
||||
-optional_formats "${OPTIONAL_FORMATS}"
|
||||
)
|
||||
endif()
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# SEQUENCER RENDER TESTS
|
||||
|
|
|
@ -0,0 +1,179 @@
|
|||
# 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=}"
|
||||
|
||||
# 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 BaseException as e:
|
||||
if self.verbose:
|
||||
print_message(e.output.decode("utf-8", 'ignore'))
|
||||
failed = True
|
||||
else:
|
||||
if not self.update:
|
||||
return False
|
||||
|
||||
failed = True
|
||||
|
||||
if failed and self.update:
|
||||
# Update reference if requested.
|
||||
ref_metadata_path.write_text(actual_metadata, encoding="utf-8")
|
||||
failed = False
|
||||
|
||||
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.skip_if_format_missing("HDR")
|
||||
|
||||
self.check("*.hdr")
|
||||
|
||||
def test_load_targa(self):
|
||||
self.check("*.tga")
|
||||
|
||||
def test_load_tiff(self):
|
||||
self.skip_if_format_missing("TIFF")
|
||||
|
||||
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.skip_if_format_missing("CINEON")
|
||||
|
||||
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 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('-idiff', 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()
|
|
@ -0,0 +1,272 @@
|
|||
# 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
|
||||
|
||||
TEMPLATE_RGBA08 = "template-rgba08.png"
|
||||
TEMPLATE_RGBA32 = "template-rgba32.exr"
|
||||
|
||||
|
||||
class ImBufTest(AbstractImBufTest):
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
AbstractImBufTest.init(args)
|
||||
|
||||
if cls.update:
|
||||
os.makedirs(cls.reference_dir, exist_ok=True)
|
||||
|
||||
def _load_template_image(self, name, template_name):
|
||||
image_path = str(self.test_dir.joinpath(template_name))
|
||||
bpy.ops.image.open(filepath=image_path)
|
||||
img = bpy.data.images[template_name]
|
||||
img.name = name
|
||||
return img
|
||||
|
||||
def _setup_image(self, src, ext, settings):
|
||||
scene = bpy.data.scenes[0]
|
||||
image_settings = scene.render.image_settings
|
||||
|
||||
# Make an appropriate filename which embeds all relevant settings and
|
||||
# set the file output parameters for the exact configuration we want
|
||||
name = ""
|
||||
for s in settings:
|
||||
if s == "color_depth":
|
||||
name += str(settings[s]).rjust(2, '0') + "-"
|
||||
else:
|
||||
name += str(settings[s]) + "-"
|
||||
|
||||
setattr(image_settings, s, settings[s])
|
||||
|
||||
image_name = name[:-1].lower() + "__from__" + src + "." + ext
|
||||
|
||||
return image_name
|
||||
|
||||
def _save_image(self, src, image_name):
|
||||
loaders = {
|
||||
"rgba08": lambda name: self._load_template_image(name, TEMPLATE_RGBA08),
|
||||
"rgba32": lambda name: self._load_template_image(name, TEMPLATE_RGBA32),
|
||||
}
|
||||
|
||||
# Load the template image and assign it the image name
|
||||
img = loaders[src](image_name)
|
||||
|
||||
# Save the image in the desired format with the desired settings
|
||||
scene = bpy.data.scenes[0]
|
||||
ref_image_path = self.reference_dir.joinpath(img.name)
|
||||
out_image_path = self.output_dir.joinpath(img.name)
|
||||
img.save_render(str(out_image_path), scene=scene)
|
||||
|
||||
# Completely remove image in case it was modified during save
|
||||
img.user_clear()
|
||||
bpy.data.images.remove(img)
|
||||
return ref_image_path, out_image_path
|
||||
|
||||
def _validate(self, ref_image_path, out_image_path):
|
||||
return self.call_idiff(ref_image_path, out_image_path)
|
||||
|
||||
def check(self, src, ext, settings):
|
||||
image_name = self._setup_image(src, ext, settings)
|
||||
print_message(image_name, 'SUCCESS', 'RUN')
|
||||
|
||||
ref_image_path, out_image_path = self._save_image(src, image_name)
|
||||
|
||||
if not self._validate(ref_image_path, out_image_path):
|
||||
self.errors += 1
|
||||
print_message("Save result is different from reference image")
|
||||
print_message(ref_image_path.name, 'FAILURE', 'FAILED')
|
||||
else:
|
||||
print_message(ref_image_path.name, 'SUCCESS', 'OK')
|
||||
|
||||
|
||||
# autopep8: off
|
||||
class ImBufSaveTest(ImBufTest):
|
||||
def test_save_bmp(self):
|
||||
self.check(src="rgba08", ext="bmp", settings={"file_format": "BMP", "color_mode": "BW"})
|
||||
self.check(src="rgba08", ext="bmp", settings={"file_format": "BMP", "color_mode": "RGB"})
|
||||
|
||||
self.check(src="rgba32", ext="bmp", settings={"file_format": "BMP", "color_mode": "BW"})
|
||||
self.check(src="rgba32", ext="bmp", settings={"file_format": "BMP", "color_mode": "RGB"})
|
||||
|
||||
def test_save_png(self):
|
||||
self.check(src="rgba08", ext="png", settings={"file_format": "PNG", "color_mode": "BW", "color_depth": "8", "compression": 15})
|
||||
self.check(src="rgba08", ext="png", settings={"file_format": "PNG", "color_mode": "RGB", "color_depth": "8", "compression": 15})
|
||||
self.check(src="rgba08", ext="png", settings={"file_format": "PNG", "color_mode": "RGBA", "color_depth": "8", "compression": 15})
|
||||
self.check(src="rgba08", ext="png", settings={"file_format": "PNG", "color_mode": "BW", "color_depth": "16", "compression": 25})
|
||||
self.check(src="rgba08", ext="png", settings={"file_format": "PNG", "color_mode": "RGB", "color_depth": "16", "compression": 25})
|
||||
self.check(src="rgba08", ext="png", settings={"file_format": "PNG", "color_mode": "RGBA", "color_depth": "16", "compression": 25})
|
||||
|
||||
self.check(src="rgba32", ext="png", settings={"file_format": "PNG", "color_mode": "BW", "color_depth": "8", "compression": 15})
|
||||
self.check(src="rgba32", ext="png", settings={"file_format": "PNG", "color_mode": "RGB", "color_depth": "8", "compression": 15})
|
||||
self.check(src="rgba32", ext="png", settings={"file_format": "PNG", "color_mode": "RGBA", "color_depth": "8", "compression": 15})
|
||||
self.check(src="rgba32", ext="png", settings={"file_format": "PNG", "color_mode": "BW", "color_depth": "16", "compression": 25})
|
||||
self.check(src="rgba32", ext="png", settings={"file_format": "PNG", "color_mode": "RGB", "color_depth": "16", "compression": 25})
|
||||
self.check(src="rgba32", ext="png", settings={"file_format": "PNG", "color_mode": "RGBA", "color_depth": "16", "compression": 25})
|
||||
|
||||
def test_save_exr(self):
|
||||
self.skip_if_format_missing("OPENEXR")
|
||||
|
||||
self.check(src="rgba08", ext="exr", settings={"file_format": "OPEN_EXR", "color_mode": "BW", "color_depth": "16", "exr_codec": "ZIP"})
|
||||
self.check(src="rgba08", ext="exr", settings={"file_format": "OPEN_EXR", "color_mode": "RGB", "color_depth": "16", "exr_codec": "DWAA"})
|
||||
self.check(src="rgba08", ext="exr", settings={"file_format": "OPEN_EXR", "color_mode": "RGBA", "color_depth": "16", "exr_codec": "DWAB"})
|
||||
self.check(src="rgba08", ext="exr", settings={"file_format": "OPEN_EXR", "color_mode": "BW", "color_depth": "32", "exr_codec": "DWAB"})
|
||||
self.check(src="rgba08", ext="exr", settings={"file_format": "OPEN_EXR", "color_mode": "RGB", "color_depth": "32", "exr_codec": "DWAA"})
|
||||
self.check(src="rgba08", ext="exr", settings={"file_format": "OPEN_EXR", "color_mode": "RGBA", "color_depth": "32", "exr_codec": "ZIP"})
|
||||
|
||||
self.check(src="rgba32", ext="exr", settings={"file_format": "OPEN_EXR", "color_mode": "BW", "color_depth": "16", "exr_codec": "ZIP"})
|
||||
self.check(src="rgba32", ext="exr", settings={"file_format": "OPEN_EXR", "color_mode": "RGB", "color_depth": "16", "exr_codec": "DWAA"})
|
||||
self.check(src="rgba32", ext="exr", settings={"file_format": "OPEN_EXR", "color_mode": "RGBA", "color_depth": "16", "exr_codec": "DWAB"})
|
||||
self.check(src="rgba32", ext="exr", settings={"file_format": "OPEN_EXR", "color_mode": "BW", "color_depth": "32", "exr_codec": "DWAB"})
|
||||
self.check(src="rgba32", ext="exr", settings={"file_format": "OPEN_EXR", "color_mode": "RGB", "color_depth": "32", "exr_codec": "DWAA"})
|
||||
self.check(src="rgba32", ext="exr", settings={"file_format": "OPEN_EXR", "color_mode": "RGBA", "color_depth": "32", "exr_codec": "ZIP"})
|
||||
|
||||
def test_save_hdr(self):
|
||||
self.skip_if_format_missing("HDR")
|
||||
|
||||
self.check(src="rgba08", ext="hdr", settings={"file_format": "HDR", "color_mode": "BW"})
|
||||
self.check(src="rgba08", ext="hdr", settings={"file_format": "HDR", "color_mode": "RGB"})
|
||||
|
||||
self.check(src="rgba32", ext="hdr", settings={"file_format": "HDR", "color_mode": "BW"})
|
||||
self.check(src="rgba32", ext="hdr", settings={"file_format": "HDR", "color_mode": "RGB"})
|
||||
|
||||
def test_save_targa(self):
|
||||
self.check(src="rgba08", ext="tga", settings={"file_format": "TARGA", "color_mode": "BW"})
|
||||
self.check(src="rgba08", ext="tga", settings={"file_format": "TARGA", "color_mode": "RGB"})
|
||||
self.check(src="rgba08", ext="tga", settings={"file_format": "TARGA", "color_mode": "RGBA"})
|
||||
|
||||
self.check(src="rgba32", ext="tga", settings={"file_format": "TARGA", "color_mode": "BW"})
|
||||
self.check(src="rgba32", ext="tga", settings={"file_format": "TARGA", "color_mode": "RGB"})
|
||||
self.check(src="rgba32", ext="tga", settings={"file_format": "TARGA", "color_mode": "RGBA"})
|
||||
|
||||
def test_save_targa_raw(self):
|
||||
self.check(src="rgba08", ext="tga", settings={"file_format": "TARGA_RAW", "color_mode": "BW"})
|
||||
self.check(src="rgba08", ext="tga", settings={"file_format": "TARGA_RAW", "color_mode": "RGB"})
|
||||
self.check(src="rgba08", ext="tga", settings={"file_format": "TARGA_RAW", "color_mode": "RGBA"})
|
||||
|
||||
self.check(src="rgba32", ext="tga", settings={"file_format": "TARGA_RAW", "color_mode": "BW"})
|
||||
self.check(src="rgba32", ext="tga", settings={"file_format": "TARGA_RAW", "color_mode": "RGB"})
|
||||
self.check(src="rgba32", ext="tga", settings={"file_format": "TARGA_RAW", "color_mode": "RGBA"})
|
||||
|
||||
def test_save_tiff(self):
|
||||
self.skip_if_format_missing("TIFF")
|
||||
|
||||
self.check(src="rgba08", ext="tif", settings={"file_format": "TIFF", "color_mode": "BW", "color_depth": "8", "tiff_codec": "DEFLATE"})
|
||||
self.check(src="rgba08", ext="tif", settings={"file_format": "TIFF", "color_mode": "RGB", "color_depth": "8", "tiff_codec": "LZW"})
|
||||
self.check(src="rgba08", ext="tif", settings={"file_format": "TIFF", "color_mode": "RGBA", "color_depth": "8", "tiff_codec": "PACKBITS"})
|
||||
self.check(src="rgba08", ext="tif", settings={"file_format": "TIFF", "color_mode": "BW", "color_depth": "16", "tiff_codec": "PACKBITS"})
|
||||
self.check(src="rgba08", ext="tif", settings={"file_format": "TIFF", "color_mode": "RGB", "color_depth": "16", "tiff_codec": "LZW"})
|
||||
self.check(src="rgba08", ext="tif", settings={"file_format": "TIFF", "color_mode": "RGBA", "color_depth": "16", "tiff_codec": "DEFLATE"})
|
||||
|
||||
self.check(src="rgba32", ext="tif", settings={"file_format": "TIFF", "color_mode": "BW", "color_depth": "8", "tiff_codec": "DEFLATE"})
|
||||
self.check(src="rgba32", ext="tif", settings={"file_format": "TIFF", "color_mode": "RGB", "color_depth": "8", "tiff_codec": "LZW"})
|
||||
self.check(src="rgba32", ext="tif", settings={"file_format": "TIFF", "color_mode": "RGBA", "color_depth": "8", "tiff_codec": "PACKBITS"})
|
||||
self.check(src="rgba32", ext="tif", settings={"file_format": "TIFF", "color_mode": "BW", "color_depth": "16", "tiff_codec": "PACKBITS"})
|
||||
self.check(src="rgba32", ext="tif", settings={"file_format": "TIFF", "color_mode": "RGB", "color_depth": "16", "tiff_codec": "LZW"})
|
||||
self.check(src="rgba32", ext="tif", settings={"file_format": "TIFF", "color_mode": "RGBA", "color_depth": "16", "tiff_codec": "DEFLATE"})
|
||||
|
||||
def test_save_jpeg(self):
|
||||
self.check(src="rgba08", ext="jpg", settings={"file_format": "JPEG", "color_mode": "BW", "quality": 90})
|
||||
self.check(src="rgba08", ext="jpg", settings={"file_format": "JPEG", "color_mode": "RGB", "quality": 90})
|
||||
|
||||
self.check(src="rgba32", ext="jpg", settings={"file_format": "JPEG", "color_mode": "BW", "quality": 70})
|
||||
self.check(src="rgba32", ext="jpg", settings={"file_format": "JPEG", "color_mode": "RGB", "quality": 70})
|
||||
|
||||
def test_save_jpeg2000(self):
|
||||
self.skip_if_format_missing("OPENJPEG")
|
||||
|
||||
# Is there a better combination of settings we can use so there's not so many?
|
||||
# Is this a good mix?
|
||||
self.check(src="rgba08", ext="jp2", settings={"file_format": "JPEG2000", "color_mode": "BW", "color_depth": "8", "jpeg2k_codec": "JP2", "quality": 90})
|
||||
self.check(src="rgba08", ext="jp2", settings={"file_format": "JPEG2000", "color_mode": "BW", "color_depth": "12", "jpeg2k_codec": "JP2", "quality": 90})
|
||||
self.check(src="rgba08", ext="j2c", settings={"file_format": "JPEG2000", "color_mode": "BW", "color_depth": "16", "jpeg2k_codec": "J2K", "quality": 90})
|
||||
self.check(src="rgba08", ext="jp2", settings={"file_format": "JPEG2000", "color_mode": "RGB", "color_depth": "8", "jpeg2k_codec": "JP2", "quality": 90})
|
||||
self.check(src="rgba08", ext="jp2", settings={"file_format": "JPEG2000", "color_mode": "RGB", "color_depth": "12", "jpeg2k_codec": "JP2", "quality": 90})
|
||||
self.check(src="rgba08", ext="j2c", settings={"file_format": "JPEG2000", "color_mode": "RGB", "color_depth": "16", "jpeg2k_codec": "J2K", "quality": 90})
|
||||
self.check(src="rgba08", ext="jp2", settings={"file_format": "JPEG2000", "color_mode": "RGBA", "color_depth": "8", "jpeg2k_codec": "JP2", "quality": 90})
|
||||
self.check(src="rgba08", ext="jp2", settings={"file_format": "JPEG2000", "color_mode": "RGBA", "color_depth": "12", "jpeg2k_codec": "JP2", "quality": 90})
|
||||
self.check(src="rgba08", ext="j2c", settings={"file_format": "JPEG2000", "color_mode": "RGBA", "color_depth": "16", "jpeg2k_codec": "J2K", "quality": 90})
|
||||
|
||||
self.check(src="rgba32", ext="jp2", settings={"file_format": "JPEG2000", "color_mode": "BW", "color_depth": "8", "jpeg2k_codec": "JP2", "quality": 70})
|
||||
self.check(src="rgba32", ext="jp2", settings={"file_format": "JPEG2000", "color_mode": "BW", "color_depth": "12", "jpeg2k_codec": "JP2", "quality": 70})
|
||||
self.check(src="rgba32", ext="j2c", settings={"file_format": "JPEG2000", "color_mode": "BW", "color_depth": "16", "jpeg2k_codec": "J2K", "quality": 70})
|
||||
self.check(src="rgba32", ext="jp2", settings={"file_format": "JPEG2000", "color_mode": "RGB", "color_depth": "8", "jpeg2k_codec": "JP2", "quality": 70})
|
||||
self.check(src="rgba32", ext="jp2", settings={"file_format": "JPEG2000", "color_mode": "RGB", "color_depth": "12", "jpeg2k_codec": "JP2", "quality": 70})
|
||||
self.check(src="rgba32", ext="j2c", settings={"file_format": "JPEG2000", "color_mode": "RGB", "color_depth": "16", "jpeg2k_codec": "J2K", "quality": 70})
|
||||
self.check(src="rgba32", ext="jp2", settings={"file_format": "JPEG2000", "color_mode": "RGBA", "color_depth": "8", "jpeg2k_codec": "JP2", "quality": 70})
|
||||
self.check(src="rgba32", ext="jp2", settings={"file_format": "JPEG2000", "color_mode": "RGBA", "color_depth": "12", "jpeg2k_codec": "JP2", "quality": 70})
|
||||
self.check(src="rgba32", ext="j2c", settings={"file_format": "JPEG2000", "color_mode": "RGBA", "color_depth": "16", "jpeg2k_codec": "J2K", "quality": 70})
|
||||
|
||||
# Note: The 'use_jpeg2k_cinema_preset' option mandates very large images
|
||||
# self.check(src="rgba08", ext="jpg", settings={"file_format":"JPEG2000", "color_mode":"RGBA", "color_depth":"8", "jpeg2k_codec":"JP2", "use_jpeg2k_cinema_preset":True, "use_jpeg2k_cinema_48":False, "use_jpeg2k_ycc":False, "quality":70})
|
||||
# self.check(src="rgba32", ext="jpg", settings={"file_format":"JPEG2000", "color_mode":"RGBA", "color_depth":"8", "jpeg2k_codec":"JP2", "use_jpeg2k_cinema_preset":True, "use_jpeg2k_cinema_48":False, "use_jpeg2k_ycc":False, "quality":70})
|
||||
|
||||
self.check(src="rgba08", ext="jp2", settings={"file_format": "JPEG2000", "color_mode": "RGBA", "color_depth": "12", "jpeg2k_codec": "JP2", "use_jpeg2k_cinema_preset": False, "use_jpeg2k_cinema_48": True, "use_jpeg2k_ycc": False, "quality": 70})
|
||||
self.check(src="rgba32", ext="jp2", settings={"file_format": "JPEG2000", "color_mode": "RGBA", "color_depth": "12", "jpeg2k_codec": "JP2", "use_jpeg2k_cinema_preset": False, "use_jpeg2k_cinema_48": True, "use_jpeg2k_ycc": False, "quality": 70})
|
||||
|
||||
self.check(src="rgba08", ext="jp2", settings={"file_format": "JPEG2000", "color_mode": "RGBA", "color_depth": "16", "jpeg2k_codec": "JP2", "use_jpeg2k_cinema_preset": False, "use_jpeg2k_cinema_48": False, "use_jpeg2k_ycc": True, "quality": 70})
|
||||
self.check(src="rgba32", ext="jp2", settings={"file_format": "JPEG2000", "color_mode": "RGBA", "color_depth": "16", "jpeg2k_codec": "JP2", "use_jpeg2k_cinema_preset": False, "use_jpeg2k_cinema_48": False, "use_jpeg2k_ycc": True, "quality": 70})
|
||||
|
||||
def test_save_dpx(self):
|
||||
self.skip_if_format_missing("CINEON")
|
||||
|
||||
self.check(src="rgba08", ext="dpx", settings={"file_format": "DPX", "color_mode": "RGB", "color_depth": "8", "use_cineon_log": False})
|
||||
self.check(src="rgba08", ext="dpx", settings={"file_format": "DPX", "color_mode": "RGB", "color_depth": "12", "use_cineon_log": False})
|
||||
self.check(src="rgba08", ext="dpx", settings={"file_format": "DPX", "color_mode": "RGB", "color_depth": "16", "use_cineon_log": False})
|
||||
self.check(src="rgba08", ext="dpx", settings={"file_format": "DPX", "color_mode": "RGBA", "color_depth": "10", "use_cineon_log": True})
|
||||
self.check(src="rgba08", ext="dpx", settings={"file_format": "DPX", "color_mode": "RGBA", "color_depth": "12", "use_cineon_log": True})
|
||||
self.check(src="rgba08", ext="dpx", settings={"file_format": "DPX", "color_mode": "RGBA", "color_depth": "16", "use_cineon_log": True})
|
||||
|
||||
self.check(src="rgba32", ext="dpx", settings={"file_format": "DPX", "color_mode": "RGB", "color_depth": "8", "use_cineon_log": False})
|
||||
self.check(src="rgba32", ext="dpx", settings={"file_format": "DPX", "color_mode": "RGB", "color_depth": "12", "use_cineon_log": False})
|
||||
self.check(src="rgba32", ext="dpx", settings={"file_format": "DPX", "color_mode": "RGB", "color_depth": "16", "use_cineon_log": False})
|
||||
self.check(src="rgba32", ext="dpx", settings={"file_format": "DPX", "color_mode": "RGBA", "color_depth": "10", "use_cineon_log": True})
|
||||
self.check(src="rgba32", ext="dpx", settings={"file_format": "DPX", "color_mode": "RGBA", "color_depth": "12", "use_cineon_log": True})
|
||||
self.check(src="rgba32", ext="dpx", settings={"file_format": "DPX", "color_mode": "RGBA", "color_depth": "16", "use_cineon_log": True})
|
||||
|
||||
def test_save_cineon(self):
|
||||
self.skip_if_format_missing("CINEON")
|
||||
|
||||
self.check(src="rgba08", ext="cin", settings={"file_format": "CINEON", "color_mode": "RGB"})
|
||||
self.check(src="rgba32", ext="cin", settings={"file_format": "CINEON", "color_mode": "RGB"})
|
||||
|
||||
def test_save_webp(self):
|
||||
self.skip_if_format_missing("WEBP")
|
||||
|
||||
self.check(src="rgba08", ext="webp", settings={"file_format": "WEBP", "color_mode": "RGB", "quality": 90})
|
||||
self.check(src="rgba08", ext="webp", settings={"file_format": "WEBP", "color_mode": "RGBA", "quality": 90})
|
||||
|
||||
self.check(src="rgba32", ext="webp", settings={"file_format": "WEBP", "color_mode": "RGB", "quality": 70})
|
||||
self.check(src="rgba32", ext="webp", settings={"file_format": "WEBP", "color_mode": "RGBA", "quality": 70})
|
||||
# autopep8: on
|
||||
|
||||
|
||||
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('-idiff', 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()
|
|
@ -0,0 +1,46 @@
|
|||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
import sys
|
||||
|
||||
|
||||
class COLORS_ANSI:
|
||||
RED = '\033[00;31m'
|
||||
GREEN = '\033[00;32m'
|
||||
ENDC = '\033[0m'
|
||||
|
||||
|
||||
class COLORS_NONE:
|
||||
RED = ''
|
||||
GREEN = ''
|
||||
ENDC = ''
|
||||
|
||||
|
||||
COLORS = COLORS_NONE
|
||||
|
||||
|
||||
def use_message_colors():
|
||||
global COLORS, COLORS_ANSI
|
||||
COLORS = COLORS_ANSI
|
||||
|
||||
|
||||
def print_message(message, type=None, status=''):
|
||||
if type == 'SUCCESS':
|
||||
print(COLORS.GREEN, end="")
|
||||
elif type == 'FAILURE':
|
||||
print(COLORS.RED, end="")
|
||||
status_text = ...
|
||||
if status == 'RUN':
|
||||
status_text = " RUN "
|
||||
elif status == 'OK':
|
||||
status_text = " OK "
|
||||
elif status == 'PASSED':
|
||||
status_text = " PASSED "
|
||||
elif status == 'FAILED':
|
||||
status_text = " FAILED "
|
||||
else:
|
||||
status_text = status
|
||||
if status_text:
|
||||
print("[{}]" . format(status_text), end="")
|
||||
print(COLORS.ENDC, end="")
|
||||
print(" {}" . format(message))
|
||||
sys.stdout.flush()
|
|
@ -0,0 +1,92 @@
|
|||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
import os
|
||||
import pathlib
|
||||
import shutil
|
||||
import subprocess
|
||||
import unittest
|
||||
|
||||
from .colored_print import (print_message, use_message_colors)
|
||||
|
||||
|
||||
class AbstractImBufTest(unittest.TestCase):
|
||||
@classmethod
|
||||
def init(cls, args):
|
||||
cls.test_dir = pathlib.Path(args.test_dir)
|
||||
cls.reference_dir = pathlib.Path(args.test_dir).joinpath("reference")
|
||||
cls.reference_load_dir = pathlib.Path(args.test_dir).joinpath("reference_load")
|
||||
cls.output_dir = pathlib.Path(args.output_dir)
|
||||
cls.diff_dir = pathlib.Path(args.output_dir).joinpath("diff")
|
||||
cls.idiff = pathlib.Path(args.idiff)
|
||||
cls.optional_formats = args.optional_formats
|
||||
|
||||
os.makedirs(cls.diff_dir, exist_ok=True)
|
||||
|
||||
cls.errors = 0
|
||||
cls.fail_threshold = 0.001
|
||||
cls.fail_percent = 1
|
||||
cls.verbose = os.environ.get("BLENDER_VERBOSE") is not None
|
||||
cls.update = os.getenv('BLENDER_TEST_UPDATE') is not None
|
||||
if os.environ.get("BLENDER_TEST_COLOR") is not None:
|
||||
use_message_colors()
|
||||
|
||||
def setUp(self):
|
||||
self.errors = 0
|
||||
print_message("")
|
||||
|
||||
def tearDown(self):
|
||||
if self.errors > 0:
|
||||
self.fail("{} errors encountered" . format(self.errors))
|
||||
|
||||
def skip_if_format_missing(self, format):
|
||||
if self.optional_formats.find(format) < 0:
|
||||
self.skipTest("format not available")
|
||||
|
||||
def call_idiff(self, ref_path, out_path):
|
||||
ref_filepath = str(ref_path)
|
||||
out_filepath = str(out_path)
|
||||
out_name = out_path.name
|
||||
if os.path.exists(ref_filepath):
|
||||
# Diff images test with threshold.
|
||||
command = (
|
||||
str(self.idiff),
|
||||
"-fail", str(self.fail_threshold),
|
||||
"-failpercent", str(self.fail_percent),
|
||||
ref_filepath,
|
||||
out_filepath,
|
||||
)
|
||||
try:
|
||||
subprocess.check_output(command)
|
||||
failed = False
|
||||
except subprocess.CalledProcessError as e:
|
||||
if self.verbose:
|
||||
print_message(e.output.decode("utf-8", 'ignore'))
|
||||
failed = e.returncode != 1
|
||||
else:
|
||||
if not self.update:
|
||||
return False
|
||||
|
||||
failed = True
|
||||
|
||||
if failed and self.update:
|
||||
# Update reference image if requested.
|
||||
shutil.copy(out_filepath, ref_filepath)
|
||||
failed = False
|
||||
|
||||
# Generate diff image.
|
||||
diff_img = str(self.diff_dir.joinpath(out_name + ".diff.png"))
|
||||
command = (
|
||||
str(self.idiff),
|
||||
"-o", diff_img,
|
||||
"-abs", "-scale", "16",
|
||||
ref_filepath,
|
||||
out_filepath
|
||||
)
|
||||
|
||||
try:
|
||||
subprocess.check_output(command)
|
||||
except subprocess.CalledProcessError as e:
|
||||
if self.verbose:
|
||||
print_message(e.output.decode("utf-8", 'ignore'))
|
||||
|
||||
return not failed
|
|
@ -14,44 +14,7 @@ import sys
|
|||
import time
|
||||
|
||||
from . import global_report
|
||||
|
||||
|
||||
class COLORS_ANSI:
|
||||
RED = '\033[00;31m'
|
||||
GREEN = '\033[00;32m'
|
||||
ENDC = '\033[0m'
|
||||
|
||||
|
||||
class COLORS_DUMMY:
|
||||
RED = ''
|
||||
GREEN = ''
|
||||
ENDC = ''
|
||||
|
||||
|
||||
COLORS = COLORS_DUMMY
|
||||
|
||||
|
||||
def print_message(message, type=None, status=''):
|
||||
if type == 'SUCCESS':
|
||||
print(COLORS.GREEN, end="")
|
||||
elif type == 'FAILURE':
|
||||
print(COLORS.RED, end="")
|
||||
status_text = ...
|
||||
if status == 'RUN':
|
||||
status_text = " RUN "
|
||||
elif status == 'OK':
|
||||
status_text = " OK "
|
||||
elif status == 'PASSED':
|
||||
status_text = " PASSED "
|
||||
elif status == 'FAILED':
|
||||
status_text = " FAILED "
|
||||
else:
|
||||
status_text = status
|
||||
if status_text:
|
||||
print("[{}]" . format(status_text), end="")
|
||||
print(COLORS.ENDC, end="")
|
||||
print(" {}" . format(message))
|
||||
sys.stdout.flush()
|
||||
from .colored_print import (print_message, use_message_colors)
|
||||
|
||||
|
||||
def blend_list(dirpath, device, blacklist):
|
||||
|
@ -151,8 +114,7 @@ class Report:
|
|||
self.update = os.getenv('BLENDER_TEST_UPDATE') is not None
|
||||
|
||||
if os.environ.get("BLENDER_TEST_COLOR") is not None:
|
||||
global COLORS, COLORS_ANSI
|
||||
COLORS = COLORS_ANSI
|
||||
use_message_colors()
|
||||
|
||||
self.failed_tests = ""
|
||||
self.passed_tests = ""
|
||||
|
|
Loading…
Reference in New Issue