| #!/usr/bin/env python3 |
| # SPDX-License-Identifier: Apache-2.0 |
| # ----------------------------------------------------------------------------- |
| # Copyright 2021 Arm Limited |
| # |
| # Licensed under the Apache License, Version 2.0 (the "License"); you may not |
| # use this file except in compliance with the License. You may obtain a copy |
| # of the License at: |
| # |
| # http://www.apache.org/licenses/LICENSE-2.0 |
| # |
| # Unless required by applicable law or agreed to in writing, software |
| # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
| # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the |
| # License for the specific language governing permissions and limitations |
| # under the License. |
| # ----------------------------------------------------------------------------- |
| """ |
| The ``astc_quality_test`` utility provides a tool to sweep quality settings. |
| """ |
| |
| import numpy as np |
| import re |
| import subprocess as sp |
| import sys |
| |
| |
| def get_psnr_pattern(): |
| return r"\s*PSNR \(LDR-RGB\):\s*([0-9.]*) dB" |
| |
| |
| def get_coding_rate_pattern(): |
| return r"\s*Coding rate:\s*([0-9.]*) MT/s" |
| |
| |
| def parse_output(output): |
| # Regex pattern for image quality |
| patternPSNR = re.compile(get_psnr_pattern()) |
| patternCRate = re.compile(get_coding_rate_pattern()) |
| |
| # Extract results from the log |
| runPSNR = None |
| runCRate = None |
| |
| for line in output: |
| match = patternPSNR.match(line) |
| if match: |
| runPSNR = float(match.group(1)) |
| |
| match = patternCRate.match(line) |
| if match: |
| runCRate = float(match.group(1)) |
| |
| assert runPSNR is not None, "No coding PSNR found" |
| assert runCRate is not None, "No coding rate found" |
| return (runPSNR, runCRate) |
| |
| def execute(command): |
| """ |
| Run a subprocess with the specified command. |
| |
| Args: |
| command (list(str)): The list of command line arguments. |
| |
| Returns: |
| list(str): The output log (stdout) split into lines. |
| """ |
| try: |
| result = sp.run(command, stdout=sp.PIPE, stderr=sp.PIPE, |
| check=True, universal_newlines=True) |
| except (OSError, sp.CalledProcessError): |
| print("ERROR: Test run failed") |
| print(" + %s" % " ".join(command)) |
| qcommand = ["\"%s\"" % x for x in command] |
| print(" + %s" % ", ".join(qcommand)) |
| sys.exit(1) |
| |
| return result.stdout.splitlines() |
| |
| def main(): |
| """ |
| The main function. |
| |
| Returns: |
| int: The process return code. |
| """ |
| for block in ("4x4", "5x5", "6x6", "8x8", "10x10"): |
| |
| for quality in range (0, 101, 2): |
| |
| resultsQ = [] |
| resultsS = [] |
| |
| if (quality < 40): |
| repeats = 20 |
| elif (quality < 75): |
| repeats = 10 |
| else: |
| repeats = 5 |
| |
| for _ in range(0, repeats): |
| command = [ |
| "./astcenc/astcenc-avx2", |
| "-tl", |
| "./Test/Images/Kodak/LDR-RGB/ldr-rgb-kodak23.png", |
| "/dev/null", |
| block, |
| "%s" % quality, |
| "-silent" |
| ] |
| |
| stdout = execute(command) |
| psnr, mts = parse_output(stdout) |
| resultsQ.append(psnr) |
| resultsS.append(mts) |
| |
| print("%s, %u, %0.3f, %0.3f" % (block, quality, np.mean(resultsS), np.mean(resultsQ))) |
| |
| |
| return 0 |
| |
| |
| if __name__ == "__main__": |
| sys.exit(main()) |