freedoom/scripts/fix-deutex-pngs
Steven Elliott 6e0dc42013 build: Add fix-pngs make target and scripts
Add scripts:
  fix-deutex-pngs - Apply the output of deutex to the build
  map-color-index - Map from one color index to another

Script fix-deutex-pngs is to standardize PNGs by applying the result of
the expanding IWADs produced with deutex to the build. It is invoked by
build target fix-deutex-pngs

Script map-color-index can map from one color index to another. Most
likely it will be used to map form legacy transparency 255 to similar
color 133, which can be done by build target
fix-legacy-transparency-pngs.
2023-06-17 15:52:14 -04:00

130 lines
4.3 KiB
Python
Executable file

#!/usr/bin/env python3
# SPDX-License-Identifier: BSD-3-Clause
#
# deutex-pngs - Use deutex to process the PNGs in order to standardize them.
#
# Often there are PNG files that are not in the preferred format (that are not
# indexed, or that are indexed with something other than PLAYPAL, that have
# chunks that are not supported, etc.). For example, gAMA and similar color
# correction chunks only cause the PNG to look different in image editors than
# they do in game engines, which is bad. It's also for the palette to have
# invalid colors, or to be missing colors, which makes the PNG hard to work
# with. The solution is to use deutex to extract the WADs produced by the build,
# and apply the PNGs exctracted to the build.
#
# This programs strives to be safe by only applying PNGs to the build when the
# PNG already exists in the build since otherwise the relationship between the
# extracted PNG and the build PNG is not clear. If -a, --all is specified then
# the PNG will be be copied regardless.
# When multiple WADs are passed to the script the each WAD effectively
# overwrites the previous ones, so the preferred WAD should be passed last.
# Normally this script is invoked by "make":
# make fix-deutex-pngs
# Imports
import argparse
import os
import shutil
import sys
import tempfile
import time
# Globals. Alphabetical.
# Command line arguments.
args = {}
# A count of unexpected errors. These are errors other than what this script
# intends to check for, such as the file not being readable. These errors
# suggest that something is fundamentally wrong, and that the results should
# not be trusted.
unexpected_count = 0
# Parse the command line arguments and store the result in 'args'.
def parse_args():
global args
parser = argparse.ArgumentParser(
description="Use deutex to process the PNGs in order to standardize them.",
formatter_class=argparse.ArgumentDefaultsHelpFormatter)
# The following is sorted by long argument.
parser.add_argument(
"-a",
"--all",
action="store_true",
help="Copy all PNGs, not just the ones that already exist in the build.")
parser.add_argument(
"-d",
"--doom2",
default="bootstrap",
help="The '-doom2' deutex argument.")
parser.add_argument(
"wads",
metavar="WAD",
nargs="+",
help="WAD files to apply. The preferred WAD should be last.")
args = parser.parse_args()
return args
# Main enty point.
def main():
parse_args()
process_wads()
summarize()
# Process a WAD file.
def process_wad(wad_path):
global unexpected_count
wad_dir = os.path.dirname(wad_path)
wad_name = os.path.basename(wad_path).split(".")[0]
print()
print("Processing WAD", wad_path)
pngs_copied = 0
with tempfile.TemporaryDirectory(prefix=wad_name + "-") as tmp_dir:
print('created temporary directory', tmp_dir)
ec = os.system("deutex -doom2 " + args.doom2 + " -dir " + tmp_dir +
" -x " + wad_path)
if ec:
print("deutex failed with exit code", ec, "for WAD", wad_path,
file=sys.stderr)
unexpected_count += 1
return
# Successful deutex from this point forward.
before = time.time()
for dirpath, dirnames, filenames in os.walk(tmp_dir):
for png_base in filenames:
if not png_base.lower().endswith(".png"):
continue
png_source_path = os.path.join(dirpath, png_base)
png_relative = os.path.relpath(png_source_path, tmp_dir)
if args.all or os.path.exists(png_relative):
shutil.copyfile(png_source_path, png_relative)
pngs_copied += 1
print("Processed WAD", wad_path, "copied", pngs_copied, "PNG files.")
# Process multiple WAD files.
def process_wads():
for wad_path in args.wads:
process_wad(wad_path)
# Summarize what happened, and then exit with the appropriate exit code.
def summarize():
print()
print("Processed", len(args.wads), "WAD files.")
if unexpected_count:
print("There were", unexpected_count, "unexpected errors - see above. " +
"The output produced should not be trusted.", file=sys.stderr)
sys.exit(1)
# So that this script may be accessed as a module.
if __name__ == "__main__":
main()