mirror of
https://github.com/drewcassidy/quicktex.git
synced 2024-09-13 06:37:34 +00:00
Add decode command
This commit is contained in:
parent
8b6ea69300
commit
156880d430
@ -1,6 +1,6 @@
|
||||
import click
|
||||
from encode import encode
|
||||
from decode import decode
|
||||
from quicktex.cli.encode import encode
|
||||
from quicktex.cli.decode import decode
|
||||
|
||||
|
||||
@click.group()
|
||||
|
@ -1,16 +1,46 @@
|
||||
import click
|
||||
import io
|
||||
import os
|
||||
import os.path
|
||||
import quicktex.dds as dds
|
||||
from PIL import Image
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
@click.command()
|
||||
@click.option('-f', '--flip', type=bool, default=True, show_default=True, help="vertically flip image after converting")
|
||||
@click.option('-f', '--flip', help="vertically flip image after converting")
|
||||
@click.option('-r', '--remove', help="remove input images after converting")
|
||||
@click.option('-o', '--output', help="output file name. Must only specify one input image.")
|
||||
@click.option('-s', '--suffix', type=str, default='', help="suffix to append to output file(s).")
|
||||
@click.argument('filenames', nargs=-1, type=click.Path(exists=True))
|
||||
def decode(flip, remove, output, suffix, filenames):
|
||||
@click.option('-x', '--extension',
|
||||
type=str, default='png',
|
||||
help="extension to use for output. ignored if output is a single file. output filetype is deduced from this")
|
||||
@click.option('-o', '--output',
|
||||
type=click.Path(exists=True, readable=True), default='.',
|
||||
help="output file name or directory. If outputting to a file, input filenames must be only a single item.")
|
||||
@click.argument('filenames',
|
||||
nargs=-1,
|
||||
type=click.Path(exists=True, readable=True))
|
||||
def decode(flip, remove, suffix, extension, output, filenames):
|
||||
"""Decode an input texture file to an image"""
|
||||
|
||||
assert len(filenames) != 0, 'No input files provided.'
|
||||
outpath = Path(output)
|
||||
|
||||
if outpath.is_file():
|
||||
assert len(filenames) == 1, 'Provided an output file with multiple inputs.'
|
||||
|
||||
def make_outpath(p):
|
||||
return outpath
|
||||
else:
|
||||
def make_outpath(p):
|
||||
return outpath / (p.stem + suffix + '.' + extension)
|
||||
|
||||
for filename in filenames:
|
||||
assert filename.endswith(".dds"), "Incorrect file extension"
|
||||
filepath = Path(filename)
|
||||
outpath = make_outpath(filepath)
|
||||
|
||||
assert filepath.is_file(), f"{filename} is not a file!"
|
||||
assert filepath.suffix == '.dds', f"{filename} is not a DDS file!"
|
||||
|
||||
ddsfile = dds.read(filepath)
|
||||
image = ddsfile.decode()
|
||||
image.save(outpath)
|
||||
|
@ -5,10 +5,10 @@ import os
|
||||
import struct
|
||||
import typing
|
||||
import quicktex.image_utils
|
||||
import quicktex.s3tc.bc1
|
||||
import quicktex.s3tc.bc3
|
||||
import quicktex.s3tc.bc4
|
||||
import quicktex.s3tc.bc5
|
||||
import quicktex.s3tc.bc1 as bc1
|
||||
import quicktex.s3tc.bc3 as bc3
|
||||
import quicktex.s3tc.bc4 as bc4
|
||||
import quicktex.s3tc.bc5 as bc5
|
||||
from PIL import Image
|
||||
|
||||
|
||||
@ -22,10 +22,10 @@ class DDSFormat:
|
||||
|
||||
|
||||
dds_formats = [
|
||||
DDSFormat('BC1', quicktex.s3tc.bc1.BC1Texture, quicktex.s3tc.bc1.BC1Encoder, quicktex.s3tc.bc1.BC1Decoder, 'DXT1'),
|
||||
DDSFormat('BC3', quicktex.s3tc.bc3.BC3Texture, quicktex.s3tc.bc3.BC3Encoder, quicktex.s3tc.bc3.BC3Decoder, 'DXT5'),
|
||||
DDSFormat('BC4', quicktex.s3tc.bc4.BC4Texture, quicktex.s3tc.bc4.BC4Encoder, quicktex.s3tc.bc4.BC4Decoder, 'ATI1'),
|
||||
DDSFormat('BC5', quicktex.s3tc.bc5.BC5Texture, quicktex.s3tc.bc5.BC5Encoder, quicktex.s3tc.bc5.BC5Decoder, 'ATI2'),
|
||||
DDSFormat('BC1', bc1.BC1Texture, bc1.BC1Encoder, bc1.BC1Decoder, 'DXT1'),
|
||||
DDSFormat('BC3', bc3.BC3Texture, bc3.BC3Encoder, bc3.BC3Decoder, 'DXT5'),
|
||||
DDSFormat('BC4', bc4.BC4Texture, bc4.BC4Encoder, bc4.BC4Decoder, 'ATI1'),
|
||||
DDSFormat('BC5', bc5.BC5Texture, bc5.BC5Encoder, bc5.BC5Decoder, 'ATI2'),
|
||||
]
|
||||
|
||||
|
||||
@ -194,16 +194,17 @@ def read(path: os.PathLike) -> DDSFile:
|
||||
dds = DDSFile()
|
||||
|
||||
# READ HEADER
|
||||
assert struct.unpack('<I', file.read(4)) == DDSFile.header_bytes, "Incorrect DDS header size."
|
||||
header_bytes = struct.unpack('<I', file.read(4))[0]
|
||||
assert header_bytes == DDSFile.header_bytes, "Incorrect DDS header size."
|
||||
|
||||
dds.flags = DDSFlags(struct.unpack('<I', file.read(4))) # read flags enum
|
||||
dds.flags = DDSFlags(struct.unpack('<I', file.read(4))[0]) # read flags enum
|
||||
dds.size = struct.unpack('<2I', file.read(8))[::-1] # read dimensions
|
||||
dds.pitch, dds.depth, dds.mipmap_count = struct.unpack('<3I', file.read(12))
|
||||
file.read(44) # skip 44 unused bytes of data
|
||||
|
||||
assert struct.unpack('<I', file.read(4)) == 32, "Incorrect pixel format size."
|
||||
assert struct.unpack('<I', file.read(4))[0] == 32, "Incorrect pixel format size."
|
||||
|
||||
dds.pf_flags = PFFlags(struct.unpack('<I', file.read(4)))
|
||||
dds.pf_flags = PFFlags(struct.unpack('<I', file.read(4))[0])
|
||||
dds.four_cc = file.read(4).decode()
|
||||
dds.pixel_size, *pixel_bitmasks = struct.unpack('<5I', file.read(20))
|
||||
|
||||
@ -235,7 +236,7 @@ def read(path: os.PathLike) -> DDSFile:
|
||||
texture = dds.format.texture(*size) # make a new blocktexture of the current mip size
|
||||
nbytes = file.readinto(texture)
|
||||
|
||||
assert nbytes == texture.size, 'Unexpected end of file'
|
||||
assert nbytes == texture.nbytes, 'Unexpected end of file'
|
||||
|
||||
dds.textures.append(texture)
|
||||
|
||||
|
@ -27,11 +27,8 @@ def mip_sizes(dimensions: typing.Tuple[int, int], mip_count: typing.Optional[int
|
||||
|
||||
for mip in range(mip_count):
|
||||
chain.append(dimensions)
|
||||
dimensions = tuple([max(dim // 2, 1) for dim in dimensions])
|
||||
|
||||
if all([dim == 1 for dim in dimensions]):
|
||||
break # we've reached a 1x1 mip and can get no smaller
|
||||
dimensions = tuple([max(dim // 2, 1) for dim in dimensions])
|
||||
|
||||
return chain
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user