diff --git a/.github/workflows/publish-pyktx.yml b/.github/workflows/publish-pyktx.yml
new file mode 100644
index 0000000000..b928c11684
--- /dev/null
+++ b/.github/workflows/publish-pyktx.yml
@@ -0,0 +1,126 @@
+# Copyright 2023 Shukant Pal
+# SPDX-License-Identifier: Apache-2.0
+
+name: Publish Python 🐍 distribution 📦 to PyPI or TestPyPI
+
+# https://github.com/pypa/gh-action-pypi-publish strongly recommends a
+# separate publishing job when building platform-specific distribution
+# packages, hence this.
+#
+# This should not be run until the release artifacts have been deployed.
+# The only way I can see to trigger this automatically is to have all
+# platform builds in a single workflow file and use on: `workflow_run`
+# so this is triggered when that workflow completes. Once all platform
+# builds are moved to GitHub Actions we can try making each platform
+# workflow reusable and making another workflow that calls each of
+# them via `uses` and use `on: workflow_run` here.
+#
+# We also have to figure out how to determine if the workflow deployed
+# to releases. Maybe can use the GitHub REST API to get an artifact
+# from the triggering workflow that is set only when deploying
+# releases. See https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#using-data-from-the-triggering-workflow.
+# Alternatively maybe there is some way of querying what triggered
+# the workflow that we can test in an `if:` in the job as noted below.
+
+on:
+ workflow_dispatch:
+ inputs:
+# repository-url:
+# description: 'destination repository'
+# required: true
+# default: 'https://pypi.org'
+# type: choice
+# options:
+# - https://test.pypi.org
+# - https://pypi.org
+ test-pypi:
+ type: boolean
+ description: 'Deploy to test pypi registry'
+ required: true
+ default: false
+
+# Example to try in future.
+# workflow_run:
+# workflows: [KTX-Software Build All]
+# types:
+# - completed
+# An unknown is how to limit the trigger to when deploy is run in
+# Windows CI which is happens when that workflow is triggered by
+# a push with the tags below.
+# push:
+# # Trigger on push of release tags. There is no way to limit the trigger
+# # to a specific branch. A later build step checks for the main branch.
+# tags:
+# - 'v[0-9]+\.[0-9]+\.[0-9]+'
+# - 'v[0-9]+\.[0-9]+\.[0-9]+-*'
+
+jobs:
+ publish-to-pypi:
+ name: Publish Python 🐍 distribution 📦 to PyPI
+ if: test-pypi == false
+ runs-on: ubuntu-latest
+ environment:
+ name: pypi
+ url: https://pypi.org/p/pyktx
+ permissions:
+ id-token: write # IMPORTANT: this permission is mandatory for trusted publishing
+ # When using workflow_run it is necessary to check for successful
+ # completion of the workflow with
+ #if: ${{ github.event.workflow_run.conclusion == 'success' }}
+ # Maybe it is possible to test for a release tag here too.
+ steps:
+ - name: Download latest release metadata
+ run: |
+ curl \
+ -H "Accept: application/vnd.github+json" \
+ -H "X-GitHub-Api-Version: 2022-11-28" \
+ -o latest.json \
+ https://api.github.com/repos/KhronosGroup/KTX-Software/releases/latest
+ - name: Filter out pyktx- assets
+ run: |
+ jq '.assets | map(select(.name | startswith("pyktx-"))) | map(.browser_download_url)' < latest.json > pyktx.json
+ - name: Create dist directory
+ run: |
+ mkdir dist
+ - name: Download assets
+ run: |
+ cd dist; jq -c '.[]' ../pyktx.json | xargs -L 1 curl -O -J; cd..
+ - name: Publish distribution 📦 to PyPI
+ uses: pypa/gh-action-pypi-publish@release/v1
+ with:
+ password: ${{ secrets.PYPI_API_TOKEN }}
+
+ publish-to-testpypi:
+ name: Publish Python 🐍 distribution 📦 to TestPyPI
+ if: test-pypi
+ runs-on: ubuntu-latest
+ environment:
+ name: testpypi
+ url: https://pypi.org/p/pyktx
+ permissions:
+ id-token: write # IMPORTANT: this permission is mandatory for trusted publishing
+ # When using workflow_run it is necessary to check for successful
+ # completion of the workflow with
+ #if: ${{ github.event.workflow_run.conclusion == 'success' }}
+ # Maybe it is possible to test for a release tag here too.
+ steps:
+ - name: Download latest release metadata
+ run: |
+ curl \
+ -H "Accept: application/vnd.github+json" \
+ -H "X-GitHub-Api-Version: 2022-11-28" \
+ -o latest.json \
+ https://api.github.com/repos/KhronosGroup/KTX-Software/releases/latest
+ - name: Filter out pyktx- assets
+ run: |
+ jq '.assets | map(select(.name | startswith("pyktx-"))) | map(.browser_download_url)' < latest.json > pyktx.json
+ - name: Create dist directory
+ run: |
+ mkdir dist
+ - name: Download assets
+ run: |
+ cd dist; jq -c '.[]' ../pyktx.json | xargs -L 1 curl -O -J; cd..
+ - name: Publish distribution 📦 to TestPyPI
+ uses: pypa/gh-action-pypi-publish@release/v1
+ with:
+ password: ${{ secrets.PYPI_API_TOKEN }}
diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml
deleted file mode 100644
index dffb146955..0000000000
--- a/.github/workflows/publish.yml
+++ /dev/null
@@ -1,38 +0,0 @@
-# Copyright 2023 Shukant Pal
-# SPDX-License-Identifier: Apache-2.0
-name: Publish to PyPI
-
-on:
- workflow_dispatch:
- push:
- # Trigger on push of release tags. There is no way to limit the trigger
- # to a specific branch. A later build step checks for the main branch.
- tags:
- - 'v[0-9]+\.[0-9]+\.[0-9]+'
- - 'v[0-9]+\.[0-9]+\.[0-9]+-*'
-
-jobs:
- pypi:
- runs-on: ubuntu-latest
- if: endsWith(github.event.base_ref, 'main')
- steps:
- - name: Download latest release metadata
- run: |
- curl \
- -H "Accept: application/vnd.github+json" \
- -H "X-GitHub-Api-Version: 2022-11-28" \
- -o latest.json \
- https://api.github.com/repos/KhronosGroup/KTX-Software/releases/latest
- - name: Filter out pyktx- assets
- run: |
- jq '.assets | map(select(.name | startswith("pyktx-"))) | map(.browser_download_url)' < latest.json > pyktx.json
- - name: Create dist directory
- run: |
- mkdir dist
- - name: Download assets
- run: |
- cd dist; jq -c '.[]' ../pyktx.json | xargs -L 1 curl -O -J; cd..
- - name: Publish distribution 📦 to PyPI
- uses: pypa/gh-action-pypi-publish@release/v1
- with:
- password: ${{ secrets.PYPI_API_TOKEN }}
\ No newline at end of file
diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml
index c942ccb527..c3c09359ed 100644
--- a/.github/workflows/windows.yml
+++ b/.github/workflows/windows.yml
@@ -225,7 +225,7 @@ jobs:
# is spawned from some parent Powershell so it does not pick up
# the changes from the registry. Use Chocolatey's helper to
# pull in the changes.
- # After import `refreshenv` is an alias for
+ # After import, `refreshenv` is an alias for
# Update-SessionEnvironment. Without the import refreshenv will end
# up calling the cmd.exe version, which won't help Powershell, and
# Update-SessionEnvironment will not exist.
@@ -263,18 +263,20 @@ jobs:
path: ${{env.BUILD_DIR}}/KTX-Software-*.exe*
- name: Upload pyktx artifacts
- if: matrix.options.package == 'YES' && matrix.options.py
+ if: matrix.options.package == 'YES' && matrix.options.py == 'ON'
uses: kittaakos/upload-artifact-as-is@v0
with:
path: ${{env.BUILD_DIR}}/interface/python_binding/dist/
- - name: Upload To Release
+ - name: Upload to Release
uses: softprops/action-gh-release@v1
if: matrix.options.package == 'YES' && matrix.toolset == 'CLangCL' && github.event_name == 'push' && github.ref_type == 'tag'
with:
draft: true
prerelease: true
- files: ${{env.BUILD_DIR}}/KTX-Software-*.exe*
+ files: |
+ ${{env.BUILD_DIR}}/KTX-Software-*.exe*
+ ${{env.BUILD_DIR}}/interface/python_binding/dist/pyktx-*
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
diff --git a/.gitignore b/.gitignore
index ff627cae65..e26a0c5b00 100644
--- a/.gitignore
+++ b/.gitignore
@@ -56,3 +56,6 @@ cmake-build-*
# Temps used for Windows signing on CI
appveyor-tools
the_khronos_group_inc.p12
+
+# Place for random developer test files.
+/testground/
diff --git a/.travis.yml b/.travis.yml
index 3f9ef3e425..04d5073d2a 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -396,11 +396,25 @@ deploy:
- provider: script
edge: true
- script: ruby ci_scripts/github_release.rb -s ${GITHUB_TOKEN} -r ${TRAVIS_REPO_SLUG} -c $REL_DESC_FILE -t ${TRAVIS_TAG} --overwrite true --draft true --prerelease true $BUILD_DIR/KTX-Software-*-* $BUILD_DIR/interface/python_binding/dist/*.whl
+ # nullglob is to force a null string when there are no *.whl files.
+ script: ruby ci_scripts/github_release.rb -s ${GITHUB_TOKEN} -r ${TRAVIS_REPO_SLUG} -c $REL_DESC_FILE -t ${TRAVIS_TAG} --overwrite true --draft true --prerelease true $BUILD_DIR/KTX-Software-*-*
on:
tags: true
#branch: master
condition: $PACKAGE = "YES" && $TRAVIS_TAG =~ ^v[0-9].*
+
+ # Separate deploy for pyktx because the linux runners use sh not bash
+ # for the "script" so `shopt -s nullglob; ci_scripts/github_release.rb ...`
+ # does not work to avoid passing `.../*.whl` to github_release when
+ # FEATURE_PY not ON.
+ - provider: script
+ edge: true
+ script: ruby ci_scripts/github_release.rb -s ${GITHUB_TOKEN} -r ${TRAVIS_REPO_SLUG} -c $REL_DESC_FILE -t ${TRAVIS_TAG} --overwrite true --draft true --prerelease true $BUILD_DIR/interface/python_binding/dist/*.whl
+ on:
+ tags: true
+ #branch: master
+ condition: $PACKAGE = "YES" && $TRAVIS_TAG =~ ^v[0-9].* && $FEATURE_PY = "ON"
+
# ---------------------------------------------------------
# vim:ai:ts=4:sts=2:sw=2:expandtab
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 454c0f04b3..4c17d9cb34 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -877,6 +877,7 @@ if(EMSCRIPTEN)
"SHELL:-s EXPORT_NAME=LIBKTX"
"SHELL:-s EXPORTED_RUNTIME_METHODS=[\'GL\']"
"SHELL:-s GL_PREINITIALIZED_CONTEXT=1"
+ "SHELL:-s GL_ENABLE_GET_PROC_ADDRESS=1" # For Emscripten 3.1.51+
)
set_target_properties( ktx_js PROPERTIES OUTPUT_NAME "libktx")
diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md
index f5183971c2..e78257b2db 100644
--- a/RELEASE_NOTES.md
+++ b/RELEASE_NOTES.md
@@ -2,8 +2,9 @@
Release Notes
=============
-## Version 4.3.0-alpha3
-### New Features
+## Version 4.3.0-beta1
+### New Features in Version 4.3.0
+#### Command Line Tools Suite
v4.3.0 contains a new suite of command line tools accessed via an umbrella `ktx` command.
@@ -11,20 +12,21 @@ v4.3.0 contains a new suite of command line tools accessed via an umbrella `ktx`
| :--- | ----------- | ------------------- |
| `ktx create` | Create a KTX2 file from various input files | `toktx` |
| `ktx extract` | Export selected images from a KTX2 file | - |
-| `ktx encode` | Encode a KTX2 file | `ktxsc` |
+| `ktx encode` | Encode a KTX2 file to a Basis Universal format | `ktxsc` |
| `ktx transcode` | Transcode a KTX2 file | - |
| `ktx info` | Prints information about a KTX2 file | `ktxinfo` |
| `ktx validate` | Validate a KTX2 file | `ktx2check` |
| `ktx help` | Display help information about the ktx tools | - |
-Equivalent old tools will be removed in the next release.
+Equivalent old tools will be removed in a subsequent release soon.
Some features of the old tools are not currently available in the new equivalent.
| Old Tool | New Tool | Missing Features |
| :------: | :------: | ---------------- |
-| `toktx` | `create` | JPEG and NBPM input and scaling/resizing. |
-| `ktxsc` | `encode` | ASTC encoding. This can be done in `create`. |
+| `toktx` | `create` | JPEG and NBPM input and scaling/resizing of input images. |
+| `ktxsc` | `encode` | ASTC encoding of a KTX2 file. This can be done in `create`.
Deflation of a KTX2 file with zlib or zstd.|
+
The command-line syntax and semantics differ from the old tools including, but not limited to:
@@ -43,12 +45,17 @@ The command-line syntax and semantics differ from the old tools including, but n
Please refer to the manual pages or use the `--help` command-line option for further details on the options available and associated semantics for each individual command.
+#### Python Binding
+A Python binding for `libktx` has been added. Applications written in Python can now use `libktx` functions. Huge thanks to @ShukantPal. Please download the appropriate `pyktx` package from Releases as publishing to PyPI is not yet established.
+
### Changes
* `libktx` has been made much more robust to errors KTX files.
-
* `libktx` now validates checksums when present in a Zstd data stream.
* `libktx` has two new error codes it can return: `KTX_DECOMPRESS_LENGTH_ERROR` and `KTX_DECOMPRESS_CHECKSUM_ERROR`.
+* All tools and `libktx` now correctly process on all platforms utf8 file names
+with multi-byte code-points. Previously such names did not work on Windows.
+* The Vulkan texture uploader can now optionally be used with an extenal memory allocator such as [VulkanMemoryAllocator](https://gpuopen.com/vulkan-memory-allocator/).
### Known Issues
@@ -63,6 +70,89 @@ Please refer to the manual pages or use the `--help` command-line option for fur
* Neither the Vulkan nor GL loaders support depth/stencil textures.
+### Changes since v4.3.0-alpha3 (by part)
+### libktx
+
+* git subrepo push lib/dfdutils (ab9c27707) (@MarkCallow)
+
+* Reenable build of loadtest apps on Windows arm64 CI (#802) (6c131f75f) (@MarkCallow)
+
+* Utf-8/unicode support in legacy tools and lib. (#800) (1c5dc9cf6) (@MarkCallow)
+
+* Do not redefine NOMINMAX (#801) (6dbb24643) (@corporateshark)
+
+* libktx: update ktxTexture2\_setImageFromStream to allow setting the entire level's data in one call (#794) (88fc7a6e9) (@AlexRouSg)
+
+* Update dfdutils-included vulkan\_core.h. (#783) (9c223d950) (@MarkCallow)
+
+* Support for A8 and A1B5G5R5 formats (#785) (eeac6206c) (@aqnuep)
+
+* Major non-content documentation fixes. (#773) (e6a6a3be9) (@MarkCallow)
+
+* Fix vendor-specific/tied memory property flag detection (#771) (a10021758) (@toomuchvoltage)
+
+* Return KTX\_NOT\_FOUND when a GPU proc is not found. (#770) (aeca5e695) (@MarkCallow)
+
+* Support for external allocators: (#748) (6856fdb0d) (@toomuchvoltage)
+
+* Fix ktx\_strncasecmp (#741) (1ae04f897) (@VaderY)
+
+* Use correct counter for indexing sample. (#739) (3153e94e8) (@MarkCallow)
+
+### Tools
+
+* Disallow ASTC options when format is not ASTC (#809) (d3ef5ed8b) (@aqnuep)
+
+* Remove unnecessary nullptr checks. (#807) (072a4eb25) (@MarkCallow)
+
+* Set tools and tests rpath on Linux. (#804) (928612a71) (@MarkCallow)
+
+* Utf-8/unicode support in legacy tools and lib. (#800) (1c5dc9cf6) (@MarkCallow)
+
+* Support building of loadtest apps with locally installed dependencies (#799) (84ee59dd2) (@MarkCallow)
+
+* Update dfdutils-included vulkan\_core.h. (#783) (9c223d950) (@MarkCallow)
+
+* Add UTF-8 filename support on Windows to ktxtools (#788) (7b6eab5dc) (@aqnuep)
+
+* Support for A8 and A1B5G5R5 formats (#785) (eeac6206c) (@aqnuep)
+
+* KTXwriterScParams support (#779) (f8691ff05) (@aqnuep)
+
+* Use \-- in doc. to get -- not n-dash in output. (#767) (724790094) (@MarkCallow)
+
+* Document convert\_primaries option in toktx. (#765) (3049f5b5e) (@MarkCallow)
+
+* Do target\_type changes only in toktx (#757) (2cf053c19) (@MarkCallow)
+
+* Add support for fewer components in input files (#755) (adcccf152) (@aqnuep)
+
+* Fix --convert-primaries (#753) (e437ec45f) (@aqnuep)
+
+* Fix legacy app input from pipes on Windows. (#749) (3e7fd0af6) (@MarkCallow)
+
+* Improve output determinism and add internal ktxdiff tool for comparing test outputs (#745) (7f67af7e0) (@VaderY)
+
+* Add KTX\_WERROR config option (#746) (dab32db90) (@MarkCallow)
+
+* Fix incorrect index calculations in image conversions (#735) (682f456de) (@VaderY)
+
+* Color-space and documentation related improvements for ktx create (#732) (8b12216f7) (@VaderY)
+
+
+
+
+
+### Java Wrapper
+
+* Update dfdutils-included vulkan\_core.h. (#783) (9c223d950) (@MarkCallow)
+
+
+
+
+## Version 4.3.0-alpha3
+
+
### Changes since v4.3.0-alpha2 (by part)
### libktx
diff --git a/cmake/version.cmake b/cmake/version.cmake
index f9f20015ed..859fd0e43d 100644
--- a/cmake/version.cmake
+++ b/cmake/version.cmake
@@ -197,7 +197,7 @@ function( create_version_header dest_path target )
endfunction()
function( create_version_file )
- file(WRITE ${PROJECT_BINARY_DIR}/ktx.version "${KTX_VERSION}")
+ file(WRITE ${PROJECT_BINARY_DIR}/ktx.version "${KTX_VERSION_FULL}")
endfunction()
# vim:ai:ts=4:sts=4:sw=2:expandtab:textwidth=70
diff --git a/interface/python_binding/CMakeLists.txt b/interface/python_binding/CMakeLists.txt
index 85d5edf110..b2c4051434 100644
--- a/interface/python_binding/CMakeLists.txt
+++ b/interface/python_binding/CMakeLists.txt
@@ -2,8 +2,9 @@
# SPDX-License-Identifier: Apache-2.0
find_package (Python3 COMPONENTS Interpreter)
-file(GLOB pyktx_py_src ${CMAKE_SOURCE_DIR}/interface/python_binding/pyktx/*.py)
-list(TRANSFORM pyktx_py_src REPLACE "${CMAKE_SOURCE_DIR}/interface/python_binding/pyktx/" "${KTX_BUILD_DIR}/interface/python_binding/docs/pyktx." OUTPUT_VARIABLE pyktx_py_rst_filenames)
+set(SOURCE_DIR ${CMAKE_SOURCE_DIR}/interface/python_binding)
+file(GLOB pyktx_py_src ${SOURCE_DIR}/pyktx/*.py)
+list(TRANSFORM pyktx_py_src REPLACE "${SOURCE_DIR}/pyktx/" "${KTX_BUILD_DIR}/interface/python_binding/docs/pyktx." OUTPUT_VARIABLE pyktx_py_rst_filenames)
list(TRANSFORM pyktx_py_rst_filenames REPLACE ".py$" ".rst" OUTPUT_VARIABLE pyktx_py_rst)
set(PYTHON_EXECUTABLE ${Python3_EXECUTABLE})
@@ -28,7 +29,7 @@ add_custom_target( pyktx-deps ALL
add_custom_command(
TARGET pyktx-deps
COMMAND
- ${PYTHON_EXECUTABLE} -m pip install --no-warn-script-location -r ${CMAKE_SOURCE_DIR}/interface/python_binding/requirements.txt
+ ${PYTHON_EXECUTABLE} -m pip install --no-warn-script-location -r ${SOURCE_DIR}/requirements.txt
COMMENT
"Install dependencies for pyktx build"
)
@@ -37,7 +38,7 @@ add_custom_target( pyktx ALL
DEPENDS
ktx
WORKING_DIRECTORY
- ${CMAKE_SOURCE_DIR}/interface/python_binding
+ ${SOURCE_DIR}
COMMENT
"Python distributions"
)
@@ -51,15 +52,29 @@ add_custom_command(
COMMENT
"Clean up pyktx build artifacts"
WORKING_DIRECTORY
- ${CMAKE_SOURCE_DIR}/interface/python_binding
+ ${SOURCE_DIR}
)
+# Normalize version number as the python toolchain does. Tweaks are reduced
+# to a, b or rc immediately following the patch number. We do because names
+# of the BYPRODUCTS in the following custom_command need to match the
+# names with normalized version numbers the python tools would produce.
+function(normalize_version _var fullver)
+ string(REPLACE -alpha a normalized ${fullver})
+ string(REPLACE -beta b normalized ${normalized})
+ set(${_var} "${normalized}" PARENT_SCOPE)
+endfunction()
+
+normalize_version(KTX_VERSION_NORMALIZED ${KTX_VERSION_FULL})
+set(DIST_DIR ${KTX_BUILD_DIR}/interface/python_binding/dist)
+set(SOURCE_ARCHIVE_BASENAME ${DIST_DIR}/pyktx-${KTX_VERSION_NORMALIZED})
+
add_custom_command(
TARGET
pyktx
BYPRODUCTS
- ${KTX_BUILD_DIR}/interface/python_binding/dist/pyktx-${KTX_VERSION}.tar.gz
- ${KTX_BUILD_DIR}/interface/python_binding/dist/pyktx-${KTX_VERSION}.zip
+ ${SOURCE_ARCHIVE_BASENAME}.tar.gz
+ ${SOURCE_ARCHIVE_BASENAME}.zip
DEPENDS
${pyktx_py_src}
pyktx/ktx_texture.h
@@ -72,10 +87,10 @@ add_custom_command(
${CMAKE_COMMAND} -E env
LIBKTX_INCLUDE_DIR=${CMAKE_SOURCE_DIR}/include
LIBKTX_LIB_DIR=${LIBKTX_LIB_DIR}
- LIBKTX_VERSION=${PROJECT_VERSION}
- ${PYTHON_EXECUTABLE} -m build --sdist --outdir ${KTX_BUILD_DIR}/interface/python_binding/dist
+ LIBKTX_VERSION=${KTX_VERSION_NORMALIZED}
+ ${PYTHON_EXECUTABLE} -m build --sdist --outdir ${DIST_DIR}
WORKING_DIRECTORY
- ${CMAKE_SOURCE_DIR}/interface/python_binding
+ ${SOURCE_DIR}
)
add_custom_command(
@@ -87,18 +102,18 @@ add_custom_command(
${CMAKE_COMMAND} -E env
LIBKTX_INCLUDE_DIR=${CMAKE_SOURCE_DIR}/include
LIBKTX_LIB_DIR=${LIBKTX_LIB_DIR}
- LIBKTX_VERSION=${PROJECT_VERSION}
- ${PYTHON_EXECUTABLE} -m build --wheel --outdir ${KTX_BUILD_DIR}/interface/python_binding/dist
+ LIBKTX_VERSION=${KTX_VERSION_NORMALIZED}
+ ${PYTHON_EXECUTABLE} -m build --wheel --outdir ${DIST_DIR}
WORKING_DIRECTORY
- ${CMAKE_SOURCE_DIR}/interface/python_binding
+ ${SOURCE_DIR}
)
set(pyktx_egg_info
- ${CMAKE_SOURCE_DIR}/interface/python_binding/pyktx.egg-info/dependency_links.txt
- ${CMAKE_SOURCE_DIR}/interface/python_binding/pyktx.egg-info/PKG-INFO
- ${CMAKE_SOURCE_DIR}/interface/python_binding/pyktx.egg-info/requires.txt
- ${CMAKE_SOURCE_DIR}/interface/python_binding/pyktx.egg-info/SOURCES.txt
- ${CMAKE_SOURCE_DIR}/interface/python_binding/pyktx.egg-info/top_level.txt)
+ ${SOURCE_DIR}/pyktx.egg-info/dependency_links.txt
+ ${SOURCE_DIR}/pyktx.egg-info/PKG-INFO
+ ${SOURCE_DIR}/pyktx.egg-info/requires.txt
+ ${SOURCE_DIR}/pyktx.egg-info/SOURCES.txt
+ ${SOURCE_DIR}/pyktx.egg-info/top_level.txt)
add_test(NAME pyktx
COMMAND
@@ -110,7 +125,7 @@ add_test(NAME pyktx
LD_LIBRARY_PATH=${LIBKTX_LIB_DIR}:$ENV{LD_LIBRARY_PATH}
${PYTHON_EXECUTABLE} buildscript.py
WORKING_DIRECTORY
- ${CMAKE_SOURCE_DIR}/interface/python_binding
+ ${SOURCE_DIR}
)
if(KTX_FEATURE_DOC)
@@ -152,6 +167,6 @@ if(KTX_FEATURE_DOC)
SPHINXBUILD=${PYTHON_PATH}\ -m\ sphinx
make SOURCEDIR="${KTX_BUILD_DIR}/interface/python_binding" BUILDDIR="${KTX_BUILD_DIR}/interface/python_binding/docs/html/pyktx" html
WORKING_DIRECTORY
- ${CMAKE_SOURCE_DIR}/interface/python_binding
+ ${SOURCE_DIR}
)
-endif()
\ No newline at end of file
+endif()
diff --git a/interface/python_binding/README.md b/interface/python_binding/README.md
index a0b931b2ce..f3006142f7 100644
--- a/interface/python_binding/README.md
+++ b/interface/python_binding/README.md
@@ -31,5 +31,5 @@ If you are on a POSIX system (macOS or Linux), make sure libktx is on your `DYLD
> ```
> ld: warning: ignoring file '/usr/local/lib/libktx.4.3.0.dylib': found architecture 'arm64', required architecture 'x86_64'
> ```
->
-> 'arm64' and 'x86_64' may be reversed depending on the build machine architecture. This happens because libktx is not a universal binary so only supports the current platform architecture. The message can be ignored.
\ No newline at end of file
+>
+> 'arm64' and 'x86_64' may be reversed depending on the build machine architecture. This happens because libktx is not a universal binary so only supports the current platform architecture. The message can be ignored.
diff --git a/interface/python_binding/buildscript.py b/interface/python_binding/buildscript.py
index 9b7c8e29e3..fb823a0952 100644
--- a/interface/python_binding/buildscript.py
+++ b/interface/python_binding/buildscript.py
@@ -34,7 +34,7 @@
ffibuilder.cdef(
"""
void free(void *ptr);
-
+
typedef struct ktxTexture ktxTexture;
typedef struct ktxTextureCreateInfo ktxTextureCreateInfo;
typedef struct ktxTexture1 ktxTexture1;
@@ -45,13 +45,13 @@
uint32_t error;
ktxTexture* texture;
} ktxTextureMixed;
-
+
typedef struct {
void *bytes;
size_t size;
int error;
} ktxWriteToMemory;
-
+
typedef struct {
size_t offset;
int error;
@@ -80,7 +80,7 @@
int ktxHashList_AddKVPair(ktxHashList *, const char *key, unsigned int valueLen, const void *value);
int ktxHashList_DeleteKVPair(ktxHashList *, const char *key);
ktxHashListEntry *ktxHashList_Next(void *entry);
-
+
// Glue code
ktxTextureMixed PY_ktxTexture_CreateFromNamedFile(const char* const filename,
uint32_t create_flags);
diff --git a/interface/python_binding/pyktx/ktx_astc_params.py b/interface/python_binding/pyktx/ktx_astc_params.py
index 46c760a2dd..fef0a98fb3 100644
--- a/interface/python_binding/pyktx/ktx_astc_params.py
+++ b/interface/python_binding/pyktx/ktx_astc_params.py
@@ -25,7 +25,7 @@ class KtxAstcParams:
mode: KtxPackAstcEncoderMode = KtxPackAstcEncoderMode.DEFAULT
"""Can be {ldr/hdr} from astcenc"""
-
+
quality_level: int = KtxPackAstcQualityLevels.FASTEST
"""astcenc supports -fastest, -fast, -medium, -thorough, -exhaustive"""
@@ -41,16 +41,16 @@ class KtxAstcParams:
perceptual: bool = False
"""
The codec should optimize for perceptual error, instead of direct RMS error.
-
+
This aims to improves perceived image quality, but
typically lowers the measured PSNR score. Perceptual methods are
currently only available for normal maps and RGB color data.
"""
-
+
input_swizzle: bytes = bytes([0, 0, 0, 0])
"""
A swizzle to provide as input to astcenc.
-
+
It must match the regular expression /^[rgba01]{4}$/.
"""
diff --git a/interface/python_binding/pyktx/ktx_basis_params.py b/interface/python_binding/pyktx/ktx_basis_params.py
index 64e1fe4f43..1a883f90c8 100644
--- a/interface/python_binding/pyktx/ktx_basis_params.py
+++ b/interface/python_binding/pyktx/ktx_basis_params.py
@@ -23,8 +23,8 @@ class KtxBasisParams:
compression_level: int = 0
"""
- Encoding speed vs. quality tradeoff. Range is [0,5].
-
+ Encoding speed vs. quality tradeoff. Range is [0,5].
+
Higher values are slower, but give higher quality. There is no default.
Callers must explicitly set this value. Callers can use
KTX_ETC1S_DEFAULT_COMPRESSION_LEVEL as a default value. Currently this is 2.
@@ -35,13 +35,13 @@ class KtxBasisParams:
Compression quality. Range is [1,255].
Lower gives better compression/lower quality/faster.
- Higher gives less compression/higher quality/slower.
+ Higher gives less compression/higher quality/slower.
This automatically determines values for max_endpoints, max_selectors,
endpoint_rdo_threshold, and selector_rdo_threshold for the target quality
level. Setting these parameters overrides the values determined by quality_level
which defaults to 128 if neither it nor both of max_endpoints and max_selectors
have been set.
-
+
Both of max_endpoints and max_selectors must be set for them to have any effect.
quality_level will only determine values for endpoint_rdo_threshold and selector_rdo_threshold
when its value exceeds 128, otherwise their defaults will be used.
@@ -58,7 +58,7 @@ class KtxBasisParams:
endpoint_rdo_threshold: int = 0
"""
Set endpoint RDO quality threshold. The default is 1.25.
-
+
Lower is higher quality but less quality per output bit (try [1.0,3.0].
This will override the value chosen by quality_level.
"""
@@ -66,15 +66,15 @@ class KtxBasisParams:
max_selectors: int = 0
"""
Manually set the max number of color selector clusters. Range is [1,16128].
-
+
Default is 0, unset. If this is set, max_endpoints must also be set, otherwise
the value will be ignored.
"""
-
+
selector_rdo_threshold: int = 0
"""
Set selector RDO quality threshold. The default is 1.5.
-
+
Lower is higher quality but less quality per output bit (try [1.0,3.0]).
This will override the value chosen by @c qualityLevel.
"""
@@ -82,7 +82,7 @@ class KtxBasisParams:
input_swizzle: bytes = bytes(4)
"""
A swizzle to apply before encoding.
-
+
It must match the regular expression /^[rgba01]{4}$/. If both this and
pre_swizzle are specified KtxTexture2.compressBasis() will raise INVALID_OPERATION.
"""
@@ -98,7 +98,7 @@ class KtxBasisParams:
pre_swizzle: bool = False
"""
If the texture has swizzle metadata, apply it before compressing.
-
+
Swizzling, like rabb may yield drastically different error metrics
if done after supercompression.
"""
@@ -106,7 +106,7 @@ class KtxBasisParams:
separate_rg_to_rgb_a: bool = False
"""
This was and is a no-op.
-
+
2-component inputs have always been automatically separated
using an "rrrg" input_swizzle.
"""
@@ -114,21 +114,21 @@ class KtxBasisParams:
no_endpoint_rdo: bool = False
"""
Disable endpoint rate distortion optimizations.
-
+
Slightly faster, less noisy output, but lower quality per output bit.
"""
no_selector_rdo: bool = False
"""
Disable selector rate distortion optimizations.
-
+
Slightly faster, less noisy output, but lower quality per output bit.
"""
uastc_flags: int = KtxPackUastcFlagBits.FASTEST
"""
A set of KtxPackUastcFlagBits controlling UASTC encoding.
-
+
The most important value is the level given in the
least-significant 4 bits which selects a speed vs quality tradeoff.
"""
@@ -139,7 +139,7 @@ class KtxBasisParams:
uastc_rdo_quality_scalar: float = 0.
"""
UASTC RDO quality scalar (lambda).
-
+
Lower values yield higher quality/larger LZ compressed files, higher
values yield lower quality/smaller LZ compressed files. A good range to
try is [.2,4]. Full range is [.001,50.0]. Default is 1.0.
@@ -169,4 +169,4 @@ class KtxBasisParams:
"""Do not favor simpler UASTC modes in RDO mode."""
uastc_rdo_no_multithreading: bool = False
- """Disable RDO multithreading (slightly higher compression, deterministic)."""
\ No newline at end of file
+ """Disable RDO multithreading (slightly higher compression, deterministic)."""
diff --git a/interface/python_binding/pyktx/ktx_error_code.py b/interface/python_binding/pyktx/ktx_error_code.py
index a9d340afce..d70c9fc54e 100644
--- a/interface/python_binding/pyktx/ktx_error_code.py
+++ b/interface/python_binding/pyktx/ktx_error_code.py
@@ -45,7 +45,7 @@ class KtxErrorCode(IntEnum):
NOT_FOUND = 12
"""Requested key was not found"""
-
+
OUT_OF_MEMORY = 13
"""Not enough memory to complete the operation."""
diff --git a/interface/python_binding/pyktx/ktx_pack_astc_encoder_mode.py b/interface/python_binding/pyktx/ktx_pack_astc_encoder_mode.py
index c3435d6064..e306a6c154 100644
--- a/interface/python_binding/pyktx/ktx_pack_astc_encoder_mode.py
+++ b/interface/python_binding/pyktx/ktx_pack_astc_encoder_mode.py
@@ -7,7 +7,7 @@
class KtxPackAstcEncoderMode(IntEnum):
"""
Options specifying ASTC encoder profile mode.
-
+
This and function is used later to derive the profile.
"""
diff --git a/interface/python_binding/pyktx/ktx_pack_uastc_flag_bits.py b/interface/python_binding/pyktx/ktx_pack_uastc_flag_bits.py
index ceea6bea5f..971b8c14c9 100644
--- a/interface/python_binding/pyktx/ktx_pack_uastc_flag_bits.py
+++ b/interface/python_binding/pyktx/ktx_pack_uastc_flag_bits.py
@@ -30,7 +30,7 @@ class KtxPackUastcFlagBits(IntEnum):
FAVOR_UASTC_ERROR = 8
"""Optimize for lowest UASTC error."""
-
+
FAVOR_BC7_ERROR = 16
"""Optimize for lowest BC7 error."""
diff --git a/interface/python_binding/pyktx/ktx_texture.py b/interface/python_binding/pyktx/ktx_texture.py
index 8b531ae142..2da6b15c52 100644
--- a/interface/python_binding/pyktx/ktx_texture.py
+++ b/interface/python_binding/pyktx/ktx_texture.py
@@ -107,7 +107,7 @@ def element_size(self) -> int:
def kv_data_raw(self) -> Optional[c_buffer]:
"""
The raw KV data buffer.
-
+
This is available only if RAW_KVDATA_BIT was used in create-flag bits.
"""
@@ -150,7 +150,7 @@ def row_pitch(self, level: int) -> int:
if necessary. For all currently known compressed formats padding will
not be necessary.
"""
-
+
return lib.ktxTexture_GetRowPitch(self._ptr, level)
def image_size(self, level: int) -> int:
diff --git a/interface/python_binding/pyktx/ktx_texture1.py b/interface/python_binding/pyktx/ktx_texture1.py
index e3182c918c..51f8de91e4 100644
--- a/interface/python_binding/pyktx/ktx_texture1.py
+++ b/interface/python_binding/pyktx/ktx_texture1.py
@@ -56,7 +56,7 @@ def create_from_named_file(filename: str, create_flags: int = KtxTextureCreateFl
def gl_format(self) -> int:
"""
Format of the texture data, e.g. GL_RGB.
-
+
You can find all OpenGL formats here:
"""
return lib.PY_ktxTexture1_get_glFormat(self._ptr)
@@ -85,7 +85,7 @@ def gl_baseinternalformat(self) -> int:
def gl_type(self) -> int:
"""
Type of the texture data, e.g, GL_UNSIGNED_BYTE.
-
+
You can find all OpenGL data types here:
"""
return lib.PY_ktxTexture1_get_glType(self._ptr)
diff --git a/interface/python_binding/pyktx/ktx_texture2.py b/interface/python_binding/pyktx/ktx_texture2.py
index 2619d16a00..c2a6760c00 100644
--- a/interface/python_binding/pyktx/ktx_texture2.py
+++ b/interface/python_binding/pyktx/ktx_texture2.py
@@ -91,7 +91,7 @@ def needs_transcoding(self) -> bool:
def compress_astc(self, params: Union[int, KtxAstcParams]) -> None:
"""
Encode and compress a ktx texture with uncompressed images to ASTC.
-
+
The images are either encoded to ASTC block-compressed format. The
encoded images replace the original images and the texture's fields
including the dfd are modified to reflect the new state.
@@ -197,7 +197,7 @@ def transcode_basis(self, output_format: KtxTranscodeFmt, transcode_flags: int =
PVRTC2_4_RGB, PVRTC2_4_RGBA, ASTC_4x4_RGBA, ETC2_EAC_R11, ETC2_EAC_RG11, ETC and BC1_OR_3.
ETC automatically selects between ETC1_RGB and ETC2_RGBA according to whether an alpha
- channel is available. BC1_OR_3 does likewise between BC1_RGB and BC3_RGBA. Note that if
+ channel is available. BC1_OR_3 does likewise between BC1_RGB and BC3_RGBA. Note that if
PVRTC1_4_RGBA or PVRTC2_4_RGBA is specified and there is no alpha channel PVRTC1_4_RGB
or PVRTC2_4_RGB respectively will be selected.
diff --git a/lib/libktx_mainpage.md b/lib/libktx_mainpage.md
index 135104ad10..3e37f01597 100644
--- a/lib/libktx_mainpage.md
+++ b/lib/libktx_mainpage.md
@@ -86,7 +86,7 @@ result = ktxTexture_CreateFromNamedFile("mytex3d.ktx",
&kTexture);
glGenTextures(1, &texture); // Optional. GLUpload can generate a texture.
result = ktxTexture_GLUpload(kTexture, &texture, &target, &glerror);
-ktxTexture_Destroy(texture);
+ktxTexture_Destroy(kTexture);
// ...
// GL rendering using the texture
// ...
diff --git a/tests/loadtests/CMakeLists.txt b/tests/loadtests/CMakeLists.txt
index 28f85dd6b7..59188a0d87 100644
--- a/tests/loadtests/CMakeLists.txt
+++ b/tests/loadtests/CMakeLists.txt
@@ -18,6 +18,14 @@ if(NOT IOS)
find_package(OpenGL REQUIRED)
endif()
if(KTX_LOADTEST_APPS_USE_LOCAL_DEPENDENCIES)
+ # When using a local SDL2 package installed by brew on macOS, at
+ # least, a mysterious .../lib/$ appears in the library
+ # search paths in the generated project. I've been unable to find
+ # this in the {INTERFACE,}_LINK_DIRECTORIES properties in any of
+ # the SDL2::SDL2 or {gl3,vk}loadtests targets. My guess is the Xcode
+ # generator is adding it. It leads to a harmless warning during
+ # build, harmless because the libraries are referenced by full paths
+ # and the .../lib directory is in the search path of SDL2::SDL2.
find_package(SDL2 REQUIRED)
if(NOT EMSCRIPTEN)
# Tests that require assimp are omitted from loadtests
diff --git a/tools/imageio/imageinput.cc b/tools/imageio/imageinput.cc
index ae46e98893..2541c064e9 100644
--- a/tools/imageio/imageinput.cc
+++ b/tools/imageio/imageinput.cc
@@ -312,12 +312,16 @@ ImageInput::readImage(void* pBuffer, size_t bufferByteCount,
uint32_t subimage, uint32_t miplevel,
const FormatDescriptor& format)
{
+ const auto& targetFormat = format.isUnknown() ? spec().format() : format;
+ size_t outScanlineByteCount
+ = targetFormat.basic.bytesPlane0 * spec().width();
+
uint8_t* pDst = static_cast(pBuffer);
for (uint32_t y = 0; y < spec().height(); y++) {
readScanline(pDst, bufferByteCount,
- y, 0, subimage, miplevel, format);
- pDst += spec().scanlineByteCount();
- bufferByteCount -= spec().scanlineByteCount();
+ y, 0, subimage, miplevel, targetFormat);
+ pDst += outScanlineByteCount;
+ bufferByteCount -= outScanlineByteCount;
}
}
diff --git a/tools/imageio/jpg.imageio/jpginput.cc b/tools/imageio/jpg.imageio/jpginput.cc
index c08ee04f90..eebb243f73 100644
--- a/tools/imageio/jpg.imageio/jpginput.cc
+++ b/tools/imageio/jpg.imageio/jpginput.cc
@@ -362,13 +362,16 @@ void JpegInput::readImage(void* bufferOut, size_t bufferByteCount,
uint subimage, uint miplevel,
const FormatDescriptor& format)
{
- if (bufferByteCount < spec().imageByteCount())
+ const auto& targetFormat = format.isUnknown() ? spec().format() : format;
+ size_t outImageByteCount
+ = targetFormat.basic.bytesPlane0 * spec().width() * spec().height();
+ if (bufferByteCount < outImageByteCount)
throw buffer_too_small();
pJd->begin_decoding();
decodingBegun = true;
ImageInput::readImage(bufferOut, bufferByteCount,
subimage, miplevel,
- format);
+ targetFormat);
}
diff --git a/tools/ktxtools_mainpage.md b/tools/ktxtools_mainpage.md
index d21e8b3bcc..3a6a8588bc 100644
--- a/tools/ktxtools_mainpage.md
+++ b/tools/ktxtools_mainpage.md
@@ -23,14 +23,14 @@ ktx Overview
| @ref ktx_validate | Validate a KTX2 file | `ktx2check` |
| @ref ktx_help | Display help information about the ktx tools | - |
-Equivalent old tools are deprecated and will be removed in the near future.
+Equivalent old tools are deprecated and will be removed soon.
-Some features of old tools are not currently available in their new equivalent.
+Some features of old tools are not currently available in the new equivalent.
| Old Tool | New Tool | Missing Features |
| :------: | :------: | ---------------- |
-| @ref toktx | @ref ktx_create "create" | JPEG and NBPM input and scaling/resizing. |
-| @ref ktxsc | @ref ktx_encode "encode" | ASTC encoding. This can be done in `create`. |
+| @ref toktx | @ref ktx_create "create" | JPEG and NBPM input and scaling/resizing of input images. |
+| @ref ktxsc | @ref ktx_encode "encode" | ASTC encoding. This can be done in `create`.
Deflation of a KTX2 file with zlib or zstd.|
The command-line syntax and semantics differ from the old tools including, but not limited to: