#!/usr/bin/env python3 # Copyright (c) the JPEG XL Project Authors. All rights reserved. # # Use of this source code is governed by a BSD-style # license that can be found in the LICENSE file. """Produces demos for how progressive-saliency encoding would look like. As long as we do not have a progressive decoder that allows showing images generated from partially-available data, we can resort to building animated gifs that show how progressive loading would look like. Method: 1. JPEG-XL encode the image, but stop at the pre-final (2nd) step. 2. Use separate tool to compute a heatmap which shows where differences between the pre-final and final image are expected to be perceptually worst. 3. Use this heatmap to JPEG-XL encode the image with the final step split into 'salient parts only' and 'non-salient parts'. Generate a sequence of images that stop decoding after the 1st, 2nd, 3rd, 4th step. JPEG-XL decode these truncated images back to PNG. 4. Measure byte sizes of the truncated-encoded images. 5. Build an animated GIF with variable delays by calling ImageMagick's `convert` command. """ from __future__ import absolute_import from __future__ import division from __future__ import print_function from six.moves import zip import ast # For ast.literal_eval() only. import os import re import shlex import subprocess import sys _BLOCKSIZE = 8 _CONF_PARSERS = dict( keep_tempfiles=lambda s: bool(ast.literal_eval(s)), heatmap_command=shlex.split, simulated_progressive_loading_time_sec=float, simulated_progressive_loading_delay_until_looparound_sec=float, jpegxl_encoder=shlex.split, jpegxl_decoder=shlex.split, blurring=lambda s: s.split(), ) def parse_config(config_filename): """Parses the configuration file.""" conf = {} re_comment = re.compile(r'^\s*(?:#.*)?$') re_param = re.compile(r'^(?P