diff --git a/core/tools/toif_convert.py b/core/tools/toif_convert.py deleted file mode 100755 index 2df587145d..0000000000 --- a/core/tools/toif_convert.py +++ /dev/null @@ -1,40 +0,0 @@ -#!/usr/bin/env python3 - -import click -from PIL import Image - -from trezorlib import toif - - -@click.command() -@click.argument("infile", type=click.File("rb")) -@click.argument("outfile", type=click.File("wb")) -def toif_convert(infile, outfile): - """Convert any image format to/from TOIF or vice-versa. - - \b - Examples: - toif_convert.py somefile.jpg outfile.toif - toif_convert.py infile.toif outfile.png - - \b - # ensure gray-scale output TOIF - mogrify -colorspace gray icon.png - toif_convert.py icon.png icon.toif - """ - if infile.name.endswith(".toif") or infile.name == "-": - toi = toif.from_bytes(infile.read()) - im = toi.to_image() - im.save(outfile) - - elif outfile.name.endswith(".toif") or outfile.name == "-": - im = Image.open(infile) - toi = toif.from_image(im) - outfile.write(toi.to_bytes()) - - else: - raise click.ClickException("At least one of the arguments must end with .toif") - - -if __name__ == "__main__": - toif_convert() diff --git a/poetry.lock b/poetry.lock index eff6cdbafa..7c9f41fba7 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1475,6 +1475,24 @@ files = [ [package.extras] tests = ["pytest", "pytest-cov"] +[[package]] +name = "toiftool" +version = "0.1.0" +description = "" +optional = false +python-versions = ">=3.8" +files = [] +develop = true + +[package.dependencies] +click = ">=7.0,<9.0" +Pillow = "^9" +trezor = ">=0.13" + +[package.source] +type = "directory" +url = "python/tools/toiftool" + [[package]] name = "toml" version = "0.10.2" @@ -1776,4 +1794,4 @@ testing = ["func-timeout", "jaraco.itertools", "pytest (>=6)", "pytest-black (>= [metadata] lock-version = "2.0" python-versions = "^3.7" -content-hash = "3e671a37f0bf4b63d64d3f17c54f7a87006d65f4747335cb6d86cc07166764ed" +content-hash = "40852ed8dec342c2386342584a7bd656d2e45bade0e78a15a17bf4b7b62240af" diff --git a/pyproject.toml b/pyproject.toml index deea0d694e..c7fdb97fa1 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -74,6 +74,7 @@ vulture = "^2.6" # tools binsize = "^0.1.3" +toiftool = {path = "./python/tools/toiftool", develop = true, python = ">=3.8"} [tool.poetry.dev-dependencies] scan-build = "*" diff --git a/python/tools/toiftool/README.md b/python/tools/toiftool/README.md new file mode 100644 index 0000000000..29dd586239 --- /dev/null +++ b/python/tools/toiftool/README.md @@ -0,0 +1,40 @@ +# TOIF Tool + +A helpful CLI tool to work with TOIFs. + +## Installation + +The command `toiftool` is available within firmware repository's Poetry shell. + +To install the tool separate from the firmware repository, run: + +```bash +pip install -e . +``` + +## Displaying TOIFs + +To display a TOIF image in a viewer, run: + +```bash +toiftool show +``` + +## Converting TOIFs + +To convert to or from TOIF, run: + +```bash +toiftool convert +toiftool convert +``` + +The in/out format will be determined by the file extension. + +## Getting information about TOIFs + +To get information about a TOIF, run: + +```bash +toiftool info +``` diff --git a/python/tools/toiftool/pyproject.toml b/python/tools/toiftool/pyproject.toml new file mode 100644 index 0000000000..4b9fc679d0 --- /dev/null +++ b/python/tools/toiftool/pyproject.toml @@ -0,0 +1,19 @@ +[tool.poetry] +name = "toiftool" +version = "0.1.0" +description = "" +authors = ["matejcik "] +readme = "README.md" + +[tool.poetry.dependencies] +python = ">=3.8" +trezor = ">=0.13" +click = ">=7.0,<9.0" +Pillow = "^9" + +[build-system] +requires = ["poetry-core"] +build-backend = "poetry.core.masonry.api" + +[tool.poetry.scripts] +toiftool = "toiftool:cli" diff --git a/python/tools/toiftool/toiftool.py b/python/tools/toiftool/toiftool.py new file mode 100644 index 0000000000..4b46141692 --- /dev/null +++ b/python/tools/toiftool/toiftool.py @@ -0,0 +1,68 @@ +#!/usr/bin/env python3 +from typing import BinaryIO + +import click +from PIL import Image + +from trezorlib import toif + + +@click.group() +def cli(): + """TOIF toolkit.""" + + +@cli.command() +@click.argument("infile", type=click.File("rb")) +@click.argument("outfile", type=click.File("wb")) +def convert(infile: BinaryIO, outfile: BinaryIO) -> None: + """Convert any image format to/from TOIF or vice-versa. + + \b + Examples: + toiftool convert somefile.jpg outfile.toif + toiftool convert infile.toif outfile.png + + \b + # ensure gray-scale output TOIF + mogrify -colorspace gray icon.png + toiftool convert icon.png icon.toif + """ + if infile.name.endswith(".toif") or infile.name == "-": + toi = toif.from_bytes(infile.read()) + im = toi.to_image() + im.save(outfile) + + elif outfile.name.endswith(".toif") or outfile.name == "-": + im = Image.open(infile) + toi = toif.from_image(im) + outfile.write(toi.to_bytes()) + + else: + raise click.ClickException("At least one of the arguments must end with .toif") + + +@cli.command() +@click.argument("toif_file", type=click.File("rb")) +def info(toif_file: BinaryIO) -> None: + """Print information about TOIF file.""" + toif_bytes = toif_file.read() + toi = toif.from_bytes(toif_bytes) + click.echo(f"TOIF file: {toif_file.name}") + click.echo(f"Size: {len(toif_bytes)} bytes") + w, h = toi.size + click.echo(f"Dimensions: {w}x{h}") + click.echo(f"Format: {toi.mode}") + + +@cli.command() +@click.argument("toif_file", type=click.File("rb")) +def show(toif_file: BinaryIO) -> None: + """Show TOIF file in a new window.""" + toi = toif.from_bytes(toif_file.read()) + im = toi.to_image() + im.show() + + +if __name__ == "__main__": + cli()